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

游戏引擎

开发平台:

C++ Builder

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