PageRenderTime 46ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llpanelobjectinventory.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1940 lines | 1543 code | 219 blank | 178 comment | 216 complexity | 69acd202263f54f062d764cfc54cf727 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsidepanelinventory.cpp
  3. * @brief LLPanelObjectInventory class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&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. //
  28. // Implementation of the panel inventory - used to view and control a
  29. // task's inventory.
  30. //
  31. //*****************************************************************************
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llpanelobjectinventory.h"
  34. #include "llmenugl.h"
  35. #include "llnotificationsutil.h"
  36. #include "roles_constants.h"
  37. #include "llagent.h"
  38. #include "llavataractions.h"
  39. #include "llcallbacklist.h"
  40. #include "llbuycurrencyhtml.h"
  41. #include "llfloaterreg.h"
  42. #include "llfolderview.h"
  43. #include "llinventorybridge.h"
  44. #include "llinventorydefines.h"
  45. #include "llinventoryfilter.h"
  46. #include "llinventoryfunctions.h"
  47. #include "llpreviewanim.h"
  48. #include "llpreviewgesture.h"
  49. #include "llpreviewnotecard.h"
  50. #include "llpreviewscript.h"
  51. #include "llpreviewsound.h"
  52. #include "llpreviewtexture.h"
  53. #include "llscrollcontainer.h"
  54. #include "llselectmgr.h"
  55. #include "llstatusbar.h"
  56. #include "lltooldraganddrop.h"
  57. #include "lltrans.h"
  58. #include "llviewerassettype.h"
  59. #include "llviewerinventory.h"
  60. #include "llviewerregion.h"
  61. #include "llviewerobjectlist.h"
  62. #include "llviewermessage.h"
  63. ///----------------------------------------------------------------------------
  64. /// Class LLTaskInvFVBridge
  65. ///----------------------------------------------------------------------------
  66. class LLTaskInvFVBridge : public LLFolderViewEventListener
  67. {
  68. protected:
  69. LLUUID mUUID;
  70. std::string mName;
  71. mutable std::string mDisplayName;
  72. LLPanelObjectInventory* mPanel;
  73. U32 mFlags;
  74. LLAssetType::EType mAssetType;
  75. LLInventoryType::EType mInventoryType;
  76. LLInventoryObject* findInvObject() const;
  77. LLInventoryItem* findItem() const;
  78. public:
  79. LLTaskInvFVBridge(LLPanelObjectInventory* panel,
  80. const LLUUID& uuid,
  81. const std::string& name,
  82. U32 flags=0);
  83. virtual ~LLTaskInvFVBridge() {}
  84. virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
  85. virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
  86. static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel,
  87. LLInventoryObject* object);
  88. void showProperties();
  89. void buyItem();
  90. S32 getPrice();
  91. static bool commitBuyItem(const LLSD& notification, const LLSD& response);
  92. // LLFolderViewEventListener functionality
  93. virtual const std::string& getName() const;
  94. virtual const std::string& getDisplayName() const;
  95. virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
  96. /*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
  97. virtual const LLUUID& getUUID() const { return mUUID; }
  98. virtual time_t getCreationDate() const;
  99. virtual LLUIImagePtr getIcon() const;
  100. virtual void openItem();
  101. virtual BOOL canOpenItem() const { return FALSE; }
  102. virtual void closeItem() {}
  103. virtual void previewItem();
  104. virtual void selectItem() {}
  105. virtual BOOL isItemRenameable() const;
  106. virtual BOOL renameItem(const std::string& new_name);
  107. virtual BOOL isItemMovable() const;
  108. virtual BOOL isItemRemovable() const;
  109. virtual BOOL removeItem();
  110. virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
  111. virtual void move(LLFolderViewEventListener* parent_listener);
  112. virtual BOOL isItemCopyable() const;
  113. virtual BOOL copyToClipboard() const;
  114. virtual void cutToClipboard();
  115. virtual BOOL isClipboardPasteable() const;
  116. virtual void pasteFromClipboard();
  117. virtual void pasteLinkFromClipboard();
  118. virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
  119. virtual void performAction(LLInventoryModel* model, std::string action);
  120. virtual BOOL isUpToDate() const { return TRUE; }
  121. virtual BOOL hasChildren() const { return FALSE; }
  122. virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
  123. virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
  124. // LLDragAndDropBridge functionality
  125. virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
  126. virtual BOOL dragOrDrop(MASK mask, BOOL drop,
  127. EDragAndDropType cargo_type,
  128. void* cargo_data,
  129. std::string& tooltip_msg);
  130. };
  131. LLTaskInvFVBridge::LLTaskInvFVBridge(
  132. LLPanelObjectInventory* panel,
  133. const LLUUID& uuid,
  134. const std::string& name,
  135. U32 flags):
  136. mUUID(uuid),
  137. mName(name),
  138. mPanel(panel),
  139. mFlags(flags),
  140. mAssetType(LLAssetType::AT_NONE),
  141. mInventoryType(LLInventoryType::IT_NONE)
  142. {
  143. const LLInventoryItem *item = findItem();
  144. if (item)
  145. {
  146. mAssetType = item->getType();
  147. mInventoryType = item->getInventoryType();
  148. }
  149. }
  150. LLInventoryObject* LLTaskInvFVBridge::findInvObject() const
  151. {
  152. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  153. if (object)
  154. {
  155. return object->getInventoryObject(mUUID);
  156. }
  157. return NULL;
  158. }
  159. LLInventoryItem* LLTaskInvFVBridge::findItem() const
  160. {
  161. return dynamic_cast<LLInventoryItem*>(findInvObject());
  162. }
  163. void LLTaskInvFVBridge::showProperties()
  164. {
  165. show_task_item_profile(mUUID, mPanel->getTaskUUID());
  166. }
  167. struct LLBuyInvItemData
  168. {
  169. LLUUID mTaskID;
  170. LLUUID mItemID;
  171. LLAssetType::EType mType;
  172. LLBuyInvItemData(const LLUUID& task,
  173. const LLUUID& item,
  174. LLAssetType::EType type) :
  175. mTaskID(task), mItemID(item), mType(type)
  176. {}
  177. };
  178. void LLTaskInvFVBridge::buyItem()
  179. {
  180. llinfos << "LLTaskInvFVBridge::buyItem()" << llendl;
  181. LLInventoryItem* item = findItem();
  182. if(!item || !item->getSaleInfo().isForSale()) return;
  183. LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(),
  184. mUUID,
  185. item->getType());
  186. const LLSaleInfo& sale_info = item->getSaleInfo();
  187. const LLPermissions& perm = item->getPermissions();
  188. const std::string owner_name; // no owner name currently... FIXME?
  189. LLViewerObject* obj;
  190. if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() )
  191. {
  192. LLNotificationsUtil::add("Cannot_Purchase_an_Attachment");
  193. llinfos << "Attempt to purchase an attachment" << llendl;
  194. delete inv;
  195. }
  196. else
  197. {
  198. LLSD args;
  199. args["PRICE"] = llformat("%d",sale_info.getSalePrice());
  200. args["OWNER"] = owner_name;
  201. if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS)
  202. {
  203. U32 next_owner_mask = perm.getMaskNextOwner();
  204. args["MODIFYPERM"] = LLTrans::getString((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo");
  205. args["COPYPERM"] = LLTrans::getString((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo");
  206. args["RESELLPERM"] = LLTrans::getString((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo");
  207. }
  208. std::string alertdesc;
  209. switch(sale_info.getSaleType())
  210. {
  211. case LLSaleInfo::FS_ORIGINAL:
  212. alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal";
  213. break;
  214. case LLSaleInfo::FS_CONTENTS:
  215. alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents";
  216. break;
  217. case LLSaleInfo::FS_COPY:
  218. default:
  219. alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy";
  220. break;
  221. }
  222. LLSD payload;
  223. payload["task_id"] = inv->mTaskID;
  224. payload["item_id"] = inv->mItemID;
  225. payload["type"] = inv->mType;
  226. LLNotificationsUtil::add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem);
  227. }
  228. }
  229. S32 LLTaskInvFVBridge::getPrice()
  230. {
  231. LLInventoryItem* item = findItem();
  232. if(item)
  233. {
  234. return item->getSaleInfo().getSalePrice();
  235. }
  236. else
  237. {
  238. return -1;
  239. }
  240. }
  241. // static
  242. bool LLTaskInvFVBridge::commitBuyItem(const LLSD& notification, const LLSD& response)
  243. {
  244. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  245. if(0 == option)
  246. {
  247. LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
  248. if(!object || !object->getRegion()) return false;
  249. LLMessageSystem* msg = gMessageSystem;
  250. msg->newMessageFast(_PREHASH_BuyObjectInventory);
  251. msg->nextBlockFast(_PREHASH_AgentData);
  252. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  253. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  254. msg->nextBlockFast(_PREHASH_Data);
  255. msg->addUUIDFast(_PREHASH_ObjectID, notification["payload"]["task_id"].asUUID());
  256. msg->addUUIDFast(_PREHASH_ItemID, notification["payload"]["item_id"].asUUID());
  257. msg->addUUIDFast(_PREHASH_FolderID,
  258. gInventory.findCategoryUUIDForType((LLFolderType::EType)notification["payload"]["type"].asInteger()));
  259. msg->sendReliable(object->getRegion()->getHost());
  260. }
  261. return false;
  262. }
  263. const std::string& LLTaskInvFVBridge::getName() const
  264. {
  265. return mName;
  266. }
  267. const std::string& LLTaskInvFVBridge::getDisplayName() const
  268. {
  269. LLInventoryItem* item = findItem();
  270. if(item)
  271. {
  272. mDisplayName.assign(item->getName());
  273. // Localize "New Script", "New Script 1", "New Script 2", etc.
  274. if (item->getType() == LLAssetType::AT_LSL_TEXT &&
  275. LLStringUtil::startsWith(item->getName(), "New Script"))
  276. {
  277. LLStringUtil::replaceString(mDisplayName, "New Script", LLTrans::getString("PanelContentsNewScript"));
  278. }
  279. const LLPermissions& perm(item->getPermissions());
  280. BOOL copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
  281. BOOL mod = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE);
  282. BOOL xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE);
  283. if(!copy)
  284. {
  285. mDisplayName.append(LLTrans::getString("no_copy"));
  286. }
  287. if(!mod)
  288. {
  289. mDisplayName.append(LLTrans::getString("no_modify"));
  290. }
  291. if(!xfer)
  292. {
  293. mDisplayName.append(LLTrans::getString("no_transfer"));
  294. }
  295. }
  296. return mDisplayName;
  297. }
  298. // BUG: No creation dates for task inventory
  299. time_t LLTaskInvFVBridge::getCreationDate() const
  300. {
  301. return 0;
  302. }
  303. LLUIImagePtr LLTaskInvFVBridge::getIcon() const
  304. {
  305. const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
  306. return LLInventoryIcon::getIcon(mAssetType, mInventoryType, 0, item_is_multi );
  307. }
  308. void LLTaskInvFVBridge::openItem()
  309. {
  310. // no-op.
  311. lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
  312. }
  313. void LLTaskInvFVBridge::previewItem()
  314. {
  315. openItem();
  316. }
  317. BOOL LLTaskInvFVBridge::isItemRenameable() const
  318. {
  319. if(gAgent.isGodlike()) return TRUE;
  320. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  321. if(object)
  322. {
  323. LLInventoryItem* item = (LLInventoryItem*)(object->getInventoryObject(mUUID));
  324. if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
  325. GP_OBJECT_MANIPULATE, GOD_LIKE))
  326. {
  327. return TRUE;
  328. }
  329. }
  330. return FALSE;
  331. }
  332. BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name)
  333. {
  334. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  335. if(object)
  336. {
  337. LLViewerInventoryItem* item = NULL;
  338. item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID);
  339. if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
  340. GP_OBJECT_MANIPULATE, GOD_LIKE)))
  341. {
  342. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  343. new_item->rename(new_name);
  344. object->updateInventory(
  345. new_item,
  346. TASK_INVENTORY_ITEM_KEY,
  347. false);
  348. }
  349. }
  350. return TRUE;
  351. }
  352. BOOL LLTaskInvFVBridge::isItemMovable() const
  353. {
  354. //LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  355. //if(object && (object->permModify() || gAgent.isGodlike()))
  356. //{
  357. // return TRUE;
  358. //}
  359. //return FALSE;
  360. return TRUE;
  361. }
  362. BOOL LLTaskInvFVBridge::isItemRemovable() const
  363. {
  364. const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  365. if(object
  366. && (object->permModify() || object->permYouOwner()))
  367. {
  368. return TRUE;
  369. }
  370. return FALSE;
  371. }
  372. bool remove_task_inventory_callback(const LLSD& notification, const LLSD& response, LLPanelObjectInventory* panel)
  373. {
  374. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  375. LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
  376. if(option == 0 && object)
  377. {
  378. // yes
  379. LLSD::array_const_iterator list_end = notification["payload"]["inventory_ids"].endArray();
  380. for (LLSD::array_const_iterator list_it = notification["payload"]["inventory_ids"].beginArray();
  381. list_it != list_end;
  382. ++list_it)
  383. {
  384. object->removeInventory(list_it->asUUID());
  385. }
  386. // refresh the UI.
  387. panel->refresh();
  388. }
  389. return false;
  390. }
  391. // helper for remove
  392. // ! REFACTOR ! two_uuids_list_t is also defined in llinventorybridge.h, but differently.
  393. typedef std::pair<LLUUID, std::list<LLUUID> > panel_two_uuids_list_t;
  394. typedef std::pair<LLPanelObjectInventory*, panel_two_uuids_list_t> remove_data_t;
  395. BOOL LLTaskInvFVBridge::removeItem()
  396. {
  397. if(isItemRemovable() && mPanel)
  398. {
  399. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  400. if(object)
  401. {
  402. if(object->permModify())
  403. {
  404. // just do it.
  405. object->removeInventory(mUUID);
  406. return TRUE;
  407. }
  408. else
  409. {
  410. LLSD payload;
  411. payload["task_id"] = mPanel->getTaskUUID();
  412. payload["inventory_ids"].append(mUUID);
  413. LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
  414. return FALSE;
  415. }
  416. }
  417. }
  418. return FALSE;
  419. }
  420. void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
  421. {
  422. if (!mPanel)
  423. {
  424. return;
  425. }
  426. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  427. if (!object)
  428. {
  429. return;
  430. }
  431. if (!object->permModify())
  432. {
  433. LLSD payload;
  434. payload["task_id"] = mPanel->getTaskUUID();
  435. for (S32 i = 0; i < (S32)batch.size(); i++)
  436. {
  437. LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
  438. payload["inventory_ids"].append(itemp->getUUID());
  439. }
  440. LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
  441. }
  442. else
  443. {
  444. for (S32 i = 0; i < (S32)batch.size(); i++)
  445. {
  446. LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
  447. if(itemp->isItemRemovable())
  448. {
  449. // just do it.
  450. object->removeInventory(itemp->getUUID());
  451. }
  452. }
  453. }
  454. }
  455. void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
  456. {
  457. }
  458. BOOL LLTaskInvFVBridge::isItemCopyable() const
  459. {
  460. LLInventoryItem* item = findItem();
  461. if(!item) return FALSE;
  462. return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
  463. GP_OBJECT_MANIPULATE);
  464. }
  465. BOOL LLTaskInvFVBridge::copyToClipboard() const
  466. {
  467. return FALSE;
  468. }
  469. void LLTaskInvFVBridge::cutToClipboard()
  470. {
  471. }
  472. BOOL LLTaskInvFVBridge::isClipboardPasteable() const
  473. {
  474. return FALSE;
  475. }
  476. void LLTaskInvFVBridge::pasteFromClipboard()
  477. {
  478. }
  479. void LLTaskInvFVBridge::pasteLinkFromClipboard()
  480. {
  481. }
  482. BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
  483. {
  484. //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
  485. if(mPanel)
  486. {
  487. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  488. if(object)
  489. {
  490. LLInventoryItem* inv = NULL;
  491. if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
  492. {
  493. const LLPermissions& perm = inv->getPermissions();
  494. bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
  495. GP_OBJECT_MANIPULATE);
  496. if (object->isAttachment() && !can_copy)
  497. {
  498. //RN: no copy contents of attachments cannot be dragged out
  499. // due to a race condition and possible exploit where
  500. // attached objects do not update their inventory items
  501. // when their contents are manipulated
  502. return FALSE;
  503. }
  504. if((can_copy && perm.allowTransferTo(gAgent.getID()))
  505. || object->permYouOwner())
  506. // || gAgent.isGodlike())
  507. {
  508. *type = LLViewerAssetType::lookupDragAndDropType(inv->getType());
  509. *id = inv->getUUID();
  510. return TRUE;
  511. }
  512. }
  513. }
  514. }
  515. return FALSE;
  516. }
  517. BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
  518. EDragAndDropType cargo_type,
  519. void* cargo_data,
  520. std::string& tooltip_msg)
  521. {
  522. //llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl;
  523. return FALSE;
  524. }
  525. // virtual
  526. void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action)
  527. {
  528. if (action == "task_buy")
  529. {
  530. // Check the price of the item.
  531. S32 price = getPrice();
  532. if (-1 == price)
  533. {
  534. llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
  535. }
  536. else
  537. {
  538. if (price > 0 && price > gStatusBar->getBalance())
  539. {
  540. LLStringUtil::format_map_t args;
  541. args["AMOUNT"] = llformat("%d", price);
  542. LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_costs", args), price );
  543. }
  544. else
  545. {
  546. buyItem();
  547. }
  548. }
  549. }
  550. else if (action == "task_open")
  551. {
  552. openItem();
  553. }
  554. else if (action == "task_properties")
  555. {
  556. showProperties();
  557. }
  558. }
  559. void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
  560. {
  561. LLInventoryItem* item = findItem();
  562. std::vector<std::string> items;
  563. std::vector<std::string> disabled_items;
  564. if (!item)
  565. {
  566. hide_context_entries(menu, items, disabled_items);
  567. return;
  568. }
  569. if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(),
  570. GP_OBJECT_MANIPULATE)
  571. && item->getSaleInfo().isForSale())
  572. {
  573. items.push_back(std::string("Task Buy"));
  574. std::string label= LLTrans::getString("Buy");
  575. // Check the price of the item.
  576. S32 price = getPrice();
  577. if (-1 == price)
  578. {
  579. llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
  580. }
  581. else
  582. {
  583. std::ostringstream info;
  584. info << LLTrans::getString("BuyforL$") << price;
  585. label.assign(info.str());
  586. }
  587. const LLView::child_list_t *list = menu.getChildList();
  588. LLView::child_list_t::const_iterator itor;
  589. for (itor = list->begin(); itor != list->end(); ++itor)
  590. {
  591. std::string name = (*itor)->getName();
  592. LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
  593. if (name == "Task Buy" && menu_itemp)
  594. {
  595. menu_itemp->setLabel(label);
  596. }
  597. }
  598. }
  599. else if (canOpenItem())
  600. {
  601. items.push_back(std::string("Task Open"));
  602. if (!isItemCopyable())
  603. {
  604. disabled_items.push_back(std::string("Task Open"));
  605. }
  606. }
  607. items.push_back(std::string("Task Properties"));
  608. if(isItemRenameable())
  609. {
  610. items.push_back(std::string("Task Rename"));
  611. }
  612. if(isItemRemovable())
  613. {
  614. items.push_back(std::string("Task Remove"));
  615. }
  616. hide_context_entries(menu, items, disabled_items);
  617. }
  618. ///----------------------------------------------------------------------------
  619. /// Class LLTaskFolderBridge
  620. ///----------------------------------------------------------------------------
  621. class LLTaskCategoryBridge : public LLTaskInvFVBridge
  622. {
  623. public:
  624. LLTaskCategoryBridge(
  625. LLPanelObjectInventory* panel,
  626. const LLUUID& uuid,
  627. const std::string& name);
  628. virtual LLUIImagePtr getIcon() const;
  629. virtual const std::string& getDisplayName() const;
  630. virtual BOOL isItemRenameable() const;
  631. // virtual BOOL isItemCopyable() const { return FALSE; }
  632. virtual BOOL renameItem(const std::string& new_name);
  633. virtual BOOL isItemRemovable() const;
  634. virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
  635. virtual BOOL hasChildren() const;
  636. virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
  637. virtual BOOL dragOrDrop(MASK mask, BOOL drop,
  638. EDragAndDropType cargo_type,
  639. void* cargo_data,
  640. std::string& tooltip_msg);
  641. virtual BOOL canOpenItem() const { return TRUE; }
  642. virtual void openItem();
  643. };
  644. LLTaskCategoryBridge::LLTaskCategoryBridge(
  645. LLPanelObjectInventory* panel,
  646. const LLUUID& uuid,
  647. const std::string& name) :
  648. LLTaskInvFVBridge(panel, uuid, name)
  649. {
  650. }
  651. LLUIImagePtr LLTaskCategoryBridge::getIcon() const
  652. {
  653. return LLUI::getUIImage("Inv_FolderClosed");
  654. }
  655. // virtual
  656. const std::string& LLTaskCategoryBridge::getDisplayName() const
  657. {
  658. LLInventoryObject* cat = findInvObject();
  659. if (cat)
  660. {
  661. // Localize "Contents" folder.
  662. if (cat->getParentUUID().isNull() && cat->getName() == "Contents")
  663. {
  664. mDisplayName.assign(LLTrans::getString("ViewerObjectContents"));
  665. }
  666. else
  667. {
  668. mDisplayName.assign(cat->getName());
  669. }
  670. }
  671. return mDisplayName;
  672. }
  673. BOOL LLTaskCategoryBridge::isItemRenameable() const
  674. {
  675. return FALSE;
  676. }
  677. BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name)
  678. {
  679. return FALSE;
  680. }
  681. BOOL LLTaskCategoryBridge::isItemRemovable() const
  682. {
  683. return FALSE;
  684. }
  685. void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
  686. {
  687. std::vector<std::string> items;
  688. std::vector<std::string> disabled_items;
  689. hide_context_entries(menu, items, disabled_items);
  690. }
  691. BOOL LLTaskCategoryBridge::hasChildren() const
  692. {
  693. // return TRUE if we have or do know know if we have children.
  694. // *FIX: For now, return FALSE - we will know for sure soon enough.
  695. return FALSE;
  696. }
  697. void LLTaskCategoryBridge::openItem()
  698. {
  699. }
  700. BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
  701. {
  702. //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
  703. if(mPanel && mUUID.notNull())
  704. {
  705. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  706. if(object)
  707. {
  708. const LLInventoryObject* cat = object->getInventoryObject(mUUID);
  709. if ( (cat) && (move_inv_category_world_to_agent(mUUID, LLUUID::null, FALSE)) )
  710. {
  711. *type = LLViewerAssetType::lookupDragAndDropType(cat->getType());
  712. *id = mUUID;
  713. return TRUE;
  714. }
  715. }
  716. }
  717. return FALSE;
  718. }
  719. BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
  720. EDragAndDropType cargo_type,
  721. void* cargo_data,
  722. std::string& tooltip_msg)
  723. {
  724. //llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl;
  725. BOOL accept = FALSE;
  726. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  727. if(object)
  728. {
  729. switch(cargo_type)
  730. {
  731. case DAD_CATEGORY:
  732. accept = LLToolDragAndDrop::getInstance()->dadUpdateInventoryCategory(object,drop);
  733. break;
  734. case DAD_TEXTURE:
  735. case DAD_SOUND:
  736. case DAD_LANDMARK:
  737. case DAD_OBJECT:
  738. case DAD_NOTECARD:
  739. case DAD_CLOTHING:
  740. case DAD_BODYPART:
  741. case DAD_ANIMATION:
  742. case DAD_GESTURE:
  743. case DAD_CALLINGCARD:
  744. case DAD_MESH:
  745. accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
  746. if(accept && drop)
  747. {
  748. LLToolDragAndDrop::dropInventory(object,
  749. (LLViewerInventoryItem*)cargo_data,
  750. LLToolDragAndDrop::getInstance()->getSource(),
  751. LLToolDragAndDrop::getInstance()->getSourceID());
  752. }
  753. break;
  754. case DAD_SCRIPT:
  755. // *HACK: In order to resolve SL-22177, we need to block
  756. // drags from notecards and objects onto other
  757. // objects. uncomment the simpler version when we have
  758. // that right.
  759. //accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
  760. if(LLToolDragAndDrop::isInventoryDropAcceptable(
  761. object, (LLViewerInventoryItem*)cargo_data)
  762. && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource())
  763. && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource()))
  764. {
  765. accept = TRUE;
  766. }
  767. if(accept && drop)
  768. {
  769. LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data;
  770. // rez in the script active by default, rez in
  771. // inactive if the control key is being held down.
  772. BOOL active = ((mask & MASK_CONTROL) == 0);
  773. LLToolDragAndDrop::dropScript(object, item, active,
  774. LLToolDragAndDrop::getInstance()->getSource(),
  775. LLToolDragAndDrop::getInstance()->getSourceID());
  776. }
  777. break;
  778. default:
  779. break;
  780. }
  781. }
  782. return accept;
  783. }
  784. ///----------------------------------------------------------------------------
  785. /// Class LLTaskTextureBridge
  786. ///----------------------------------------------------------------------------
  787. class LLTaskTextureBridge : public LLTaskInvFVBridge
  788. {
  789. public:
  790. LLTaskTextureBridge(LLPanelObjectInventory* panel,
  791. const LLUUID& uuid,
  792. const std::string& name) :
  793. LLTaskInvFVBridge(panel, uuid, name) {}
  794. virtual BOOL canOpenItem() const { return TRUE; }
  795. virtual void openItem();
  796. };
  797. void LLTaskTextureBridge::openItem()
  798. {
  799. llinfos << "LLTaskTextureBridge::openItem()" << llendl;
  800. LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
  801. if(preview)
  802. {
  803. preview->setObjectID(mPanel->getTaskUUID());
  804. }
  805. }
  806. ///----------------------------------------------------------------------------
  807. /// Class LLTaskSoundBridge
  808. ///----------------------------------------------------------------------------
  809. class LLTaskSoundBridge : public LLTaskInvFVBridge
  810. {
  811. public:
  812. LLTaskSoundBridge(LLPanelObjectInventory* panel,
  813. const LLUUID& uuid,
  814. const std::string& name) :
  815. LLTaskInvFVBridge(panel, uuid, name) {}
  816. virtual BOOL canOpenItem() const { return TRUE; }
  817. virtual void openItem();
  818. virtual void performAction(LLInventoryModel* model, std::string action);
  819. virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
  820. static void openSoundPreview(void* data);
  821. };
  822. void LLTaskSoundBridge::openItem()
  823. {
  824. openSoundPreview((void*)this);
  825. }
  826. void LLTaskSoundBridge::openSoundPreview(void* data)
  827. {
  828. LLTaskSoundBridge* self = (LLTaskSoundBridge*)data;
  829. if(!self)
  830. return;
  831. LLPreviewSound* preview = LLFloaterReg::showTypedInstance<LLPreviewSound>("preview_sound", LLSD(self->mUUID), TAKE_FOCUS_YES);
  832. if (preview)
  833. {
  834. preview->setObjectID(self->mPanel->getTaskUUID());
  835. }
  836. }
  837. // virtual
  838. void LLTaskSoundBridge::performAction(LLInventoryModel* model, std::string action)
  839. {
  840. if (action == "task_play")
  841. {
  842. LLInventoryItem* item = findItem();
  843. if(item)
  844. {
  845. send_sound_trigger(item->getAssetUUID(), 1.0);
  846. }
  847. }
  848. LLTaskInvFVBridge::performAction(model, action);
  849. }
  850. void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
  851. {
  852. LLInventoryItem* item = findItem();
  853. if(!item) return;
  854. std::vector<std::string> items;
  855. std::vector<std::string> disabled_items;
  856. if(item->getPermissions().getOwner() != gAgent.getID()
  857. && item->getSaleInfo().isForSale())
  858. {
  859. items.push_back(std::string("Task Buy"));
  860. std::string label= LLTrans::getString("Buy");
  861. // Check the price of the item.
  862. S32 price = getPrice();
  863. if (-1 == price)
  864. {
  865. llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
  866. }
  867. else
  868. {
  869. std::ostringstream info;
  870. info << LLTrans::getString("BuyforL$") << price;
  871. label.assign(info.str());
  872. }
  873. const LLView::child_list_t *list = menu.getChildList();
  874. LLView::child_list_t::const_iterator itor;
  875. for (itor = list->begin(); itor != list->end(); ++itor)
  876. {
  877. std::string name = (*itor)->getName();
  878. LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
  879. if (name == "Task Buy" && menu_itemp)
  880. {
  881. menu_itemp->setLabel(label);
  882. }
  883. }
  884. }
  885. else if (canOpenItem())
  886. {
  887. if (!isItemCopyable())
  888. {
  889. disabled_items.push_back(std::string("Task Open"));
  890. }
  891. }
  892. items.push_back(std::string("Task Properties"));
  893. if(isItemRenameable())
  894. {
  895. items.push_back(std::string("Task Rename"));
  896. }
  897. if(isItemRemovable())
  898. {
  899. items.push_back(std::string("Task Remove"));
  900. }
  901. items.push_back(std::string("Task Play"));
  902. hide_context_entries(menu, items, disabled_items);
  903. }
  904. ///----------------------------------------------------------------------------
  905. /// Class LLTaskLandmarkBridge
  906. ///----------------------------------------------------------------------------
  907. class LLTaskLandmarkBridge : public LLTaskInvFVBridge
  908. {
  909. public:
  910. LLTaskLandmarkBridge(LLPanelObjectInventory* panel,
  911. const LLUUID& uuid,
  912. const std::string& name) :
  913. LLTaskInvFVBridge(panel, uuid, name) {}
  914. };
  915. ///----------------------------------------------------------------------------
  916. /// Class LLTaskCallingCardBridge
  917. ///----------------------------------------------------------------------------
  918. class LLTaskCallingCardBridge : public LLTaskInvFVBridge
  919. {
  920. public:
  921. LLTaskCallingCardBridge(LLPanelObjectInventory* panel,
  922. const LLUUID& uuid,
  923. const std::string& name) :
  924. LLTaskInvFVBridge(panel, uuid, name) {}
  925. virtual BOOL isItemRenameable() const;
  926. virtual BOOL renameItem(const std::string& new_name);
  927. };
  928. BOOL LLTaskCallingCardBridge::isItemRenameable() const
  929. {
  930. return FALSE;
  931. }
  932. BOOL LLTaskCallingCardBridge::renameItem(const std::string& new_name)
  933. {
  934. return FALSE;
  935. }
  936. ///----------------------------------------------------------------------------
  937. /// Class LLTaskScriptBridge
  938. ///----------------------------------------------------------------------------
  939. class LLTaskScriptBridge : public LLTaskInvFVBridge
  940. {
  941. public:
  942. LLTaskScriptBridge(LLPanelObjectInventory* panel,
  943. const LLUUID& uuid,
  944. const std::string& name) :
  945. LLTaskInvFVBridge(panel, uuid, name) {}
  946. //static BOOL enableIfCopyable( void* userdata );
  947. };
  948. class LLTaskLSLBridge : public LLTaskScriptBridge
  949. {
  950. public:
  951. LLTaskLSLBridge(LLPanelObjectInventory* panel,
  952. const LLUUID& uuid,
  953. const std::string& name) :
  954. LLTaskScriptBridge(panel, uuid, name) {}
  955. virtual BOOL canOpenItem() const { return TRUE; }
  956. virtual void openItem();
  957. virtual BOOL removeItem();
  958. //virtual void buildContextMenu(LLMenuGL& menu);
  959. //static void copyToInventory(void* userdata);
  960. };
  961. void LLTaskLSLBridge::openItem()
  962. {
  963. llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl;
  964. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  965. if(!object || object->isInventoryPending())
  966. {
  967. return;
  968. }
  969. if (object->permModify() || gAgent.isGodlike())
  970. {
  971. LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", LLSD(mUUID), TAKE_FOCUS_YES);
  972. if (preview)
  973. {
  974. preview->setObjectID(mPanel->getTaskUUID());
  975. }
  976. }
  977. else
  978. {
  979. LLNotificationsUtil::add("CannotOpenScriptObjectNoMod");
  980. }
  981. }
  982. BOOL LLTaskLSLBridge::removeItem()
  983. {
  984. LLFloaterReg::hideInstance("preview_scriptedit", LLSD(mUUID));
  985. return LLTaskInvFVBridge::removeItem();
  986. }
  987. ///----------------------------------------------------------------------------
  988. /// Class LLTaskObjectBridge
  989. ///----------------------------------------------------------------------------
  990. class LLTaskObjectBridge : public LLTaskInvFVBridge
  991. {
  992. public:
  993. LLTaskObjectBridge(LLPanelObjectInventory* panel,
  994. const LLUUID& uuid,
  995. const std::string& name,
  996. U32 flags = 0) :
  997. LLTaskInvFVBridge(panel, uuid, name, flags) {}
  998. };
  999. ///----------------------------------------------------------------------------
  1000. /// Class LLTaskNotecardBridge
  1001. ///----------------------------------------------------------------------------
  1002. class LLTaskNotecardBridge : public LLTaskInvFVBridge
  1003. {
  1004. public:
  1005. LLTaskNotecardBridge(LLPanelObjectInventory* panel,
  1006. const LLUUID& uuid,
  1007. const std::string& name) :
  1008. LLTaskInvFVBridge(panel, uuid, name) {}
  1009. virtual BOOL canOpenItem() const { return TRUE; }
  1010. virtual void openItem();
  1011. virtual BOOL removeItem();
  1012. };
  1013. void LLTaskNotecardBridge::openItem()
  1014. {
  1015. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  1016. if(!object || object->isInventoryPending())
  1017. {
  1018. return;
  1019. }
  1020. if(object->permModify() || gAgent.isGodlike())
  1021. {
  1022. LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(mUUID), TAKE_FOCUS_YES);
  1023. if (preview)
  1024. {
  1025. preview->setObjectID(mPanel->getTaskUUID());
  1026. }
  1027. }
  1028. }
  1029. BOOL LLTaskNotecardBridge::removeItem()
  1030. {
  1031. LLFloaterReg::hideInstance("preview_notecard", LLSD(mUUID));
  1032. return LLTaskInvFVBridge::removeItem();
  1033. }
  1034. ///----------------------------------------------------------------------------
  1035. /// Class LLTaskGestureBridge
  1036. ///----------------------------------------------------------------------------
  1037. class LLTaskGestureBridge : public LLTaskInvFVBridge
  1038. {
  1039. public:
  1040. LLTaskGestureBridge(LLPanelObjectInventory* panel,
  1041. const LLUUID& uuid,
  1042. const std::string& name) :
  1043. LLTaskInvFVBridge(panel, uuid, name) {}
  1044. virtual BOOL canOpenItem() const { return TRUE; }
  1045. virtual void openItem();
  1046. virtual BOOL removeItem();
  1047. };
  1048. void LLTaskGestureBridge::openItem()
  1049. {
  1050. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  1051. if(!object || object->isInventoryPending())
  1052. {
  1053. return;
  1054. }
  1055. LLPreviewGesture::show(mUUID, mPanel->getTaskUUID());
  1056. }
  1057. BOOL LLTaskGestureBridge::removeItem()
  1058. {
  1059. // Don't need to deactivate gesture because gestures inside objects can never be active.
  1060. LLFloaterReg::hideInstance("preview_gesture", LLSD(mUUID));
  1061. return LLTaskInvFVBridge::removeItem();
  1062. }
  1063. ///----------------------------------------------------------------------------
  1064. /// Class LLTaskAnimationBridge
  1065. ///----------------------------------------------------------------------------
  1066. class LLTaskAnimationBridge : public LLTaskInvFVBridge
  1067. {
  1068. public:
  1069. LLTaskAnimationBridge(LLPanelObjectInventory* panel,
  1070. const LLUUID& uuid,
  1071. const std::string& name) :
  1072. LLTaskInvFVBridge(panel, uuid, name) {}
  1073. virtual BOOL canOpenItem() const { return TRUE; }
  1074. virtual void openItem();
  1075. virtual BOOL removeItem();
  1076. };
  1077. void LLTaskAnimationBridge::openItem()
  1078. {
  1079. LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
  1080. if(!object || object->isInventoryPending())
  1081. {
  1082. return;
  1083. }
  1084. LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
  1085. if (preview && (object->permModify() || gAgent.isGodlike()))
  1086. {
  1087. preview->setObjectID(mPanel->getTaskUUID());
  1088. }
  1089. }
  1090. BOOL LLTaskAnimationBridge::removeItem()
  1091. {
  1092. LLFloaterReg::hideInstance("preview_anim", LLSD(mUUID));
  1093. return LLTaskInvFVBridge::removeItem();
  1094. }
  1095. ///----------------------------------------------------------------------------
  1096. /// Class LLTaskWearableBridge
  1097. ///----------------------------------------------------------------------------
  1098. class LLTaskWearableBridge : public LLTaskInvFVBridge
  1099. {
  1100. public:
  1101. LLTaskWearableBridge(LLPanelObjectInventory* panel,
  1102. const LLUUID& uuid,
  1103. const std::string& name,
  1104. U32 flags) :
  1105. LLTaskInvFVBridge(panel, uuid, name, flags) {}
  1106. virtual LLUIImagePtr getIcon() const;
  1107. };
  1108. LLUIImagePtr LLTaskWearableBridge::getIcon() const
  1109. {
  1110. return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE );
  1111. }
  1112. ///----------------------------------------------------------------------------
  1113. /// Class LLTaskMeshBridge
  1114. ///----------------------------------------------------------------------------
  1115. class LLTaskMeshBridge : public LLTaskInvFVBridge
  1116. {
  1117. public:
  1118. LLTaskMeshBridge(
  1119. LLPanelObjectInventory* panel,
  1120. const LLUUID& uuid,
  1121. const std::string& name);
  1122. virtual LLUIImagePtr getIcon() const;
  1123. virtual void openItem();
  1124. virtual void performAction(LLInventoryModel* model, std::string action);
  1125. virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
  1126. };
  1127. LLTaskMeshBridge::LLTaskMeshBridge(
  1128. LLPanelObjectInventory* panel,
  1129. const LLUUID& uuid,
  1130. const std::string& name) :
  1131. LLTaskInvFVBridge(panel, uuid, name)
  1132. {
  1133. }
  1134. LLUIImagePtr LLTaskMeshBridge::getIcon() const
  1135. {
  1136. return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
  1137. }
  1138. void LLTaskMeshBridge::openItem()
  1139. {
  1140. // open mesh
  1141. }
  1142. // virtual
  1143. void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action)
  1144. {
  1145. if (action == "mesh action")
  1146. {
  1147. LLInventoryItem* item = findItem();
  1148. if(item)
  1149. {
  1150. // do action
  1151. }
  1152. }
  1153. LLTaskInvFVBridge::performAction(model, action);
  1154. }
  1155. void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
  1156. {
  1157. LLInventoryItem* item = findItem();
  1158. if(!item) return;
  1159. std::vector<std::string> items;
  1160. std::vector<std::string> disabled_items;
  1161. if(item->getPermissions().getOwner() != gAgent.getID()
  1162. && item->getSaleInfo().isForSale())
  1163. {
  1164. items.push_back(std::string("Task Buy"));
  1165. std::string label= LLTrans::getString("Buy");
  1166. // Check the price of the item.
  1167. S32 price = getPrice();
  1168. if (-1 == price)
  1169. {
  1170. llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
  1171. }
  1172. else
  1173. {
  1174. std::ostringstream info;
  1175. info << LLTrans::getString("BuyforL$") << price;
  1176. label.assign(info.str());
  1177. }
  1178. const LLView::child_list_t *list = menu.getChildList();
  1179. LLView::child_list_t::const_iterator itor;
  1180. for (itor = list->begin(); itor != list->end(); ++itor)
  1181. {
  1182. std::string name = (*itor)->getName();
  1183. LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
  1184. if (name == "Task Buy" && menu_itemp)
  1185. {
  1186. menu_itemp->setLabel(label);
  1187. }
  1188. }
  1189. }
  1190. else
  1191. {
  1192. items.push_back(std::string("Task Open"));
  1193. if (!isItemCopyable())
  1194. {
  1195. disabled_items.push_back(std::string("Task Open"));
  1196. }
  1197. }
  1198. items.push_back(std::string("Task Properties"));
  1199. if(isItemRenameable())
  1200. {
  1201. items.push_back(std::string("Task Rename"));
  1202. }
  1203. if(isItemRemovable())
  1204. {
  1205. items.push_back(std::string("Task Remove"));
  1206. }
  1207. hide_context_entries(menu, items, disabled_items);
  1208. }
  1209. ///----------------------------------------------------------------------------
  1210. /// LLTaskInvFVBridge impl
  1211. //----------------------------------------------------------------------------
  1212. LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* panel,
  1213. LLInventoryObject* object)
  1214. {
  1215. LLTaskInvFVBridge* new_bridge = NULL;
  1216. const LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(object);
  1217. const U32 itemflags = ( NULL == item ? 0 : item->getFlags() );
  1218. LLAssetType::EType type = object ? object->getType() : LLAssetType::AT_CATEGORY;
  1219. LLUUID object_id = object ? object->getUUID() : LLUUID::null;
  1220. std::string object_name = object ? object->getName() : std::string();
  1221. switch(type)
  1222. {
  1223. case LLAssetType::AT_TEXTURE:
  1224. new_bridge = new LLTaskTextureBridge(panel,
  1225. object_id,
  1226. object_name);
  1227. break;
  1228. case LLAssetType::AT_SOUND:
  1229. new_bridge = new LLTaskSoundBridge(panel,
  1230. object_id,
  1231. object_name);
  1232. break;
  1233. case LLAssetType::AT_LANDMARK:
  1234. new_bridge = new LLTaskLandmarkBridge(panel,
  1235. object_id,
  1236. object_name);
  1237. break;
  1238. case LLAssetType::AT_CALLINGCARD:
  1239. new_bridge = new LLTaskCallingCardBridge(panel,
  1240. object_id,
  1241. object_name);
  1242. break;
  1243. case LLAssetType::AT_SCRIPT:
  1244. // OLD SCRIPTS DEPRECATED - JC
  1245. llwarns << "Old script" << llendl;
  1246. //new_bridge = new LLTaskOldScriptBridge(panel,
  1247. // object_id,
  1248. // object_name);
  1249. break;
  1250. case LLAssetType::AT_OBJECT:
  1251. new_bridge = new LLTaskObjectBridge(panel,
  1252. object_id,
  1253. object_name,
  1254. itemflags);
  1255. break;
  1256. case LLAssetType::AT_NOTECARD:
  1257. new_bridge = new LLTaskNotecardBridge(panel,
  1258. object_id,
  1259. object_name);
  1260. break;
  1261. case LLAssetType::AT_ANIMATION:
  1262. new_bridge = new LLTaskAnimationBridge(panel,
  1263. object_id,
  1264. object_name);
  1265. break;
  1266. case LLAssetType::AT_GESTURE:
  1267. new_bridge = new LLTaskGestureBridge(panel,
  1268. object_id,
  1269. object_name);
  1270. break;
  1271. case LLAssetType::AT_CLOTHING:
  1272. case LLAssetType::AT_BODYPART:
  1273. new_bridge = new LLTaskWearableBridge(panel,
  1274. object_id,
  1275. object_name,
  1276. itemflags);
  1277. break;
  1278. case LLAssetType::AT_CATEGORY:
  1279. new_bridge = new LLTaskCategoryBridge(panel,
  1280. object_id,
  1281. object_name);
  1282. break;
  1283. case LLAssetType::AT_LSL_TEXT:
  1284. new_bridge = new LLTaskLSLBridge(panel,
  1285. object_id,
  1286. object_name);
  1287. break;
  1288. case LLAssetType::AT_MESH:
  1289. new_bridge = new LLTaskMeshBridge(panel,
  1290. object_id,
  1291. object_name);
  1292. break;
  1293. default:
  1294. llinfos << "Unhandled inventory type (llassetstorage.h): "
  1295. << (S32)type << llendl;
  1296. break;
  1297. }
  1298. return new_bridge;
  1299. }
  1300. ///----------------------------------------------------------------------------
  1301. /// Class LLPanelObjectInventory
  1302. ///----------------------------------------------------------------------------
  1303. static LLDefaultChildRegistry::Register<LLPanelObjectInventory> r("panel_inventory_object");
  1304. void do_nothing()
  1305. {
  1306. }
  1307. // Default constructor
  1308. LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Params& p) :
  1309. LLPanel(p),
  1310. mScroller(NULL),
  1311. mFolders(NULL),
  1312. mHaveInventory(FALSE),
  1313. mIsInventoryEmpty(TRUE),
  1314. mInventoryNeedsUpdate(FALSE)
  1315. {
  1316. // Setup context menu callbacks
  1317. mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2));
  1318. mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
  1319. mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
  1320. mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
  1321. mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
  1322. mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
  1323. mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
  1324. }
  1325. // Destroys the object
  1326. LLPanelObjectInventory::~LLPanelObjectInventory()
  1327. {
  1328. if (!gIdleCallbacks.deleteFunction(idle, this))
  1329. {
  1330. llwarns << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << llendl;
  1331. }
  1332. }
  1333. BOOL LLPanelObjectInventory::postBuild()
  1334. {
  1335. // clear contents and initialize menus, sets up mFolders
  1336. reset();
  1337. // Register an idle update callback
  1338. gIdleCallbacks.addFunction(idle, this);
  1339. return TRUE;
  1340. }
  1341. void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
  1342. {
  1343. mFolders->doToSelected(&gInventory, userdata);
  1344. }
  1345. void LLPanelObjectInventory::clearContents()
  1346. {
  1347. mHaveInventory = FALSE;
  1348. mIsInventoryEmpty = TRUE;
  1349. if (LLToolDragAndDrop::getInstance() && LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_WORLD)
  1350. {
  1351. LLToolDragAndDrop::getInstance()->endDrag();
  1352. }
  1353. if( mScroller )
  1354. {
  1355. // removes mFolders
  1356. removeChild( mScroller ); //*TODO: Really shouldn't do this during draw()/refresh()
  1357. mScroller->die();
  1358. mScroller = NULL;
  1359. mFolders = NULL;
  1360. }
  1361. }
  1362. void LLPanelObjectInventory::reset()
  1363. {
  1364. clearContents();
  1365. //setBorderVisible(FALSE);
  1366. mCommitCallbackRegistrar.pushScope(); // push local callbacks
  1367. LLRect dummy_rect(0, 1, 1, 0);
  1368. LLFolderView::Params p;
  1369. p.name = "task inventory";
  1370. p.title = "task inventory";
  1371. p.task_id = getTaskUUID();
  1372. p.parent_panel = this;
  1373. p.tool_tip= LLTrans::getString("PanelContentsTooltip");
  1374. p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
  1375. mFolders = LLUICtrlFactory::create<LLFolderView>(p);
  1376. // this ensures that we never say "searching..." or "no items found"
  1377. mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
  1378. mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
  1379. if (hasFocus())
  1380. {
  1381. LLEditMenuHandler::gEditMenuHandler = mFolders;
  1382. }
  1383. LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
  1384. LLScrollContainer::Params scroll_p;
  1385. scroll_p.name("task inventory scroller");
  1386. scroll_p.rect(scroller_rect);
  1387. scroll_p.tab_stop(true);
  1388. scroll_p.follows.flags(FOLLOWS_ALL);
  1389. mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_p);
  1390. addChild(mScroller);
  1391. mScroller->addChild(mFolders);
  1392. mFolders->setScrollContainer( mScroller );
  1393. mCommitCallbackRegistrar.popScope();
  1394. }
  1395. void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
  1396. LLInventoryObject::object_list_t* inventory,
  1397. S32 serial_num,
  1398. void* data)
  1399. {
  1400. if(!object) return;
  1401. //llinfos << "invetnory arrived: \n"
  1402. // << " panel UUID: " << panel->mTaskUUID << "\n"
  1403. // << " task UUID: " << object->mID << llendl;
  1404. if(mTaskUUID == object->mID)
  1405. {
  1406. mInventoryNeedsUpdate = TRUE;
  1407. }
  1408. // refresh any properties floaters that are hanging around.
  1409. if(inventory)
  1410. {
  1411. for (LLInventoryObject::object_list_t::const_iterator iter = inventory->begin();
  1412. iter != inventory->end(); )
  1413. {
  1414. LLInventoryObject* item = *iter++;
  1415. LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID());
  1416. if(floater)
  1417. {
  1418. floater->refresh();
  1419. }
  1420. }
  1421. }
  1422. }
  1423. void LLPanelObjectInventory::updateInventory()
  1424. {
  1425. //llinfos << "inventory arrived: \n"
  1426. // << " panel UUID: " << panel->mTaskUUID << "\n"
  1427. // << " task UUID: " << object->mID << llendl;
  1428. // We're still interested in this task's inventory.
  1429. std::set<LLUUID> selected_items;
  1430. BOOL inventory_has_focus = FALSE;
  1431. if (mHaveInventory)
  1432. {
  1433. selected_items = mFolders->getSelectionList();
  1434. inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
  1435. }
  1436. reset();
  1437. LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
  1438. if (objectp)
  1439. {
  1440. LLInventoryObject* inventory_root = objectp->getInventoryRoot();
  1441. LLInventoryObject::object_list_t contents;
  1442. objectp->getInventoryContents(contents);
  1443. if (inventory_root)
  1444. {
  1445. createFolderViews(inventory_root, contents);
  1446. mHaveInventory = TRUE;
  1447. mIsInventoryEmpty = FALSE;
  1448. mFolders->setEnabled(TRUE);
  1449. }
  1450. else
  1451. {
  1452. // TODO: create an empty inventory
  1453. mIsInventoryEmpty = TRUE;
  1454. mHaveInventory = TRUE;
  1455. }
  1456. }
  1457. else
  1458. {
  1459. // TODO: create an empty inventory
  1460. mIsInventoryEmpty = TRUE;
  1461. mHaveInventory = TRUE;
  1462. }
  1463. // restore previous selection
  1464. std::set<LLUUID>::iterator selection_it;
  1465. BOOL first_item = TRUE;
  1466. for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
  1467. {
  1468. LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
  1469. if (selected_item)
  1470. {
  1471. //HACK: "set" first item then "change" each other one to get keyboard focus right
  1472. if (first_item)
  1473. {
  1474. mFolders->setSelection(selected_item, TRUE, inventory_has_focus);
  1475. first_item = FALSE;
  1476. }
  1477. else
  1478. {
  1479. mFolders->changeSelection(selected_item, TRUE);
  1480. }
  1481. }
  1482. }
  1483. mFolders->requestArrange();
  1484. mInventoryNeedsUpdate = FALSE;
  1485. // Edit menu handler is set in onFocusReceived
  1486. }
  1487. // *FIX: This is currently a very expensive operation, because we have
  1488. // to iterate through the inventory one time for each category. This
  1489. // leads to an N^2 based on the category count. This could be greatly
  1490. // speeded with an efficient multimap implementation, but we don't
  1491. // have that in our current arsenal.
  1492. void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root, LLInventoryObject::object_list_t& contents)
  1493. {
  1494. if (!inventory_root)
  1495. {
  1496. return;
  1497. }
  1498. // Create a visible root category.
  1499. LLTaskInvFVBridge* bridge = NULL;
  1500. bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
  1501. if(bridge)
  1502. {
  1503. LLFolderViewFolder* new_folder = NULL;
  1504. LLFolderViewFolder::Params p;
  1505. p.name = inventory_root->getName();
  1506. p.icon = LLUI::getUIImage("Inv_FolderClosed");
  1507. p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
  1508. p.root = mFolders;
  1509. p.listener = bridge;
  1510. p.tool_tip = p.name;
  1511. new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
  1512. new_folder->addToFolder(mFolders, mFolders);
  1513. new_folder->toggleOpen();
  1514. createViewsForCategory(&contents, inventory_root, new_folder);
  1515. }
  1516. }
  1517. typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair;
  1518. void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_list_t* inventory,
  1519. LLInventoryObject* parent,
  1520. LLFolderViewFolder* folder)
  1521. {
  1522. // Find all in the first pass
  1523. LLDynamicArray<obj_folder_pair*> child_categories;
  1524. LLTaskInvFVBridge* bridge;
  1525. LLFolderViewItem* view;
  1526. LLInventoryObject::object_list_t::iterator it = inventory->begin();
  1527. LLInventoryObject::object_list_t::iterator end = inventory->end();
  1528. for( ; it != end; ++it)
  1529. {
  1530. LLInventoryObject* obj = *it;
  1531. if(parent->getUUID() == obj->getParentUUID())
  1532. {
  1533. bridge = LLTaskInvFVBridge::createObjectBridge(this, obj);
  1534. if(!bridge)
  1535. {
  1536. continue;
  1537. }
  1538. if(LLAssetType::AT_CATEGORY == obj->getType())
  1539. {
  1540. LLFolderViewFolder::Params p;
  1541. p.name = obj->getName();
  1542. p.icon = LLUI::getUIImage("Inv_FolderClosed");
  1543. p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
  1544. p.root = mFolders;
  1545. p.listener = bridge;
  1546. p.tool_tip = p.name;
  1547. view = LLUICtrlFactory::create<LLFolderViewFolder>(p);
  1548. child_categories.put(new obj_folder_pair(obj,
  1549. (LLFolderViewFolder*)view));
  1550. }
  1551. else
  1552. {
  1553. LLFolderViewItem::Params params;
  1554. params.name(obj->getName());
  1555. params.icon(bridge->getIcon());
  1556. params.creation_date(bridge->getCreationDate());
  1557. params.root(mFolders);
  1558. params.listener(bridge);
  1559. params.rect(LLRect());
  1560. params.tool_tip = params.name;
  1561. view = LLUICtrlFactory::create<LLFolderViewItem> (params);
  1562. }
  1563. view->addToFolder(folder, mFolders);
  1564. }
  1565. }
  1566. // now, for each category, do the second pass
  1567. for(S32 i = 0; i < child_categories.count(); i++)
  1568. {
  1569. createViewsForCategory(inventory, child_categories[i]->first,
  1570. child_categories[i]->second );
  1571. delete child_categories[i];
  1572. }
  1573. }
  1574. void LLPanelObjectInventory::refresh()
  1575. {
  1576. //llinfos << "LLPanelObjectInventory::refresh()" << llendl;
  1577. BOOL has_inventory = FALSE;
  1578. const BOOL non_root_ok = TRUE;
  1579. LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok);
  1580. if(node)
  1581. {
  1582. LLViewerObject* object = node->getObject();
  1583. if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
  1584. || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
  1585. {
  1586. // determine if we need to make a request. Start with a
  1587. // default based on if we have inventory at all.
  1588. BOOL make_request = !mHaveInventory;
  1589. // If the task id is different than what we've stored,
  1590. // then make the request.
  1591. if(mTaskUUID != object->mID)
  1592. {
  1593. mTaskUUID = object->mID;
  1594. make_request = TRUE;
  1595. // This is a new object so pre-emptively clear the contents
  1596. // Otherwise we show the old stuff until the update comes in
  1597. clearContents();
  1598. // Register for updates from this object,
  1599. registerVOInventoryListener(object,NULL);
  1600. }
  1601. // Based on the node information, we may need to dirty the
  1602. // object inventory and get it again.
  1603. if(node->mValid)
  1604. {
  1605. if(node->mInventorySerial != object->getInventorySerial() || object->isInventoryDirty())
  1606. {
  1607. make_request = TRUE;
  1608. }
  1609. }
  1610. // do the request if necessary.
  1611. if(make_request)
  1612. {
  1613. requestVOInventory();
  1614. }
  1615. has_inventory = TRUE;
  1616. }
  1617. }
  1618. if(!has_inventory)
  1619. {
  1620. mTaskUUID = LLUUID::null;
  1621. removeVOInventoryListener();
  1622. clearContents();
  1623. }
  1624. //llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl;
  1625. }
  1626. void LLPanelObjectInventory::removeSelectedItem()
  1627. {
  1628. if(mFolders)
  1629. {
  1630. mFolders->removeSelectedItems();
  1631. }
  1632. }
  1633. void LLPanelObjectInventory::startRenamingSelectedItem()
  1634. {
  1635. if(mFolders)
  1636. {
  1637. mFolders->startRenamingSelectedItem();
  1638. }
  1639. }
  1640. void LLPanelObjectInventory::draw()
  1641. {
  1642. LLPanel::draw();
  1643. if(mIsInventoryEmpty)
  1644. {
  1645. if((LLUUID::null != mTaskUUID) && (!mHaveInventory))
  1646. {
  1647. LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("LoadingContents"), 0,
  1648. (S32)(getRect().getWidth() * 0.5f),
  1649. 10,
  1650. LLColor4( 1, 1, 1, 1 ),
  1651. LLFontGL::HCENTER,
  1652. LLFontGL::BOTTOM);
  1653. }
  1654. else if(mHaveInventory)
  1655. {
  1656. LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("NoContents"), 0,
  1657. (S32)(getRect().getWidth() * 0.5f),
  1658. 10,
  1659. LLColor4( 1, 1, 1, 1 ),
  1660. LLFontGL::HCENTER,
  1661. LLFontGL::BOTTOM);
  1662. }
  1663. }
  1664. }
  1665. void LLPanelObjectInventory::deleteAllChildren()
  1666. {
  1667. mScroller = NULL;
  1668. mFolders = NULL;
  1669. LLView::deleteAllChildren();
  1670. }
  1671. BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
  1672. {
  1673. if (mFolders && mHaveInventory)
  1674. {
  1675. LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
  1676. if (!folderp)
  1677. {
  1678. return FALSE;
  1679. }
  1680. // Try to pass on unmodified mouse coordinates
  1681. S32 local_x = x - mFolders->getRect().mLeft;
  1682. S32 local_y = y - mFolders->getRect().mBottom;
  1683. if (mFolders->pointInView(local_x, local_y))
  1684. {
  1685. return mFolders->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
  1686. }
  1687. else
  1688. {
  1689. //force mouse coordinates to be inside folder rectangle
  1690. return mFolders->handleDragAndDrop(5, 1, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
  1691. }
  1692. }
  1693. else
  1694. {
  1695. return FALSE;
  1696. }
  1697. }
  1698. //static
  1699. void LLPanelObjectInventory::idle(void* user_data)
  1700. {
  1701. LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data;
  1702. if (self->mInventoryNeedsUpdate)
  1703. {
  1704. self->updateInventory();
  1705. }
  1706. }
  1707. void LLPanelObjectInventory::onFocusLost()
  1708. {
  1709. // inventory no longer handles cut/copy/paste/delete
  1710. if (LLEditMenuHandler::gEditMenuHandler == mFolders)
  1711. {
  1712. LLEditMenuHandler::gEditMenuHandler = NULL;
  1713. }
  1714. LLPanel::onFocusLost();
  1715. }
  1716. void LLPanelObjectInventory::onFocusReceived()
  1717. {
  1718. // inventory now handles cut/copy/paste/delete
  1719. LLEditMenuHandler::gEditMenuHandler = mFolders;
  1720. LLPanel::onFocusReceived();
  1721. }