PageRenderTime 101ms CodeModel.GetById 18ms app.highlight 73ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llpanelpicks.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1455 lines | 1120 code | 229 blank | 106 comment | 167 complexity | e0bf79e5530b35058efb8f2667f796dc MD5 | raw file
   1/** 
   2 * @file llpanelpicks.cpp
   3 * @brief LLPanelPicks and related class implementations
   4 *
   5 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28
  29#include "llpanelpicks.h"
  30
  31#include "llagent.h"
  32#include "llagentpicksinfo.h"
  33#include "llavatarconstants.h"
  34#include "llcommandhandler.h"
  35#include "lldispatcher.h"
  36#include "llflatlistview.h"
  37#include "llfloaterreg.h"
  38#include "llfloatersidepanelcontainer.h"
  39#include "llfloaterworldmap.h"
  40#include "llnotificationsutil.h"
  41#include "lltexturectrl.h"
  42#include "lltoggleablemenu.h"
  43#include "lltrans.h"
  44#include "llviewergenericmessage.h"	// send_generic_message
  45#include "llmenugl.h"
  46#include "llviewermenu.h"
  47#include "llregistry.h"
  48
  49#include "llaccordionctrl.h"
  50#include "llaccordionctrltab.h"
  51#include "llavatarpropertiesprocessor.h"
  52#include "llfloatersidepanelcontainer.h"
  53#include "llpanelavatar.h"
  54#include "llpanelprofile.h"
  55#include "llpanelpick.h"
  56#include "llpanelclassified.h"
  57
  58static const std::string XML_BTN_NEW = "new_btn";
  59static const std::string XML_BTN_DELETE = "trash_btn";
  60static const std::string XML_BTN_INFO = "info_btn";
  61static const std::string XML_BTN_TELEPORT = "teleport_btn";
  62static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
  63
  64static const std::string PICK_ID("pick_id");
  65static const std::string PICK_CREATOR_ID("pick_creator_id");
  66static const std::string PICK_NAME("pick_name");
  67
  68static const std::string CLASSIFIED_ID("classified_id");
  69static const std::string CLASSIFIED_NAME("classified_name");
  70
  71
  72static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
  73
  74
  75class LLPickHandler : public LLCommandHandler,
  76					  public LLAvatarPropertiesObserver
  77{
  78public:
  79
  80	std::set<LLUUID> mPickIds;
  81	
  82	// requires trusted browser to trigger
  83	LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
  84
  85	bool handle(const LLSD& params, const LLSD& query_map,
  86		LLMediaCtrl* web)
  87	{
  88		if (!LLUI::sSettingGroups["config"]->getBOOL("EnablePicks"))
  89		{
  90			LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
  91			return true;
  92		}
  93
  94		// handle app/classified/create urls first
  95		if (params.size() == 1 && params[0].asString() == "create")
  96		{
  97			createPick();
  98			return true;
  99		}
 100
 101		// then handle the general app/pick/{UUID}/{CMD} urls
 102		if (params.size() < 2)
 103		{
 104			return false;
 105		}
 106
 107		// get the ID for the pick_id
 108		LLUUID pick_id;
 109		if (!pick_id.set(params[0], FALSE))
 110		{
 111			return false;
 112		}
 113
 114		// edit the pick in the side tray.
 115		// need to ask the server for more info first though...
 116		const std::string verb = params[1].asString();
 117		if (verb == "edit")
 118		{		
 119			mPickIds.insert(pick_id);
 120			LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
 121			LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(gAgent.getID(),pick_id);
 122			return true;
 123		}
 124		else
 125		{
 126			llwarns << "unknown verb " << verb << llendl;
 127			return false;
 128		}
 129	}
 130
 131	void createPick()
 132	{
 133		// open the new pick panel on the Picks floater
 134		LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
 135
 136		LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
 137		if (picks)
 138		{
 139			picks->createNewPick();
 140		}
 141	}
 142
 143	void editPick(LLPickData* pick_info)
 144	{
 145		LLSD params;
 146		params["open_tab_name"] = "panel_picks";
 147		params["show_tab_panel"] = "edit_pick";
 148		params["pick_id"] = pick_info->pick_id;
 149		params["avatar_id"] = pick_info->creator_id;
 150		params["snapshot_id"] = pick_info->snapshot_id;
 151		params["pick_name"] = pick_info->name;
 152		params["pick_desc"] = pick_info->desc;
 153		LLFloaterSidePanelContainer::showPanel("picks", params);
 154	}
 155	
 156	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
 157	{
 158		if (APT_PICK_INFO != type)
 159		{
 160			return;
 161		}
 162
 163		// is this the pick that we asked for?
 164		LLPickData* pick_info = static_cast<LLPickData*>(data);
 165		if (!pick_info || mPickIds.find(pick_info->pick_id) == mPickIds.end())
 166		{
 167			return;
 168		}
 169
 170		// open the edit side tray for this pick
 171		if (pick_info->creator_id == gAgent.getID())
 172		{
 173			editPick(pick_info);
 174		}
 175		else
 176		{
 177			llwarns << "Can't edit a pick you did not create" << llendl;
 178		}
 179
 180		// remove our observer now that we're done
 181		mPickIds.erase(pick_info->pick_id);
 182		LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
 183	}
 184};
 185
 186LLPickHandler gPickHandler;
 187
 188class LLClassifiedHandler :
 189	public LLCommandHandler,
 190	public LLAvatarPropertiesObserver
 191{
 192public:
 193	// throttle calls from untrusted browsers
 194	LLClassifiedHandler() :	LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
 195
 196	std::set<LLUUID> mClassifiedIds;
 197
 198	std::string mRequestVerb;
 199	
 200	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
 201	{
 202		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableClassifieds"))
 203		{
 204			LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
 205			return true;
 206		}
 207
 208		// handle app/classified/create urls first
 209		if (params.size() == 1 && params[0].asString() == "create")
 210		{
 211			createClassified();
 212			return true;
 213		}
 214
 215		// then handle the general app/classified/{UUID}/{CMD} urls
 216		if (params.size() < 2)
 217		{
 218			return false;
 219		}
 220
 221		// get the ID for the classified
 222		LLUUID classified_id;
 223		if (!classified_id.set(params[0], FALSE))
 224		{
 225			return false;
 226		}
 227
 228		// show the classified in the side tray.
 229		// need to ask the server for more info first though...
 230		const std::string verb = params[1].asString();
 231		if (verb == "about")
 232		{
 233			mRequestVerb = verb;
 234			mClassifiedIds.insert(classified_id);
 235			LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
 236			LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
 237			return true;
 238		}
 239		else if (verb == "edit")
 240		{
 241			mRequestVerb = verb;
 242			mClassifiedIds.insert(classified_id);
 243			LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
 244			LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
 245			return true;
 246		}
 247
 248		return false;
 249	}
 250
 251	void createClassified()
 252	{
 253		// open the new classified panel on the Picks floater
 254		LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
 255
 256		LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
 257		if (picks)
 258		{
 259			picks->createNewClassified();
 260		}
 261	}
 262
 263	void openClassified(LLAvatarClassifiedInfo* c_info)
 264	{
 265		if (mRequestVerb == "about")
 266		{
 267			// open the classified info panel on the Me > Picks sidetray
 268			LLSD params;
 269			params["id"] = c_info->creator_id;
 270			params["open_tab_name"] = "panel_picks";
 271			params["show_tab_panel"] = "classified_details";
 272			params["classified_id"] = c_info->classified_id;
 273			params["classified_creator_id"] = c_info->creator_id;
 274			params["classified_snapshot_id"] = c_info->snapshot_id;
 275			params["classified_name"] = c_info->name;
 276			params["classified_desc"] = c_info->description;
 277			params["from_search"] = true;
 278			LLFloaterSidePanelContainer::showPanel("picks", params);
 279		}
 280		else if (mRequestVerb == "edit")
 281		{
 282			if (c_info->creator_id == gAgent.getID())
 283			{
 284				llwarns << "edit in progress" << llendl;
 285				// open the new classified panel on the Me > Picks sidetray
 286				LLSD params;
 287				params["id"] = gAgent.getID();
 288				params["open_tab_name"] = "panel_picks";
 289				params["show_tab_panel"] = "edit_classified";
 290				params["classified_id"] = c_info->classified_id;
 291				LLFloaterSidePanelContainer::showPanel("my_profile", params);
 292			}
 293			else
 294			{
 295				llwarns << "Can't edit a classified you did not create" << llendl;
 296			}
 297		}
 298	}
 299
 300	/*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
 301	{
 302		if (APT_CLASSIFIED_INFO != type)
 303		{
 304			return;
 305		}
 306
 307		// is this the classified that we asked for?
 308		LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
 309		if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
 310		{
 311			return;
 312		}
 313
 314		// open the detail side tray for this classified
 315		openClassified(c_info);
 316
 317		// remove our observer now that we're done
 318		mClassifiedIds.erase(c_info->classified_id);
 319		LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
 320	}
 321
 322};
 323LLClassifiedHandler gClassifiedHandler;
 324
 325//////////////////////////////////////////////////////////////////////////
 326
 327
 328//-----------------------------------------------------------------------------
 329// LLPanelPicks
 330//-----------------------------------------------------------------------------
 331LLPanelPicks::LLPanelPicks()
 332:	LLPanelProfileTab(),
 333	mPopupMenu(NULL),
 334	mProfilePanel(NULL),
 335	mPickPanel(NULL),
 336	mPicksList(NULL),
 337	mClassifiedsList(NULL),
 338	mPanelPickInfo(NULL),
 339	mPanelPickEdit(NULL),
 340	mPlusMenu(NULL),
 341	mPicksAccTab(NULL),
 342	mClassifiedsAccTab(NULL),
 343	mPanelClassifiedInfo(NULL),
 344	mNoClassifieds(false),
 345	mNoPicks(false)
 346{
 347}
 348
 349LLPanelPicks::~LLPanelPicks()
 350{
 351	if(getAvatarId().notNull())
 352	{
 353		LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
 354	}
 355}
 356
 357void* LLPanelPicks::create(void* data /* = NULL */)
 358{
 359	return new LLPanelPicks();
 360}
 361
 362void LLPanelPicks::updateData()
 363{
 364	// Send Picks request only when we need to, not on every onOpen(during tab switch).
 365	if(isDirty())
 366	{
 367		mNoPicks = false;
 368		mNoClassifieds = false;
 369
 370		mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
 371		mNoItemsLabel->setVisible(TRUE);
 372
 373		mPicksList->clear();
 374		LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
 375
 376		mClassifiedsList->clear();
 377		LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
 378	}
 379}
 380
 381void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 382{
 383	if(APT_PICKS == type)
 384	{
 385		LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
 386		if(avatar_picks && getAvatarId() == avatar_picks->target_id)
 387		{
 388			std::string full_name;
 389			gCacheName->getFullName(getAvatarId(), full_name);
 390			getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", full_name);
 391			
 392			// Save selection, to be able to edit same item after saving changes. See EXT-3023.
 393			LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
 394
 395			mPicksList->clear();
 396
 397			LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
 398			for(; avatar_picks->picks_list.end() != it; ++it)
 399			{
 400				LLUUID pick_id = it->first;
 401				std::string pick_name = it->second;
 402
 403				LLPickItem* picture = LLPickItem::create();
 404				picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
 405				picture->setPickName(pick_name);
 406				picture->setPickId(pick_id);
 407				picture->setCreatorId(getAvatarId());
 408
 409				LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
 410				picture->update();
 411
 412				LLSD pick_value = LLSD();
 413				pick_value.insert(PICK_ID, pick_id);
 414				pick_value.insert(PICK_NAME, pick_name);
 415				pick_value.insert(PICK_CREATOR_ID, getAvatarId());
 416
 417				mPicksList->addItem(picture, pick_value);
 418
 419				// Restore selection by item id. 
 420				if ( pick_id == selected_id )
 421					mPicksList->selectItemByValue(pick_value);
 422
 423				picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
 424				picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
 425				picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
 426			}
 427
 428			showAccordion("tab_picks", mPicksList->size());
 429
 430			resetDirty();
 431			updateButtons();
 432		}
 433		
 434		mNoPicks = !mPicksList->size();
 435	}
 436	else if(APT_CLASSIFIEDS == type)
 437	{
 438		LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
 439		if(c_info && getAvatarId() == c_info->target_id)
 440		{
 441			// do not clear classified list in case we will receive two or more data packets.
 442			// list has been cleared in updateData(). (fix for EXT-6436)
 443
 444			LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
 445			for(; c_info->classifieds_list.end() != it; ++it)
 446			{
 447				LLAvatarClassifieds::classified_data c_data = *it;
 448
 449				LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
 450				c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
 451				c_item->setClassifiedName(c_data.name);
 452
 453				LLSD pick_value = LLSD();
 454				pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
 455				pick_value.insert(CLASSIFIED_NAME, c_data.name);
 456
 457				if (!findClassifiedById(c_data.classified_id))
 458				{
 459					mClassifiedsList->addItem(c_item, pick_value);
 460				}
 461
 462				c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
 463				c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
 464				c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
 465			}
 466
 467			showAccordion("tab_classifieds", mClassifiedsList->size());
 468
 469			resetDirty();
 470			updateButtons();
 471		}
 472		
 473		mNoClassifieds = !mClassifiedsList->size();
 474	}
 475
 476	bool no_data = mNoPicks && mNoClassifieds;
 477	mNoItemsLabel->setVisible(no_data);
 478	if (no_data)
 479	{
 480		if(getAvatarId() == gAgentID)
 481		{
 482			mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
 483		}
 484		else
 485		{
 486			mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
 487		}
 488	}
 489}
 490
 491LLPickItem* LLPanelPicks::getSelectedPickItem()
 492{
 493	LLPanel* selected_item = mPicksList->getSelectedItem();
 494	if (!selected_item) return NULL;
 495
 496	return dynamic_cast<LLPickItem*>(selected_item);
 497}
 498
 499LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem()
 500{
 501	LLPanel* selected_item = mClassifiedsList->getSelectedItem();
 502	if (!selected_item) 
 503	{
 504		return NULL;
 505	}
 506	return dynamic_cast<LLClassifiedItem*>(selected_item);
 507}
 508
 509BOOL LLPanelPicks::postBuild()
 510{
 511	mPicksList = getChild<LLFlatListView>("picks_list");
 512	mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
 513
 514	mPicksList->setCommitOnSelectionChange(true);
 515	mClassifiedsList->setCommitOnSelectionChange(true);
 516
 517	mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList));
 518	mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList));
 519
 520	mPicksList->setNoItemsCommentText(getString("no_picks"));
 521	mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
 522
 523	mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
 524
 525	childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
 526	childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
 527	childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
 528	childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this));
 529	childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this));
 530
 531	mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks");
 532	mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab));
 533	mPicksAccTab->setDisplayChildren(true);
 534
 535	mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds");
 536	mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab));
 537	mClassifiedsAccTab->setDisplayChildren(false);
 538	
 539	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
 540	registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
 541	registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this)); 
 542	registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
 543	registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
 544	registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
 545	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar;
 546	enable_registar.add("Pick.Enable", boost::bind(&LLPanelPicks::onEnableMenuItem, this, _2));
 547
 548	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 549
 550	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar;
 551	plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2));
 552	mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelPicks::isActionEnabled, this, _2));
 553	mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 554	
 555	return TRUE;
 556}
 557
 558void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param)
 559{
 560	std::string value = param.asString();
 561
 562	if("new_pick" == value)
 563	{
 564		createNewPick();
 565	}
 566	else if("new_classified" == value)
 567	{
 568		createNewClassified();
 569	}
 570}
 571
 572bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const
 573{
 574	std::string command_name = userdata.asString();
 575
 576	if (command_name == "new_pick" && LLAgentPicksInfo::getInstance()->isPickLimitReached())
 577	{
 578		return false;
 579	}
 580
 581	return true;
 582}
 583
 584bool LLPanelPicks::isClassifiedPublished(LLClassifiedItem* c_item)
 585{
 586	if(c_item)
 587	{
 588		LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
 589		if(panel)
 590		{
 591			 return !panel->isNewWithErrors();
 592		}
 593
 594		// we've got this classified from server - it's published
 595		return true;
 596	}
 597	return false;
 598}
 599
 600void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
 601{
 602	if(!mPicksAccTab->getDisplayChildren())
 603	{
 604		mPicksList->resetSelection(true);
 605	}
 606	if(!mClassifiedsAccTab->getDisplayChildren())
 607	{
 608		mClassifiedsList->resetSelection(true);
 609	}
 610
 611	updateButtons();
 612}
 613
 614void LLPanelPicks::onOpen(const LLSD& key)
 615{
 616	const LLUUID id(key.asUUID());
 617	BOOL self = (gAgent.getID() == id);
 618
 619	// only agent can edit her picks 
 620	getChildView("edit_panel")->setEnabled(self);
 621	getChildView("edit_panel")->setVisible( self);
 622
 623	// Disable buttons when viewing profile for first time
 624	if(getAvatarId() != id)
 625	{
 626		getChildView(XML_BTN_INFO)->setEnabled(FALSE);
 627		getChildView(XML_BTN_TELEPORT)->setEnabled(FALSE);
 628		getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(FALSE);
 629	}
 630
 631	// and see a special title - set as invisible by default in xml file
 632	if (self)
 633	{
 634		getChildView("pick_title")->setVisible( !self);
 635		getChildView("pick_title_agent")->setVisible( self);
 636
 637		mPopupMenu->setItemVisible("pick_delete", TRUE);
 638		mPopupMenu->setItemVisible("pick_edit", TRUE);
 639		mPopupMenu->setItemVisible("pick_separator", TRUE);
 640	}
 641
 642	if(getAvatarId() != id)
 643	{
 644		showAccordion("tab_picks", false);
 645		showAccordion("tab_classifieds", false);
 646
 647		mPicksList->goToTop();
 648		// Set dummy value to make panel dirty and make it reload picks
 649		setValue(LLSD());
 650	}
 651
 652	LLPanelProfileTab::onOpen(key);
 653}
 654
 655void LLPanelPicks::onClosePanel()
 656{
 657	if (mPanelClassifiedInfo)
 658	{
 659		onPanelClassifiedClose(mPanelClassifiedInfo);
 660	}
 661	if (mPanelPickInfo)
 662	{
 663		onPanelPickClose(mPanelPickInfo);
 664	}
 665}
 666
 667void LLPanelPicks::onListCommit(const LLFlatListView* f_list)
 668{
 669	// Make sure only one of the lists has selection.
 670	if(f_list == mPicksList)
 671	{
 672		mClassifiedsList->resetSelection(true);
 673	}
 674	else if(f_list == mClassifiedsList)
 675	{
 676		mPicksList->resetSelection(true);
 677	}
 678	else
 679	{
 680		llwarns << "Unknown list" << llendl;
 681	}
 682
 683	updateButtons();
 684}
 685
 686//static
 687void LLPanelPicks::onClickDelete()
 688{
 689	LLSD value = mPicksList->getSelectedValue();
 690	if (value.isDefined())
 691	{
 692		LLSD args; 
 693		args["PICK"] = value[PICK_NAME]; 
 694		LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2)); 
 695		return;
 696	}
 697
 698	value = mClassifiedsList->getSelectedValue();
 699	if(value.isDefined())
 700	{
 701		LLSD args; 
 702		args["NAME"] = value[CLASSIFIED_NAME]; 
 703		LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2)); 
 704		return;
 705	}
 706}
 707
 708bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response) 
 709{
 710	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 711	LLSD pick_value = mPicksList->getSelectedValue();
 712
 713	if (0 == option)
 714	{
 715		LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
 716		mPicksList->removeItemByValue(pick_value);
 717	}
 718	updateButtons();
 719	return false;
 720}
 721
 722bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response) 
 723{
 724	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 725	LLSD value = mClassifiedsList->getSelectedValue();
 726
 727	if (0 == option)
 728	{
 729		LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
 730		mClassifiedsList->removeItemByValue(value);
 731	}
 732	updateButtons();
 733	return false;
 734}
 735
 736bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
 737{
 738	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 739
 740	if (0 == option)
 741	{
 742		onClickTeleport();
 743	}
 744	return false;
 745}
 746
 747//static
 748void LLPanelPicks::onClickTeleport()
 749{
 750	LLPickItem* pick_item = getSelectedPickItem();
 751	LLClassifiedItem* c_item = getSelectedClassifiedItem();
 752
 753	LLVector3d pos;
 754	if(pick_item)
 755		pos = pick_item->getPosGlobal();
 756	else if(c_item)
 757	{
 758		pos = c_item->getPosGlobal();
 759		LLPanelClassifiedInfo::sendClickMessage("teleport", false,
 760			c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
 761	}
 762
 763	if (!pos.isExactlyZero())
 764	{
 765		gAgent.teleportViaLocation(pos);
 766		LLFloaterWorldMap::getInstance()->trackLocation(pos);
 767	}
 768}
 769
 770//static
 771void LLPanelPicks::onClickMap()
 772{
 773	LLPickItem* pick_item = getSelectedPickItem();
 774	LLClassifiedItem* c_item = getSelectedClassifiedItem();
 775
 776	LLVector3d pos;
 777	if (pick_item)
 778		pos = pick_item->getPosGlobal();
 779	else if(c_item)
 780	{
 781		LLPanelClassifiedInfo::sendClickMessage("map", false,
 782			c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
 783		pos = c_item->getPosGlobal();
 784	}
 785
 786	LLFloaterWorldMap::getInstance()->trackLocation(pos);
 787	LLFloaterReg::showInstance("world_map", "center");
 788}
 789
 790
 791void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
 792{
 793	updateButtons();
 794
 795	if (mPopupMenu)
 796	{
 797		mPopupMenu->buildDrawLabels();
 798		mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
 799		((LLContextMenu*)mPopupMenu)->show(x, y);
 800		LLMenuGL::showPopup(item, mPopupMenu, x, y);
 801	}
 802}
 803
 804void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item)
 805{
 806	LLSD pick_value = mPicksList->getSelectedValue();
 807	if (pick_value.isUndefined()) return;
 808	
 809	LLSD args; 
 810	args["PICK"] = pick_value[PICK_NAME]; 
 811	LLNotificationsUtil::add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); 
 812}
 813
 814void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item)
 815{
 816	LLSD value = mClassifiedsList->getSelectedValue();
 817	if (value.isUndefined()) return;
 818
 819	LLSD args; 
 820	args["CLASSIFIED"] = value[CLASSIFIED_NAME]; 
 821	LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); 
 822}
 823
 824void LLPanelPicks::updateButtons()
 825{
 826	bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0;
 827
 828	if (getAvatarId() == gAgentID)
 829	{
 830		getChildView(XML_BTN_DELETE)->setEnabled(has_selected);
 831	}
 832
 833	getChildView(XML_BTN_INFO)->setEnabled(has_selected);
 834	getChildView(XML_BTN_TELEPORT)->setEnabled(has_selected);
 835	getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(has_selected);
 836
 837	LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
 838	if(c_item)
 839	{
 840		getChildView(XML_BTN_INFO)->setEnabled(isClassifiedPublished(c_item));
 841	}
 842}
 843
 844void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
 845{
 846	mProfilePanel = profile_panel;
 847}
 848
 849
 850void LLPanelPicks::buildPickPanel()
 851{
 852// 	if (mPickPanel == NULL)
 853// 	{
 854// 		mPickPanel = new LLPanelPick();
 855// 		mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL));
 856// 	}
 857}
 858
 859void LLPanelPicks::onClickPlusBtn()
 860{
 861	LLRect rect(getChildView(XML_BTN_NEW)->getRect());
 862
 863	mPlusMenu->updateParent(LLMenuGL::sMenuContainer);
 864	mPlusMenu->setButtonRect(rect, this);
 865	LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop);
 866}
 867
 868void LLPanelPicks::createNewPick()
 869{
 870	createPickEditPanel();
 871
 872	getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
 873}
 874
 875void LLPanelPicks::createNewClassified()
 876{
 877	LLPanelClassifiedEdit* panel = NULL;
 878	createClassifiedEditPanel(&panel);
 879
 880	getProfilePanel()->openPanel(panel, LLSD());
 881}
 882
 883void LLPanelPicks::onClickInfo()
 884{
 885	if(mPicksList->numSelected() > 0)
 886	{
 887		openPickInfo();
 888	}
 889	else if(mClassifiedsList->numSelected() > 0)
 890	{
 891		openClassifiedInfo();
 892	}
 893}
 894
 895void LLPanelPicks::openPickInfo()
 896{
 897	LLSD selected_value = mPicksList->getSelectedValue();
 898	if (selected_value.isUndefined()) return;
 899
 900	LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem();
 901
 902	createPickInfoPanel();
 903
 904	LLSD params;
 905	params["pick_id"] = pick->getPickId();
 906	params["avatar_id"] = pick->getCreatorId();
 907	params["snapshot_id"] = pick->getSnapshotId();
 908	params["pick_name"] = pick->getPickName();
 909	params["pick_desc"] = pick->getPickDesc();
 910
 911	getProfilePanel()->openPanel(mPanelPickInfo, params);
 912}
 913
 914void LLPanelPicks::openClassifiedInfo()
 915{
 916	LLSD selected_value = mClassifiedsList->getSelectedValue();
 917	if (selected_value.isUndefined()) return;
 918
 919	LLClassifiedItem* c_item = getSelectedClassifiedItem();
 920	LLSD params;
 921	params["classified_id"] = c_item->getClassifiedId();
 922	params["classified_creator_id"] = c_item->getAvatarId();
 923	params["classified_snapshot_id"] = c_item->getSnapshotId();
 924	params["classified_name"] = c_item->getClassifiedName();
 925	params["classified_desc"] = c_item->getDescription();
 926	params["from_search"] = false;
 927
 928	openClassifiedInfo(params);
 929}
 930
 931void LLPanelPicks::openClassifiedInfo(const LLSD &params)
 932{
 933	createClassifiedInfoPanel();
 934	getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
 935}
 936
 937void LLPanelPicks::openClassifiedEdit(const LLSD& params)
 938{
 939	LLUUID classified_id = params["classified_id"].asUUID();;
 940	llinfos << "opening classified " << classified_id << " for edit" << llendl;
 941	editClassified(classified_id);
 942}
 943
 944void LLPanelPicks::showAccordion(const std::string& name, bool show)
 945{
 946	LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
 947	tab->setVisible(show);
 948	LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
 949	acc->arrange();
 950}
 951
 952void LLPanelPicks::onPanelPickClose(LLPanel* panel)
 953{
 954	getProfilePanel()->closePanel(panel);
 955}
 956
 957void LLPanelPicks::onPanelPickSave(LLPanel* panel)
 958{
 959	onPanelPickClose(panel);
 960	updateButtons();
 961}
 962
 963void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
 964{
 965	if(!panel->canClose())
 966	{
 967		return;
 968	}
 969
 970	if(panel->isNew())
 971	{
 972		mEditClassifiedPanels[panel->getClassifiedId()] = panel;
 973
 974		LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
 975		c_item->fillIn(panel);
 976
 977		LLSD c_value;
 978		c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
 979		c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
 980		mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
 981
 982		c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
 983		c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
 984		c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
 985		c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
 986
 987		// order does matter, showAccordion will invoke arrange for accordions.
 988		mClassifiedsAccTab->changeOpenClose(false);
 989		showAccordion("tab_classifieds", true);
 990	}
 991	else if(panel->isNewWithErrors())
 992	{
 993		LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
 994		llassert(c_item);
 995		if (c_item)
 996		{
 997			c_item->fillIn(panel);
 998		}
 999	}
1000	else 
1001	{
1002		onPanelClassifiedClose(panel);
1003		return;
1004	}
1005
1006	onPanelPickClose(panel);
1007	updateButtons();
1008}
1009
1010void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
1011{
1012	if(panel->getInfoLoaded() && !panel->isDirty())
1013	{
1014		std::vector<LLSD> values;
1015		mClassifiedsList->getValues(values);
1016		for(size_t n = 0; n < values.size(); ++n)
1017		{
1018			LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
1019			if(panel->getClassifiedId() == c_id)
1020			{
1021				LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(
1022					mClassifiedsList->getItemByValue(values[n]));
1023				llassert(c_item);
1024				if (c_item)
1025				{
1026					c_item->setClassifiedName(panel->getClassifiedName());
1027					c_item->setDescription(panel->getDescription());
1028					c_item->setSnapshotId(panel->getSnapshotId());
1029				}
1030			}
1031		}
1032	}
1033
1034	onPanelPickClose(panel);
1035	updateButtons();
1036}
1037
1038void LLPanelPicks::createPickInfoPanel()
1039{
1040	if(!mPanelPickInfo)
1041	{
1042		mPanelPickInfo = LLPanelPickInfo::create();
1043		mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
1044		mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
1045		mPanelPickInfo->setVisible(FALSE);
1046	}
1047}
1048
1049void LLPanelPicks::createClassifiedInfoPanel()
1050{
1051	mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
1052	mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
1053	mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this));
1054	mPanelClassifiedInfo->setVisible(FALSE);
1055}
1056
1057void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel)
1058{
1059	if(panel)
1060	{
1061		LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create();
1062		new_panel->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
1063		new_panel->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, new_panel));
1064		new_panel->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
1065		new_panel->setVisible(FALSE);
1066		*panel = new_panel;
1067	}
1068}
1069
1070void LLPanelPicks::createPickEditPanel()
1071{
1072	mPanelPickEdit = LLPanelPickEdit::create();
1073	mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
1074	mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit));
1075	mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
1076	mPanelPickEdit->setVisible(FALSE);
1077}
1078
1079// void LLPanelPicks::openPickEditPanel(LLPickItem* pick)
1080// {
1081// 	if(!pick)
1082// 	{
1083// 		return;
1084// 	}
1085// }
1086
1087// void LLPanelPicks::openPickInfoPanel(LLPickItem* pick)
1088// {
1089// 	if(!mPanelPickInfo)
1090// 	{
1091// 		mPanelPickInfo = LLPanelPickInfo::create();
1092// 		mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
1093// 		mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
1094// 		mPanelPickInfo->setVisible(FALSE);
1095// 	}
1096// 
1097// 	LLSD params;
1098// 	params["pick_id"] = pick->getPickId();
1099// 	params["avatar_id"] = pick->getCreatorId();
1100// 	params["snapshot_id"] = pick->getSnapshotId();
1101// 	params["pick_name"] = pick->getPickName();
1102// 	params["pick_desc"] = pick->getPickDesc();
1103// 
1104// 	getProfilePanel()->openPanel(mPanelPickInfo, params);
1105// }
1106
1107void LLPanelPicks::openPickEdit(const LLSD& params)
1108{
1109	createPickEditPanel();
1110	getProfilePanel()->openPanel(mPanelPickEdit, params);
1111}
1112
1113void LLPanelPicks::onPanelPickEdit()
1114{
1115	LLSD selected_value = mPicksList->getSelectedValue();
1116	if (selected_value.isUndefined()) return;
1117
1118	LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
1119	
1120	createPickEditPanel();
1121
1122	LLSD params;
1123	params["pick_id"] = pick->getPickId();
1124	params["avatar_id"] = pick->getCreatorId();
1125	params["snapshot_id"] = pick->getSnapshotId();
1126	params["pick_name"] = pick->getPickName();
1127	params["pick_desc"] = pick->getPickDesc();
1128
1129	getProfilePanel()->openPanel(mPanelPickEdit, params);
1130}
1131
1132void LLPanelPicks::onPanelClassifiedEdit()
1133{
1134	LLSD selected_value = mClassifiedsList->getSelectedValue();
1135	if (selected_value.isUndefined()) 
1136	{
1137		return;
1138	}
1139
1140	LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
1141	llassert(c_item);
1142	if (!c_item)
1143	{
1144		return;
1145	}
1146	editClassified(c_item->getClassifiedId());
1147}
1148
1149LLClassifiedItem *LLPanelPicks::findClassifiedById(const LLUUID& classified_id)
1150{
1151	// HACK - find item by classified id.  Should be a better way.
1152	std::vector<LLPanel*> items;
1153	mClassifiedsList->getItems(items);
1154	LLClassifiedItem* c_item = NULL;
1155	for(std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
1156	{
1157		LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(*it);
1158		if (test_item && test_item->getClassifiedId() == classified_id)
1159		{
1160			c_item = test_item;
1161			break;
1162		}
1163	}
1164	return c_item;
1165}
1166
1167void LLPanelPicks::editClassified(const LLUUID&  classified_id)
1168{
1169	LLClassifiedItem* c_item = findClassifiedById(classified_id);
1170	if (!c_item)
1171	{
1172		llwarns << "item not found for classified_id " << classified_id << llendl;
1173		return;
1174	}
1175
1176	LLSD params;
1177	params["classified_id"] = c_item->getClassifiedId();
1178	params["classified_creator_id"] = c_item->getAvatarId();
1179	params["snapshot_id"] = c_item->getSnapshotId();
1180	params["name"] = c_item->getClassifiedName();
1181	params["desc"] = c_item->getDescription();
1182	params["category"] = (S32)c_item->getCategory();
1183	params["content_type"] = (S32)c_item->getContentType();
1184	params["auto_renew"] = c_item->getAutoRenew();
1185	params["price_for_listing"] = c_item->getPriceForListing();
1186	params["location_text"] = c_item->getLocationText();
1187
1188	LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
1189	if(!panel)
1190	{
1191		createClassifiedEditPanel(&panel);
1192		mEditClassifiedPanels[c_item->getClassifiedId()] = panel;
1193	}
1194	getProfilePanel()->openPanel(panel, params);
1195	panel->setPosGlobal(c_item->getPosGlobal());
1196}
1197
1198void LLPanelPicks::onClickMenuEdit()
1199{
1200	if(getSelectedPickItem())
1201	{
1202		onPanelPickEdit();
1203	}
1204	else if(getSelectedClassifiedItem())
1205	{
1206		onPanelClassifiedEdit();
1207	}
1208}
1209
1210bool LLPanelPicks::onEnableMenuItem(const LLSD& user_data)
1211{
1212	std::string param = user_data.asString();
1213
1214	LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
1215	if(c_item && "info" == param)
1216	{
1217		// dont show Info panel if classified was not created
1218		return isClassifiedPublished(c_item);
1219	}
1220
1221	return true;
1222}
1223
1224inline LLPanelProfile* LLPanelPicks::getProfilePanel()
1225{
1226	llassert_always(NULL != mProfilePanel);
1227	return mProfilePanel;
1228}
1229
1230//-----------------------------------------------------------------------------
1231// LLPanelPicks
1232//-----------------------------------------------------------------------------
1233LLPickItem::LLPickItem()
1234: LLPanel()
1235, mPickID(LLUUID::null)
1236, mCreatorID(LLUUID::null)
1237, mParcelID(LLUUID::null)
1238, mSnapshotID(LLUUID::null)
1239, mNeedData(true)
1240{
1241	buildFromFile("panel_pick_list_item.xml");
1242}
1243
1244LLPickItem::~LLPickItem()
1245{
1246	if (mCreatorID.notNull())
1247	{
1248		LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
1249	}
1250
1251}
1252
1253LLPickItem* LLPickItem::create()
1254{
1255	return new LLPickItem();
1256}
1257
1258void LLPickItem::init(LLPickData* pick_data)
1259{
1260	setPickDesc(pick_data->desc);
1261	setSnapshotId(pick_data->snapshot_id);
1262	mPosGlobal = pick_data->pos_global;
1263	mSimName = pick_data->sim_name;
1264	mPickDescription = pick_data->desc;
1265	mUserName = pick_data->user_name;
1266	mOriginalName = pick_data->original_name;
1267
1268	LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
1269	picture->setImageAssetID(pick_data->snapshot_id);
1270}
1271
1272void LLPickItem::setPickName(const std::string& name)
1273{
1274	mPickName = name;
1275	getChild<LLUICtrl>("picture_name")->setValue(name);
1276
1277}
1278
1279const std::string& LLPickItem::getPickName()
1280{
1281	return mPickName;
1282}
1283
1284const LLUUID& LLPickItem::getCreatorId()
1285{
1286	return mCreatorID;
1287}
1288
1289const LLUUID& LLPickItem::getSnapshotId()
1290{
1291	return mSnapshotID;
1292}
1293
1294void LLPickItem::setPickDesc(const std::string& descr)
1295{
1296	getChild<LLUICtrl>("picture_descr")->setValue(descr);
1297}
1298
1299void LLPickItem::setPickId(const LLUUID& id)
1300{
1301	mPickID = id;
1302}
1303
1304const LLUUID& LLPickItem::getPickId()
1305{
1306	return mPickID;
1307}
1308
1309const LLVector3d& LLPickItem::getPosGlobal()
1310{
1311	return mPosGlobal;
1312}
1313
1314const std::string LLPickItem::getDescription()
1315{
1316	return getChild<LLUICtrl>("picture_descr")->getValue().asString();
1317}
1318
1319void LLPickItem::update()
1320{
1321	setNeedData(true);
1322	LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID);
1323}
1324
1325void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
1326{
1327	if (APT_PICK_INFO != type) 
1328	{
1329		return;
1330	}
1331
1332	LLPickData* pick_data = static_cast<LLPickData *>(data);
1333	if (!pick_data || mPickID != pick_data->pick_id) 
1334	{
1335		return;
1336	}
1337
1338	init(pick_data);
1339	setNeedData(false);
1340	LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
1341}
1342
1343void set_child_visible(LLView* parent, const std::string& child_name, bool visible)
1344{
1345	parent->getChildView(child_name)->setVisible(visible);
1346}
1347
1348BOOL LLPickItem::postBuild()
1349{
1350	setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
1351	setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
1352	return TRUE;
1353}
1354
1355void LLPickItem::setValue(const LLSD& value)
1356{
1357	if (!value.isMap()) return;;
1358	if (!value.has("selected")) return;
1359	getChildView("selected_icon")->setVisible( value["selected"]);
1360}
1361
1362//////////////////////////////////////////////////////////////////////////
1363//////////////////////////////////////////////////////////////////////////
1364//////////////////////////////////////////////////////////////////////////
1365
1366LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
1367 : LLPanel()
1368 , mAvatarId(avatar_id)
1369 , mClassifiedId(classified_id)
1370{
1371	buildFromFile("panel_classifieds_list_item.xml");
1372
1373	LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
1374	LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
1375}
1376
1377LLClassifiedItem::~LLClassifiedItem()
1378{
1379	LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
1380}
1381
1382void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
1383{
1384	if(APT_CLASSIFIED_INFO != type)
1385	{
1386		return;
1387	}
1388
1389	LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
1390	if( !c_info || c_info->classified_id != getClassifiedId() )
1391	{
1392		return;
1393	}
1394
1395	setClassifiedName(c_info->name);
1396	setDescription(c_info->description);
1397	setSnapshotId(c_info->snapshot_id);
1398	setPosGlobal(c_info->pos_global);
1399
1400	LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
1401}
1402
1403BOOL LLClassifiedItem::postBuild()
1404{
1405	setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
1406	setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
1407	return TRUE;
1408}
1409
1410void LLClassifiedItem::setValue(const LLSD& value)
1411{
1412	if (!value.isMap()) return;;
1413	if (!value.has("selected")) return;
1414	getChildView("selected_icon")->setVisible( value["selected"]);
1415}
1416
1417void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel)
1418{
1419	if(!panel)
1420	{
1421		return;
1422	}
1423
1424	setClassifiedName(panel->getClassifiedName());
1425	setDescription(panel->getDescription());
1426	setSnapshotId(panel->getSnapshotId());
1427	setCategory(panel->getCategory());
1428	setContentType(panel->getContentType());
1429	setAutoRenew(panel->getAutoRenew());
1430	setPriceForListing(panel->getPriceForListing());
1431	setPosGlobal(panel->getPosGlobal());
1432	setLocationText(panel->getClassifiedLocation());
1433}
1434
1435void LLClassifiedItem::setClassifiedName(const std::string& name)
1436{
1437	getChild<LLUICtrl>("name")->setValue(name);
1438}
1439
1440void LLClassifiedItem::setDescription(const std::string& desc)
1441{
1442	getChild<LLUICtrl>("description")->setValue(desc);
1443}
1444
1445void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
1446{
1447	getChild<LLUICtrl>("picture")->setValue(snapshot_id);
1448}
1449
1450LLUUID LLClassifiedItem::getSnapshotId()
1451{
1452	return getChild<LLUICtrl>("picture")->getValue();
1453}
1454
1455//EOF