llpanelinventory.cpp 54 KB

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