PageRenderTime 60ms CodeModel.GetById 18ms app.highlight 36ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/newview/llsidepanelinventory.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 715 lines | 506 code | 127 blank | 82 comment | 73 complexity | 4adb86ac2f23d98c3460d661bfc1b4de MD5 | raw file
  1/**
  2 * @file LLSidepanelInventory.cpp
  3 * @brief Side Bar "Inventory" panel
  4 *
  5 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28#include "llsidepanelinventory.h"
 29
 30#include "llagent.h"
 31#include "llappearancemgr.h"
 32#include "llappviewer.h"
 33#include "llavataractions.h"
 34#include "llbutton.h"
 35#include "lldate.h"
 36#include "llfirstuse.h"
 37#include "llfloatersidepanelcontainer.h"
 38#include "llfoldertype.h"
 39#include "llhttpclient.h"
 40#include "llinventorybridge.h"
 41#include "llinventoryfunctions.h"
 42#include "llinventorymodel.h"
 43#include "llinventorymodelbackgroundfetch.h"
 44#include "llinventoryobserver.h"
 45#include "llinventorypanel.h"
 46#include "lllayoutstack.h"
 47#include "lloutfitobserver.h"
 48#include "llpanelmaininventory.h"
 49#include "llpanelmarketplaceinbox.h"
 50#include "llselectmgr.h"
 51#include "llsidepaneliteminfo.h"
 52#include "llsidepaneltaskinfo.h"
 53#include "llstring.h"
 54#include "lltabcontainer.h"
 55#include "lltextbox.h"
 56#include "lltrans.h"
 57#include "llviewermedia.h"
 58#include "llviewernetwork.h"
 59#include "llweb.h"
 60
 61static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory");
 62
 63//
 64// Constants
 65//
 66
 67// No longer want the inbox panel to auto-expand since it creates issues with the "new" tag time stamp
 68#define AUTO_EXPAND_INBOX	0
 69
 70static const char * const INBOX_BUTTON_NAME = "inbox_btn";
 71static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel";
 72static const char * const MAIN_INVENTORY_LAYOUT_PANEL_NAME = "main_inventory_layout_panel";
 73
 74static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack";
 75
 76static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox";
 77
 78//
 79// Helpers
 80//
 81
 82class LLInboxAddedObserver : public LLInventoryCategoryAddedObserver
 83{
 84public:
 85	LLInboxAddedObserver(LLSidepanelInventory * sidepanelInventory)
 86		: LLInventoryCategoryAddedObserver()
 87		, mSidepanelInventory(sidepanelInventory)
 88	{
 89	}
 90	
 91	void done()
 92	{
 93		for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it)
 94		{
 95			LLViewerInventoryCategory* added_category = *it;
 96			
 97			LLFolderType::EType added_category_type = added_category->getPreferredType();
 98			
 99			switch (added_category_type)
100			{
101				case LLFolderType::FT_INBOX:
102					mSidepanelInventory->enableInbox(true);
103					mSidepanelInventory->observeInboxModifications(added_category->getUUID());
104					break;
105				default:
106					break;
107			}
108		}
109	}
110	
111private:
112	LLSidepanelInventory * mSidepanelInventory;
113};
114
115//
116// Implementation
117//
118
119LLSidepanelInventory::LLSidepanelInventory()
120	: LLPanel()
121	, mItemPanel(NULL)
122	, mInventoryPanelInbox(NULL)
123	, mPanelMainInventory(NULL)
124	, mInboxEnabled(false)
125	, mCategoriesObserver(NULL)
126	, mInboxAddedObserver(NULL)
127{
128	//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
129}
130
131LLSidepanelInventory::~LLSidepanelInventory()
132{
133	if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
134	{
135		gInventory.removeObserver(mCategoriesObserver);
136	}
137	delete mCategoriesObserver;
138	
139	if (mInboxAddedObserver && gInventory.containsObserver(mInboxAddedObserver))
140	{
141		gInventory.removeObserver(mInboxAddedObserver);
142	}
143	delete mInboxAddedObserver;
144}
145
146void handleInventoryDisplayInboxChanged()
147{
148	LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
149	if (sidepanel_inventory)
150	{
151		sidepanel_inventory->enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
152	}
153}
154
155BOOL LLSidepanelInventory::postBuild()
156{
157	// UI elements from inventory panel
158	{
159		mInventoryPanel = getChild<LLPanel>("sidepanel__inventory_panel");
160
161		mInfoBtn = mInventoryPanel->getChild<LLButton>("info_btn");
162		mInfoBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onInfoButtonClicked, this));
163		
164		mShareBtn = mInventoryPanel->getChild<LLButton>("share_btn");
165		mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this));
166		
167		mShopBtn = mInventoryPanel->getChild<LLButton>("shop_btn");
168		mShopBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShopButtonClicked, this));
169
170		mWearBtn = mInventoryPanel->getChild<LLButton>("wear_btn");
171		mWearBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onWearButtonClicked, this));
172		
173		mPlayBtn = mInventoryPanel->getChild<LLButton>("play_btn");
174		mPlayBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onPlayButtonClicked, this));
175		
176		mTeleportBtn = mInventoryPanel->getChild<LLButton>("teleport_btn");
177		mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this));
178		
179		mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn");
180		mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this));
181		
182		mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
183		mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));
184		LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs");
185		tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));
186
187		/* 
188		   EXT-4846 : "Can we suppress the "Landmarks" and "My Favorites" folder since they have their own Task Panel?"
189		   Deferring this until 2.1.
190		LLInventoryPanel *my_inventory_panel = mPanelMainInventory->getChild<LLInventoryPanel>("All Items");
191		my_inventory_panel->addHideFolderType(LLFolderType::FT_LANDMARK);
192		my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE);
193		*/
194
195		LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));
196	}
197
198	// UI elements from item panel
199	{
200		mItemPanel = getChild<LLSidepanelItemInfo>("sidepanel__item_panel");
201		
202		LLButton* back_btn = mItemPanel->getChild<LLButton>("back_btn");
203		back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this));
204	}
205
206	// UI elements from task panel
207	{
208		mTaskPanel = findChild<LLSidepanelTaskInfo>("sidepanel__task_panel");
209		if (mTaskPanel)
210		{
211			LLButton* back_btn = mTaskPanel->getChild<LLButton>("back_btn");
212			back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this));
213		}
214	}
215	
216	// Received items inbox setup
217	{
218		LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
219
220		// Collapse inbox panel
221		inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true);
222		
223		// Set up button states and callbacks
224		LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME);
225
226		inbox_button->setToggleState(false);
227		inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this));
228
229		// Set the inbox visible based on debug settings (final setting comes from http request below)
230		enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
231
232		// Trigger callback for after login so we can setup to track inbox changes after initial inventory load
233		LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::updateInbox, this));
234	}
235
236	gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged));
237
238	// Update the verbs buttons state.
239	updateVerbs();
240
241	return TRUE;
242}
243
244void LLSidepanelInventory::updateInbox()
245{
246	//
247	// Track inbox folder changes
248	//
249
250	const bool do_not_create_folder = false;
251	const bool do_not_find_in_library = false;
252
253	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library);
254	
255	// Set up observer to listen for creation of inbox if at least one of them doesn't exist
256	if (inbox_id.isNull())
257	{
258		observeInboxCreation();
259	}
260	// Set up observer for inbox changes, if we have an inbox already
261	else 
262	{
263		// Enable the display of the inbox if it exists
264		enableInbox(true);
265
266		observeInboxModifications(inbox_id);
267	}
268}
269
270void LLSidepanelInventory::observeInboxCreation()
271{
272	//
273	// Set up observer to track inbox folder creation
274	//
275	
276	if (mInboxAddedObserver == NULL)
277	{
278		mInboxAddedObserver = new LLInboxAddedObserver(this);
279		
280		gInventory.addObserver(mInboxAddedObserver);
281	}
282}
283
284void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
285{
286	//
287	// Silently do nothing if we already have an inbox inventory panel set up
288	// (this can happen multiple times on the initial session that creates the inbox)
289	//
290
291	if (mInventoryPanelInbox != NULL)
292	{
293		return;
294	}
295
296	//
297	// Track inbox folder changes
298	//
299
300	if (inboxID.isNull())
301	{
302		llwarns << "Attempting to track modifications to non-existent inbox" << llendl;
303		return;
304	}
305
306	if (mCategoriesObserver == NULL)
307	{
308		mCategoriesObserver = new LLInventoryCategoriesObserver();
309		gInventory.addObserver(mCategoriesObserver);
310	}
311
312	mCategoriesObserver->addCategory(inboxID, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inboxID));
313
314	//
315	// Trigger a load for the entire contents of the Inbox
316	//
317
318	LLInventoryModelBackgroundFetch::instance().start(inboxID);
319
320	//
321	// Set up the inbox inventory view
322	//
323
324	LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
325	mInventoryPanelInbox = inbox->setupInventoryPanel();
326}
327
328void LLSidepanelInventory::enableInbox(bool enabled)
329{
330	mInboxEnabled = enabled;
331	
332	LLLayoutPanel * inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
333	inbox_layout_panel->setVisible(enabled);
334}
335
336void LLSidepanelInventory::openInbox()
337{
338	if (mInboxEnabled)
339	{
340		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
341		onToggleInboxBtn();
342	}
343}
344
345void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id)
346{
347	// Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting
348	LLInventoryModelBackgroundFetch::instance().start(inbox_id);
349
350#if AUTO_EXPAND_INBOX
351	// Expand the inbox since we have fresh items
352	if (mInboxEnabled)
353	{
354		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
355		onToggleInboxBtn();
356	}
357#endif
358}
359
360void LLSidepanelInventory::onToggleInboxBtn()
361{
362	LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME);
363	LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
364	LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
365	
366	const bool inbox_expanded = inboxButton->getToggleState();
367	
368	// Expand/collapse the indicated panel
369	inv_stack->collapsePanel(inboxPanel, !inbox_expanded);
370
371	if (inbox_expanded && inboxPanel->isInVisibleChain())
372	{
373		gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
374	}
375}
376
377void LLSidepanelInventory::onOpen(const LLSD& key)
378{
379	LLFirstUse::newInventory(false);
380
381#if AUTO_EXPAND_INBOX
382	// Expand the inbox if we have fresh items
383	LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
384	if (inbox && (inbox->getFreshItemCount() > 0))
385	{
386		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
387		onToggleInboxBtn();
388	}
389#else
390	if (mInboxEnabled && getChild<LLButton>(INBOX_BUTTON_NAME)->getToggleState())
391	{
392		gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
393	}
394#endif
395
396	if(key.size() == 0)
397		return;
398
399	mItemPanel->reset();
400
401	if (key.has("id"))
402	{
403		mItemPanel->setItemID(key["id"].asUUID());
404		if (key.has("object"))
405		{
406			mItemPanel->setObjectID(key["object"].asUUID());
407		}
408		showItemInfoPanel();
409	}
410	if (key.has("task"))
411	{
412		if (mTaskPanel)
413			mTaskPanel->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
414		showTaskInfoPanel();
415	}
416}
417
418void LLSidepanelInventory::onInfoButtonClicked()
419{
420	LLInventoryItem *item = getSelectedItem();
421	if (item)
422	{
423		mItemPanel->reset();
424		mItemPanel->setItemID(item->getUUID());
425		showItemInfoPanel();
426	}
427}
428
429void LLSidepanelInventory::onShareButtonClicked()
430{
431	LLAvatarActions::shareWithAvatars();
432}
433
434void LLSidepanelInventory::onShopButtonClicked()
435{
436	LLWeb::loadURLExternal(gSavedSettings.getString("MarketplaceURL"));
437}
438
439void LLSidepanelInventory::performActionOnSelection(const std::string &action)
440{
441	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
442	if (!current_item)
443	{
444		if (mInventoryPanelInbox)
445		{
446			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
447		}
448
449		if (!current_item)
450		{
451			return;
452		}
453	}
454
455	current_item->getListener()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
456}
457
458void LLSidepanelInventory::onWearButtonClicked()
459{
460	// Get selected items set.
461	const std::set<LLUUID> selected_uuids_set = LLAvatarActions::getInventorySelectedUUIDs();
462	if (selected_uuids_set.empty()) return; // nothing selected
463
464	// Convert the set to a vector.
465	uuid_vec_t selected_uuids_vec;
466	for (std::set<LLUUID>::const_iterator it = selected_uuids_set.begin(); it != selected_uuids_set.end(); ++it)
467	{
468		selected_uuids_vec.push_back(*it);
469	}
470
471	// Wear all selected items.
472	wear_multiple(selected_uuids_vec, true);
473}
474
475void LLSidepanelInventory::onPlayButtonClicked()
476{
477	const LLInventoryItem *item = getSelectedItem();
478	if (!item)
479	{
480		return;
481	}
482
483	switch(item->getInventoryType())
484	{
485	case LLInventoryType::IT_GESTURE:
486		performActionOnSelection("play");
487		break;
488	default:
489		performActionOnSelection("open");
490		break;
491	}
492}
493
494void LLSidepanelInventory::onTeleportButtonClicked()
495{
496	performActionOnSelection("teleport");
497}
498
499void LLSidepanelInventory::onOverflowButtonClicked()
500{
501}
502
503void LLSidepanelInventory::onBackButtonClicked()
504{
505	showInventoryPanel();
506}
507
508void LLSidepanelInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
509{
510	updateVerbs();
511}
512
513void LLSidepanelInventory::showItemInfoPanel()
514{
515	mItemPanel->setVisible(TRUE);
516	if (mTaskPanel)
517		mTaskPanel->setVisible(FALSE);
518	mInventoryPanel->setVisible(FALSE);
519
520	mItemPanel->dirty();
521	mItemPanel->setIsEditing(FALSE);
522}
523
524void LLSidepanelInventory::showTaskInfoPanel()
525{
526	mItemPanel->setVisible(FALSE);
527	mInventoryPanel->setVisible(FALSE);
528
529	if (mTaskPanel)
530	{
531		mTaskPanel->setVisible(TRUE);
532		mTaskPanel->dirty();
533		mTaskPanel->setIsEditing(FALSE);
534	}
535}
536
537void LLSidepanelInventory::showInventoryPanel()
538{
539	mItemPanel->setVisible(FALSE);
540	if (mTaskPanel)
541		mTaskPanel->setVisible(FALSE);
542	mInventoryPanel->setVisible(TRUE);
543	updateVerbs();
544}
545
546void LLSidepanelInventory::updateVerbs()
547{
548	mInfoBtn->setEnabled(FALSE);
549	mShareBtn->setEnabled(FALSE);
550
551	mWearBtn->setVisible(FALSE);
552	mWearBtn->setEnabled(FALSE);
553	mPlayBtn->setVisible(FALSE);
554	mPlayBtn->setEnabled(FALSE);
555 	mTeleportBtn->setVisible(FALSE);
556 	mTeleportBtn->setEnabled(FALSE);
557 	mShopBtn->setVisible(TRUE);
558
559	mShareBtn->setEnabled(canShare());
560
561	const LLInventoryItem *item = getSelectedItem();
562	if (!item)
563		return;
564
565	bool is_single_selection = getSelectedCount() == 1;
566
567	mInfoBtn->setEnabled(is_single_selection);
568
569	switch(item->getInventoryType())
570	{
571		case LLInventoryType::IT_WEARABLE:
572		case LLInventoryType::IT_OBJECT:
573		case LLInventoryType::IT_ATTACHMENT:
574			mWearBtn->setVisible(TRUE);
575			mWearBtn->setEnabled(canWearSelected());
576		 	mShopBtn->setVisible(FALSE);
577			break;
578		case LLInventoryType::IT_SOUND:
579		case LLInventoryType::IT_GESTURE:
580		case LLInventoryType::IT_ANIMATION:
581			mPlayBtn->setVisible(TRUE);
582			mPlayBtn->setEnabled(TRUE);
583		 	mShopBtn->setVisible(FALSE);
584			break;
585		case LLInventoryType::IT_LANDMARK:
586			mTeleportBtn->setVisible(TRUE);
587			mTeleportBtn->setEnabled(TRUE);
588		 	mShopBtn->setVisible(FALSE);
589			break;
590		default:
591			break;
592	}
593}
594
595bool LLSidepanelInventory::canShare()
596{
597	LLInventoryPanel* inbox = mInventoryPanelInbox;
598
599	// Avoid flicker in the Recent tab while inventory is being loaded.
600	if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty())
601		&& (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
602	{
603		return false;
604	}
605
606	return ( (mPanelMainInventory ? LLAvatarActions::canShareSelectedItems(mPanelMainInventory->getActivePanel()) : false)
607			|| (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) );
608}
609
610
611bool LLSidepanelInventory::canWearSelected()
612{
613
614	std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
615
616	if (selected_uuids.empty())
617		return false;
618
619	for (std::set<LLUUID>::const_iterator it = selected_uuids.begin();
620		it != selected_uuids.end();
621		++it)
622	{
623		if (!get_can_item_be_worn(*it)) return false;
624	}
625
626	return true;
627}
628
629LLInventoryItem *LLSidepanelInventory::getSelectedItem()
630{
631	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
632	
633	if (!current_item)
634	{
635		if (mInventoryPanelInbox)
636		{
637			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
638		}
639
640		if (!current_item)
641		{
642			return NULL;
643		}
644	}
645	const LLUUID &item_id = current_item->getListener()->getUUID();
646	LLInventoryItem *item = gInventory.getItem(item_id);
647	return item;
648}
649
650U32 LLSidepanelInventory::getSelectedCount()
651{
652	int count = 0;
653
654	std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
655	count += selection_list.size();
656
657	if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
658	{
659		selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList();
660
661		count += selection_list.size();
662	}
663
664	return count;
665}
666
667LLInventoryPanel *LLSidepanelInventory::getActivePanel()
668{
669	if (!getVisible())
670	{
671		return NULL;
672	}
673	if (mInventoryPanel->getVisible())
674	{
675		return mPanelMainInventory->getActivePanel();
676	}
677	return NULL;
678}
679
680BOOL LLSidepanelInventory::isMainInventoryPanelActive() const
681{
682	return mInventoryPanel->getVisible();
683}
684
685void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
686{
687	if (clearMain)
688	{
689		LLInventoryPanel * inv_panel = getActivePanel();
690		
691		if (inv_panel)
692		{
693			inv_panel->clearSelection();
694		}
695	}
696	
697	if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL))
698	{
699		mInventoryPanelInbox->clearSelection();
700	}
701	
702	updateVerbs();
703}
704
705std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList()
706{
707	std::set<LLUUID> inventory_selected_uuids;
708	
709	if (mInboxEnabled && (mInventoryPanelInbox != NULL))
710	{
711		inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList();
712	}
713	
714	return inventory_selected_uuids;
715}