llinventoryactions.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506
  1. /**
  2. * @file llinventoryactions.cpp
  3. * @brief Implementation of the actions associated with menu items.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-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. #include "llviewerprecompiledheaders.h"
  33. #include <utility>
  34. #include "llinventoryactions.h"
  35. #include "llnotifications.h"
  36. #include "lltrans.h"
  37. #include "llagent.h"
  38. #include "llappearancemgr.h"
  39. #include "llavatartracker.h"
  40. #include "llenvsettings.h"
  41. #include "llfloateravatarinfo.h"
  42. #include "llfloaterinventory.h"
  43. #include "hbfloatermakenewoutfit.h"
  44. #include "llfloaterperms.h"
  45. #include "llfloaterproperties.h"
  46. #include "llfloaterworldmap.h"
  47. #include "llfolderview.h"
  48. #include "llimmgr.h"
  49. #include "llinventorybridge.h"
  50. #include "llpanelinventory.h"
  51. #include "llpreviewanim.h"
  52. #include "llpreviewgesture.h"
  53. #include "llpreviewlandmark.h"
  54. #include "llpreviewmaterial.h"
  55. #include "llpreviewnotecard.h"
  56. #include "llpreviewscript.h"
  57. #include "llpreviewsound.h"
  58. #include "llpreviewtexture.h"
  59. //MK
  60. #include "mkrlinterface.h"
  61. //mk
  62. #include "llviewercontrol.h"
  63. #include "llviewerinventory.h"
  64. #include "llviewerregion.h"
  65. #include "llvoavatarself.h"
  66. #include "llwearablelist.h"
  67. using namespace LLOldEvents;
  68. const std::string NEW_LSL_NAME = "New script";
  69. const std::string NEW_NOTECARD_NAME = "New note";
  70. const std::string NEW_GESTURE_NAME = "New gesture";
  71. const std::string NEW_MATERIAL_NAME = "New material";
  72. typedef LLMemberListener<LLPanelInventory> object_inventory_listener_t;
  73. typedef LLMemberListener<LLFloaterInventory> inventory_listener_t;
  74. typedef LLMemberListener<LLInventoryPanel> inventory_panel_listener_t;
  75. static void create_category_cb(const LLUUID& cat_id, LLHandle<LLPanel> handle)
  76. {
  77. gInventory.notifyObservers();
  78. // If possible, select the newly created folder in the inventory panel
  79. // (when still around).
  80. LLInventoryPanel* panelp = (LLInventoryPanel*)handle.get();
  81. if (panelp)
  82. {
  83. panelp->setSelection(cat_id, true);
  84. LLFolderView* folderp = panelp->getRootFolder();
  85. LLFolderViewItem* itemp = folderp->getItemByID(cat_id);
  86. if (itemp)
  87. {
  88. itemp->setOpen(true);
  89. }
  90. }
  91. }
  92. static void move_to_folder_cb(const LLUUID& cat_id, uuid_vec_t selected_items,
  93. LLHandle<LLPanel> handle)
  94. {
  95. if (cat_id.isNull())
  96. {
  97. return;
  98. }
  99. gInventory.notifyObservers();
  100. reparent_to_folder(cat_id, selected_items);
  101. create_category_cb(cat_id, handle);
  102. }
  103. static bool move_to_folder(LLInventoryPanel* panelp,
  104. uuid_vec_t selected_items,
  105. const LLSD& notification, const LLSD& response)
  106. {
  107. if (LLNotification::getSelectedOption(notification, response) == 0)
  108. {
  109. std::string folder_name = response["message"].asString();
  110. LLInventoryObject::correctInventoryName(folder_name);
  111. if (folder_name.empty())
  112. {
  113. folder_name = "New folder";
  114. }
  115. LLInventoryObject* invobjp = gInventory.getObject(selected_items[0]);
  116. if (!invobjp)
  117. {
  118. return false;
  119. }
  120. LLHandle<LLPanel> handle;
  121. if (panelp)
  122. {
  123. handle = panelp->getHandle();
  124. }
  125. inventory_func_t func = boost::bind(&move_to_folder_cb, _1,
  126. selected_items, handle);
  127. gInventory.createNewCategory(invobjp->getParentUUID(),
  128. LLFolderType::FT_NONE, folder_name, func);
  129. }
  130. return false;
  131. }
  132. bool doToSelected(LLInventoryPanel* panelp, LLFolderView* folderp,
  133. const std::string& action)
  134. {
  135. LLInventoryModel* modelp = &gInventory;
  136. if (action == "rename")
  137. {
  138. folderp->startRenamingSelectedItem();
  139. return true;
  140. }
  141. if (action == "delete")
  142. {
  143. folderp->removeSelectedItems();
  144. modelp->checkTrashOverflow();
  145. return true;
  146. }
  147. if (action == "copy")
  148. {
  149. folderp->copy();
  150. return true;
  151. }
  152. if (action == "cut")
  153. {
  154. folderp->cut();
  155. return true;
  156. }
  157. if (action == "paste")
  158. {
  159. folderp->paste();
  160. return true;
  161. }
  162. uuid_vec_t selected_items;
  163. folderp->getSelection(selected_items);
  164. if (panelp && action == "group")
  165. {
  166. if (movable_objects_with_same_parent(selected_items))
  167. {
  168. gNotifications.add("CreateSubfolder", LLSD(), LLSD(),
  169. boost::bind(&move_to_folder, panelp,
  170. selected_items, _1, _2));
  171. }
  172. return true;
  173. }
  174. if (panelp && action == "degroup")
  175. {
  176. if (selected_items.size() != 1)
  177. {
  178. return true;
  179. }
  180. LLUUID cat_id = selected_items[0];
  181. LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
  182. if (!cat)
  183. {
  184. return true;
  185. }
  186. const LLUUID& parent_id = cat->getParentUUID();
  187. if (parent_id.isNull())
  188. {
  189. return true;
  190. }
  191. LLInventoryModel::cat_array_t* cats;
  192. LLInventoryModel::item_array_t* items;
  193. gInventory.getDirectDescendentsOf(cat_id, cats, items);
  194. // NOTE: we cannot direclty use the pointers to inventory objects in
  195. // cats and items (because these are pointer on the internal inventory
  196. // structure that itself gets modifed as we move the objects): we must
  197. // instead collect all the UUIDs, and then use our reparent_to_folder()
  198. // utility function. HB
  199. selected_items.clear();
  200. typedef LLInventoryModel::cat_array_t::const_iterator cat_it_t;
  201. for (cat_it_t it = cats->begin(), end = cats->end(); it != end; ++it)
  202. {
  203. selected_items.emplace_back(it->get()->getUUID());
  204. }
  205. typedef LLInventoryModel::item_array_t::const_iterator item_it_t;
  206. for (item_it_t it = items->begin(), end = items->end(); it != end;
  207. ++it)
  208. {
  209. selected_items.emplace_back(it->get()->getUUID());
  210. }
  211. reparent_to_folder(parent_id, selected_items);
  212. cat = gInventory.getCategory(cat_id);
  213. if (cat)
  214. {
  215. const LLUUID& trash_id = gInventory.getTrashID();
  216. if (trash_id.notNull())
  217. {
  218. gInventory.changeCategoryParent(cat, trash_id, false);
  219. gInventory.notifyObservers();
  220. }
  221. }
  222. return true;
  223. }
  224. LLMultiPreview* multi_previewp = NULL;
  225. LLMultiProperties* multi_propertiesp = NULL;
  226. { // Scope for LLHostFloater (must be closed before calling open() on the
  227. // multi-preview). HB
  228. LLHostFloater host;
  229. if (selected_items.size() > 1)
  230. {
  231. if (action == "task_open" || action == "open")
  232. {
  233. bool open_multi_preview = true;
  234. for (U32 i = 0, count = selected_items.size(); i < count; ++i)
  235. {
  236. const LLUUID& id = selected_items[i];
  237. LLFolderViewItem* folder_item = folderp->getItemByID(id);
  238. if (!folder_item)
  239. {
  240. continue;
  241. }
  242. LLInvFVBridge* bridge =
  243. dynamic_cast<LLInvFVBridge*>(folder_item->getListener());
  244. if (bridge && !bridge->isMultiPreviewAllowed())
  245. {
  246. open_multi_preview = false;
  247. break;
  248. }
  249. }
  250. if (open_multi_preview)
  251. {
  252. S32 left, top;
  253. gFloaterViewp->getNewFloaterPosition(&left, &top);
  254. multi_previewp = new LLMultiPreview(LLRect(left, top,
  255. left + 300,
  256. top - 100));
  257. gFloaterViewp->addChild(multi_previewp);
  258. host.set(multi_previewp);
  259. }
  260. }
  261. else if (action == "task_properties" || action == "properties")
  262. {
  263. S32 left, top;
  264. gFloaterViewp->getNewFloaterPosition(&left, &top);
  265. multi_propertiesp = new LLMultiProperties(LLRect(left, top,
  266. left + 100,
  267. top - 100));
  268. gFloaterViewp->addChild(multi_propertiesp);
  269. host.set(multi_propertiesp);
  270. }
  271. }
  272. for (U32 i = 0, count = selected_items.size(); i < count; ++i)
  273. {
  274. const LLUUID& id = selected_items[i];
  275. LLFolderViewItem* folder_item = folderp->getItemByID(id);
  276. if (folder_item)
  277. {
  278. LLFolderViewEventListener* listener =
  279. folder_item->getListener();
  280. if (listener)
  281. {
  282. listener->performAction(folderp, modelp, action);
  283. }
  284. }
  285. }
  286. }
  287. if (multi_previewp)
  288. {
  289. multi_previewp->open();
  290. }
  291. else if (multi_propertiesp)
  292. {
  293. multi_propertiesp->open();
  294. }
  295. return true;
  296. }
  297. class LLDoToSelectedPanel : public object_inventory_listener_t
  298. {
  299. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  300. {
  301. std::string action = userdata.asString();
  302. LLPanelInventory* panelp = mPtr;
  303. LLFolderView* folderp = panelp->getRootFolder();
  304. if (!folderp) return true;
  305. return doToSelected(NULL, folderp, action);
  306. }
  307. };
  308. class LLDoToSelectedFloater : public inventory_listener_t
  309. {
  310. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  311. {
  312. std::string action = userdata.asString();
  313. LLInventoryPanel* panelp = mPtr->getPanel();
  314. LLFolderView* folderp = panelp->getRootFolder();
  315. if (!folderp) return true;
  316. return doToSelected(panelp, folderp, action);
  317. }
  318. };
  319. class LLDoToSelected : public inventory_panel_listener_t
  320. {
  321. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  322. {
  323. std::string action = userdata.asString();
  324. LLInventoryPanel* panelp = mPtr;
  325. LLFolderView* folderp = panelp->getRootFolder();
  326. if (!folderp) return true;
  327. return doToSelected(panelp, folderp, action);
  328. }
  329. };
  330. class LLNewWindow : public inventory_listener_t
  331. {
  332. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  333. {
  334. LLInventoryPanel* panelp = mPtr->getActivePanel();
  335. if (!panelp) return true; // Paranoia
  336. LLRect rect(gSavedSettings.getRect("FloaterInventoryRect"));
  337. S32 left = 0 , top = 0;
  338. gFloaterViewp->getNewFloaterPosition(&left, &top);
  339. rect.setLeftTopAndSize(left, top, rect.getWidth(), rect.getHeight());
  340. LLFloaterInventory* floaterp =
  341. new LLFloaterInventory("Inventory", rect, panelp->getModel());
  342. floaterp->getActivePanel()->setFilterTypes(panelp->getFilterTypes());
  343. floaterp->getActivePanel()->setFilterSubString(panelp->getFilterSubString());
  344. floaterp->open();
  345. // Force on screen
  346. gFloaterViewp->adjustToFitScreen(floaterp);
  347. return true;
  348. }
  349. };
  350. class LLShowFilters : public inventory_listener_t
  351. {
  352. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  353. {
  354. mPtr->toggleFindOptions();
  355. return true;
  356. }
  357. };
  358. class LLResetFilter : public inventory_listener_t
  359. {
  360. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  361. {
  362. if (!mPtr->getActivePanel()) return true; // Paranoia
  363. LLFloaterInventoryFilters* filters = mPtr->getInvFilters();
  364. mPtr->getActivePanel()->getFilter()->resetDefault();
  365. if (filters)
  366. {
  367. filters->updateElementsFromFilter();
  368. }
  369. mPtr->setFilterTextFromFilter();
  370. return true;
  371. }
  372. };
  373. class LLCloseAllFolders : public inventory_panel_listener_t
  374. {
  375. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  376. {
  377. mPtr->closeAllFolders();
  378. return true;
  379. }
  380. };
  381. class LLCloseAllFoldersFloater : public inventory_listener_t
  382. {
  383. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  384. {
  385. if (mPtr->getPanel()) // Paranoia
  386. {
  387. mPtr->getPanel()->closeAllFolders();
  388. }
  389. return true;
  390. }
  391. };
  392. class LLEmptyTrash : public inventory_panel_listener_t
  393. {
  394. protected:
  395. LOG_CLASS(LLEmptyTrash);
  396. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  397. {
  398. LLInventoryModel* modelp = mPtr->getModel();
  399. if (!modelp) return true;
  400. const LLUUID& trash_id = modelp->getTrashID();
  401. if (trash_id.isNull() || !modelp->isCategoryComplete(trash_id))
  402. {
  403. llwarns << "Not purging the incompletely downloaded Trash folder"
  404. << llendl;
  405. return true;
  406. }
  407. gNotifications.add("ConfirmEmptyTrash", LLSD(), LLSD(),
  408. boost::bind(&LLEmptyTrash::cb_empty_trash,
  409. this, _1, _2));
  410. return true;
  411. }
  412. bool cb_empty_trash(const LLSD& notification, const LLSD& response)
  413. {
  414. if (LLNotification::getSelectedOption(notification, response) == 0)
  415. {
  416. LLInventoryModel* modelp = mPtr->getModel();
  417. if (modelp)
  418. {
  419. const LLUUID& trash_id = modelp->getTrashID();
  420. if (trash_id.isNull())
  421. {
  422. llwarns << "Could not find the Trash folder" << llendl;
  423. return false;
  424. }
  425. purge_descendents_of(trash_id);
  426. modelp->notifyObservers();
  427. }
  428. }
  429. return false;
  430. }
  431. };
  432. class LLEmptyLostAndFound : public inventory_panel_listener_t
  433. {
  434. protected:
  435. LOG_CLASS(LLEmptyLostAndFound);
  436. bool handleEvent(LLPointer<LLEvent> event, const LLSD&)
  437. {
  438. LLInventoryModel* modelp = mPtr->getModel();
  439. if (!modelp) return true;
  440. const LLUUID& laf_id = modelp->getLostAndFoundID();
  441. if (laf_id.isNull() || !modelp->isCategoryComplete(laf_id))
  442. {
  443. llwarns << "Not purging the incompletely downloaded Lost and found folder"
  444. << llendl;
  445. return true;
  446. }
  447. gNotifications.add("ConfirmEmptyLostAndFound", LLSD(), LLSD(),
  448. boost::bind(&LLEmptyLostAndFound::cb_purge_laf,
  449. this, _1, _2));
  450. return true;
  451. }
  452. bool cb_purge_laf(const LLSD& notification, const LLSD& response)
  453. {
  454. if (LLNotification::getSelectedOption(notification, response) == 0)
  455. {
  456. LLInventoryModel* modelp = mPtr->getModel();
  457. if (!modelp) return false;
  458. const LLUUID& laf_id = modelp->getLostAndFoundID();
  459. if (laf_id.notNull())
  460. {
  461. purge_descendents_of(laf_id);
  462. modelp->notifyObservers();
  463. }
  464. }
  465. return false;
  466. }
  467. };
  468. class LLHideEmptySystemFolders : public inventory_listener_t
  469. {
  470. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  471. {
  472. bool hide = !gSavedSettings.getBool("HideEmptySystemFolders");
  473. gSavedSettings.setBool("HideEmptySystemFolders", hide);
  474. // Force a new filtering
  475. mPtr->getActivePanel()->getFilter()->setModified();
  476. return true;
  477. }
  478. };
  479. class LLHideMarketplaceFolder : public inventory_listener_t
  480. {
  481. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  482. {
  483. bool hide = !gSavedSettings.getBool("HideMarketplaceFolder");
  484. gSavedSettings.setBool("HideMarketplaceFolder", hide);
  485. // Force a new filtering
  486. mPtr->getActivePanel()->getFilter()->setModified();
  487. return true;
  488. }
  489. };
  490. class LLHideCurrentOutfitFolder : public inventory_listener_t
  491. {
  492. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  493. {
  494. bool hide = !gSavedSettings.getBool("HideCurrentOutfitFolder");
  495. gSavedSettings.setBool("HideCurrentOutfitFolder", hide);
  496. // Force a new filtering
  497. mPtr->getActivePanel()->getFilter()->setModified();
  498. return true;
  499. }
  500. };
  501. class LLCheckSystemFolders : public inventory_listener_t
  502. {
  503. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  504. {
  505. LLInventoryModel::checkSystemFolders();
  506. return true;
  507. }
  508. };
  509. class LLResyncCallingCards : public inventory_listener_t
  510. {
  511. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  512. {
  513. const LLUUID& parent_id =
  514. gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
  515. LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
  516. if (!cat) return true;
  517. // First, get the list of existing calling cards in the folder and its
  518. // sub-folders.
  519. LLBuddyCollector match_functor;
  520. LLInventoryModel::cat_array_t cats;
  521. cats.emplace_back(cat);
  522. LLInventoryModel::item_array_t items;
  523. while (!cats.empty())
  524. {
  525. const LLUUID& cat_id = cats[0]->getUUID();
  526. cats.erase(cats.begin());
  527. gInventory.collectDescendentsIf(cat_id, cats, items,
  528. LLInventoryModel::EXCLUDE_TRASH,
  529. match_functor);
  530. }
  531. std::set<std::string> buddy_cards;
  532. for (U32 i = 0, count = items.size(); i < count; ++i)
  533. {
  534. buddy_cards.emplace(items[i]->getName());
  535. }
  536. items.clear();
  537. LLCollectAllBuddies collector;
  538. gAvatarTracker.applyFunctor(collector);
  539. typedef LLCollectAllBuddies::buddy_map_t::const_iterator buddies_it;
  540. for (buddies_it it = collector.mOnline.begin(),
  541. end = collector.mOnline.end();
  542. it != end; ++it)
  543. {
  544. if (buddy_cards.count(it->first))
  545. {
  546. continue;
  547. }
  548. create_new_item(it->first, parent_id, LLAssetType::AT_CALLINGCARD,
  549. LLInventoryType::IT_CALLINGCARD,
  550. PERM_ALL & ~PERM_MODIFY, it->second.asString());
  551. }
  552. for (buddies_it it = collector.mOffline.begin(),
  553. end = collector.mOffline.end();
  554. it != end; ++it)
  555. {
  556. if (buddy_cards.count(it->first))
  557. {
  558. continue;
  559. }
  560. create_new_item(it->first, parent_id, LLAssetType::AT_CALLINGCARD,
  561. LLInventoryType::IT_CALLINGCARD,
  562. PERM_ALL & ~PERM_MODIFY, it->second.asString());
  563. }
  564. return true;
  565. }
  566. };
  567. class LLMakeNewOutfit : public inventory_listener_t
  568. {
  569. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  570. {
  571. HBFloaterMakeNewOutfit::showInstance();
  572. return true;
  573. }
  574. };
  575. class LLEmptyTrashFloater : public inventory_listener_t
  576. {
  577. protected:
  578. LOG_CLASS(LLEmptyTrashFloater);
  579. bool handleEvent(LLPointer<LLEvent> event, const LLSD&)
  580. {
  581. LLInventoryModel* modelp = mPtr->getPanel()->getModel();
  582. if (modelp)
  583. {
  584. const LLUUID& trash_id = modelp->getTrashID();
  585. if (trash_id.notNull())
  586. {
  587. purge_descendents_of(trash_id);
  588. modelp->notifyObservers();
  589. }
  590. else
  591. {
  592. llwarns << "Could not find the Trash folder" << llendl;
  593. }
  594. }
  595. return true;
  596. }
  597. };
  598. #if 0 // Wear on create is not implemented/used in the Cool VL Viewer
  599. static void create_wearable(LLWearableType::EType type,
  600. const LLUUID& parent_id, bool wear = false)
  601. #else
  602. static void create_wearable(LLWearableType::EType type,
  603. const LLUUID& parent_id)
  604. #endif
  605. {
  606. if (type == LLWearableType::WT_INVALID ||
  607. type == LLWearableType::WT_NONE ||
  608. !isAgentAvatarValid())
  609. {
  610. return;
  611. }
  612. if (type == LLWearableType::WT_UNIVERSAL)
  613. {
  614. LLViewerRegion* regionp = gAgent.getRegion();
  615. if (!regionp || !regionp->bakesOnMeshEnabled())
  616. {
  617. llwarns << "Cannot create Universal wearable type in this region"
  618. << llendl;
  619. return;
  620. }
  621. }
  622. LLViewerWearable* wearable =
  623. LLWearableList::getInstance()->createNewWearable(type, gAgentAvatarp);
  624. LLAssetType::EType asset_type = wearable->getAssetType();
  625. LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
  626. #if 0 // Not implemented/used in the Cool VL Viewer
  627. LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL;
  628. #else
  629. LLPointer<LLInventoryCallback> cb = NULL;
  630. #endif
  631. LLUUID folder_id;
  632. if (parent_id.notNull())
  633. {
  634. folder_id = parent_id;
  635. }
  636. else
  637. {
  638. LLFolderType::EType folder_type =
  639. LLFolderType::assetTypeToFolderType(asset_type);
  640. folder_id = gInventory.findCategoryUUIDForType(folder_type);
  641. }
  642. create_inventory_item(folder_id, wearable->getTransactionID(),
  643. wearable->getName(), wearable->getDescription(),
  644. asset_type, inv_type, (U8)wearable->getType(),
  645. wearable->getPermissions().getMaskNextOwner(), cb);
  646. }
  647. static void do_create(LLInventoryModel* modelp, LLInventoryPanel* panelp,
  648. const std::string& type, LLFolderBridge* self = NULL)
  649. {
  650. if (type == "category")
  651. {
  652. const LLUUID& parent_id = self ? self->getUUID()
  653. : gInventory.getRootFolderID();
  654. LLHandle<LLPanel> handle;
  655. if (panelp)
  656. {
  657. handle = panelp->getHandle();
  658. }
  659. inventory_func_t func = boost::bind(&create_category_cb, _1, handle);
  660. modelp->createNewCategory(parent_id, LLFolderType::FT_NONE,
  661. LLStringUtil::null, func);
  662. }
  663. else if (type == "lsl")
  664. {
  665. U32 perms = PERM_MOVE | LLFloaterPerms::getNextOwnerPerms();
  666. if (gSavedSettings.getBool("NoModScripts"))
  667. {
  668. perms = perms & ~PERM_MODIFY;
  669. }
  670. const LLUUID& parent_id =
  671. self ? self->getUUID()
  672. : modelp->findCategoryUUIDForType(LLFolderType::FT_LSL_TEXT);
  673. create_new_item(NEW_LSL_NAME, parent_id, LLAssetType::AT_LSL_TEXT,
  674. LLInventoryType::IT_LSL, perms);
  675. }
  676. else if (type == "notecard")
  677. {
  678. U32 perms = PERM_MOVE | LLFloaterPerms::getNextOwnerPerms();
  679. if (gSavedSettings.getBool("FullPermNotecards"))
  680. {
  681. perms = PERM_ALL;
  682. }
  683. const LLUUID& parent_id =
  684. self ? self->getUUID()
  685. : modelp->findCategoryUUIDForType(LLFolderType::FT_NOTECARD);
  686. create_new_item(NEW_NOTECARD_NAME, parent_id, LLAssetType::AT_NOTECARD,
  687. LLInventoryType::IT_NOTECARD, perms);
  688. }
  689. else if (type == "gesture")
  690. {
  691. const LLUUID& parent_id =
  692. self ? self->getUUID()
  693. : modelp->findCategoryUUIDForType(LLFolderType::FT_GESTURE);
  694. create_new_item(NEW_GESTURE_NAME, parent_id, LLAssetType::AT_GESTURE,
  695. LLInventoryType::IT_GESTURE,
  696. PERM_MOVE | LLFloaterPerms::getNextOwnerPerms());
  697. }
  698. else if (type == "material")
  699. {
  700. const LLUUID& parent_id =
  701. self ? self->getUUID()
  702. : modelp->findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
  703. create_new_item(NEW_MATERIAL_NAME, parent_id, LLAssetType::AT_MATERIAL,
  704. LLInventoryType::IT_MATERIAL,
  705. LLFloaterPerms::getNextOwnerPerms());
  706. }
  707. else if (type == "callingcard")
  708. {
  709. const LLUUID& parent_id =
  710. self ? self->getUUID()
  711. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
  712. std::string name;
  713. gAgent.getName(name);
  714. create_new_item(name, parent_id, LLAssetType::AT_CALLINGCARD,
  715. LLInventoryType::IT_CALLINGCARD,
  716. PERM_ALL & ~PERM_MODIFY, gAgentID.asString());
  717. }
  718. else if (type == "shirt")
  719. {
  720. const LLUUID& parent_id =
  721. self ? self->getUUID()
  722. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  723. create_wearable(LLWearableType::WT_SHIRT, parent_id);
  724. }
  725. else if (type == "pants")
  726. {
  727. const LLUUID& parent_id =
  728. self ? self->getUUID()
  729. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  730. create_wearable(LLWearableType::WT_PANTS, parent_id);
  731. }
  732. else if (type == "shoes")
  733. {
  734. const LLUUID& parent_id =
  735. self ? self->getUUID()
  736. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  737. create_wearable(LLWearableType::WT_SHOES, parent_id);
  738. }
  739. else if (type == "socks")
  740. {
  741. const LLUUID& parent_id =
  742. self ? self->getUUID()
  743. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  744. create_wearable(LLWearableType::WT_SOCKS, parent_id);
  745. }
  746. else if (type == "jacket")
  747. {
  748. const LLUUID& parent_id =
  749. self ? self->getUUID()
  750. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  751. create_wearable(LLWearableType::WT_JACKET, parent_id);
  752. }
  753. else if (type == "skirt")
  754. {
  755. const LLUUID& parent_id =
  756. self ? self->getUUID()
  757. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  758. create_wearable(LLWearableType::WT_SKIRT, parent_id);
  759. }
  760. else if (type == "gloves")
  761. {
  762. const LLUUID& parent_id =
  763. self ? self->getUUID()
  764. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  765. create_wearable(LLWearableType::WT_GLOVES, parent_id);
  766. }
  767. else if (type == "undershirt")
  768. {
  769. const LLUUID& parent_id =
  770. self ? self->getUUID()
  771. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  772. create_wearable(LLWearableType::WT_UNDERSHIRT, parent_id);
  773. }
  774. else if (type == "underpants")
  775. {
  776. const LLUUID& parent_id =
  777. self ? self->getUUID()
  778. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  779. create_wearable(LLWearableType::WT_UNDERPANTS, parent_id);
  780. }
  781. else if (type == "alpha")
  782. {
  783. const LLUUID& parent_id =
  784. self ? self->getUUID()
  785. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  786. create_wearable(LLWearableType::WT_ALPHA, parent_id);
  787. }
  788. else if (type == "tattoo")
  789. {
  790. const LLUUID& parent_id =
  791. self ? self->getUUID()
  792. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  793. create_wearable(LLWearableType::WT_TATTOO, parent_id);
  794. }
  795. else if (type == "universal")
  796. {
  797. const LLUUID& parent_id =
  798. self ? self->getUUID()
  799. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  800. create_wearable(LLWearableType::WT_UNIVERSAL, parent_id);
  801. }
  802. else if (type == "physics")
  803. {
  804. const LLUUID& parent_id =
  805. self ? self->getUUID()
  806. : gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
  807. create_wearable(LLWearableType::WT_PHYSICS, parent_id);
  808. }
  809. else if (type == "shape")
  810. {
  811. const LLUUID& parent_id =
  812. self ? self->getUUID()
  813. : gInventory.findCategoryUUIDForType(LLFolderType::FT_BODYPART);
  814. create_wearable(LLWearableType::WT_SHAPE, parent_id);
  815. }
  816. else if (type == "skin")
  817. {
  818. const LLUUID& parent_id =
  819. self ? self->getUUID()
  820. : gInventory.findCategoryUUIDForType(LLFolderType::FT_BODYPART);
  821. create_wearable(LLWearableType::WT_SKIN, parent_id);
  822. }
  823. else if (type == "hair")
  824. {
  825. const LLUUID& parent_id =
  826. self ? self->getUUID()
  827. : gInventory.findCategoryUUIDForType(LLFolderType::FT_BODYPART);
  828. create_wearable(LLWearableType::WT_HAIR, parent_id);
  829. }
  830. else if (type == "eyes")
  831. {
  832. const LLUUID& parent_id =
  833. self ? self->getUUID()
  834. : gInventory.findCategoryUUIDForType(LLFolderType::FT_BODYPART);
  835. create_wearable(LLWearableType::WT_EYES, parent_id);
  836. }
  837. else if (type == "sky")
  838. {
  839. const LLUUID& parent_id =
  840. self ? self->getUUID()
  841. : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
  842. LLEnvSettingsBase::createNewInventoryItem(LLSettingsType::ST_SKY,
  843. parent_id);
  844. }
  845. else if (type == "water")
  846. {
  847. const LLUUID& parent_id =
  848. self ? self->getUUID()
  849. : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
  850. LLEnvSettingsBase::createNewInventoryItem(LLSettingsType::ST_WATER,
  851. parent_id);
  852. }
  853. else if (type == "day")
  854. {
  855. const LLUUID& parent_id =
  856. self ? self->getUUID()
  857. : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
  858. LLEnvSettingsBase::createNewInventoryItem(LLSettingsType::ST_DAYCYCLE,
  859. parent_id);
  860. }
  861. panelp->getRootFolder()->setNeedsAutoRename(true);
  862. }
  863. class LLDoCreate : public inventory_panel_listener_t
  864. {
  865. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  866. {
  867. LLInventoryModel* modelp = mPtr->getModel();
  868. if (modelp)
  869. {
  870. do_create(modelp, mPtr, userdata.asString(),
  871. LLFolderBridge::sSelf);
  872. }
  873. return true;
  874. }
  875. };
  876. class LLFileUploadLocation : public inventory_panel_listener_t
  877. {
  878. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  879. {
  880. LLInventoryModel* modelp = mPtr->getModel();
  881. if (!modelp) return true;
  882. std::string setting_name = userdata.asString();
  883. LLControlVariable* control =
  884. gSavedPerAccountSettings.getControl(setting_name.c_str());
  885. if (control)
  886. {
  887. control->setValue(LLFolderBridge::sSelf->getUUID().asString());
  888. }
  889. return true;
  890. }
  891. };
  892. class LLDoCreateFloater : public inventory_listener_t
  893. {
  894. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  895. {
  896. LLInventoryModel* modelp = mPtr->getPanel()->getModel();
  897. if (modelp)
  898. {
  899. do_create(modelp, mPtr->getPanel(), userdata.asString());
  900. }
  901. return true;
  902. }
  903. };
  904. class LLSetSortBy : public inventory_listener_t
  905. {
  906. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  907. {
  908. std::string sort_field = userdata.asString();
  909. U32 order = mPtr->getActivePanel()->getSortOrder();
  910. if (sort_field == "name")
  911. {
  912. order &= ~LLInventoryFilter::SO_DATE;
  913. }
  914. else if (sort_field == "date")
  915. {
  916. order |= LLInventoryFilter::SO_DATE;
  917. }
  918. else if (sort_field == "foldersalwaysbyname")
  919. {
  920. if (order & LLInventoryFilter::SO_FOLDERS_BY_NAME)
  921. {
  922. order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
  923. }
  924. else
  925. {
  926. order |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
  927. }
  928. }
  929. else if (sort_field == "systemfolderstotop")
  930. {
  931. if (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP)
  932. {
  933. order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
  934. }
  935. else
  936. {
  937. order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
  938. }
  939. }
  940. mPtr->getActivePanel()->setSortOrder(order);
  941. mPtr->updateSortControls();
  942. return true;
  943. }
  944. };
  945. class LLSetSearchType : public inventory_listener_t
  946. {
  947. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  948. {
  949. std::string toggle = userdata.asString();
  950. U32 flags = mPtr->getActivePanel()->getRootFolder()->toggleSearchType(toggle);
  951. mPtr->getControl("Inventory.SearchName")->setValue((flags & 1) != 0);
  952. mPtr->getControl("Inventory.SearchDesc")->setValue((flags & 2) != 0);
  953. mPtr->getControl("Inventory.SearchCreator")->setValue((flags & 4) != 0);
  954. return true;
  955. }
  956. };
  957. class LLBeginIMSession : public inventory_panel_listener_t
  958. {
  959. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  960. {
  961. LLInventoryPanel* panelp = mPtr;
  962. LLInventoryModel* modelp = panelp->getModel();
  963. if (!modelp) return true;
  964. uuid_list_t selected_items;
  965. panelp->getRootFolder()->getSelectionList(selected_items);
  966. std::string name;
  967. static S32 session_num = 1;
  968. uuid_vec_t members;
  969. EInstantMessage type = IM_SESSION_CONFERENCE_START;
  970. for (uuid_list_t::const_iterator iter = selected_items.begin(),
  971. end = selected_items.end();
  972. iter != end; ++iter)
  973. {
  974. LLUUID item = *iter;
  975. LLFolderViewItem* folder_item =
  976. panelp->getRootFolder()->getItemByID(item);
  977. if (folder_item)
  978. {
  979. LLFolderViewEventListener* fve_listener =
  980. folder_item->getListener();
  981. if (fve_listener &&
  982. fve_listener->getInventoryType() ==
  983. LLInventoryType::IT_CATEGORY)
  984. {
  985. LLFolderBridge* bridge =
  986. (LLFolderBridge*)folder_item->getListener();
  987. if (!bridge) return true;
  988. LLViewerInventoryCategory* cat = bridge->getCategory();
  989. if (!cat) return true;
  990. name = cat->getName();
  991. LLUniqueBuddyCollector is_buddy;
  992. LLInventoryModel::cat_array_t cat_array;
  993. LLInventoryModel::item_array_t item_array;
  994. modelp->collectDescendentsIf(bridge->getUUID(),
  995. cat_array,
  996. item_array,
  997. LLInventoryModel::EXCLUDE_TRASH,
  998. is_buddy);
  999. S32 count = item_array.size();
  1000. if (count > 0)
  1001. {
  1002. // Create the session
  1003. gIMMgrp->setFloaterOpen(true);
  1004. LLAvatarTracker& at = gAvatarTracker;
  1005. LLUUID id;
  1006. for (S32 i = 0; i < count; ++i)
  1007. {
  1008. id = item_array[i]->getCreatorUUID();
  1009. if (at.isBuddyOnline(id))
  1010. {
  1011. members.emplace_back(id);
  1012. }
  1013. }
  1014. }
  1015. }
  1016. else
  1017. {
  1018. LLFolderViewItem* folder_item =
  1019. panelp->getRootFolder()->getItemByID(item);
  1020. if (!folder_item) return true;
  1021. LLFolderViewEventListener* listener =
  1022. folder_item->getListener();
  1023. if (listener &&
  1024. listener->getInventoryType() ==
  1025. LLInventoryType::IT_CALLINGCARD)
  1026. {
  1027. LLInventoryItem* itemp =
  1028. gInventory.getItem(listener->getUUID());
  1029. if (itemp)
  1030. {
  1031. LLUUID id = itemp->getCreatorUUID();
  1032. if (gAvatarTracker.isBuddyOnline(id))
  1033. {
  1034. members.emplace_back(id);
  1035. }
  1036. }
  1037. }
  1038. }
  1039. }
  1040. }
  1041. // The session_id is randomly generated UUID which will be replaced
  1042. // later with a server side generated number
  1043. if (name.empty())
  1044. {
  1045. name = llformat("Session %d", session_num++);
  1046. }
  1047. gIMMgrp->addSession(name, type, members[0], members);
  1048. return true;
  1049. }
  1050. };
  1051. class LLAttachObject : public inventory_panel_listener_t
  1052. {
  1053. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  1054. {
  1055. LLInventoryPanel* panelp = mPtr;
  1056. LLFolderView* folderp = panelp->getRootFolder();
  1057. if (!folderp || !isAgentAvatarValid()) return true;
  1058. uuid_list_t selected_items;
  1059. folderp->getSelectionList(selected_items);
  1060. LLUUID id = *selected_items.begin();
  1061. std::string joint_name = userdata.asString();
  1062. LLViewerJointAttachment* attachmentp = NULL;
  1063. for (LLVOAvatar::attachment_map_t::iterator
  1064. iter = gAgentAvatarp->mAttachmentPoints.begin();
  1065. iter != gAgentAvatarp->mAttachmentPoints.end(); )
  1066. {
  1067. LLVOAvatar::attachment_map_t::iterator curiter = iter++;
  1068. LLViewerJointAttachment* attachment = curiter->second;
  1069. std::string name = LLTrans::getString(attachment->getName());
  1070. if (name == joint_name)
  1071. {
  1072. attachmentp = attachment;
  1073. break;
  1074. }
  1075. }
  1076. if (attachmentp == NULL)
  1077. {
  1078. return true;
  1079. }
  1080. LLViewerInventoryItem* item;
  1081. item = (LLViewerInventoryItem*)gInventory.getItem(id);
  1082. if (item &&
  1083. gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()))
  1084. {
  1085. gAppearanceMgr.rezAttachment(item, attachmentp);
  1086. }
  1087. else if (item && item->isFinished())
  1088. {
  1089. // Must be in library. copy it to our inventory and put it on.
  1090. LLPointer<LLInventoryCallback> cb =
  1091. new LLRezAttachmentCallback(attachmentp);
  1092. copy_inventory_item(item->getPermissions().getOwner(),
  1093. item->getUUID(), LLUUID::null, std::string(),
  1094. cb);
  1095. }
  1096. gFocusMgr.setKeyboardFocus(NULL);
  1097. return true;
  1098. }
  1099. };
  1100. class LLEnableUniversal : public inventory_listener_t
  1101. {
  1102. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  1103. {
  1104. LLViewerRegion* regionp = gAgent.getRegion();
  1105. bool enable = regionp && regionp->bakesOnMeshEnabled();
  1106. mPtr->findControl(userdata["control"].asString())->setValue(enable);
  1107. return true;
  1108. }
  1109. };
  1110. class LLEnableSettings : public inventory_listener_t
  1111. {
  1112. bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
  1113. {
  1114. bool enable = gAgent.hasInventorySettings();
  1115. mPtr->findControl(userdata["control"].asString())->setValue(enable);
  1116. return true;
  1117. }
  1118. };
  1119. void init_object_inventory_panel_actions(LLPanelInventory* panelp)
  1120. {
  1121. (new LLDoToSelectedPanel())->registerListener(panelp,
  1122. "Inventory.DoToSelected");
  1123. }
  1124. void init_inventory_actions(LLFloaterInventory* floater)
  1125. {
  1126. (new LLDoToSelectedFloater())->registerListener(floater,
  1127. "Inventory.DoToSelected");
  1128. (new LLCloseAllFoldersFloater())->registerListener(floater,
  1129. "Inventory.CloseAllFolders");
  1130. (new LLHideEmptySystemFolders())->registerListener(floater,
  1131. "Inventory.HideEmptySystemFolders");
  1132. (new LLHideMarketplaceFolder())->registerListener(floater,
  1133. "Inventory.HideMarketplaceFolder");
  1134. (new LLHideCurrentOutfitFolder())->registerListener(floater,
  1135. "Inventory.HideCurrentOutfitFolder");
  1136. (new LLCheckSystemFolders())->registerListener(floater,
  1137. "Inventory.CheckSystemFolders");
  1138. (new LLResyncCallingCards())->registerListener(floater,
  1139. "Inventory.ResyncCallingCards");
  1140. (new LLMakeNewOutfit())->registerListener(floater,
  1141. "Inventory.MakeNewOutfit");
  1142. (new LLEmptyTrashFloater())->registerListener(floater,
  1143. "Inventory.EmptyTrash");
  1144. (new LLDoCreateFloater())->registerListener(floater,
  1145. "Inventory.DoCreate");
  1146. (new LLNewWindow())->registerListener(floater, "Inventory.NewWindow");
  1147. (new LLShowFilters())->registerListener(floater, "Inventory.ShowFilters");
  1148. (new LLResetFilter())->registerListener(floater, "Inventory.ResetFilter");
  1149. (new LLSetSortBy())->registerListener(floater, "Inventory.SetSortBy");
  1150. (new LLSetSearchType())->registerListener(floater,
  1151. "Inventory.SetSearchType");
  1152. (new LLEnableUniversal())->registerListener(floater,
  1153. "Inventory.EnableUniversal");
  1154. (new LLEnableSettings())->registerListener(floater,
  1155. "Inventory.EnableSettings");
  1156. }
  1157. void init_inventory_panel_actions(LLInventoryPanel* panelp)
  1158. {
  1159. (new LLDoToSelected())->registerListener(panelp, "Inventory.DoToSelected");
  1160. (new LLAttachObject())->registerListener(panelp, "Inventory.AttachObject");
  1161. (new LLCloseAllFolders())->registerListener(panelp,
  1162. "Inventory.CloseAllFolders");
  1163. (new LLEmptyTrash())->registerListener(panelp, "Inventory.EmptyTrash");
  1164. (new LLEmptyLostAndFound())->registerListener(panelp,
  1165. "Inventory.EmptyLostAndFound");
  1166. (new LLDoCreate())->registerListener(panelp, "Inventory.DoCreate");
  1167. (new LLFileUploadLocation())->registerListener(panelp,
  1168. "Inventory.FileUploadLocation");
  1169. (new LLBeginIMSession())->registerListener(panelp,
  1170. "Inventory.BeginIMSession");
  1171. }
  1172. void open_notecard(LLViewerInventoryItem* itemp, const std::string& title,
  1173. bool show_keep_discard, const LLUUID& object_id,
  1174. bool take_focus)
  1175. {
  1176. //MK
  1177. if (gRLenabled && gRLInterface.contains("viewnote"))
  1178. {
  1179. return;
  1180. }
  1181. //mk
  1182. // See if we can bring an existing preview to the front
  1183. if (itemp && !LLPreview::show(itemp->getUUID(), take_focus))
  1184. {
  1185. // There is none, so make a new preview
  1186. S32 left, top;
  1187. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1188. LLRect rect = gSavedSettings.getRect("NotecardEditorRect");
  1189. rect.translate(left - rect.mLeft, top - rect.mTop);
  1190. LLPreviewNotecard* previewp =
  1191. new LLPreviewNotecard("preview notecard", rect, title,
  1192. itemp->getUUID(), object_id,
  1193. itemp->getAssetUUID(), show_keep_discard,
  1194. itemp);
  1195. if (take_focus)
  1196. {
  1197. previewp->setFocus(true);
  1198. }
  1199. // Force to be entirely on screen.
  1200. gFloaterViewp->adjustToFitScreen(previewp);
  1201. }
  1202. }
  1203. void open_landmark(LLViewerInventoryItem* itemp, const std::string& title,
  1204. bool show_keep_discard, bool take_focus)
  1205. {
  1206. // See if we can bring an exiting preview to the front
  1207. if (itemp && !LLPreview::show(itemp->getUUID(), take_focus))
  1208. {
  1209. // There is none, so make a new preview
  1210. S32 left, top;
  1211. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1212. LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect");
  1213. rect.translate(left - rect.mLeft, top - rect.mTop);
  1214. LLPreviewLandmark* previewp =
  1215. new LLPreviewLandmark(title, rect, title, itemp->getUUID(),
  1216. show_keep_discard, itemp);
  1217. if (take_focus)
  1218. {
  1219. previewp->setFocus(true);
  1220. }
  1221. // Force to be entirely on screen.
  1222. gFloaterViewp->adjustToFitScreen(previewp);
  1223. }
  1224. }
  1225. static bool open_landmark_callback(const LLSD& notification,
  1226. const LLSD& response)
  1227. {
  1228. LLUUID asset_id = notification["payload"]["asset_id"].asUUID();
  1229. LLUUID item_id = notification["payload"]["item_id"].asUUID();
  1230. if (LLNotification::getSelectedOption(notification, response) == 0) // YES
  1231. {
  1232. gAgent.teleportViaLandmark(asset_id);
  1233. // We now automatically track the landmark you're teleporting to
  1234. // because you will probably arrive at a fixed TP point instead.
  1235. if (gFloaterWorldMapp)
  1236. {
  1237. // Remember this is the item UUID not the asset UUID
  1238. gFloaterWorldMapp->trackLandmark(item_id);
  1239. }
  1240. }
  1241. return false;
  1242. }
  1243. static LLNotificationFunctorRegistration open_landmark_callback_reg("TeleportFromLandmark",
  1244. open_landmark_callback);
  1245. void open_texture(const LLUUID& item_id, const std::string& title,
  1246. bool show_keep_discard, const LLUUID& object_id,
  1247. bool take_focus)
  1248. {
  1249. //MK
  1250. if (gRLenabled && gRLInterface.contains("viewtexture"))
  1251. {
  1252. return;
  1253. }
  1254. //mk
  1255. // See if we can bring an exiting preview to the front
  1256. if (!LLPreview::show(item_id, take_focus))
  1257. {
  1258. // There is none, so make a new preview
  1259. S32 left, top;
  1260. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1261. LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
  1262. rect.translate(left - rect.mLeft, top - rect.mTop);
  1263. LLPreviewTexture* previewp = new LLPreviewTexture("preview texture",
  1264. rect, title, item_id,
  1265. object_id,
  1266. show_keep_discard);
  1267. if (take_focus)
  1268. {
  1269. previewp->setFocus(true);
  1270. }
  1271. // Force to be entirely on screen.
  1272. gFloaterViewp->adjustToFitScreen(previewp);
  1273. }
  1274. }
  1275. void open_callingcard(LLViewerInventoryItem* itemp)
  1276. {
  1277. LLUUID id = get_calling_card_buddy_id(itemp, true);
  1278. if (id.notNull())
  1279. {
  1280. bool online = id == gAgentID || gAvatarTracker.isBuddyOnline(id);
  1281. LLFloaterAvatarInfo::showFromFriend(id, online);
  1282. }
  1283. }
  1284. void open_sound(const LLUUID& item_id, const std::string& title,
  1285. const LLUUID& object_id, bool take_focus)
  1286. {
  1287. // See if we can bring an existing preview to the front
  1288. if (LLPreview::show(item_id, take_focus))
  1289. {
  1290. return;
  1291. }
  1292. // There is none, so make a new preview
  1293. S32 left, top;
  1294. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1295. LLRect rect = gSavedSettings.getRect("PreviewSoundRect");
  1296. rect.translate(left - rect.mLeft, top - rect.mTop);
  1297. LLPreviewSound* previewp = new LLPreviewSound("preview sound", rect, title,
  1298. item_id, object_id);
  1299. if (take_focus)
  1300. {
  1301. previewp->setFocus(true);
  1302. }
  1303. // Force to be entirely on screen.
  1304. gFloaterViewp->adjustToFitScreen(previewp);
  1305. }
  1306. void open_animation(const LLUUID& item_id, const std::string& title,
  1307. S32 activate, const LLUUID& object_id, bool take_focus)
  1308. {
  1309. // See if we can bring an existing preview to the front
  1310. if (LLPreview::show(item_id, take_focus))
  1311. {
  1312. return;
  1313. }
  1314. // There is none, so make a new preview
  1315. S32 left, top;
  1316. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1317. LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
  1318. rect.translate(left - rect.mLeft, top - rect.mTop);
  1319. LLPreviewAnim* previewp = new LLPreviewAnim("preview anim", rect, title,
  1320. item_id, activate, object_id);
  1321. if (take_focus)
  1322. {
  1323. previewp->setFocus(true);
  1324. }
  1325. // Force to be entirely on screen.
  1326. gFloaterViewp->adjustToFitScreen(previewp);
  1327. }
  1328. void open_script(const LLUUID& item_id, const std::string& title,
  1329. bool take_focus)
  1330. {
  1331. //MK
  1332. if (gRLenabled && gRLInterface.mContainsViewscript)
  1333. {
  1334. return;
  1335. }
  1336. //mk
  1337. // See if we can bring an existing preview to the front
  1338. if (LLPreview::show(item_id, take_focus))
  1339. {
  1340. return;
  1341. }
  1342. // There is none, so make a new preview
  1343. S32 left, top;
  1344. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1345. LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
  1346. rect.translate(left - rect.mLeft, top - rect.mTop);
  1347. LLPreviewScript* previewp = new LLPreviewScript("preview script", rect,
  1348. title, item_id);
  1349. if (take_focus)
  1350. {
  1351. previewp->setFocus(true);
  1352. }
  1353. // Force to be entirely on screen.
  1354. gFloaterViewp->adjustToFitScreen(previewp);
  1355. }
  1356. void open_gesture(const LLUUID& item_id, const std::string& title,
  1357. const LLUUID& object_id, bool take_focus)
  1358. {
  1359. // See if we can bring an existing preview to the front
  1360. if (LLPreview::show(item_id, take_focus))
  1361. {
  1362. return;
  1363. }
  1364. // There is none, so make a new preview
  1365. // *TODO: save the rectangle
  1366. LLPreviewGesture* previewp = LLPreviewGesture::show(title, item_id,
  1367. object_id, take_focus);
  1368. // Force to be entirely on screen.
  1369. gFloaterViewp->adjustToFitScreen(previewp);
  1370. }
  1371. void open_material(const LLUUID& item_id, const std::string& title,
  1372. const LLUUID& object_id, bool take_focus)
  1373. {
  1374. // See if we can bring an existing preview to the front
  1375. if (LLPreview::show(item_id, take_focus))
  1376. {
  1377. return;
  1378. }
  1379. // There is none, so make a new preview
  1380. S32 left, top;
  1381. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1382. LLRect rect = gSavedSettings.getRect("PreviewMaterialRect");
  1383. rect.translate(left - rect.mLeft, top - rect.mTop);
  1384. LLPreviewMaterial* previewp = new LLPreviewMaterial("preview material",
  1385. rect, title, item_id,
  1386. object_id);
  1387. // Force to be entirely on screen.
  1388. gFloaterViewp->adjustToFitScreen(previewp);
  1389. if (take_focus)
  1390. {
  1391. previewp->setFocus(true);
  1392. }
  1393. }