PageRenderTime 36ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/newview/llinventoryfilter.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 976 lines | 769 code | 109 blank | 98 comment | 183 complexity | e4d064c44270c62835703de75364bbf2 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llinventoryfilter.cpp
  3. * @brief Support for filtering your inventory to only display a subset of the
  4. * available items.
  5. *
  6. * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "llviewerprecompiledheaders.h"
  28. #include "llinventoryfilter.h"
  29. // viewer includes
  30. #include "llfoldervieweventlistener.h"
  31. #include "llfolderviewitem.h"
  32. #include "llinventorymodel.h"
  33. #include "llinventorymodelbackgroundfetch.h"
  34. #include "llviewercontrol.h"
  35. #include "llfolderview.h"
  36. #include "llinventorybridge.h"
  37. #include "llviewerfoldertype.h"
  38. // linden library includes
  39. #include "lltrans.h"
  40. LLInventoryFilter::FilterOps::FilterOps() :
  41. mFilterObjectTypes(0xffffffffffffffffULL),
  42. mFilterCategoryTypes(0xffffffffffffffffULL),
  43. mFilterWearableTypes(0xffffffffffffffffULL),
  44. mMinDate(time_min()),
  45. mMaxDate(time_max()),
  46. mHoursAgo(0),
  47. mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
  48. mPermissions(PERM_NONE),
  49. mFilterTypes(FILTERTYPE_OBJECT),
  50. mFilterUUID(LLUUID::null),
  51. mFilterLinks(FILTERLINK_INCLUDE_LINKS)
  52. {
  53. }
  54. ///----------------------------------------------------------------------------
  55. /// Class LLInventoryFilter
  56. ///----------------------------------------------------------------------------
  57. LLInventoryFilter::LLInventoryFilter(const std::string& name)
  58. : mName(name),
  59. mModified(FALSE),
  60. mNeedTextRebuild(TRUE),
  61. mEmptyLookupMessage("InventoryNoMatchingItems")
  62. {
  63. mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
  64. mSubStringMatchOffset = 0;
  65. mFilterSubString.clear();
  66. mFilterGeneration = 0;
  67. mMustPassGeneration = S32_MAX;
  68. mMinRequiredGeneration = 0;
  69. mFilterCount = 0;
  70. mNextFilterGeneration = mFilterGeneration + 1;
  71. mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
  72. mFilterBehavior = FILTER_NONE;
  73. // copy mFilterOps into mDefaultFilterOps
  74. markDefault();
  75. }
  76. LLInventoryFilter::~LLInventoryFilter()
  77. {
  78. }
  79. BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
  80. {
  81. // If it's a folder and we're showing all folders, return TRUE automatically.
  82. const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
  83. if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
  84. {
  85. return TRUE;
  86. }
  87. mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
  88. const BOOL passed_filtertype = checkAgainstFilterType(item);
  89. const BOOL passed_permissions = checkAgainstPermissions(item);
  90. const BOOL passed_filterlink = checkAgainstFilterLinks(item);
  91. const BOOL passed = (passed_filtertype &&
  92. passed_permissions &&
  93. passed_filterlink &&
  94. (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
  95. return passed;
  96. }
  97. bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
  98. {
  99. // we're showing all folders, overriding filter
  100. if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
  101. {
  102. return true;
  103. }
  104. const LLFolderViewEventListener* listener = folder->getListener();
  105. const LLUUID folder_id = listener->getUUID();
  106. if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
  107. {
  108. // Can only filter categories for items in your inventory
  109. // (e.g. versus in-world object contents).
  110. const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
  111. if (!cat)
  112. return false;
  113. LLFolderType::EType cat_type = cat->getPreferredType();
  114. if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
  115. return false;
  116. }
  117. return true;
  118. }
  119. BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
  120. {
  121. const LLFolderViewEventListener* listener = item->getListener();
  122. if (!listener) return FALSE;
  123. LLInventoryType::EType object_type = listener->getInventoryType();
  124. const LLUUID object_id = listener->getUUID();
  125. const LLInventoryObject *object = gInventory.getObject(object_id);
  126. const U32 filterTypes = mFilterOps.mFilterTypes;
  127. ////////////////////////////////////////////////////////////////////////////////
  128. // FILTERTYPE_OBJECT
  129. // Pass if this item's type is of the correct filter type
  130. if (filterTypes & FILTERTYPE_OBJECT)
  131. {
  132. // If it has no type, pass it, unless it's a link.
  133. if (object_type == LLInventoryType::IT_NONE)
  134. {
  135. if (object && object->getIsLinkType())
  136. {
  137. return FALSE;
  138. }
  139. }
  140. else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
  141. {
  142. return FALSE;
  143. }
  144. }
  145. ////////////////////////////////////////////////////////////////////////////////
  146. // FILTERTYPE_UUID
  147. // Pass if this item is the target UUID or if it links to the target UUID
  148. if (filterTypes & FILTERTYPE_UUID)
  149. {
  150. if (!object) return FALSE;
  151. if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
  152. return FALSE;
  153. }
  154. ////////////////////////////////////////////////////////////////////////////////
  155. // FILTERTYPE_DATE
  156. // Pass if this item is within the date range.
  157. if (filterTypes & FILTERTYPE_DATE)
  158. {
  159. const U16 HOURS_TO_SECONDS = 3600;
  160. time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
  161. if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
  162. {
  163. earliest = mFilterOps.mMinDate;
  164. }
  165. else if (!mFilterOps.mHoursAgo)
  166. {
  167. earliest = 0;
  168. }
  169. if (listener->getCreationDate() < earliest ||
  170. listener->getCreationDate() > mFilterOps.mMaxDate)
  171. return FALSE;
  172. }
  173. ////////////////////////////////////////////////////////////////////////////////
  174. // FILTERTYPE_WEARABLE
  175. // Pass if this item is a wearable of the appropriate type
  176. if (filterTypes & FILTERTYPE_WEARABLE)
  177. {
  178. LLWearableType::EType type = listener->getWearableType();
  179. if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
  180. {
  181. return FALSE;
  182. }
  183. }
  184. ////////////////////////////////////////////////////////////////////////////////
  185. // FILTERTYPE_EMPTYFOLDERS
  186. // Pass if this item is a folder and is not a system folder that should be hidden
  187. if (filterTypes & FILTERTYPE_EMPTYFOLDERS)
  188. {
  189. if (object_type == LLInventoryType::IT_CATEGORY)
  190. {
  191. bool is_hidden_if_empty = LLViewerFolderType::lookupIsHiddenIfEmpty(listener->getPreferredType());
  192. if (is_hidden_if_empty)
  193. {
  194. // Force the fetching of those folders so they are hidden iff they really are empty...
  195. gInventory.fetchDescendentsOf(object_id);
  196. return FALSE;
  197. }
  198. }
  199. }
  200. return TRUE;
  201. }
  202. BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
  203. {
  204. const LLFolderViewEventListener* listener = item->getListener();
  205. if (!listener) return FALSE;
  206. PermissionMask perm = listener->getPermissionMask();
  207. const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener());
  208. if (bridge && bridge->isLink())
  209. {
  210. const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
  211. const LLViewerInventoryItem *linked_item = gInventory.getItem(linked_uuid);
  212. if (linked_item)
  213. perm = linked_item->getPermissionMask();
  214. }
  215. return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
  216. }
  217. BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
  218. {
  219. const LLFolderViewEventListener* listener = item->getListener();
  220. if (!listener) return TRUE;
  221. const LLUUID object_id = listener->getUUID();
  222. const LLInventoryObject *object = gInventory.getObject(object_id);
  223. if (!object) return TRUE;
  224. const BOOL is_link = object->getIsLinkType();
  225. if (is_link && (mFilterOps.mFilterLinks == FILTERLINK_EXCLUDE_LINKS))
  226. return FALSE;
  227. if (!is_link && (mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS))
  228. return FALSE;
  229. return TRUE;
  230. }
  231. const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
  232. {
  233. return mFilterSubString;
  234. }
  235. std::string::size_type LLInventoryFilter::getStringMatchOffset() const
  236. {
  237. return mSubStringMatchOffset;
  238. }
  239. // has user modified default filter params?
  240. BOOL LLInventoryFilter::isNotDefault() const
  241. {
  242. BOOL not_default = FALSE;
  243. not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
  244. not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
  245. not_default |= (mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes);
  246. not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes);
  247. not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks);
  248. not_default |= (mFilterSubString.size());
  249. not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions);
  250. not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
  251. not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
  252. not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
  253. return not_default;
  254. }
  255. BOOL LLInventoryFilter::isActive() const
  256. {
  257. return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
  258. || mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
  259. || mFilterOps.mFilterWearableTypes != 0xffffffffffffffffULL
  260. || mFilterOps.mFilterTypes != FILTERTYPE_OBJECT
  261. || mFilterOps.mFilterLinks != FILTERLINK_INCLUDE_LINKS
  262. || mFilterSubString.size()
  263. || mFilterOps.mPermissions != PERM_NONE
  264. || mFilterOps.mMinDate != time_min()
  265. || mFilterOps.mMaxDate != time_max()
  266. || mFilterOps.mHoursAgo != 0;
  267. }
  268. BOOL LLInventoryFilter::isModified() const
  269. {
  270. return mModified;
  271. }
  272. BOOL LLInventoryFilter::isModifiedAndClear()
  273. {
  274. BOOL ret = mModified;
  275. mModified = FALSE;
  276. return ret;
  277. }
  278. void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
  279. {
  280. if (current_types != types)
  281. {
  282. // keep current items only if no type bits getting turned off
  283. bool fewer_bits_set = (current_types & ~types) != 0;
  284. bool more_bits_set = (~current_types & types) != 0;
  285. current_types = types;
  286. if (more_bits_set && fewer_bits_set)
  287. {
  288. // neither less or more restrive, both simultaneously
  289. // so we need to filter from scratch
  290. setModified(FILTER_RESTART);
  291. }
  292. else if (more_bits_set)
  293. {
  294. // target is only one of all requested types so more type bits == less restrictive
  295. setModified(FILTER_LESS_RESTRICTIVE);
  296. }
  297. else if (fewer_bits_set)
  298. {
  299. setModified(FILTER_MORE_RESTRICTIVE);
  300. }
  301. }
  302. }
  303. void LLInventoryFilter::setFilterObjectTypes(U64 types)
  304. {
  305. updateFilterTypes(types, mFilterOps.mFilterObjectTypes);
  306. mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
  307. }
  308. void LLInventoryFilter::setFilterCategoryTypes(U64 types)
  309. {
  310. updateFilterTypes(types, mFilterOps.mFilterCategoryTypes);
  311. mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
  312. }
  313. void LLInventoryFilter::setFilterWearableTypes(U64 types)
  314. {
  315. updateFilterTypes(types, mFilterOps.mFilterWearableTypes);
  316. mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
  317. }
  318. void LLInventoryFilter::setFilterEmptySystemFolders()
  319. {
  320. mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS;
  321. }
  322. void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)
  323. {
  324. if (mFilterOps.mFilterUUID == LLUUID::null)
  325. {
  326. setModified(FILTER_MORE_RESTRICTIVE);
  327. }
  328. else
  329. {
  330. setModified(FILTER_RESTART);
  331. }
  332. mFilterOps.mFilterUUID = object_id;
  333. mFilterOps.mFilterTypes = FILTERTYPE_UUID;
  334. }
  335. void LLInventoryFilter::setFilterSubString(const std::string& string)
  336. {
  337. std::string filter_sub_string_new = string;
  338. mFilterSubStringOrig = string;
  339. LLStringUtil::trimHead(filter_sub_string_new);
  340. LLStringUtil::toUpper(filter_sub_string_new);
  341. if (mFilterSubString != filter_sub_string_new)
  342. {
  343. // hitting BACKSPACE, for example
  344. const BOOL less_restrictive = mFilterSubString.size() >= filter_sub_string_new.size()
  345. && !mFilterSubString.substr(0, filter_sub_string_new.size()).compare(filter_sub_string_new);
  346. // appending new characters
  347. const BOOL more_restrictive = mFilterSubString.size() < filter_sub_string_new.size()
  348. && !filter_sub_string_new.substr(0, mFilterSubString.size()).compare(mFilterSubString);
  349. mFilterSubString = filter_sub_string_new;
  350. if (less_restrictive)
  351. {
  352. setModified(FILTER_LESS_RESTRICTIVE);
  353. }
  354. else if (more_restrictive)
  355. {
  356. setModified(FILTER_MORE_RESTRICTIVE);
  357. }
  358. else
  359. {
  360. setModified(FILTER_RESTART);
  361. }
  362. // Cancel out UUID once the search string is modified
  363. if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)
  364. {
  365. mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
  366. mFilterOps.mFilterUUID == LLUUID::null;
  367. setModified(FILTER_RESTART);
  368. }
  369. // Cancel out filter links once the search string is modified
  370. {
  371. mFilterOps.mFilterLinks = FILTERLINK_INCLUDE_LINKS;
  372. }
  373. }
  374. }
  375. void LLInventoryFilter::setFilterPermissions(PermissionMask perms)
  376. {
  377. if (mFilterOps.mPermissions != perms)
  378. {
  379. // keep current items only if no perm bits getting turned off
  380. BOOL fewer_bits_set = (mFilterOps.mPermissions & ~perms);
  381. BOOL more_bits_set = (~mFilterOps.mPermissions & perms);
  382. mFilterOps.mPermissions = perms;
  383. if (more_bits_set && fewer_bits_set)
  384. {
  385. setModified(FILTER_RESTART);
  386. }
  387. else if (more_bits_set)
  388. {
  389. // target must have all requested permission bits, so more bits == more restrictive
  390. setModified(FILTER_MORE_RESTRICTIVE);
  391. }
  392. else if (fewer_bits_set)
  393. {
  394. setModified(FILTER_LESS_RESTRICTIVE);
  395. }
  396. }
  397. }
  398. void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
  399. {
  400. mFilterOps.mHoursAgo = 0;
  401. if (mFilterOps.mMinDate != min_date)
  402. {
  403. mFilterOps.mMinDate = min_date;
  404. setModified();
  405. }
  406. if (mFilterOps.mMaxDate != llmax(mFilterOps.mMinDate, max_date))
  407. {
  408. mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date);
  409. setModified();
  410. }
  411. mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
  412. }
  413. void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
  414. {
  415. if (sl && !isSinceLogoff())
  416. {
  417. setDateRange(mLastLogoff, time_max());
  418. setModified();
  419. }
  420. if (!sl && isSinceLogoff())
  421. {
  422. setDateRange(0, time_max());
  423. setModified();
  424. }
  425. mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
  426. }
  427. BOOL LLInventoryFilter::isSinceLogoff() const
  428. {
  429. return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
  430. (mFilterOps.mMaxDate == time_max()) &&
  431. (mFilterOps.mFilterTypes & FILTERTYPE_DATE);
  432. }
  433. void LLInventoryFilter::clearModified()
  434. {
  435. mModified = FALSE;
  436. mFilterBehavior = FILTER_NONE;
  437. }
  438. void LLInventoryFilter::setHoursAgo(U32 hours)
  439. {
  440. if (mFilterOps.mHoursAgo != hours)
  441. {
  442. bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max();
  443. bool is_increasing = hours > mFilterOps.mHoursAgo;
  444. bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo;
  445. // *NOTE: need to cache last filter time, in case filter goes stale
  446. BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours);
  447. BOOL more_restrictive = (are_date_limits_valid && (!is_increasing && hours) || is_increasing_from_zero);
  448. mFilterOps.mHoursAgo = hours;
  449. mFilterOps.mMinDate = time_min();
  450. mFilterOps.mMaxDate = time_max();
  451. if (less_restrictive)
  452. {
  453. setModified(FILTER_LESS_RESTRICTIVE);
  454. }
  455. else if (more_restrictive)
  456. {
  457. setModified(FILTER_MORE_RESTRICTIVE);
  458. }
  459. else
  460. {
  461. setModified(FILTER_RESTART);
  462. }
  463. }
  464. mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
  465. }
  466. void LLInventoryFilter::setFilterLinks(U64 filter_links)
  467. {
  468. if (mFilterOps.mFilterLinks != filter_links)
  469. {
  470. if (mFilterOps.mFilterLinks == FILTERLINK_EXCLUDE_LINKS ||
  471. mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS)
  472. setModified(FILTER_MORE_RESTRICTIVE);
  473. else
  474. setModified(FILTER_LESS_RESTRICTIVE);
  475. }
  476. mFilterOps.mFilterLinks = filter_links;
  477. }
  478. void LLInventoryFilter::setShowFolderState(EFolderShow state)
  479. {
  480. if (mFilterOps.mShowFolderState != state)
  481. {
  482. mFilterOps.mShowFolderState = state;
  483. if (state == SHOW_NON_EMPTY_FOLDERS)
  484. {
  485. // showing fewer folders than before
  486. setModified(FILTER_MORE_RESTRICTIVE);
  487. }
  488. else if (state == SHOW_ALL_FOLDERS)
  489. {
  490. // showing same folders as before and then some
  491. setModified(FILTER_LESS_RESTRICTIVE);
  492. }
  493. else
  494. {
  495. setModified();
  496. }
  497. }
  498. }
  499. void LLInventoryFilter::setSortOrder(U32 order)
  500. {
  501. if (mOrder != order)
  502. {
  503. mOrder = order;
  504. setModified();
  505. }
  506. }
  507. void LLInventoryFilter::markDefault()
  508. {
  509. mDefaultFilterOps = mFilterOps;
  510. }
  511. void LLInventoryFilter::resetDefault()
  512. {
  513. mFilterOps = mDefaultFilterOps;
  514. setModified();
  515. }
  516. void LLInventoryFilter::setModified(EFilterBehavior behavior)
  517. {
  518. mModified = TRUE;
  519. mNeedTextRebuild = TRUE;
  520. mFilterGeneration = mNextFilterGeneration++;
  521. if (mFilterBehavior == FILTER_NONE)
  522. {
  523. mFilterBehavior = behavior;
  524. }
  525. else if (mFilterBehavior != behavior)
  526. {
  527. // trying to do both less restrictive and more restrictive filter
  528. // basically means restart from scratch
  529. mFilterBehavior = FILTER_RESTART;
  530. }
  531. if (isNotDefault())
  532. {
  533. // if not keeping current filter results, update last valid as well
  534. switch(mFilterBehavior)
  535. {
  536. case FILTER_RESTART:
  537. mMustPassGeneration = mFilterGeneration;
  538. mMinRequiredGeneration = mFilterGeneration;
  539. break;
  540. case FILTER_LESS_RESTRICTIVE:
  541. mMustPassGeneration = mFilterGeneration;
  542. break;
  543. case FILTER_MORE_RESTRICTIVE:
  544. mMinRequiredGeneration = mFilterGeneration;
  545. // must have passed either current filter generation (meaningless, as it hasn't been run yet)
  546. // or some older generation, so keep the value
  547. mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
  548. break;
  549. default:
  550. llerrs << "Bad filter behavior specified" << llendl;
  551. }
  552. }
  553. else
  554. {
  555. // shortcut disabled filters to show everything immediately
  556. mMinRequiredGeneration = 0;
  557. mMustPassGeneration = S32_MAX;
  558. }
  559. }
  560. BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
  561. {
  562. return mFilterOps.mFilterObjectTypes & (1LL << t);
  563. }
  564. const std::string& LLInventoryFilter::getFilterText()
  565. {
  566. if (!mNeedTextRebuild)
  567. {
  568. return mFilterText;
  569. }
  570. mNeedTextRebuild = FALSE;
  571. std::string filtered_types;
  572. std::string not_filtered_types;
  573. BOOL filtered_by_type = FALSE;
  574. BOOL filtered_by_all_types = TRUE;
  575. S32 num_filter_types = 0;
  576. mFilterText.clear();
  577. if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
  578. {
  579. //filtered_types += " Animations,";
  580. filtered_types += LLTrans::getString("Animations");
  581. filtered_by_type = TRUE;
  582. num_filter_types++;
  583. }
  584. else
  585. {
  586. //not_filtered_types += " Animations,";
  587. not_filtered_types += LLTrans::getString("Animations");
  588. filtered_by_all_types = FALSE;
  589. }
  590. if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
  591. {
  592. //filtered_types += " Calling Cards,";
  593. filtered_types += LLTrans::getString("Calling Cards");
  594. filtered_by_type = TRUE;
  595. num_filter_types++;
  596. }
  597. else
  598. {
  599. //not_filtered_types += " Calling Cards,";
  600. not_filtered_types += LLTrans::getString("Calling Cards");
  601. filtered_by_all_types = FALSE;
  602. }
  603. if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
  604. {
  605. //filtered_types += " Clothing,";
  606. filtered_types += LLTrans::getString("Clothing");
  607. filtered_by_type = TRUE;
  608. num_filter_types++;
  609. }
  610. else
  611. {
  612. //not_filtered_types += " Clothing,";
  613. not_filtered_types += LLTrans::getString("Clothing");
  614. filtered_by_all_types = FALSE;
  615. }
  616. if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
  617. {
  618. //filtered_types += " Gestures,";
  619. filtered_types += LLTrans::getString("Gestures");
  620. filtered_by_type = TRUE;
  621. num_filter_types++;
  622. }
  623. else
  624. {
  625. //not_filtered_types += " Gestures,";
  626. not_filtered_types += LLTrans::getString("Gestures");
  627. filtered_by_all_types = FALSE;
  628. }
  629. if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
  630. {
  631. //filtered_types += " Landmarks,";
  632. filtered_types += LLTrans::getString("Landmarks");
  633. filtered_by_type = TRUE;
  634. num_filter_types++;
  635. }
  636. else
  637. {
  638. //not_filtered_types += " Landmarks,";
  639. not_filtered_types += LLTrans::getString("Landmarks");
  640. filtered_by_all_types = FALSE;
  641. }
  642. if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
  643. {
  644. //filtered_types += " Notecards,";
  645. filtered_types += LLTrans::getString("Notecards");
  646. filtered_by_type = TRUE;
  647. num_filter_types++;
  648. }
  649. else
  650. {
  651. //not_filtered_types += " Notecards,";
  652. not_filtered_types += LLTrans::getString("Notecards");
  653. filtered_by_all_types = FALSE;
  654. }
  655. if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
  656. {
  657. //filtered_types += " Objects,";
  658. filtered_types += LLTrans::getString("Objects");
  659. filtered_by_type = TRUE;
  660. num_filter_types++;
  661. }
  662. else
  663. {
  664. //not_filtered_types += " Objects,";
  665. not_filtered_types += LLTrans::getString("Objects");
  666. filtered_by_all_types = FALSE;
  667. }
  668. if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
  669. {
  670. //filtered_types += " Scripts,";
  671. filtered_types += LLTrans::getString("Scripts");
  672. filtered_by_type = TRUE;
  673. num_filter_types++;
  674. }
  675. else
  676. {
  677. //not_filtered_types += " Scripts,";
  678. not_filtered_types += LLTrans::getString("Scripts");
  679. filtered_by_all_types = FALSE;
  680. }
  681. if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
  682. {
  683. //filtered_types += " Sounds,";
  684. filtered_types += LLTrans::getString("Sounds");
  685. filtered_by_type = TRUE;
  686. num_filter_types++;
  687. }
  688. else
  689. {
  690. //not_filtered_types += " Sounds,";
  691. not_filtered_types += LLTrans::getString("Sounds");
  692. filtered_by_all_types = FALSE;
  693. }
  694. if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
  695. {
  696. //filtered_types += " Textures,";
  697. filtered_types += LLTrans::getString("Textures");
  698. filtered_by_type = TRUE;
  699. num_filter_types++;
  700. }
  701. else
  702. {
  703. //not_filtered_types += " Textures,";
  704. not_filtered_types += LLTrans::getString("Textures");
  705. filtered_by_all_types = FALSE;
  706. }
  707. if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
  708. {
  709. //filtered_types += " Snapshots,";
  710. filtered_types += LLTrans::getString("Snapshots");
  711. filtered_by_type = TRUE;
  712. num_filter_types++;
  713. }
  714. else
  715. {
  716. //not_filtered_types += " Snapshots,";
  717. not_filtered_types += LLTrans::getString("Snapshots");
  718. filtered_by_all_types = FALSE;
  719. }
  720. if (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()
  721. && filtered_by_type
  722. && !filtered_by_all_types)
  723. {
  724. mFilterText += " - ";
  725. if (num_filter_types < 5)
  726. {
  727. mFilterText += filtered_types;
  728. }
  729. else
  730. {
  731. //mFilterText += "No ";
  732. mFilterText += LLTrans::getString("No Filters");
  733. mFilterText += not_filtered_types;
  734. }
  735. // remove the ',' at the end
  736. mFilterText.erase(mFilterText.size() - 1, 1);
  737. }
  738. if (isSinceLogoff())
  739. {
  740. //mFilterText += " - Since Logoff";
  741. mFilterText += LLTrans::getString("Since Logoff");
  742. }
  743. return mFilterText;
  744. }
  745. void LLInventoryFilter::toLLSD(LLSD& data) const
  746. {
  747. data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
  748. data["min_date"] = (LLSD::Integer)getMinDate();
  749. data["max_date"] = (LLSD::Integer)getMaxDate();
  750. data["hours_ago"] = (LLSD::Integer)getHoursAgo();
  751. data["show_folder_state"] = (LLSD::Integer)getShowFolderState();
  752. data["permissions"] = (LLSD::Integer)getFilterPermissions();
  753. data["substring"] = (LLSD::String)getFilterSubString();
  754. data["sort_order"] = (LLSD::Integer)getSortOrder();
  755. data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
  756. }
  757. void LLInventoryFilter::fromLLSD(LLSD& data)
  758. {
  759. if(data.has("filter_types"))
  760. {
  761. setFilterObjectTypes((U32)data["filter_types"].asInteger());
  762. }
  763. if(data.has("min_date") && data.has("max_date"))
  764. {
  765. setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger());
  766. }
  767. if(data.has("hours_ago"))
  768. {
  769. setHoursAgo((U32)data["hours_ago"].asInteger());
  770. }
  771. if(data.has("show_folder_state"))
  772. {
  773. setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
  774. }
  775. if(data.has("permissions"))
  776. {
  777. setFilterPermissions((PermissionMask)data["permissions"].asInteger());
  778. }
  779. if(data.has("substring"))
  780. {
  781. setFilterSubString(std::string(data["substring"].asString()));
  782. }
  783. if(data.has("sort_order"))
  784. {
  785. setSortOrder((U32)data["sort_order"].asInteger());
  786. }
  787. if(data.has("since_logoff"))
  788. {
  789. setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
  790. }
  791. }
  792. U64 LLInventoryFilter::getFilterObjectTypes() const
  793. {
  794. return mFilterOps.mFilterObjectTypes;
  795. }
  796. U64 LLInventoryFilter::getFilterCategoryTypes() const
  797. {
  798. return mFilterOps.mFilterCategoryTypes;
  799. }
  800. BOOL LLInventoryFilter::hasFilterString() const
  801. {
  802. return mFilterSubString.size() > 0;
  803. }
  804. PermissionMask LLInventoryFilter::getFilterPermissions() const
  805. {
  806. return mFilterOps.mPermissions;
  807. }
  808. time_t LLInventoryFilter::getMinDate() const
  809. {
  810. return mFilterOps.mMinDate;
  811. }
  812. time_t LLInventoryFilter::getMaxDate() const
  813. {
  814. return mFilterOps.mMaxDate;
  815. }
  816. U32 LLInventoryFilter::getHoursAgo() const
  817. {
  818. return mFilterOps.mHoursAgo;
  819. }
  820. U64 LLInventoryFilter::getFilterLinks() const
  821. {
  822. return mFilterOps.mFilterLinks;
  823. }
  824. LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
  825. {
  826. return mFilterOps.mShowFolderState;
  827. }
  828. U32 LLInventoryFilter::getSortOrder() const
  829. {
  830. return mOrder;
  831. }
  832. const std::string& LLInventoryFilter::getName() const
  833. {
  834. return mName;
  835. }
  836. void LLInventoryFilter::setFilterCount(S32 count)
  837. {
  838. mFilterCount = count;
  839. }
  840. S32 LLInventoryFilter::getFilterCount() const
  841. {
  842. return mFilterCount;
  843. }
  844. void LLInventoryFilter::decrementFilterCount()
  845. {
  846. mFilterCount--;
  847. }
  848. S32 LLInventoryFilter::getCurrentGeneration() const
  849. {
  850. return mFilterGeneration;
  851. }
  852. S32 LLInventoryFilter::getMinRequiredGeneration() const
  853. {
  854. return mMinRequiredGeneration;
  855. }
  856. S32 LLInventoryFilter::getMustPassGeneration() const
  857. {
  858. return mMustPassGeneration;
  859. }
  860. void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
  861. {
  862. mEmptyLookupMessage = message;
  863. }
  864. const std::string& LLInventoryFilter::getEmptyLookupMessage() const
  865. {
  866. return mEmptyLookupMessage;
  867. }