/indra/newview/llinventoryitemslist.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 227 lines · 151 code · 38 blank · 38 comment · 26 complexity · a1859dcdc324c670588f9b989c3c5a45 MD5 · raw file

  1. /**
  2. * @file llinventoryitemslist.cpp
  3. * @brief A list of inventory items represented by LLFlatListView.
  4. *
  5. * Class LLInventoryItemsList implements a flat list of inventory items.
  6. *
  7. * $LicenseInfo:firstyear=2010&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #include "llviewerprecompiledheaders.h"
  29. #include "llinventoryitemslist.h"
  30. // llcommon
  31. #include "llcommonutils.h"
  32. #include "lltrans.h"
  33. #include "llcallbacklist.h"
  34. #include "llinventorylistitem.h"
  35. #include "llinventorymodel.h"
  36. #include "llviewerinventory.h"
  37. LLInventoryItemsList::Params::Params()
  38. {}
  39. LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p)
  40. : LLFlatListViewEx(p)
  41. , mNeedsRefresh(false)
  42. , mForceRefresh(false)
  43. {
  44. // TODO: mCommitOnSelectionChange is set to "false" in LLFlatListView
  45. // but reset to true in all derived classes. This settings might need to
  46. // be added to LLFlatListView::Params() and/or set to "true" by default.
  47. setCommitOnSelectionChange(true);
  48. setNoFilteredItemsMsg(LLTrans::getString("InventoryNoMatchingItems"));
  49. gIdleCallbacks.addFunction(idle, this);
  50. }
  51. // virtual
  52. LLInventoryItemsList::~LLInventoryItemsList()
  53. {
  54. gIdleCallbacks.deleteFunction(idle, this);
  55. }
  56. void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
  57. {
  58. getIDs().clear();
  59. LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
  60. for( ; item_array.end() != it; ++it)
  61. {
  62. getIDs().push_back((*it)->getUUID());
  63. }
  64. mNeedsRefresh = true;
  65. }
  66. boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(const commit_signal_t::slot_type& cb)
  67. {
  68. return mRefreshCompleteSignal.connect(cb);
  69. }
  70. bool LLInventoryItemsList::selectItemByValue(const LLSD& value, bool select)
  71. {
  72. if (!LLFlatListView::selectItemByValue(value, select) && !value.isUndefined())
  73. {
  74. mSelectTheseIDs.push_back(value);
  75. return false;
  76. }
  77. return true;
  78. }
  79. void LLInventoryItemsList::updateSelection()
  80. {
  81. if(mSelectTheseIDs.empty()) return;
  82. std::vector<LLSD> cur;
  83. getValues(cur);
  84. for(std::vector<LLSD>::const_iterator cur_id_it = cur.begin(); cur_id_it != cur.end() && !mSelectTheseIDs.empty(); ++cur_id_it)
  85. {
  86. uuid_vec_t::iterator select_ids_it = std::find(mSelectTheseIDs.begin(), mSelectTheseIDs.end(), *cur_id_it);
  87. if(select_ids_it != mSelectTheseIDs.end())
  88. {
  89. selectItemByUUID(*select_ids_it);
  90. mSelectTheseIDs.erase(select_ids_it);
  91. }
  92. }
  93. scrollToShowFirstSelectedItem();
  94. mSelectTheseIDs.clear();
  95. }
  96. void LLInventoryItemsList::doIdle()
  97. {
  98. if (!mNeedsRefresh) return;
  99. if (isInVisibleChain() || mForceRefresh)
  100. {
  101. refresh();
  102. mRefreshCompleteSignal(this, LLSD());
  103. }
  104. }
  105. //static
  106. void LLInventoryItemsList::idle(void* user_data)
  107. {
  108. LLInventoryItemsList* self = static_cast<LLInventoryItemsList*>(user_data);
  109. if ( self )
  110. { // Do the real idle
  111. self->doIdle();
  112. }
  113. }
  114. LLFastTimer::DeclareTimer FTM_INVENTORY_ITEMS_REFRESH("Inventory List Refresh");
  115. void LLInventoryItemsList::refresh()
  116. {
  117. LLFastTimer _(FTM_INVENTORY_ITEMS_REFRESH);
  118. static const unsigned ADD_LIMIT = 20;
  119. uuid_vec_t added_items;
  120. uuid_vec_t removed_items;
  121. computeDifference(getIDs(), added_items, removed_items);
  122. bool add_limit_exceeded = false;
  123. unsigned int nadded = 0;
  124. uuid_vec_t::const_iterator it = added_items.begin();
  125. for( ; added_items.end() != it; ++it)
  126. {
  127. if(nadded >= ADD_LIMIT)
  128. {
  129. add_limit_exceeded = true;
  130. break;
  131. }
  132. LLViewerInventoryItem* item = gInventory.getItem(*it);
  133. // Do not rearrange items on each adding, let's do that on filter call
  134. llassert(item);
  135. if (item)
  136. {
  137. addNewItem(item, false);
  138. ++nadded;
  139. }
  140. }
  141. it = removed_items.begin();
  142. for( ; removed_items.end() != it; ++it)
  143. {
  144. // don't filter items right away
  145. removeItemByUUID(*it, false);
  146. }
  147. // Filter, rearrange and notify parent about shape changes
  148. filterItems();
  149. bool needs_refresh = add_limit_exceeded;
  150. setNeedsRefresh(needs_refresh);
  151. setForceRefresh(needs_refresh);
  152. // After list building completed, select items that had been requested to select before list was build
  153. if(!needs_refresh)
  154. {
  155. updateSelection();
  156. }
  157. }
  158. void LLInventoryItemsList::computeDifference(
  159. const uuid_vec_t& vnew,
  160. uuid_vec_t& vadded,
  161. uuid_vec_t& vremoved)
  162. {
  163. uuid_vec_t vcur;
  164. {
  165. std::vector<LLSD> vcur_values;
  166. getValues(vcur_values);
  167. for (size_t i=0; i<vcur_values.size(); i++)
  168. vcur.push_back(vcur_values[i].asUUID());
  169. }
  170. LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
  171. }
  172. void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/)
  173. {
  174. if (!item)
  175. {
  176. llwarns << "No inventory item. Couldn't create flat list item." << llendl;
  177. llassert(item != NULL);
  178. }
  179. LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item);
  180. if (!list_item)
  181. return;
  182. bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange);
  183. if (!is_item_added)
  184. {
  185. llwarns << "Couldn't add flat list item." << llendl;
  186. llassert(is_item_added);
  187. }
  188. }
  189. // EOF