PageRenderTime 27ms CodeModel.GetById 2ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 29#include "llviewerprecompiledheaders.h"
 30
 31#include "llinventoryitemslist.h"
 32
 33// llcommon
 34#include "llcommonutils.h"
 35
 36#include "lltrans.h"
 37
 38#include "llcallbacklist.h"
 39#include "llinventorylistitem.h"
 40#include "llinventorymodel.h"
 41#include "llviewerinventory.h"
 42
 43LLInventoryItemsList::Params::Params()
 44{}
 45
 46LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p)
 47:	LLFlatListViewEx(p)
 48,	mNeedsRefresh(false)
 49,	mForceRefresh(false)
 50{
 51	// TODO: mCommitOnSelectionChange is set to "false" in LLFlatListView
 52	// but reset to true in all derived classes. This settings might need to
 53	// be added to LLFlatListView::Params() and/or set to "true" by default.
 54	setCommitOnSelectionChange(true);
 55
 56	setNoFilteredItemsMsg(LLTrans::getString("InventoryNoMatchingItems"));
 57
 58	gIdleCallbacks.addFunction(idle, this);
 59}
 60
 61// virtual
 62LLInventoryItemsList::~LLInventoryItemsList()
 63{
 64	gIdleCallbacks.deleteFunction(idle, this);
 65}
 66
 67void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
 68{
 69	getIDs().clear();
 70	LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
 71	for( ; item_array.end() != it; ++it)
 72	{
 73		getIDs().push_back((*it)->getUUID());
 74	}
 75	mNeedsRefresh = true;
 76}
 77
 78boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(const commit_signal_t::slot_type& cb)
 79{
 80	return mRefreshCompleteSignal.connect(cb);
 81}
 82
 83bool LLInventoryItemsList::selectItemByValue(const LLSD& value, bool select)
 84{
 85	if (!LLFlatListView::selectItemByValue(value, select) && !value.isUndefined())
 86	{
 87		mSelectTheseIDs.push_back(value);
 88		return false;
 89	}
 90	return true;
 91}
 92
 93void LLInventoryItemsList::updateSelection()
 94{
 95	if(mSelectTheseIDs.empty()) return;
 96
 97	std::vector<LLSD> cur;
 98	getValues(cur);
 99
100	for(std::vector<LLSD>::const_iterator cur_id_it = cur.begin(); cur_id_it != cur.end() && !mSelectTheseIDs.empty(); ++cur_id_it)
101	{
102		uuid_vec_t::iterator select_ids_it = std::find(mSelectTheseIDs.begin(), mSelectTheseIDs.end(), *cur_id_it);
103		if(select_ids_it != mSelectTheseIDs.end())
104		{
105			selectItemByUUID(*select_ids_it);
106			mSelectTheseIDs.erase(select_ids_it);
107		}
108	}
109
110	scrollToShowFirstSelectedItem();
111	mSelectTheseIDs.clear();
112}
113
114void LLInventoryItemsList::doIdle()
115{
116	if (!mNeedsRefresh) return;
117
118	if (isInVisibleChain() || mForceRefresh)
119	{
120		refresh();
121
122		mRefreshCompleteSignal(this, LLSD());
123	}
124}
125
126//static
127void LLInventoryItemsList::idle(void* user_data)
128{
129	LLInventoryItemsList* self = static_cast<LLInventoryItemsList*>(user_data);
130	if ( self )
131	{	// Do the real idle
132		self->doIdle();
133	}
134}
135
136LLFastTimer::DeclareTimer FTM_INVENTORY_ITEMS_REFRESH("Inventory List Refresh");
137
138void LLInventoryItemsList::refresh()
139{
140	LLFastTimer _(FTM_INVENTORY_ITEMS_REFRESH);
141	static const unsigned ADD_LIMIT = 20;
142
143	uuid_vec_t added_items;
144	uuid_vec_t removed_items;
145
146	computeDifference(getIDs(), added_items, removed_items);
147
148	bool add_limit_exceeded = false;
149	unsigned int nadded = 0;
150
151	uuid_vec_t::const_iterator it = added_items.begin();
152	for( ; added_items.end() != it; ++it)
153	{
154		if(nadded >= ADD_LIMIT)
155		{
156			add_limit_exceeded = true;
157			break;
158		}
159		LLViewerInventoryItem* item = gInventory.getItem(*it);
160		// Do not rearrange items on each adding, let's do that on filter call
161		llassert(item);
162		if (item)
163		{
164			addNewItem(item, false);
165			++nadded;
166		}
167	}
168
169	it = removed_items.begin();
170	for( ; removed_items.end() != it; ++it)
171	{
172		// don't filter items right away
173		removeItemByUUID(*it, false);
174	}
175
176	// Filter, rearrange and notify parent about shape changes
177	filterItems();
178
179	bool needs_refresh = add_limit_exceeded;
180	setNeedsRefresh(needs_refresh);
181	setForceRefresh(needs_refresh);
182
183	// After list building completed, select items that had been requested to select before list was build
184	if(!needs_refresh)
185	{
186		updateSelection();
187	}
188}
189
190void LLInventoryItemsList::computeDifference(
191	const uuid_vec_t& vnew,
192	uuid_vec_t& vadded,
193	uuid_vec_t& vremoved)
194{
195	uuid_vec_t vcur;
196	{
197		std::vector<LLSD> vcur_values;
198		getValues(vcur_values);
199
200		for (size_t i=0; i<vcur_values.size(); i++)
201			vcur.push_back(vcur_values[i].asUUID());
202	}
203
204	LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
205}
206
207void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/)
208{
209	if (!item)
210	{
211		llwarns << "No inventory item. Couldn't create flat list item." << llendl;
212		llassert(item != NULL);
213	}
214
215	LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item);
216	if (!list_item)
217		return;
218
219	bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange);
220	if (!is_item_added)
221	{
222		llwarns << "Couldn't add flat list item." << llendl;
223		llassert(is_item_added);
224	}
225}
226
227// EOF