llpanelpicks.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:33k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llpanelpicks.cpp
  3.  * @brief LLPanelPicks and related class implementations
  4.  *
  5.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2009-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llpanelpicks.h"
  34. #include "llagent.h"
  35. #include "llagentpicksinfo.h"
  36. #include "llavatarconstants.h"
  37. #include "llcommandhandler.h"
  38. #include "lldispatcher.h"
  39. #include "llflatlistview.h"
  40. #include "llfloaterreg.h"
  41. #include "llfloaterworldmap.h"
  42. #include "llnotificationsutil.h"
  43. #include "lltexturectrl.h"
  44. #include "lltoggleablemenu.h"
  45. #include "lltrans.h"
  46. #include "llviewergenericmessage.h" // send_generic_message
  47. #include "llmenugl.h"
  48. #include "llviewermenu.h"
  49. #include "llregistry.h"
  50. #include "llaccordionctrl.h"
  51. #include "llaccordionctrltab.h"
  52. #include "llavatarpropertiesprocessor.h"
  53. #include "llpanelavatar.h"
  54. #include "llpanelprofile.h"
  55. #include "llpanelpick.h"
  56. #include "llpanelclassified.h"
  57. #include "llsidetray.h"
  58. static const std::string XML_BTN_NEW = "new_btn";
  59. static const std::string XML_BTN_DELETE = "trash_btn";
  60. static const std::string XML_BTN_INFO = "info_btn";
  61. static const std::string XML_BTN_TELEPORT = "teleport_btn";
  62. static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
  63. static const std::string PICK_ID("pick_id");
  64. static const std::string PICK_CREATOR_ID("pick_creator_id");
  65. static const std::string PICK_NAME("pick_name");
  66. static const std::string CLASSIFIED_ID("classified_id");
  67. static const std::string CLASSIFIED_NAME("classified_name");
  68. static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
  69. class LLClassifiedHandler :
  70. public LLCommandHandler,
  71. public LLAvatarPropertiesObserver
  72. {
  73. public:
  74. // throttle calls from untrusted browsers
  75. LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
  76. std::set<LLUUID> mClassifiedIds;
  77. bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
  78. {
  79. // handle app/classified/create urls first
  80. if (params.size() == 1 && params[0].asString() == "create")
  81. {
  82. createClassified();
  83. return true;
  84. }
  85. // then handle the general app/classified/{UUID}/{CMD} urls
  86. if (params.size() < 2)
  87. {
  88. return false;
  89. }
  90. // get the ID for the classified
  91. LLUUID classified_id;
  92. if (!classified_id.set(params[0], FALSE))
  93. {
  94. return false;
  95. }
  96. // show the classified in the side tray.
  97. // need to ask the server for more info first though...
  98. const std::string verb = params[1].asString();
  99. if (verb == "about")
  100. {
  101. mClassifiedIds.insert(classified_id);
  102. LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
  103. LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
  104. return true;
  105. }
  106. return false;
  107. }
  108. void createClassified()
  109. {
  110. // open the new classified panel on the Me > Picks sidetray
  111. LLSD params;
  112. params["id"] = gAgent.getID();
  113. params["open_tab_name"] = "panel_picks";
  114. params["show_tab_panel"] = "create_classified";
  115. LLSideTray::getInstance()->showPanel("panel_me", params);
  116. }
  117. void openClassified(LLAvatarClassifiedInfo* c_info)
  118. {
  119. // open the classified info panel on the Me > Picks sidetray
  120. LLSD params;
  121. params["id"] = c_info->creator_id;
  122. params["open_tab_name"] = "panel_picks";
  123. params["show_tab_panel"] = "classified_details";
  124. params["classified_id"] = c_info->classified_id;
  125. params["classified_avatar_id"] = c_info->creator_id;
  126. params["classified_snapshot_id"] = c_info->snapshot_id;
  127. params["classified_name"] = c_info->name;
  128. params["classified_desc"] = c_info->description;
  129. LLSideTray::getInstance()->showPanel("panel_profile_view", params);
  130. }
  131. /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
  132. {
  133. if (APT_CLASSIFIED_INFO != type)
  134. {
  135. return;
  136. }
  137. // is this the classified that we asked for?
  138. LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
  139. if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
  140. {
  141. return;
  142. }
  143. // open the detail side tray for this classified
  144. openClassified(c_info);
  145. // remove our observer now that we're done
  146. mClassifiedIds.erase(c_info->classified_id);
  147. LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
  148. }
  149. };
  150. LLClassifiedHandler gClassifiedHandler;
  151. //////////////////////////////////////////////////////////////////////////
  152. /**
  153.  * Copy&Pasted from old LLPanelClassified. This class does nothing at the moment.
  154.  * Subscribing to "classifiedclickthrough" removes a few warnings.
  155.  */
  156. class LLClassifiedClickThrough : public LLDispatchHandler
  157. {
  158. public:
  159. // "classifiedclickthrough"
  160. // strings[0] = classified_id
  161. // strings[1] = teleport_clicks
  162. // strings[2] = map_clicks
  163. // strings[3] = profile_clicks
  164. virtual bool operator()(
  165. const LLDispatcher* dispatcher,
  166. const std::string& key,
  167. const LLUUID& invoice,
  168. const sparam_t& strings)
  169. {
  170. if (strings.size() != 4) 
  171. return false;
  172. return true;
  173. }
  174. };
  175. //-----------------------------------------------------------------------------
  176. // LLPanelPicks
  177. //-----------------------------------------------------------------------------
  178. LLPanelPicks::LLPanelPicks()
  179. : LLPanelProfileTab(),
  180. mPopupMenu(NULL),
  181. mProfilePanel(NULL),
  182. mPickPanel(NULL),
  183. mPicksList(NULL),
  184. mClassifiedsList(NULL),
  185. mPanelPickInfo(NULL),
  186. mPanelPickEdit(NULL),
  187. mPlusMenu(NULL),
  188. mPicksAccTab(NULL),
  189. mClassifiedsAccTab(NULL),
  190. mPanelClassifiedInfo(NULL),
  191. mPanelClassifiedEdit(NULL),
  192. mClickThroughDisp(NULL),
  193. mNoClassifieds(false),
  194. mNoPicks(false)
  195. {
  196. mClickThroughDisp = new LLClassifiedClickThrough();
  197. gGenericDispatcher.addHandler("classifiedclickthrough", mClickThroughDisp);
  198. }
  199. LLPanelPicks::~LLPanelPicks()
  200. {
  201. if(getAvatarId().notNull())
  202. {
  203. LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
  204. }
  205. delete mClickThroughDisp;
  206. }
  207. void* LLPanelPicks::create(void* data /* = NULL */)
  208. {
  209. return new LLPanelPicks();
  210. }
  211. void LLPanelPicks::updateData()
  212. {
  213. // Send Picks request only when we need to, not on every onOpen(during tab switch).
  214. if(isDirty())
  215. {
  216. mNoPicks = false;
  217. mNoClassifieds = false;
  218. childSetValue("picks_panel_text", LLTrans::getString("PicksClassifiedsLoadingText"));
  219. mPicksList->clear();
  220. LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
  221. mClassifiedsList->clear();
  222. LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
  223. }
  224. }
  225. void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
  226. {
  227. if(APT_PICKS == type)
  228. {
  229. LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
  230. if(avatar_picks && getAvatarId() == avatar_picks->target_id)
  231. {
  232. std::string name, second_name;
  233. gCacheName->getName(getAvatarId(),name,second_name);
  234. childSetTextArg("pick_title", "[NAME]",name);
  235. // Save selection, to be able to edit same item after saving changes. See EXT-3023.
  236. LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
  237. mPicksList->clear();
  238. LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
  239. for(; avatar_picks->picks_list.end() != it; ++it)
  240. {
  241. LLUUID pick_id = it->first;
  242. std::string pick_name = it->second;
  243. LLPickItem* picture = LLPickItem::create();
  244. picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
  245. picture->setPickName(pick_name);
  246. picture->setPickId(pick_id);
  247. picture->setCreatorId(getAvatarId());
  248. LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
  249. picture->update();
  250. LLSD pick_value = LLSD();
  251. pick_value.insert(PICK_ID, pick_id);
  252. pick_value.insert(PICK_NAME, pick_name);
  253. pick_value.insert(PICK_CREATOR_ID, getAvatarId());
  254. mPicksList->addItem(picture, pick_value);
  255. // Restore selection by item id. 
  256. if ( pick_id == selected_id )
  257. mPicksList->selectItemByValue(pick_value);
  258. picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
  259. picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
  260. picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
  261. }
  262. showAccordion("tab_picks", mPicksList->size());
  263. resetDirty();
  264. updateButtons();
  265. }
  266. mNoPicks = !mPicksList->size();
  267. }
  268. else if(APT_CLASSIFIEDS == type)
  269. {
  270. LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
  271. if(c_info && getAvatarId() == c_info->target_id)
  272. {
  273. mClassifiedsList->clear();
  274. LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
  275. for(; c_info->classifieds_list.end() != it; ++it)
  276. {
  277. LLAvatarClassifieds::classified_data c_data = *it;
  278. LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
  279. c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
  280. c_item->setClassifiedName(c_data.name);
  281. LLSD pick_value = LLSD();
  282. pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
  283. pick_value.insert(CLASSIFIED_NAME, c_data.name);
  284. mClassifiedsList->addItem(c_item, pick_value);
  285. c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
  286. c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
  287. c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
  288. }
  289. showAccordion("tab_classifieds", mClassifiedsList->size());
  290. resetDirty();
  291. updateButtons();
  292. }
  293. mNoClassifieds = !mClassifiedsList->size();
  294. }
  295. if (mNoPicks && mNoClassifieds)
  296. {
  297. if(getAvatarId() == gAgentID)
  298. {
  299. childSetValue("picks_panel_text", LLTrans::getString("NoPicksClassifiedsText"));
  300. }
  301. else
  302. {
  303. childSetValue("picks_panel_text", LLTrans::getString("NoAvatarPicksClassifiedsText"));
  304. }
  305. }
  306. }
  307. LLPickItem* LLPanelPicks::getSelectedPickItem()
  308. {
  309. LLPanel* selected_item = mPicksList->getSelectedItem();
  310. if (!selected_item) return NULL;
  311. return dynamic_cast<LLPickItem*>(selected_item);
  312. }
  313. LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem()
  314. {
  315. LLPanel* selected_item = mClassifiedsList->getSelectedItem();
  316. if (!selected_item) 
  317. {
  318. return NULL;
  319. }
  320. return dynamic_cast<LLClassifiedItem*>(selected_item);
  321. }
  322. BOOL LLPanelPicks::postBuild()
  323. {
  324. mPicksList = getChild<LLFlatListView>("picks_list");
  325. mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
  326. mPicksList->setCommitOnSelectionChange(true);
  327. mClassifiedsList->setCommitOnSelectionChange(true);
  328. mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList));
  329. mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList));
  330. mPicksList->setNoItemsCommentText(getString("no_picks"));
  331. mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
  332. childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
  333. childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
  334. childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
  335. childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this));
  336. childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this));
  337. mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks");
  338. mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab));
  339. mPicksAccTab->setDisplayChildren(true);
  340. mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds");
  341. mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab));
  342. mClassifiedsAccTab->setDisplayChildren(false);
  343. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
  344. registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
  345. registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this)); 
  346. registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
  347. registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
  348. registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
  349. mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
  350. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar;
  351. plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2));
  352. mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelPicks::isActionEnabled, this, _2));
  353. mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
  354. return TRUE;
  355. }
  356. void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param)
  357. {
  358. std::string value = param.asString();
  359. if("new_pick" == value)
  360. {
  361. createNewPick();
  362. }
  363. else if("new_classified" == value)
  364. {
  365. createNewClassified();
  366. }
  367. }
  368. bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const
  369. {
  370. std::string command_name = userdata.asString();
  371. if (command_name == "new_pick" && LLAgentPicksInfo::getInstance()->isPickLimitReached())
  372. {
  373. return false;
  374. }
  375. return true;
  376. }
  377. void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
  378. {
  379. if(!mPicksAccTab->getDisplayChildren())
  380. {
  381. mPicksList->resetSelection(true);
  382. }
  383. if(!mClassifiedsAccTab->getDisplayChildren())
  384. {
  385. mClassifiedsList->resetSelection(true);
  386. }
  387. updateButtons();
  388. }
  389. void LLPanelPicks::onOpen(const LLSD& key)
  390. {
  391. const LLUUID id(key.asUUID());
  392. BOOL self = (gAgent.getID() == id);
  393. // only agent can edit her picks 
  394. childSetEnabled("edit_panel", self);
  395. childSetVisible("edit_panel", self);
  396. // Disable buttons when viewing profile for first time
  397. if(getAvatarId() != id)
  398. {
  399. childSetEnabled(XML_BTN_INFO,FALSE);
  400. childSetEnabled(XML_BTN_TELEPORT,FALSE);
  401. childSetEnabled(XML_BTN_SHOW_ON_MAP,FALSE);
  402. }
  403. // and see a special title - set as invisible by default in xml file
  404. if (self)
  405. {
  406. childSetVisible("pick_title", !self);
  407. childSetVisible("pick_title_agent", self);
  408. mPopupMenu->setItemVisible("pick_delete", TRUE);
  409. mPopupMenu->setItemVisible("pick_edit", TRUE);
  410. mPopupMenu->setItemVisible("pick_separator", TRUE);
  411. }
  412. if(getAvatarId() != id)
  413. {
  414. showAccordion("tab_picks", false);
  415. showAccordion("tab_classifieds", false);
  416. mPicksList->goToTop();
  417. // Set dummy value to make panel dirty and make it reload picks
  418. setValue(LLSD());
  419. }
  420. LLPanelProfileTab::onOpen(key);
  421. }
  422. void LLPanelPicks::onClosePanel()
  423. {
  424. if (mPanelClassifiedInfo)
  425. {
  426. onPanelClassifiedClose(mPanelClassifiedInfo);
  427. }
  428. if (mPanelPickInfo)
  429. {
  430. onPanelPickClose(mPanelPickInfo);
  431. }
  432. }
  433. void LLPanelPicks::onListCommit(const LLFlatListView* f_list)
  434. {
  435. // Make sure only one of the lists has selection.
  436. if(f_list == mPicksList)
  437. {
  438. mClassifiedsList->resetSelection(true);
  439. }
  440. else if(f_list == mClassifiedsList)
  441. {
  442. mPicksList->resetSelection(true);
  443. }
  444. else
  445. {
  446. llwarns << "Unknown list" << llendl;
  447. }
  448. updateButtons();
  449. }
  450. //static
  451. void LLPanelPicks::onClickDelete()
  452. {
  453. LLSD value = mPicksList->getSelectedValue();
  454. if (value.isDefined())
  455. {
  456. LLSD args; 
  457. args["PICK"] = value[PICK_NAME]; 
  458. LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2)); 
  459. return;
  460. }
  461. value = mClassifiedsList->getSelectedValue();
  462. if(value.isDefined())
  463. {
  464. LLSD args; 
  465. args["NAME"] = value[CLASSIFIED_NAME]; 
  466. LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2)); 
  467. return;
  468. }
  469. }
  470. bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response) 
  471. {
  472. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  473. LLSD pick_value = mPicksList->getSelectedValue();
  474. if (0 == option)
  475. {
  476. LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
  477. mPicksList->removeItemByValue(pick_value);
  478. }
  479. updateButtons();
  480. return false;
  481. }
  482. bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response) 
  483. {
  484. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  485. LLSD value = mClassifiedsList->getSelectedValue();
  486. if (0 == option)
  487. {
  488. LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
  489. mClassifiedsList->removeItemByValue(value);
  490. }
  491. updateButtons();
  492. return false;
  493. }
  494. bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
  495. {
  496. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  497. if (0 == option)
  498. {
  499. onClickTeleport();
  500. }
  501. return false;
  502. }
  503. //static
  504. void LLPanelPicks::onClickTeleport()
  505. {
  506. LLPickItem* pick_item = getSelectedPickItem();
  507. LLClassifiedItem* c_item = getSelectedClassifiedItem();
  508. LLVector3d pos;
  509. if(pick_item)
  510. pos = pick_item->getPosGlobal();
  511. else if(c_item)
  512. pos = c_item->getPosGlobal();
  513. if (!pos.isExactlyZero())
  514. {
  515. gAgent.teleportViaLocation(pos);
  516. LLFloaterWorldMap::getInstance()->trackLocation(pos);
  517. }
  518. }
  519. //static
  520. void LLPanelPicks::onClickMap()
  521. {
  522. LLPickItem* pick_item = getSelectedPickItem();
  523. LLClassifiedItem* c_item = getSelectedClassifiedItem();
  524. LLVector3d pos;
  525. if (pick_item)
  526. pos = pick_item->getPosGlobal();
  527. else if(c_item)
  528. pos = c_item->getPosGlobal();
  529. LLFloaterWorldMap::getInstance()->trackLocation(pos);
  530. LLFloaterReg::showInstance("world_map", "center");
  531. }
  532. void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
  533. {
  534. updateButtons();
  535. if (mPopupMenu)
  536. {
  537. mPopupMenu->buildDrawLabels();
  538. mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
  539. ((LLContextMenu*)mPopupMenu)->show(x, y);
  540. LLMenuGL::showPopup(item, mPopupMenu, x, y);
  541. }
  542. }
  543. void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item)
  544. {
  545. LLSD pick_value = mPicksList->getSelectedValue();
  546. if (pick_value.isUndefined()) return;
  547. LLSD args; 
  548. args["PICK"] = pick_value[PICK_NAME]; 
  549. LLNotificationsUtil::add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); 
  550. }
  551. void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item)
  552. {
  553. LLSD value = mClassifiedsList->getSelectedValue();
  554. if (value.isUndefined()) return;
  555. LLSD args; 
  556. args["CLASSIFIED"] = value[CLASSIFIED_NAME]; 
  557. LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); 
  558. }
  559. void LLPanelPicks::updateButtons()
  560. {
  561. bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0;
  562. if (getAvatarId() == gAgentID)
  563. {
  564. childSetEnabled(XML_BTN_DELETE, has_selected);
  565. }
  566. childSetEnabled(XML_BTN_INFO, has_selected);
  567. childSetEnabled(XML_BTN_TELEPORT, has_selected);
  568. childSetEnabled(XML_BTN_SHOW_ON_MAP, has_selected);
  569. }
  570. void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
  571. {
  572. mProfilePanel = profile_panel;
  573. }
  574. void LLPanelPicks::buildPickPanel()
  575. {
  576. //  if (mPickPanel == NULL)
  577. //  {
  578. //  mPickPanel = new LLPanelPick();
  579. //  mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL));
  580. //  }
  581. }
  582. void LLPanelPicks::onClickPlusBtn()
  583. {
  584. LLRect rect;
  585. childGetRect(XML_BTN_NEW, rect);
  586. mPlusMenu->updateParent(LLMenuGL::sMenuContainer);
  587. mPlusMenu->setButtonRect(rect, this);
  588. LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop);
  589. }
  590. void LLPanelPicks::createNewPick()
  591. {
  592. createPickEditPanel();
  593. getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
  594. }
  595. void LLPanelPicks::createNewClassified()
  596. {
  597. createClassifiedEditPanel();
  598. getProfilePanel()->openPanel(mPanelClassifiedEdit, LLSD());
  599. }
  600. void LLPanelPicks::onClickInfo()
  601. {
  602. if(mPicksList->numSelected() > 0)
  603. {
  604. openPickInfo();
  605. }
  606. else if(mClassifiedsList->numSelected() > 0)
  607. {
  608. openClassifiedInfo();
  609. }
  610. }
  611. void LLPanelPicks::openPickInfo()
  612. {
  613. LLSD selected_value = mPicksList->getSelectedValue();
  614. if (selected_value.isUndefined()) return;
  615. LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem();
  616. createPickInfoPanel();
  617. LLSD params;
  618. params["pick_id"] = pick->getPickId();
  619. params["avatar_id"] = pick->getCreatorId();
  620. params["snapshot_id"] = pick->getSnapshotId();
  621. params["pick_name"] = pick->getPickName();
  622. params["pick_desc"] = pick->getPickDesc();
  623. getProfilePanel()->openPanel(mPanelPickInfo, params);
  624. }
  625. void LLPanelPicks::openClassifiedInfo()
  626. {
  627. LLSD selected_value = mClassifiedsList->getSelectedValue();
  628. if (selected_value.isUndefined()) return;
  629. LLClassifiedItem* c_item = getSelectedClassifiedItem();
  630. openClassifiedInfo(c_item->getClassifiedId(), c_item->getAvatarId(),
  631.    c_item->getSnapshotId(), c_item->getClassifiedName(),
  632.    c_item->getDescription());
  633. }
  634. void LLPanelPicks::openClassifiedInfo(const LLUUID &classified_id, 
  635.   const LLUUID &avatar_id,
  636.   const LLUUID &snapshot_id,
  637.   const std::string &name, const std::string &desc)
  638. {
  639. createClassifiedInfoPanel();
  640. LLSD params;
  641. params["classified_id"] = classified_id;
  642. params["avatar_id"] = avatar_id;
  643. params["snapshot_id"] = snapshot_id;
  644. params["name"] = name;
  645. params["desc"] = desc;
  646. getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
  647. }
  648. void LLPanelPicks::showAccordion(const std::string& name, bool show)
  649. {
  650. LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
  651. tab->setVisible(show);
  652. LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
  653. acc->arrange();
  654. }
  655. void LLPanelPicks::onPanelPickClose(LLPanel* panel)
  656. {
  657. panel->setVisible(FALSE);
  658. }
  659. void LLPanelPicks::onPanelPickSave(LLPanel* panel)
  660. {
  661. onPanelPickClose(panel);
  662. updateButtons();
  663. }
  664. void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
  665. {
  666. if(!panel->canClose())
  667. {
  668. return;
  669. }
  670. if(panel->isNew())
  671. {
  672. LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
  673. c_item->setClassifiedName(panel->getClassifiedName());
  674. c_item->setDescription(panel->getDescription());
  675. c_item->setSnapshotId(panel->getSnapshotId());
  676. LLSD c_value;
  677. c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
  678. c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
  679. mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
  680. c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
  681. c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
  682. c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
  683. c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
  684. // order does matter, showAccordion will invoke arrange for accordions.
  685. mClassifiedsAccTab->changeOpenClose(false);
  686. showAccordion("tab_classifieds", true);
  687. }
  688. else 
  689. {
  690. onPanelClassifiedClose(panel);
  691. return;
  692. }
  693. onPanelPickClose(panel);
  694. updateButtons();
  695. }
  696. void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
  697. {
  698. if(panel->getInfoLoaded() && !panel->isDirty())
  699. {
  700. std::vector<LLSD> values;
  701. mClassifiedsList->getValues(values);
  702. for(size_t n = 0; n < values.size(); ++n)
  703. {
  704. LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
  705. if(panel->getClassifiedId() == c_id)
  706. {
  707. LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(
  708. mClassifiedsList->getItemByValue(values[n]));
  709. llassert(c_item);
  710. if (c_item)
  711. {
  712. c_item->setClassifiedName(panel->getClassifiedName());
  713. c_item->setDescription(panel->getDescription());
  714. c_item->setSnapshotId(panel->getSnapshotId());
  715. }
  716. }
  717. }
  718. }
  719. onPanelPickClose(panel);
  720. updateButtons();
  721. }
  722. void LLPanelPicks::createPickInfoPanel()
  723. {
  724. if(!mPanelPickInfo)
  725. {
  726. mPanelPickInfo = LLPanelPickInfo::create();
  727. mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
  728. mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
  729. mPanelPickInfo->setVisible(FALSE);
  730. }
  731. }
  732. void LLPanelPicks::createClassifiedInfoPanel()
  733. {
  734. if(!mPanelClassifiedInfo)
  735. {
  736. mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
  737. mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
  738. mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this));
  739. mPanelClassifiedInfo->setVisible(FALSE);
  740. }
  741. }
  742. void LLPanelPicks::createClassifiedEditPanel()
  743. {
  744. if(!mPanelClassifiedEdit)
  745. {
  746. mPanelClassifiedEdit = LLPanelClassifiedEdit::create();
  747. mPanelClassifiedEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedEdit));
  748. mPanelClassifiedEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, mPanelClassifiedEdit));
  749. mPanelClassifiedEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedEdit));
  750. mPanelClassifiedEdit->setVisible(FALSE);
  751. }
  752. }
  753. void LLPanelPicks::createPickEditPanel()
  754. {
  755. if(!mPanelPickEdit)
  756. {
  757. mPanelPickEdit = LLPanelPickEdit::create();
  758. mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
  759. mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit));
  760. mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
  761. mPanelPickEdit->setVisible(FALSE);
  762. }
  763. }
  764. // void LLPanelPicks::openPickEditPanel(LLPickItem* pick)
  765. // {
  766. //  if(!pick)
  767. //  {
  768. //  return;
  769. //  }
  770. // }
  771. // void LLPanelPicks::openPickInfoPanel(LLPickItem* pick)
  772. // {
  773. //  if(!mPanelPickInfo)
  774. //  {
  775. //  mPanelPickInfo = LLPanelPickInfo::create();
  776. //  mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
  777. //  mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
  778. //  mPanelPickInfo->setVisible(FALSE);
  779. //  }
  780. // 
  781. //  LLSD params;
  782. //  params["pick_id"] = pick->getPickId();
  783. //  params["avatar_id"] = pick->getCreatorId();
  784. //  params["snapshot_id"] = pick->getSnapshotId();
  785. //  params["pick_name"] = pick->getPickName();
  786. //  params["pick_desc"] = pick->getPickDesc();
  787. // 
  788. //  getProfilePanel()->openPanel(mPanelPickInfo, params);
  789. // }
  790. void LLPanelPicks::onPanelPickEdit()
  791. {
  792. LLSD selected_value = mPicksList->getSelectedValue();
  793. if (selected_value.isUndefined()) return;
  794. LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
  795. createPickEditPanel();
  796. LLSD params;
  797. params["pick_id"] = pick->getPickId();
  798. params["avatar_id"] = pick->getCreatorId();
  799. params["snapshot_id"] = pick->getSnapshotId();
  800. params["pick_name"] = pick->getPickName();
  801. params["pick_desc"] = pick->getPickDesc();
  802. getProfilePanel()->openPanel(mPanelPickEdit, params);
  803. }
  804. void LLPanelPicks::onPanelClassifiedEdit()
  805. {
  806. LLSD selected_value = mClassifiedsList->getSelectedValue();
  807. if (selected_value.isUndefined()) 
  808. {
  809. return;
  810. }
  811. LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
  812. createClassifiedEditPanel();
  813. LLSD params;
  814. params["classified_id"] = c_item->getClassifiedId();
  815. params["avatar_id"] = c_item->getAvatarId();
  816. params["snapshot_id"] = c_item->getSnapshotId();
  817. params["name"] = c_item->getClassifiedName();
  818. params["desc"] = c_item->getDescription();
  819. getProfilePanel()->openPanel(mPanelClassifiedEdit, params);
  820. }
  821. void LLPanelPicks::onClickMenuEdit()
  822. {
  823. if(getSelectedPickItem())
  824. {
  825. onPanelPickEdit();
  826. }
  827. else if(getSelectedClassifiedItem())
  828. {
  829. onPanelClassifiedEdit();
  830. }
  831. }
  832. inline LLPanelProfile* LLPanelPicks::getProfilePanel()
  833. {
  834. llassert_always(NULL != mProfilePanel);
  835. return mProfilePanel;
  836. }
  837. //-----------------------------------------------------------------------------
  838. // LLPanelPicks
  839. //-----------------------------------------------------------------------------
  840. LLPickItem::LLPickItem()
  841. : LLPanel()
  842. , mPickID(LLUUID::null)
  843. , mCreatorID(LLUUID::null)
  844. , mParcelID(LLUUID::null)
  845. , mSnapshotID(LLUUID::null)
  846. , mNeedData(true)
  847. {
  848. LLUICtrlFactory::getInstance()->buildPanel(this,"panel_pick_list_item.xml");
  849. }
  850. LLPickItem::~LLPickItem()
  851. {
  852. if (mCreatorID.notNull())
  853. {
  854. LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
  855. }
  856. }
  857. LLPickItem* LLPickItem::create()
  858. {
  859. return new LLPickItem();
  860. }
  861. void LLPickItem::init(LLPickData* pick_data)
  862. {
  863. setPickDesc(pick_data->desc);
  864. setSnapshotId(pick_data->snapshot_id);
  865. mPosGlobal = pick_data->pos_global;
  866. mSimName = pick_data->sim_name;
  867. mPickDescription = pick_data->desc;
  868. mUserName = pick_data->user_name;
  869. mOriginalName = pick_data->original_name;
  870. LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
  871. picture->setImageAssetID(pick_data->snapshot_id);
  872. }
  873. void LLPickItem::setPickName(const std::string& name)
  874. {
  875. mPickName = name;
  876. childSetValue("picture_name",name);
  877. }
  878. const std::string& LLPickItem::getPickName()
  879. {
  880. return mPickName;
  881. }
  882. const LLUUID& LLPickItem::getCreatorId()
  883. {
  884. return mCreatorID;
  885. }
  886. const LLUUID& LLPickItem::getSnapshotId()
  887. {
  888. return mSnapshotID;
  889. }
  890. void LLPickItem::setPickDesc(const std::string& descr)
  891. {
  892. childSetValue("picture_descr",descr);
  893. }
  894. void LLPickItem::setPickId(const LLUUID& id)
  895. {
  896. mPickID = id;
  897. }
  898. const LLUUID& LLPickItem::getPickId()
  899. {
  900. return mPickID;
  901. }
  902. const LLVector3d& LLPickItem::getPosGlobal()
  903. {
  904. return mPosGlobal;
  905. }
  906. const std::string LLPickItem::getDescription()
  907. {
  908. return childGetValue("picture_descr").asString();
  909. }
  910. void LLPickItem::update()
  911. {
  912. setNeedData(true);
  913. LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID);
  914. }
  915. void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
  916. {
  917. if (APT_PICK_INFO != type) 
  918. {
  919. return;
  920. }
  921. LLPickData* pick_data = static_cast<LLPickData *>(data);
  922. if (!pick_data || mPickID != pick_data->pick_id) 
  923. {
  924. return;
  925. }
  926. init(pick_data);
  927. setNeedData(false);
  928. LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
  929. }
  930. BOOL LLPickItem::postBuild()
  931. {
  932. setMouseEnterCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", true));
  933. setMouseLeaveCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", false));
  934. return TRUE;
  935. }
  936. void LLPickItem::setValue(const LLSD& value)
  937. {
  938. if (!value.isMap()) return;;
  939. if (!value.has("selected")) return;
  940. childSetVisible("selected_icon", value["selected"]);
  941. }
  942. //////////////////////////////////////////////////////////////////////////
  943. //////////////////////////////////////////////////////////////////////////
  944. //////////////////////////////////////////////////////////////////////////
  945. LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
  946.  : LLPanel()
  947.  , mAvatarId(avatar_id)
  948.  , mClassifiedId(classified_id)
  949. {
  950. LLUICtrlFactory::getInstance()->buildPanel(this,"panel_classifieds_list_item.xml");
  951. LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
  952. LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
  953. }
  954. LLClassifiedItem::~LLClassifiedItem()
  955. {
  956. LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
  957. }
  958. void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
  959. {
  960. if(APT_CLASSIFIED_INFO != type)
  961. {
  962. return;
  963. }
  964. LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
  965. if( !c_info || c_info->classified_id != getClassifiedId() )
  966. {
  967. return;
  968. }
  969. setClassifiedName(c_info->name);
  970. setDescription(c_info->description);
  971. setSnapshotId(c_info->snapshot_id);
  972. setPosGlobal(c_info->pos_global);
  973. LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
  974. }
  975. BOOL LLClassifiedItem::postBuild()
  976. {
  977. setMouseEnterCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", true));
  978. setMouseLeaveCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", false));
  979. return TRUE;
  980. }
  981. void LLClassifiedItem::setValue(const LLSD& value)
  982. {
  983. if (!value.isMap()) return;;
  984. if (!value.has("selected")) return;
  985. childSetVisible("selected_icon", value["selected"]);
  986. }
  987. void LLClassifiedItem::setClassifiedName(const std::string& name)
  988. {
  989. childSetValue("name", name);
  990. }
  991. void LLClassifiedItem::setDescription(const std::string& desc)
  992. {
  993. childSetValue("description", desc);
  994. }
  995. void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
  996. {
  997. childSetValue("picture", snapshot_id);
  998. }
  999. LLUUID LLClassifiedItem::getSnapshotId()
  1000. {
  1001. return childGetValue("picture");
  1002. }
  1003. //EOF