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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llsidepanelmaininventory.cpp
  3.  * @brief Implementation of llsidepanelmaininventory.
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llpanelmaininventory.h"
  34. #include "llagent.h"
  35. #include "lldndbutton.h"
  36. #include "lleconomy.h"
  37. #include "llfilepicker.h"
  38. #include "llfloaterinventory.h"
  39. #include "llinventorybridge.h"
  40. #include "llinventoryfunctions.h"
  41. #include "llinventorypanel.h"
  42. #include "llfiltereditor.h"
  43. #include "llfloaterreg.h"
  44. #include "llpreviewtexture.h"
  45. #include "llscrollcontainer.h"
  46. #include "llsdserialize.h"
  47. #include "llspinctrl.h"
  48. #include "lltooldraganddrop.h"
  49. #include "llviewermenu.h"
  50. #include "llviewertexturelist.h"
  51. const std::string FILTERS_FILENAME("filters.xml");
  52. static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory");
  53. void on_file_loaded_for_save(BOOL success, 
  54.  LLViewerFetchedTexture *src_vi,
  55.  LLImageRaw* src, 
  56.  LLImageRaw* aux_src, 
  57.  S32 discard_level,
  58.  BOOL final,
  59.  void* userdata);
  60. ///----------------------------------------------------------------------------
  61. /// LLFloaterInventoryFinder
  62. ///----------------------------------------------------------------------------
  63. class LLFloaterInventoryFinder : public LLFloater
  64. {
  65. public:
  66. LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view);
  67. virtual void draw();
  68. /*virtual*/ BOOL postBuild();
  69. void changeFilter(LLInventoryFilter* filter);
  70. void updateElementsFromFilter();
  71. BOOL getCheckShowEmpty();
  72. BOOL getCheckSinceLogoff();
  73. static void onTimeAgo(LLUICtrl*, void *);
  74. static void onCheckSinceLogoff(LLUICtrl*, void *);
  75. static void onCloseBtn(void* user_data);
  76. static void selectAllTypes(void* user_data);
  77. static void selectNoTypes(void* user_data);
  78. private:
  79. LLPanelMainInventory* mPanelMainInventory;
  80. LLSpinCtrl* mSpinSinceDays;
  81. LLSpinCtrl* mSpinSinceHours;
  82. LLInventoryFilter* mFilter;
  83. };
  84. ///----------------------------------------------------------------------------
  85. /// LLPanelMainInventory
  86. ///----------------------------------------------------------------------------
  87. LLPanelMainInventory::LLPanelMainInventory()
  88. : LLPanel(),
  89.   mActivePanel(NULL),
  90.   mSavedFolderState(NULL),
  91.   mFilterText(""),
  92.   mMenuGearDefault(NULL),
  93.   mMenuAdd(NULL),
  94.   mNeedUploadCost(true)
  95. {
  96. LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT);
  97. // Menu Callbacks (non contex menus)
  98. mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
  99. mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
  100. mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
  101. mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
  102. mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
  103.   mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this));
  104. mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
  105. mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
  106. mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
  107. // Controls
  108. // *TODO: Just use persistant settings for each of these
  109. U32 sort_order = gSavedSettings.getU32("InventorySortOrder");
  110. BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE );
  111. BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME );
  112. BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP );
  113. gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE);
  114. gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE);
  115. gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE);
  116. gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE);
  117. mSavedFolderState = new LLSaveFolderState();
  118. mSavedFolderState->setApply(FALSE);
  119. }
  120. BOOL LLPanelMainInventory::postBuild()
  121. {
  122. gInventory.addObserver(this);
  123. mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
  124. mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
  125. //panel->getFilter()->markDefault();
  126. // Set up the default inv. panel/filter settings.
  127. mActivePanel = getChild<LLInventoryPanel>("All Items");
  128. if (mActivePanel)
  129. {
  130. // "All Items" is the previous only view, so it gets the InventorySortOrder
  131. mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder"));
  132. mActivePanel->getFilter()->markDefault();
  133. mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
  134. mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
  135. }
  136. LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
  137. if (recent_items_panel)
  138. {
  139. recent_items_panel->setSinceLogoff(TRUE);
  140. recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
  141. recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
  142. recent_items_panel->getFilter()->markDefault();
  143. recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
  144. }
  145. // Now load the stored settings from disk, if available.
  146. std::ostringstream filterSaveName;
  147. filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME);
  148. llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << llendl;
  149. llifstream file(filterSaveName.str());
  150. LLSD savedFilterState;
  151. if (file.is_open())
  152. {
  153. LLSDSerialize::fromXML(savedFilterState, file);
  154. file.close();
  155. // Load the persistent "Recent Items" settings.
  156. // Note that the "All Items" settings do not persist.
  157. if(recent_items_panel)
  158. {
  159. if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
  160. {
  161. LLSD recent_items = savedFilterState.get(
  162. recent_items_panel->getFilter()->getName());
  163. recent_items_panel->getFilter()->fromLLSD(recent_items);
  164. }
  165. }
  166. }
  167. mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
  168. if (mFilterEditor)
  169. {
  170. mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
  171. }
  172. // *TODO:Get the cost info from the server
  173. const std::string upload_cost("10");
  174. childSetLabelArg("Upload Image", "[COST]", upload_cost);
  175. childSetLabelArg("Upload Sound", "[COST]", upload_cost);
  176. childSetLabelArg("Upload Animation", "[COST]", upload_cost);
  177. childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
  178. initListCommandsHandlers();
  179. return TRUE;
  180. }
  181. // Destroys the object
  182. LLPanelMainInventory::~LLPanelMainInventory( void )
  183. {
  184. // Save the filters state.
  185. LLSD filterRoot;
  186. LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
  187. if (all_items_panel)
  188. {
  189. LLInventoryFilter* filter = all_items_panel->getFilter();
  190. if (filter)
  191. {
  192. LLSD filterState;
  193. filter->toLLSD(filterState);
  194. filterRoot[filter->getName()] = filterState;
  195. }
  196. }
  197. LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
  198. if (recent_items_panel)
  199. {
  200. LLInventoryFilter* filter = recent_items_panel->getFilter();
  201. if (filter)
  202. {
  203. LLSD filterState;
  204. filter->toLLSD(filterState);
  205. filterRoot[filter->getName()] = filterState;
  206. }
  207. }
  208. std::ostringstream filterSaveName;
  209. filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME);
  210. llofstream filtersFile(filterSaveName.str());
  211. if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
  212. {
  213. llwarns << "Could not write to filters save file " << filterSaveName << llendl;
  214. }
  215. else
  216. filtersFile.close();
  217. gInventory.removeObserver(this);
  218. delete mSavedFolderState;
  219. }
  220. void LLPanelMainInventory::startSearch()
  221. {
  222. // this forces focus to line editor portion of search editor
  223. if (mFilterEditor)
  224. {
  225. mFilterEditor->focusFirstItem(TRUE);
  226. }
  227. }
  228. BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
  229. {
  230. LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
  231. if (root_folder)
  232. {
  233. // first check for user accepting current search results
  234. if (mFilterEditor 
  235. && mFilterEditor->hasFocus()
  236.     && (key == KEY_RETURN 
  237.      || key == KEY_DOWN)
  238.     && mask == MASK_NONE)
  239. {
  240. // move focus to inventory proper
  241. mActivePanel->setFocus(TRUE);
  242. root_folder->scrollToShowSelection();
  243. return TRUE;
  244. }
  245. if (mActivePanel->hasFocus() && key == KEY_UP)
  246. {
  247. startSearch();
  248. }
  249. }
  250. return LLPanel::handleKeyHere(key, mask);
  251. }
  252. //----------------------------------------------------------------------------
  253. // menu callbacks
  254. void LLPanelMainInventory::doToSelected(const LLSD& userdata)
  255. {
  256. getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
  257. }
  258. void LLPanelMainInventory::closeAllFolders()
  259. {
  260. getPanel()->getRootFolder()->closeAllFolders();
  261. }
  262. void LLPanelMainInventory::newWindow()
  263. {
  264. LLFloaterInventory::showAgentInventory();
  265. }
  266. void LLPanelMainInventory::doCreate(const LLSD& userdata)
  267. {
  268. menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
  269. }
  270. void LLPanelMainInventory::resetFilters()
  271. {
  272. LLFloaterInventoryFinder *finder = getFinder();
  273. getActivePanel()->getFilter()->resetDefault();
  274. if (finder)
  275. {
  276. finder->updateElementsFromFilter();
  277. }
  278. setFilterTextFromFilter();
  279. }
  280. void LLPanelMainInventory::setSortBy(const LLSD& userdata)
  281. {
  282. std::string sort_field = userdata.asString();
  283. if (sort_field == "name")
  284. {
  285. U32 order = getActivePanel()->getSortOrder();
  286. getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE );
  287. gSavedSettings.setBOOL("Inventory.SortByName", TRUE );
  288. gSavedSettings.setBOOL("Inventory.SortByDate", FALSE );
  289. }
  290. else if (sort_field == "date")
  291. {
  292. U32 order = getActivePanel()->getSortOrder();
  293. getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE );
  294. gSavedSettings.setBOOL("Inventory.SortByName", FALSE );
  295. gSavedSettings.setBOOL("Inventory.SortByDate", TRUE );
  296. }
  297. else if (sort_field == "foldersalwaysbyname")
  298. {
  299. U32 order = getActivePanel()->getSortOrder();
  300. if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME )
  301. {
  302. order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
  303. gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE );
  304. }
  305. else
  306. {
  307. order |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
  308. gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE );
  309. }
  310. getActivePanel()->setSortOrder( order );
  311. }
  312. else if (sort_field == "systemfolderstotop")
  313. {
  314. U32 order = getActivePanel()->getSortOrder();
  315. if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
  316. {
  317. order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
  318. gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE );
  319. }
  320. else
  321. {
  322. order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
  323. gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE );
  324. }
  325. getActivePanel()->setSortOrder( order );
  326. }
  327. }
  328. // static
  329. BOOL LLPanelMainInventory::filtersVisible(void* user_data)
  330. {
  331. LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
  332. if(!self) return FALSE;
  333. return self->getFinder() != NULL;
  334. }
  335. void LLPanelMainInventory::onClearSearch()
  336. {
  337. LLFloater *finder = getFinder();
  338. if (mActivePanel)
  339. {
  340. mActivePanel->setFilterSubString(LLStringUtil::null);
  341. mActivePanel->setFilterTypes(0xffffffff);
  342. }
  343. if (finder)
  344. {
  345. LLFloaterInventoryFinder::selectAllTypes(finder);
  346. }
  347. // re-open folders that were initially open
  348. if (mActivePanel)
  349. {
  350. mSavedFolderState->setApply(TRUE);
  351. mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
  352. LLOpenFoldersWithSelection opener;
  353. mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
  354. mActivePanel->getRootFolder()->scrollToShowSelection();
  355. }
  356. mFilterSubString = "";
  357. }
  358. void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
  359. {
  360. if (search_string == "")
  361. {
  362. onClearSearch();
  363. }
  364. if (!mActivePanel)
  365. {
  366. return;
  367. }
  368. gInventory.startBackgroundFetch();
  369. std::string uppercase_search_string = search_string;
  370. LLStringUtil::toUpper(uppercase_search_string);
  371. mFilterSubString = uppercase_search_string;
  372. if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
  373. {
  374. // current filter and new filter empty, do nothing
  375. return;
  376. }
  377. // save current folder open state if no filter currently applied
  378. if (!mActivePanel->getRootFolder()->isFilterModified())
  379. {
  380. mSavedFolderState->setApply(FALSE);
  381. mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
  382. }
  383. // set new filter string
  384. mActivePanel->setFilterSubString(mFilterSubString);
  385. }
  386.  //static
  387.  BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
  388.  {
  389.   LLPanelMainInventory* active_view = NULL;
  390. LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
  391. for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
  392. {
  393. LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter);
  394. if (iv)
  395. {
  396. if (gFocusMgr.childHasKeyboardFocus(iv))
  397. {
  398. active_view = iv;
  399. break;
  400. }
  401.   }
  402.   }
  403.   if (!active_view)
  404.   {
  405.   return FALSE;
  406.   }
  407.   std::string search_string(find_text);
  408.   if (search_string.empty())
  409.   {
  410.   return FALSE;
  411.   }
  412.   if (active_view->getPanel() &&
  413.   active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward))
  414.   {
  415.   return TRUE;
  416.   }
  417.   return FALSE;
  418.  }
  419. void LLPanelMainInventory::onFilterSelected()
  420. {
  421. // Find my index
  422. mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs");
  423. if (!mActivePanel)
  424. {
  425. return;
  426. }
  427. setFilterSubString(mFilterSubString);
  428. LLInventoryFilter* filter = mActivePanel->getFilter();
  429. LLFloaterInventoryFinder *finder = getFinder();
  430. if (finder)
  431. {
  432. finder->changeFilter(filter);
  433. }
  434. if (filter->isActive())
  435. {
  436. // If our filter is active we may be the first thing requiring a fetch so we better start it here.
  437. gInventory.startBackgroundFetch();
  438. }
  439. setFilterTextFromFilter();
  440. }
  441. const std::string LLPanelMainInventory::getFilterSubString() 
  442. return mActivePanel->getFilterSubString(); 
  443. }
  444. void LLPanelMainInventory::setFilterSubString(const std::string& string) 
  445. mActivePanel->setFilterSubString(string); 
  446. }
  447. BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
  448.  EDragAndDropType cargo_type,
  449.  void* cargo_data,
  450.  EAcceptance* accept,
  451.  std::string& tooltip_msg)
  452. {
  453. // Check to see if we are auto scrolling from the last frame
  454. LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
  455. BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y);
  456. if(mFilterTabs)
  457. {
  458. if(needsToScroll)
  459. {
  460. mFilterTabs->startDragAndDropDelayTimer();
  461. }
  462. }
  463. BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
  464. return handled;
  465. }
  466. // virtual
  467. void LLPanelMainInventory::changed(U32)
  468. {
  469. // empty, but must have this defined for abstract base class.
  470. }
  471. // virtual
  472. void LLPanelMainInventory::draw()
  473. {
  474. if (mActivePanel && mFilterEditor)
  475. {
  476. mFilterEditor->setText(mFilterSubString);
  477. }
  478. LLPanel::draw();
  479. }
  480. void LLPanelMainInventory::setFilterTextFromFilter() 
  481. mFilterText = mActivePanel->getFilter()->getFilterText(); 
  482. }
  483. void LLPanelMainInventory::toggleFindOptions()
  484. {
  485. LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE);
  486. LLFloater *floater = getFinder();
  487. if (!floater)
  488. {
  489. LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
  490. mFinderHandle = finder->getHandle();
  491. finder->openFloater();
  492. LLFloater* parent_floater = gFloaterView->getParentFloater(this);
  493. if (parent_floater) // Seraph: Fix this, shouldn't be null even for sidepanel
  494. parent_floater->addDependentFloater(mFinderHandle);
  495. // start background fetch of folders
  496. gInventory.startBackgroundFetch();
  497. }
  498. else
  499. {
  500. floater->closeFloater();
  501. }
  502. }
  503. void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
  504. {
  505. getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
  506. getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
  507. }
  508. void LLPanelMainInventory::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
  509. {
  510. updateListCommands();
  511. panel->onSelectionChange(items, user_action);
  512. }
  513. ///----------------------------------------------------------------------------
  514. /// LLFloaterInventoryFinder
  515. ///----------------------------------------------------------------------------
  516. LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() 
  517. return (LLFloaterInventoryFinder*)mFinderHandle.get();
  518. }
  519. LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :
  520. LLFloater(LLSD()),
  521. mPanelMainInventory(inventory_view),
  522. mFilter(inventory_view->getPanel()->getFilter())
  523. {
  524. LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL);
  525. updateElementsFromFilter();
  526. }
  527. void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
  528. {
  529. LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
  530. if (!self) return;
  531. bool since_logoff= self->childGetValue("check_since_logoff");
  532. if (!since_logoff && 
  533.     !(  self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() ) )
  534. {
  535. self->mSpinSinceHours->set(1.0f);
  536. }
  537. }
  538. BOOL LLFloaterInventoryFinder::postBuild()
  539. {
  540. const LLRect& viewrect = mPanelMainInventory->getRect();
  541. setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
  542. childSetAction("All", selectAllTypes, this);
  543. childSetAction("None", selectNoTypes, this);
  544. mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
  545. childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
  546. mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
  547. childSetCommitCallback("spin_days_ago", onTimeAgo, this);
  548. // mCheckSinceLogoff   = getChild<LLSpinCtrl>("check_since_logoff");
  549. childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
  550. childSetAction("Close", onCloseBtn, this);
  551. updateElementsFromFilter();
  552. return TRUE;
  553. }
  554. void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
  555. {
  556. LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
  557. if (!self) return;
  558. bool since_logoff=true;
  559. if ( self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() )
  560. {
  561. since_logoff = false;
  562. }
  563. self->childSetValue("check_since_logoff", since_logoff);
  564. }
  565. void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
  566. {
  567. mFilter = filter;
  568. updateElementsFromFilter();
  569. }
  570. void LLFloaterInventoryFinder::updateElementsFromFilter()
  571. {
  572. if (!mFilter)
  573. return;
  574. // Get data needed for filter display
  575. U32 filter_types = mFilter->getFilterObjectTypes();
  576. std::string filter_string = mFilter->getFilterSubString();
  577. LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
  578. U32 hours = mFilter->getHoursAgo();
  579. // update the ui elements
  580. setTitle(mFilter->getName());
  581. childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
  582. childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
  583. childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
  584. childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
  585. childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
  586. childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
  587. childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
  588. childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
  589. childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
  590. childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
  591. childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
  592. childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
  593. childSetValue("check_since_logoff", mFilter->isSinceLogoff());
  594. mSpinSinceHours->set((F32)(hours % 24));
  595. mSpinSinceDays->set((F32)(hours / 24));
  596. }
  597. void LLFloaterInventoryFinder::draw()
  598. {
  599. LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
  600. U32 filter = 0xffffffff;
  601. BOOL filtered_by_all_types = TRUE;
  602. if (!childGetValue("check_animation"))
  603. {
  604. filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
  605. filtered_by_all_types = FALSE;
  606. }
  607. if (!childGetValue("check_calling_card"))
  608. {
  609. filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
  610. filtered_by_all_types = FALSE;
  611. }
  612. if (!childGetValue("check_clothing"))
  613. {
  614. filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
  615. filtered_by_all_types = FALSE;
  616. }
  617. if (!childGetValue("check_gesture"))
  618. {
  619. filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
  620. filtered_by_all_types = FALSE;
  621. }
  622. if (!childGetValue("check_landmark"))
  623. {
  624. filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
  625. filtered_by_all_types = FALSE;
  626. }
  627. if (!childGetValue("check_notecard"))
  628. {
  629. filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
  630. filtered_by_all_types = FALSE;
  631. }
  632. if (!childGetValue("check_object"))
  633. {
  634. filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
  635. filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
  636. filtered_by_all_types = FALSE;
  637. }
  638. if (!childGetValue("check_script"))
  639. {
  640. filter &= ~(0x1 << LLInventoryType::IT_LSL);
  641. filtered_by_all_types = FALSE;
  642. }
  643. if (!childGetValue("check_sound"))
  644. {
  645. filter &= ~(0x1 << LLInventoryType::IT_SOUND);
  646. filtered_by_all_types = FALSE;
  647. }
  648. if (!childGetValue("check_texture"))
  649. {
  650. filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
  651. filtered_by_all_types = FALSE;
  652. }
  653. if (!childGetValue("check_snapshot"))
  654. {
  655. filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
  656. filtered_by_all_types = FALSE;
  657. }
  658. if (!filtered_by_all_types)
  659. {
  660. // don't include folders in filter, unless I've selected everything
  661. filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
  662. }
  663. // update the panel, panel will update the filter
  664. mPanelMainInventory->getPanel()->setShowFolderState(getCheckShowEmpty() ?
  665. LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
  666. mPanelMainInventory->getPanel()->setFilterTypes(filter);
  667. if (getCheckSinceLogoff())
  668. {
  669. mSpinSinceDays->set(0);
  670. mSpinSinceHours->set(0);
  671. }
  672. U32 days = (U32)mSpinSinceDays->get();
  673. U32 hours = (U32)mSpinSinceHours->get();
  674. if (hours > 24)
  675. {
  676. days += hours / 24;
  677. hours = (U32)hours % 24;
  678. mSpinSinceDays->set((F32)days);
  679. mSpinSinceHours->set((F32)hours);
  680. }
  681. hours += days * 24;
  682. mPanelMainInventory->getPanel()->setHoursAgo(hours);
  683. mPanelMainInventory->getPanel()->setSinceLogoff(getCheckSinceLogoff());
  684. mPanelMainInventory->setFilterTextFromFilter();
  685. LLPanel::draw();
  686. }
  687. BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
  688. {
  689. return childGetValue("check_show_empty");
  690. }
  691. BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
  692. {
  693. return childGetValue("check_since_logoff");
  694. }
  695. void LLFloaterInventoryFinder::onCloseBtn(void* user_data)
  696. {
  697. LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
  698. finderp->closeFloater();
  699. }
  700. // static
  701. void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
  702. {
  703. LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
  704. if(!self) return;
  705. self->childSetValue("check_animation", TRUE);
  706. self->childSetValue("check_calling_card", TRUE);
  707. self->childSetValue("check_clothing", TRUE);
  708. self->childSetValue("check_gesture", TRUE);
  709. self->childSetValue("check_landmark", TRUE);
  710. self->childSetValue("check_notecard", TRUE);
  711. self->childSetValue("check_object", TRUE);
  712. self->childSetValue("check_script", TRUE);
  713. self->childSetValue("check_sound", TRUE);
  714. self->childSetValue("check_texture", TRUE);
  715. self->childSetValue("check_snapshot", TRUE);
  716. }
  717. //static
  718. void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
  719. {
  720. LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
  721. if(!self) return;
  722. self->childSetValue("check_animation", FALSE);
  723. self->childSetValue("check_calling_card", FALSE);
  724. self->childSetValue("check_clothing", FALSE);
  725. self->childSetValue("check_gesture", FALSE);
  726. self->childSetValue("check_landmark", FALSE);
  727. self->childSetValue("check_notecard", FALSE);
  728. self->childSetValue("check_object", FALSE);
  729. self->childSetValue("check_script", FALSE);
  730. self->childSetValue("check_sound", FALSE);
  731. self->childSetValue("check_texture", FALSE);
  732. self->childSetValue("check_snapshot", FALSE);
  733. }
  734. //////////////////////////////////////////////////////////////////////////////////
  735. // List Commands                                                                //
  736. void LLPanelMainInventory::initListCommandsHandlers()
  737. {
  738. mListCommands = getChild<LLPanel>("bottom_panel");
  739. mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this));
  740. mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
  741. mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
  742. LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
  743. trash_btn->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this
  744. , _4 // BOOL drop
  745. , _5 // EDragAndDropType cargo_type
  746. , _7 // EAcceptance* accept
  747. ));
  748. mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
  749. mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
  750. mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
  751. mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
  752. }
  753. void LLPanelMainInventory::updateListCommands()
  754. {
  755. bool trash_enabled = isActionEnabled("delete");
  756. mListCommands->childSetEnabled("trash_btn", trash_enabled);
  757. }
  758. void LLPanelMainInventory::onGearButtonClick()
  759. {
  760. showActionMenu(mMenuGearDefault,"options_gear_btn");
  761. }
  762. void LLPanelMainInventory::onAddButtonClick()
  763. {
  764. setUploadCostIfNeeded();
  765. showActionMenu(mMenuAdd,"add_btn");
  766. }
  767. void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
  768. {
  769. if (menu)
  770. {
  771. menu->buildDrawLabels();
  772. menu->updateParent(LLMenuGL::sMenuContainer);
  773. LLView* spawning_view = getChild<LLView> (spawning_view_name);
  774. S32 menu_x, menu_y;
  775. //show menu in co-ordinates of panel
  776. spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this);
  777. menu_y += menu->getRect().getHeight();
  778. LLMenuGL::showPopup(this, menu, menu_x, menu_y);
  779. }
  780. }
  781. void LLPanelMainInventory::onTrashButtonClick()
  782. {
  783. onClipboardAction("delete");
  784. }
  785. void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
  786. {
  787. std::string command_name = userdata.asString();
  788. getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
  789. }
  790. void LLPanelMainInventory::saveTexture(const LLSD& userdata)
  791. {
  792. LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
  793. if (!current_item)
  794. {
  795. return;
  796. }
  797. const LLUUID& item_id = current_item->getListener()->getUUID();
  798. LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
  799. if (preview_texture)
  800. {
  801. preview_texture->openToSave();
  802. }
  803. }
  804. void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
  805. {
  806. if (!isActionEnabled(userdata))
  807. return;
  808. const std::string command_name = userdata.asString();
  809. if (command_name == "new_window")
  810. {
  811. newWindow();
  812. }
  813. if (command_name == "sort_by_name")
  814. {
  815. const LLSD arg = "name";
  816. setSortBy(arg);
  817. }
  818. if (command_name == "sort_by_recent")
  819. {
  820. const LLSD arg = "date";
  821. setSortBy(arg);
  822. }
  823. if (command_name == "show_filters")
  824. {
  825. toggleFindOptions();
  826. }
  827. if (command_name == "reset_filters")
  828. {
  829. resetFilters();
  830. }
  831. if (command_name == "close_folders")
  832. {
  833. closeAllFolders();
  834. }
  835. if (command_name == "empty_trash")
  836. {
  837. const std::string notification = "ConfirmEmptyTrash";
  838. gInventory.emptyFolderType(notification, LLFolderType::FT_TRASH);
  839. }
  840. if (command_name == "empty_lostnfound")
  841. {
  842. const std::string notification = "ConfirmEmptyLostAndFound";
  843. gInventory.emptyFolderType(notification, LLFolderType::FT_LOST_AND_FOUND);
  844. }
  845. if (command_name == "save_texture")
  846. {
  847. saveTexture(userdata);
  848. }
  849. // This doesn't currently work, since the viewer can't change an assetID an item.
  850. if (command_name == "regenerate_link")
  851. {
  852. LLInventoryPanel *active_panel = getActivePanel();
  853. LLFolderViewItem* current_item = active_panel->getRootFolder()->getCurSelectedItem();
  854. if (!current_item)
  855. {
  856. return;
  857. }
  858. const LLUUID item_id = current_item->getListener()->getUUID();
  859. LLViewerInventoryItem *item = gInventory.getItem(item_id);
  860. if (item)
  861. {
  862. item->regenerateLink();
  863. }
  864. active_panel->setSelection(item_id, TAKE_FOCUS_NO);
  865. }
  866. if (command_name == "find_original")
  867. {
  868. LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
  869. if (!current_item)
  870. {
  871. return;
  872. }
  873. current_item->getListener()->performAction(getActivePanel()->getRootFolder(), getActivePanel()->getModel(), "goto");
  874. }
  875. if (command_name == "find_links")
  876. {
  877. LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
  878. if (!current_item)
  879. {
  880. return;
  881. }
  882. const LLUUID& item_id = current_item->getListener()->getUUID();
  883. const std::string &item_name = current_item->getListener()->getName();
  884. mFilterSubString = item_name;
  885. LLInventoryFilter *filter = mActivePanel->getFilter();
  886. filter->setFilterSubString(item_name);
  887. mFilterEditor->setText(item_name);
  888. mFilterEditor->setFocus(TRUE);
  889. filter->setFilterUUID(item_id);
  890. filter->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
  891. }
  892. }
  893. bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
  894. {
  895. LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
  896. if (current_item) 
  897. {
  898. LLViewerInventoryItem *inv_item = current_item->getInventoryItem();
  899. if(inv_item)
  900. {
  901. bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
  902. LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType();
  903. return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
  904. }
  905. }
  906. return false;
  907. }
  908. BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
  909. {
  910. const std::string command_name = userdata.asString();
  911. if (command_name == "delete")
  912. {
  913. BOOL can_delete = FALSE;
  914. LLFolderView *folder = getActivePanel()->getRootFolder();
  915. if (folder)
  916. {
  917. can_delete = TRUE;
  918. std::set<LLUUID> selection_set;
  919. folder->getSelectionList(selection_set);
  920. if (selection_set.empty()) return FALSE;
  921. for (std::set<LLUUID>::iterator iter = selection_set.begin();
  922.  iter != selection_set.end();
  923.  ++iter)
  924. {
  925. const LLUUID &item_id = (*iter);
  926. LLFolderViewItem *item = folder->getItemByID(item_id);
  927. const LLFolderViewEventListener *listener = item->getListener();
  928. llassert(listener);
  929. if (!listener) return FALSE;
  930. can_delete &= listener->isItemRemovable();
  931. can_delete &= !listener->isItemInTrash();
  932. }
  933. return can_delete;
  934. }
  935. return FALSE;
  936. }
  937. if (command_name == "save_texture")
  938. {
  939. return isSaveTextureEnabled(userdata);
  940. }
  941. if (command_name == "find_original")
  942. {
  943. LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
  944. if (!current_item) return FALSE;
  945. const LLUUID& item_id = current_item->getListener()->getUUID();
  946. const LLViewerInventoryItem *item = gInventory.getItem(item_id);
  947. if (item && item->getIsLinkType() && !item->getIsBrokenLink())
  948. {
  949. return TRUE;
  950. }
  951. return FALSE;
  952. }
  953. if (command_name == "find_links")
  954. {
  955. LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
  956. if (!current_item) return FALSE;
  957. const LLUUID& item_id = current_item->getListener()->getUUID();
  958. const LLInventoryObject *obj = gInventory.getObject(item_id);
  959. if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
  960. {
  961. return TRUE;
  962. }
  963. return FALSE;
  964. }
  965. // This doesn't currently work, since the viewer can't change an assetID an item.
  966. if (command_name == "regenerate_link")
  967. {
  968. LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
  969. if (!current_item) return FALSE;
  970. const LLUUID& item_id = current_item->getListener()->getUUID();
  971. const LLViewerInventoryItem *item = gInventory.getItem(item_id);
  972. if (item && item->getIsBrokenLink())
  973. {
  974. return TRUE;
  975. }
  976. return FALSE;
  977. }
  978. return TRUE;
  979. }
  980. bool LLPanelMainInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept)
  981. {
  982. *accept = ACCEPT_NO;
  983. const bool is_enabled = isActionEnabled("delete");
  984. if (is_enabled) *accept = ACCEPT_YES_MULTI;
  985. if (is_enabled && drop)
  986. {
  987. onClipboardAction("delete");
  988. }
  989. return true;
  990. }
  991. void LLPanelMainInventory::setUploadCostIfNeeded()
  992. {
  993. // *NOTE dzaporozhan
  994. // Upload cost is set in process_economy_data() (llviewermessage.cpp). But since we
  995. // have two instances of Inventory panel at the moment(and two instances of context menu),
  996. // call to gMenuHolder->childSetLabelArg() sets upload cost only for one of the instances.
  997. if(mNeedUploadCost && mMenuAdd)
  998. {
  999. LLMenuItemBranchGL* upload_menu = mMenuAdd->findChild<LLMenuItemBranchGL>("upload");
  1000. if(upload_menu)
  1001. {
  1002. S32 upload_cost = -1;//LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
  1003. std::string cost_str;
  1004. // getPriceUpload() returns -1 if no data available yet.
  1005. if(upload_cost >= 0)
  1006. {
  1007. mNeedUploadCost = false;
  1008. cost_str = llformat("%d", upload_cost);
  1009. }
  1010. else
  1011. {
  1012. cost_str = llformat("%d", gSavedSettings.getU32("DefaultUploadCost"));
  1013. }
  1014. upload_menu->getChild<LLView>("Upload Image")->setLabelArg("[COST]", cost_str);
  1015. upload_menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", cost_str);
  1016. upload_menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", cost_str);
  1017. upload_menu->getChild<LLView>("Bulk Upload")->setLabelArg("[COST]", cost_str);
  1018. }
  1019. }
  1020. }
  1021. // List Commands                                                              //
  1022. ////////////////////////////////////////////////////////////////////////////////