From 280e01729173e79e37939c3e764f9f3f674f79da Mon Sep 17 00:00:00 2001
From: Loren Shih <seraph@lindenlab.com>
Date: Thu, 5 Nov 2009 15:00:36 -0500
Subject: EXT-2229 : Task SP : Update task on new selection

Using activePanel hack to update selection when it changes.

--HG--
branch : avatar-pipeline
---
 indra/newview/llpanelmaininventory.cpp         | 1637 ++++++++++++------------
 indra/newview/llselectmgr.cpp                  |   20 +-
 indra/newview/llsidepanelinventorysubpanel.cpp |    2 +-
 indra/newview/llsidepaneltaskinfo.cpp          |   51 +-
 indra/newview/llsidepaneltaskinfo.h            |    7 +
 5 files changed, 893 insertions(+), 824 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 617445a27f..876151479f 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -1,818 +1,819 @@
-/** 
- * @file llsidepanelmaininventory.cpp
- * @brief Implementation of llsidepanelmaininventory.
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- * 
- * Copyright (c) 2001-2009, Linden Research, Inc.
- * 
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab.  Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- * 
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- * 
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- * 
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llpanelmaininventory.h"
-
-#include "llfloaterinventory.h"
-#include "llinventorybridge.h"
-#include "llinventoryfunctions.h"
-#include "llinventorypanel.h"
-#include "llfiltereditor.h"
-#include "llfloaterreg.h"
-#include "llscrollcontainer.h"
-#include "llsdserialize.h"
-#include "llspinctrl.h"
-#include "lltooldraganddrop.h"
-
-static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor?
-
-///----------------------------------------------------------------------------
-/// LLFloaterInventoryFinder
-///----------------------------------------------------------------------------
-
-class LLFloaterInventoryFinder : public LLFloater
-{
-public:
-	LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view);
-	virtual void draw();
-	/*virtual*/	BOOL	postBuild();
-	void changeFilter(LLInventoryFilter* filter);
-	void updateElementsFromFilter();
-	BOOL getCheckShowEmpty();
-	BOOL getCheckSinceLogoff();
-
-	static void onTimeAgo(LLUICtrl*, void *);
-	static void onCheckSinceLogoff(LLUICtrl*, void *);
-	static void onCloseBtn(void* user_data);
-	static void selectAllTypes(void* user_data);
-	static void selectNoTypes(void* user_data);
-private:
-	LLPanelMainInventory*	mPanelInventoryDecorated;
-	LLSpinCtrl*			mSpinSinceDays;
-	LLSpinCtrl*			mSpinSinceHours;
-	LLInventoryFilter*	mFilter;
-};
-
-///----------------------------------------------------------------------------
-/// LLPanelMainInventory
-///----------------------------------------------------------------------------
-
-LLPanelMainInventory::LLPanelMainInventory()
-	: LLPanel()
-{
-	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT);
-	// Menu Callbacks (non contex menus)
-	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
-	mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
-	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH));
-	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND));
-	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
- 	mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this));
-	mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
-	mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
-	mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
-
-	// Controls
-	// *TODO: Just use persistant settings for each of these
-	U32 sort_order = gSavedSettings.getU32("InventorySortOrder");
-	BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE );
-	BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME );
-	BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP );
-	
-	gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE);
-	gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE);
-	gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE);
-	gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE);
-	
-	mSavedFolderState = new LLSaveFolderState();
-	mSavedFolderState->setApply(FALSE);
-}
-
-BOOL LLPanelMainInventory::postBuild()
-{
-	gInventory.addObserver(this);
-	
-	mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
-	mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
-	
-	//panel->getFilter()->markDefault();
-
-	// Set up the default inv. panel/filter settings.
-	mActivePanel = getChild<LLInventoryPanel>("All Items");
-	if (mActivePanel)
-	{
-		// "All Items" is the previous only view, so it gets the InventorySortOrder
-		mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder"));
-		mActivePanel->getFilter()->markDefault();
-		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
-		mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2));
-	}
-	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
-	if (recent_items_panel)
-	{
-		recent_items_panel->setSinceLogoff(TRUE);
-		recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
-		recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
-		recent_items_panel->getFilter()->markDefault();
-		recent_items_panel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2));
-	}
-
-	// Now load the stored settings from disk, if available.
-	std::ostringstream filterSaveName;
-	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
-	llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << llendl;
-	llifstream file(filterSaveName.str());
-	LLSD savedFilterState;
-	if (file.is_open())
-	{
-		LLSDSerialize::fromXML(savedFilterState, file);
-		file.close();
-
-		// Load the persistent "Recent Items" settings.
-		// Note that the "All Items" settings do not persist.
-		if(recent_items_panel)
-		{
-			if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
-			{
-				LLSD recent_items = savedFilterState.get(
-					recent_items_panel->getFilter()->getName());
-				recent_items_panel->getFilter()->fromLLSD(recent_items);
-			}
-		}
-
-	}
-
-
-	mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
-	if (mFilterEditor)
-	{
-		mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
-	}
-
-	// *TODO:Get the cost info from the server
-	const std::string upload_cost("10");
-	childSetLabelArg("Upload Image", "[COST]", upload_cost);
-	childSetLabelArg("Upload Sound", "[COST]", upload_cost);
-	childSetLabelArg("Upload Animation", "[COST]", upload_cost);
-	childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
-	
-	return TRUE;
-}
-
-// Destroys the object
-LLPanelMainInventory::~LLPanelMainInventory( void )
-{
-	// Save the filters state.
-	LLSD filterRoot;
-	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
-	if (all_items_panel)
-	{
-		LLInventoryFilter* filter = all_items_panel->getFilter();
-		if (filter)
-		{
-			LLSD filterState;
-			filter->toLLSD(filterState);
-			filterRoot[filter->getName()] = filterState;
-		}
-	}
-
-	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
-	if (recent_items_panel)
-	{
-		LLInventoryFilter* filter = recent_items_panel->getFilter();
-		if (filter)
-		{
-			LLSD filterState;
-			filter->toLLSD(filterState);
-			filterRoot[filter->getName()] = filterState;
-		}
-	}
-
-	std::ostringstream filterSaveName;
-	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
-	llofstream filtersFile(filterSaveName.str());
-	if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
-	{
-		llwarns << "Could not write to filters save file " << filterSaveName << llendl;
-	}
-	else
-		filtersFile.close();
-
-	gInventory.removeObserver(this);
-	delete mSavedFolderState;
-}
-
-void LLPanelMainInventory::startSearch()
-{
-	// this forces focus to line editor portion of search editor
-	if (mFilterEditor)
-	{
-		mFilterEditor->focusFirstItem(TRUE);
-	}
-}
-
-BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
-{
-	LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
-	if (root_folder)
-	{
-		// first check for user accepting current search results
-		if (mFilterEditor 
-			&& mFilterEditor->hasFocus()
-		    && (key == KEY_RETURN 
-		    	|| key == KEY_DOWN)
-		    && mask == MASK_NONE)
-		{
-			// move focus to inventory proper
-			mActivePanel->setFocus(TRUE);
-			root_folder->scrollToShowSelection();
-			return TRUE;
-		}
-
-		if (mActivePanel->hasFocus() && key == KEY_UP)
-		{
-			startSearch();
-		}
-	}
-
-	return LLPanel::handleKeyHere(key, mask);
-
-}
-
-//----------------------------------------------------------------------------
-// menu callbacks
-
-void LLPanelMainInventory::doToSelected(const LLSD& userdata)
-{
-	getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
-}
-
-void LLPanelMainInventory::closeAllFolders()
-{
-	getPanel()->getRootFolder()->closeAllFolders();
-}
-
-void LLPanelMainInventory::newWindow()
-{
-	LLFloaterInventory::showAgentInventory();
-}
-
-void LLPanelMainInventory::doCreate(const LLSD& userdata)
-{
-	menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
-}
-
-void LLPanelMainInventory::resetFilters()
-{
-	LLFloaterInventoryFinder *finder = getFinder();
-	getActivePanel()->getFilter()->resetDefault();
-	if (finder)
-	{
-		finder->updateElementsFromFilter();
-	}
-
-	setFilterTextFromFilter();
-}
-
-void LLPanelMainInventory::setSortBy(const LLSD& userdata)
-{
-	std::string sort_field = userdata.asString();
-	if (sort_field == "name")
-	{
-		U32 order = getActivePanel()->getSortOrder();
-		getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE );
-			
-		gSavedSettings.setBOOL("Inventory.SortByName", TRUE );
-		gSavedSettings.setBOOL("Inventory.SortByDate", FALSE );
-	}
-	else if (sort_field == "date")
-	{
-		U32 order = getActivePanel()->getSortOrder();
-		getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE );
-
-		gSavedSettings.setBOOL("Inventory.SortByName", FALSE );
-		gSavedSettings.setBOOL("Inventory.SortByDate", TRUE );
-	}
-	else if (sort_field == "foldersalwaysbyname")
-	{
-		U32 order = getActivePanel()->getSortOrder();
-		if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME )
-		{
-			order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
-
-			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE );
-		}
-		else
-		{
-			order |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
-
-			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE );
-		}
-		getActivePanel()->setSortOrder( order );
-	}
-	else if (sort_field == "systemfolderstotop")
-	{
-		U32 order = getActivePanel()->getSortOrder();
-		if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
-		{
-			order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
-
-			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE );
-		}
-		else
-		{
-			order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
-
-			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE );
-		}
-		getActivePanel()->setSortOrder( order );
-	}
-}
-
-// static
-BOOL LLPanelMainInventory::filtersVisible(void* user_data)
-{
-	LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
-	if(!self) return FALSE;
-
-	return self->getFinder() != NULL;
-}
-
-void LLPanelMainInventory::onClearSearch()
-{
-	LLFloater *finder = getFinder();
-	if (mActivePanel)
-	{
-		mActivePanel->setFilterSubString(LLStringUtil::null);
-		mActivePanel->setFilterTypes(0xffffffff);
-	}
-
-	if (finder)
-	{
-		LLFloaterInventoryFinder::selectAllTypes(finder);
-	}
-
-	// re-open folders that were initially open
-	if (mActivePanel)
-	{
-		mSavedFolderState->setApply(TRUE);
-		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
-		LLOpenFoldersWithSelection opener;
-		mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
-		mActivePanel->getRootFolder()->scrollToShowSelection();
-	}
-}
-
-void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
-{
-	if (search_string == "")
-	{
-		onClearSearch();
-	}
-	if (!mActivePanel)
-	{
-		return;
-	}
-
-	gInventory.startBackgroundFetch();
-
-	std::string uppercase_search_string = search_string;
-	LLStringUtil::toUpper(uppercase_search_string);
-	if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
-	{
-			// current filter and new filter empty, do nothing
-			return;
-	}
-
-	// save current folder open state if no filter currently applied
-	if (!mActivePanel->getRootFolder()->isFilterModified())
-	{
-		mSavedFolderState->setApply(FALSE);
-		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
-	}
-
-	// set new filter string
-	mActivePanel->setFilterSubString(uppercase_search_string);
-}
-
-
- //static
- BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
- {
- 	LLPanelMainInventory* active_view = NULL;
-	
-	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
-	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
-	{
-		LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter);
-		if (iv)
-		{
-			if (gFocusMgr.childHasKeyboardFocus(iv))
-			{
-				active_view = iv;
-				break;
-			}
- 		}
- 	}
-
- 	if (!active_view)
- 	{
- 		return FALSE;
- 	}
-
- 	std::string search_string(find_text);
-
- 	if (search_string.empty())
- 	{
- 		return FALSE;
- 	}
-
- 	if (active_view->getPanel() &&
- 		active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward))
- 	{
- 		return TRUE;
- 	}
-
- 	return FALSE;
- }
-
-void LLPanelMainInventory::onFilterSelected()
-{
-	// Find my index
-	mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs");
-
-	if (!mActivePanel)
-	{
-		return;
-	}
-	LLInventoryFilter* filter = mActivePanel->getFilter();
-	LLFloaterInventoryFinder *finder = getFinder();
-	if (finder)
-	{
-		finder->changeFilter(filter);
-	}
-	if (filter->isActive())
-	{
-		// If our filter is active we may be the first thing requiring a fetch so we better start it here.
-		gInventory.startBackgroundFetch();
-	}
-	setFilterTextFromFilter();
-}
-
-const std::string LLPanelMainInventory::getFilterSubString() 
-{ 
-	return mActivePanel->getFilterSubString(); 
-}
-
-void LLPanelMainInventory::setFilterSubString(const std::string& string) 
-{ 
-	mActivePanel->setFilterSubString(string); 
-}
-
-BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-										 EDragAndDropType cargo_type,
-										 void* cargo_data,
-										 EAcceptance* accept,
-										 std::string& tooltip_msg)
-{
-	// Check to see if we are auto scrolling from the last frame
-	LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
-	BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y);
-	if(mFilterTabs)
-	{
-		if(needsToScroll)
-		{
-			mFilterTabs->startDragAndDropDelayTimer();
-		}
-	}
-	
-	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-
-	return handled;
-}
-
-void LLPanelMainInventory::changed(U32 mask)
-{
-}
-
-
-void LLPanelMainInventory::setFilterTextFromFilter() 
-{ 
-	mFilterText = mActivePanel->getFilter()->getFilterText(); 
-}
-
-void LLPanelMainInventory::toggleFindOptions()
-{
-	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE);
-	LLFloater *floater = getFinder();
-	if (!floater)
-	{
-		LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
-		mFinderHandle = finder->getHandle();
-		finder->openFloater();
-
-		LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-		if (parent_floater) // Seraph: Fix this, shouldn't be null even for sidepanel
-			parent_floater->addDependentFloater(mFinderHandle);
-		// start background fetch of folders
-		gInventory.startBackgroundFetch();
-	}
-	else
-	{
-		floater->closeFloater();
-	}
-}
-
-void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
-{
-	getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
-	getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
-}
-
-///----------------------------------------------------------------------------
-/// LLFloaterInventoryFinder
-///----------------------------------------------------------------------------
-
-LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() 
-{ 
-	return (LLFloaterInventoryFinder*)mFinderHandle.get();
-}
-
-
-LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :	
-	LLFloater(LLSD()),
-	mPanelInventoryDecorated(inventory_view),
-	mFilter(inventory_view->getPanel()->getFilter())
-{
-	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL);
-	updateElementsFromFilter();
-}
-
-
-void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
-{
-	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
-	if (!self) return;
-
-	bool since_logoff= self->childGetValue("check_since_logoff");
-	
-	if (!since_logoff && 
-	    !(  self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() ) )
-	{
-		self->mSpinSinceHours->set(1.0f);
-	}	
-}
-BOOL LLFloaterInventoryFinder::postBuild()
-{
-	const LLRect& viewrect = mPanelInventoryDecorated->getRect();
-	setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
-
-	childSetAction("All", selectAllTypes, this);
-	childSetAction("None", selectNoTypes, this);
-
-	mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
-	childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
-
-	mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
-	childSetCommitCallback("spin_days_ago", onTimeAgo, this);
-
-	//	mCheckSinceLogoff   = getChild<LLSpinCtrl>("check_since_logoff");
-	childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
-
-	childSetAction("Close", onCloseBtn, this);
-
-	updateElementsFromFilter();
-	return TRUE;
-}
-void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
-{
-	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
-	if (!self) return;
-	
-	bool since_logoff=true;
-	if ( self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() )
-	{
-		since_logoff = false;
-	}
-	self->childSetValue("check_since_logoff", since_logoff);
-}
-
-void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
-{
-	mFilter = filter;
-	updateElementsFromFilter();
-}
-
-void LLFloaterInventoryFinder::updateElementsFromFilter()
-{
-	if (!mFilter)
-		return;
-
-	// Get data needed for filter display
-	U32 filter_types = mFilter->getFilterTypes();
-	std::string filter_string = mFilter->getFilterSubString();
-	LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
-	U32 hours = mFilter->getHoursAgo();
-
-	// update the ui elements
-	setTitle(mFilter->getName());
-
-	childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
-
-	childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
-	childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
-	childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
-	childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
-	childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
-	childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
-	childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
-	childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
-	childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
-	childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
-	childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
-	childSetValue("check_since_logoff", mFilter->isSinceLogoff());
-	mSpinSinceHours->set((F32)(hours % 24));
-	mSpinSinceDays->set((F32)(hours / 24));
-}
-
-void LLFloaterInventoryFinder::draw()
-{
-	LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
-	U32 filter = 0xffffffff;
-	BOOL filtered_by_all_types = TRUE;
-
-	if (!childGetValue("check_animation"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
-		filtered_by_all_types = FALSE;
-	}
-
-
-	if (!childGetValue("check_calling_card"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_clothing"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_gesture"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_landmark"))
-
-
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_notecard"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_object"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
-		filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_script"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_LSL);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_sound"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_SOUND);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_texture"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!childGetValue("check_snapshot"))
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
-		filtered_by_all_types = FALSE;
-	}
-
-	if (!filtered_by_all_types)
-	{
-		// don't include folders in filter, unless I've selected everything
-		filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
-	}
-
-	// update the panel, panel will update the filter
-	mPanelInventoryDecorated->getPanel()->setShowFolderState(getCheckShowEmpty() ?
-		LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
-	mPanelInventoryDecorated->getPanel()->setFilterTypes(filter);
-	if (getCheckSinceLogoff())
-	{
-		mSpinSinceDays->set(0);
-		mSpinSinceHours->set(0);
-	}
-	U32 days = (U32)mSpinSinceDays->get();
-	U32 hours = (U32)mSpinSinceHours->get();
-	if (hours > 24)
-	{
-		days += hours / 24;
-		hours = (U32)hours % 24;
-		mSpinSinceDays->set((F32)days);
-		mSpinSinceHours->set((F32)hours);
-	}
-	hours += days * 24;
-	mPanelInventoryDecorated->getPanel()->setHoursAgo(hours);
-	mPanelInventoryDecorated->getPanel()->setSinceLogoff(getCheckSinceLogoff());
-	mPanelInventoryDecorated->setFilterTextFromFilter();
-
-	LLPanel::draw();
-}
-
-BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
-{
-	return childGetValue("check_show_empty");
-}
-
-BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
-{
-	return childGetValue("check_since_logoff");
-}
-
-void LLFloaterInventoryFinder::onCloseBtn(void* user_data)
-{
-	LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
-	finderp->closeFloater();
-}
-
-// static
-void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
-{
-	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
-	if(!self) return;
-
-	self->childSetValue("check_animation", TRUE);
-	self->childSetValue("check_calling_card", TRUE);
-	self->childSetValue("check_clothing", TRUE);
-	self->childSetValue("check_gesture", TRUE);
-	self->childSetValue("check_landmark", TRUE);
-	self->childSetValue("check_notecard", TRUE);
-	self->childSetValue("check_object", TRUE);
-	self->childSetValue("check_script", TRUE);
-	self->childSetValue("check_sound", TRUE);
-	self->childSetValue("check_texture", TRUE);
-	self->childSetValue("check_snapshot", TRUE);
-}
-
-//static
-void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
-{
-	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
-	if(!self) return;
-
-	self->childSetValue("check_animation", FALSE);
-	self->childSetValue("check_calling_card", FALSE);
-	self->childSetValue("check_clothing", FALSE);
-	self->childSetValue("check_gesture", FALSE);
-	self->childSetValue("check_landmark", FALSE);
-	self->childSetValue("check_notecard", FALSE);
-	self->childSetValue("check_object", FALSE);
-	self->childSetValue("check_script", FALSE);
-	self->childSetValue("check_sound", FALSE);
-	self->childSetValue("check_texture", FALSE);
-	self->childSetValue("check_snapshot", FALSE);
-}
+/** 
+ * @file llsidepanelmaininventory.cpp
+ * @brief Implementation of llsidepanelmaininventory.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelmaininventory.h"
+
+#include "llfloaterinventory.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventorypanel.h"
+#include "llfiltereditor.h"
+#include "llfloaterreg.h"
+#include "llscrollcontainer.h"
+#include "llsdserialize.h"
+#include "llspinctrl.h"
+#include "lltooldraganddrop.h"
+
+static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor?
+
+///----------------------------------------------------------------------------
+/// LLFloaterInventoryFinder
+///----------------------------------------------------------------------------
+
+class LLFloaterInventoryFinder : public LLFloater
+{
+public:
+	LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view);
+	virtual void draw();
+	/*virtual*/	BOOL	postBuild();
+	void changeFilter(LLInventoryFilter* filter);
+	void updateElementsFromFilter();
+	BOOL getCheckShowEmpty();
+	BOOL getCheckSinceLogoff();
+
+	static void onTimeAgo(LLUICtrl*, void *);
+	static void onCheckSinceLogoff(LLUICtrl*, void *);
+	static void onCloseBtn(void* user_data);
+	static void selectAllTypes(void* user_data);
+	static void selectNoTypes(void* user_data);
+private:
+	LLPanelMainInventory*	mPanelMainInventory;
+	LLSpinCtrl*			mSpinSinceDays;
+	LLSpinCtrl*			mSpinSinceHours;
+	LLInventoryFilter*	mFilter;
+};
+
+///----------------------------------------------------------------------------
+/// LLPanelMainInventory
+///----------------------------------------------------------------------------
+
+LLPanelMainInventory::LLPanelMainInventory()
+	: LLPanel()
+{
+	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT);
+	// Menu Callbacks (non contex menus)
+	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
+	mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
+	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH));
+	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND));
+	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
+ 	mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this));
+	mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
+	mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
+	mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
+
+	// Controls
+	// *TODO: Just use persistant settings for each of these
+	U32 sort_order = gSavedSettings.getU32("InventorySortOrder");
+	BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE );
+	BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME );
+	BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP );
+	
+	gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE);
+	gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE);
+	gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE);
+	gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE);
+	
+	mSavedFolderState = new LLSaveFolderState();
+	mSavedFolderState->setApply(FALSE);
+}
+
+BOOL LLPanelMainInventory::postBuild()
+{
+	gInventory.addObserver(this);
+	
+	mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
+	mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
+	
+	//panel->getFilter()->markDefault();
+
+	// Set up the default inv. panel/filter settings.
+	mActivePanel = getChild<LLInventoryPanel>("All Items");
+	if (mActivePanel)
+	{
+		// "All Items" is the previous only view, so it gets the InventorySortOrder
+		mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder"));
+		mActivePanel->getFilter()->markDefault();
+		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+		mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2));
+		mActivePanel->getRootFolder()->openFolder("My Inventory");
+	}
+	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
+	if (recent_items_panel)
+	{
+		recent_items_panel->setSinceLogoff(TRUE);
+		recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
+		recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+		recent_items_panel->getFilter()->markDefault();
+		recent_items_panel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2));
+	}
+
+	// Now load the stored settings from disk, if available.
+	std::ostringstream filterSaveName;
+	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
+	llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << llendl;
+	llifstream file(filterSaveName.str());
+	LLSD savedFilterState;
+	if (file.is_open())
+	{
+		LLSDSerialize::fromXML(savedFilterState, file);
+		file.close();
+
+		// Load the persistent "Recent Items" settings.
+		// Note that the "All Items" settings do not persist.
+		if(recent_items_panel)
+		{
+			if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
+			{
+				LLSD recent_items = savedFilterState.get(
+					recent_items_panel->getFilter()->getName());
+				recent_items_panel->getFilter()->fromLLSD(recent_items);
+			}
+		}
+
+	}
+
+
+	mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
+	if (mFilterEditor)
+	{
+		mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
+	}
+
+	// *TODO:Get the cost info from the server
+	const std::string upload_cost("10");
+	childSetLabelArg("Upload Image", "[COST]", upload_cost);
+	childSetLabelArg("Upload Sound", "[COST]", upload_cost);
+	childSetLabelArg("Upload Animation", "[COST]", upload_cost);
+	childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
+	
+	return TRUE;
+}
+
+// Destroys the object
+LLPanelMainInventory::~LLPanelMainInventory( void )
+{
+	// Save the filters state.
+	LLSD filterRoot;
+	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
+	if (all_items_panel)
+	{
+		LLInventoryFilter* filter = all_items_panel->getFilter();
+		if (filter)
+		{
+			LLSD filterState;
+			filter->toLLSD(filterState);
+			filterRoot[filter->getName()] = filterState;
+		}
+	}
+
+	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
+	if (recent_items_panel)
+	{
+		LLInventoryFilter* filter = recent_items_panel->getFilter();
+		if (filter)
+		{
+			LLSD filterState;
+			filter->toLLSD(filterState);
+			filterRoot[filter->getName()] = filterState;
+		}
+	}
+
+	std::ostringstream filterSaveName;
+	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
+	llofstream filtersFile(filterSaveName.str());
+	if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
+	{
+		llwarns << "Could not write to filters save file " << filterSaveName << llendl;
+	}
+	else
+		filtersFile.close();
+
+	gInventory.removeObserver(this);
+	delete mSavedFolderState;
+}
+
+void LLPanelMainInventory::startSearch()
+{
+	// this forces focus to line editor portion of search editor
+	if (mFilterEditor)
+	{
+		mFilterEditor->focusFirstItem(TRUE);
+	}
+}
+
+BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
+{
+	LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
+	if (root_folder)
+	{
+		// first check for user accepting current search results
+		if (mFilterEditor 
+			&& mFilterEditor->hasFocus()
+		    && (key == KEY_RETURN 
+		    	|| key == KEY_DOWN)
+		    && mask == MASK_NONE)
+		{
+			// move focus to inventory proper
+			mActivePanel->setFocus(TRUE);
+			root_folder->scrollToShowSelection();
+			return TRUE;
+		}
+
+		if (mActivePanel->hasFocus() && key == KEY_UP)
+		{
+			startSearch();
+		}
+	}
+
+	return LLPanel::handleKeyHere(key, mask);
+
+}
+
+//----------------------------------------------------------------------------
+// menu callbacks
+
+void LLPanelMainInventory::doToSelected(const LLSD& userdata)
+{
+	getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
+}
+
+void LLPanelMainInventory::closeAllFolders()
+{
+	getPanel()->getRootFolder()->closeAllFolders();
+}
+
+void LLPanelMainInventory::newWindow()
+{
+	LLFloaterInventory::showAgentInventory();
+}
+
+void LLPanelMainInventory::doCreate(const LLSD& userdata)
+{
+	menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
+}
+
+void LLPanelMainInventory::resetFilters()
+{
+	LLFloaterInventoryFinder *finder = getFinder();
+	getActivePanel()->getFilter()->resetDefault();
+	if (finder)
+	{
+		finder->updateElementsFromFilter();
+	}
+
+	setFilterTextFromFilter();
+}
+
+void LLPanelMainInventory::setSortBy(const LLSD& userdata)
+{
+	std::string sort_field = userdata.asString();
+	if (sort_field == "name")
+	{
+		U32 order = getActivePanel()->getSortOrder();
+		getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE );
+			
+		gSavedSettings.setBOOL("Inventory.SortByName", TRUE );
+		gSavedSettings.setBOOL("Inventory.SortByDate", FALSE );
+	}
+	else if (sort_field == "date")
+	{
+		U32 order = getActivePanel()->getSortOrder();
+		getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE );
+
+		gSavedSettings.setBOOL("Inventory.SortByName", FALSE );
+		gSavedSettings.setBOOL("Inventory.SortByDate", TRUE );
+	}
+	else if (sort_field == "foldersalwaysbyname")
+	{
+		U32 order = getActivePanel()->getSortOrder();
+		if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME )
+		{
+			order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
+
+			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE );
+		}
+		else
+		{
+			order |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
+
+			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE );
+		}
+		getActivePanel()->setSortOrder( order );
+	}
+	else if (sort_field == "systemfolderstotop")
+	{
+		U32 order = getActivePanel()->getSortOrder();
+		if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
+		{
+			order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+
+			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE );
+		}
+		else
+		{
+			order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+
+			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE );
+		}
+		getActivePanel()->setSortOrder( order );
+	}
+}
+
+// static
+BOOL LLPanelMainInventory::filtersVisible(void* user_data)
+{
+	LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
+	if(!self) return FALSE;
+
+	return self->getFinder() != NULL;
+}
+
+void LLPanelMainInventory::onClearSearch()
+{
+	LLFloater *finder = getFinder();
+	if (mActivePanel)
+	{
+		mActivePanel->setFilterSubString(LLStringUtil::null);
+		mActivePanel->setFilterTypes(0xffffffff);
+	}
+
+	if (finder)
+	{
+		LLFloaterInventoryFinder::selectAllTypes(finder);
+	}
+
+	// re-open folders that were initially open
+	if (mActivePanel)
+	{
+		mSavedFolderState->setApply(TRUE);
+		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+		LLOpenFoldersWithSelection opener;
+		mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
+		mActivePanel->getRootFolder()->scrollToShowSelection();
+	}
+}
+
+void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
+{
+	if (search_string == "")
+	{
+		onClearSearch();
+	}
+	if (!mActivePanel)
+	{
+		return;
+	}
+
+	gInventory.startBackgroundFetch();
+
+	std::string uppercase_search_string = search_string;
+	LLStringUtil::toUpper(uppercase_search_string);
+	if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
+	{
+			// current filter and new filter empty, do nothing
+			return;
+	}
+
+	// save current folder open state if no filter currently applied
+	if (!mActivePanel->getRootFolder()->isFilterModified())
+	{
+		mSavedFolderState->setApply(FALSE);
+		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+	}
+
+	// set new filter string
+	mActivePanel->setFilterSubString(uppercase_search_string);
+}
+
+
+ //static
+ BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
+ {
+ 	LLPanelMainInventory* active_view = NULL;
+	
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+	{
+		LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter);
+		if (iv)
+		{
+			if (gFocusMgr.childHasKeyboardFocus(iv))
+			{
+				active_view = iv;
+				break;
+			}
+ 		}
+ 	}
+
+ 	if (!active_view)
+ 	{
+ 		return FALSE;
+ 	}
+
+ 	std::string search_string(find_text);
+
+ 	if (search_string.empty())
+ 	{
+ 		return FALSE;
+ 	}
+
+ 	if (active_view->getPanel() &&
+ 		active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward))
+ 	{
+ 		return TRUE;
+ 	}
+
+ 	return FALSE;
+ }
+
+void LLPanelMainInventory::onFilterSelected()
+{
+	// Find my index
+	mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs");
+
+	if (!mActivePanel)
+	{
+		return;
+	}
+	LLInventoryFilter* filter = mActivePanel->getFilter();
+	LLFloaterInventoryFinder *finder = getFinder();
+	if (finder)
+	{
+		finder->changeFilter(filter);
+	}
+	if (filter->isActive())
+	{
+		// If our filter is active we may be the first thing requiring a fetch so we better start it here.
+		gInventory.startBackgroundFetch();
+	}
+	setFilterTextFromFilter();
+}
+
+const std::string LLPanelMainInventory::getFilterSubString() 
+{ 
+	return mActivePanel->getFilterSubString(); 
+}
+
+void LLPanelMainInventory::setFilterSubString(const std::string& string) 
+{ 
+	mActivePanel->setFilterSubString(string); 
+}
+
+BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+										 EDragAndDropType cargo_type,
+										 void* cargo_data,
+										 EAcceptance* accept,
+										 std::string& tooltip_msg)
+{
+	// Check to see if we are auto scrolling from the last frame
+	LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
+	BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y);
+	if(mFilterTabs)
+	{
+		if(needsToScroll)
+		{
+			mFilterTabs->startDragAndDropDelayTimer();
+		}
+	}
+	
+	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+	return handled;
+}
+
+void LLPanelMainInventory::changed(U32 mask)
+{
+}
+
+
+void LLPanelMainInventory::setFilterTextFromFilter() 
+{ 
+	mFilterText = mActivePanel->getFilter()->getFilterText(); 
+}
+
+void LLPanelMainInventory::toggleFindOptions()
+{
+	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE);
+	LLFloater *floater = getFinder();
+	if (!floater)
+	{
+		LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
+		mFinderHandle = finder->getHandle();
+		finder->openFloater();
+
+		LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+		if (parent_floater) // Seraph: Fix this, shouldn't be null even for sidepanel
+			parent_floater->addDependentFloater(mFinderHandle);
+		// start background fetch of folders
+		gInventory.startBackgroundFetch();
+	}
+	else
+	{
+		floater->closeFloater();
+	}
+}
+
+void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
+{
+	getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
+	getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
+}
+
+///----------------------------------------------------------------------------
+/// LLFloaterInventoryFinder
+///----------------------------------------------------------------------------
+
+LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() 
+{ 
+	return (LLFloaterInventoryFinder*)mFinderHandle.get();
+}
+
+
+LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :	
+	LLFloater(LLSD()),
+	mPanelMainInventory(inventory_view),
+	mFilter(inventory_view->getPanel()->getFilter())
+{
+	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL);
+	updateElementsFromFilter();
+}
+
+
+void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
+{
+	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
+	if (!self) return;
+
+	bool since_logoff= self->childGetValue("check_since_logoff");
+	
+	if (!since_logoff && 
+	    !(  self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() ) )
+	{
+		self->mSpinSinceHours->set(1.0f);
+	}	
+}
+BOOL LLFloaterInventoryFinder::postBuild()
+{
+	const LLRect& viewrect = mPanelMainInventory->getRect();
+	setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
+
+	childSetAction("All", selectAllTypes, this);
+	childSetAction("None", selectNoTypes, this);
+
+	mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
+	childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
+
+	mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
+	childSetCommitCallback("spin_days_ago", onTimeAgo, this);
+
+	//	mCheckSinceLogoff   = getChild<LLSpinCtrl>("check_since_logoff");
+	childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
+
+	childSetAction("Close", onCloseBtn, this);
+
+	updateElementsFromFilter();
+	return TRUE;
+}
+void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
+{
+	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
+	if (!self) return;
+	
+	bool since_logoff=true;
+	if ( self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() )
+	{
+		since_logoff = false;
+	}
+	self->childSetValue("check_since_logoff", since_logoff);
+}
+
+void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
+{
+	mFilter = filter;
+	updateElementsFromFilter();
+}
+
+void LLFloaterInventoryFinder::updateElementsFromFilter()
+{
+	if (!mFilter)
+		return;
+
+	// Get data needed for filter display
+	U32 filter_types = mFilter->getFilterTypes();
+	std::string filter_string = mFilter->getFilterSubString();
+	LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
+	U32 hours = mFilter->getHoursAgo();
+
+	// update the ui elements
+	setTitle(mFilter->getName());
+
+	childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
+
+	childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
+	childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
+	childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
+	childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
+	childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
+	childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
+	childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
+	childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
+	childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
+	childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
+	childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
+	childSetValue("check_since_logoff", mFilter->isSinceLogoff());
+	mSpinSinceHours->set((F32)(hours % 24));
+	mSpinSinceDays->set((F32)(hours / 24));
+}
+
+void LLFloaterInventoryFinder::draw()
+{
+	LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
+	U32 filter = 0xffffffff;
+	BOOL filtered_by_all_types = TRUE;
+
+	if (!childGetValue("check_animation"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
+		filtered_by_all_types = FALSE;
+	}
+
+
+	if (!childGetValue("check_calling_card"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_clothing"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_gesture"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_landmark"))
+
+
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_notecard"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_object"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
+		filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_script"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_LSL);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_sound"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_SOUND);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_texture"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!childGetValue("check_snapshot"))
+	{
+		filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
+		filtered_by_all_types = FALSE;
+	}
+
+	if (!filtered_by_all_types)
+	{
+		// don't include folders in filter, unless I've selected everything
+		filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
+	}
+
+	// update the panel, panel will update the filter
+	mPanelMainInventory->getPanel()->setShowFolderState(getCheckShowEmpty() ?
+		LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+	mPanelMainInventory->getPanel()->setFilterTypes(filter);
+	if (getCheckSinceLogoff())
+	{
+		mSpinSinceDays->set(0);
+		mSpinSinceHours->set(0);
+	}
+	U32 days = (U32)mSpinSinceDays->get();
+	U32 hours = (U32)mSpinSinceHours->get();
+	if (hours > 24)
+	{
+		days += hours / 24;
+		hours = (U32)hours % 24;
+		mSpinSinceDays->set((F32)days);
+		mSpinSinceHours->set((F32)hours);
+	}
+	hours += days * 24;
+	mPanelMainInventory->getPanel()->setHoursAgo(hours);
+	mPanelMainInventory->getPanel()->setSinceLogoff(getCheckSinceLogoff());
+	mPanelMainInventory->setFilterTextFromFilter();
+
+	LLPanel::draw();
+}
+
+BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
+{
+	return childGetValue("check_show_empty");
+}
+
+BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
+{
+	return childGetValue("check_since_logoff");
+}
+
+void LLFloaterInventoryFinder::onCloseBtn(void* user_data)
+{
+	LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
+	finderp->closeFloater();
+}
+
+// static
+void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
+{
+	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
+	if(!self) return;
+
+	self->childSetValue("check_animation", TRUE);
+	self->childSetValue("check_calling_card", TRUE);
+	self->childSetValue("check_clothing", TRUE);
+	self->childSetValue("check_gesture", TRUE);
+	self->childSetValue("check_landmark", TRUE);
+	self->childSetValue("check_notecard", TRUE);
+	self->childSetValue("check_object", TRUE);
+	self->childSetValue("check_script", TRUE);
+	self->childSetValue("check_sound", TRUE);
+	self->childSetValue("check_texture", TRUE);
+	self->childSetValue("check_snapshot", TRUE);
+}
+
+//static
+void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
+{
+	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
+	if(!self) return;
+
+	self->childSetValue("check_animation", FALSE);
+	self->childSetValue("check_calling_card", FALSE);
+	self->childSetValue("check_clothing", FALSE);
+	self->childSetValue("check_gesture", FALSE);
+	self->childSetValue("check_landmark", FALSE);
+	self->childSetValue("check_notecard", FALSE);
+	self->childSetValue("check_object", FALSE);
+	self->childSetValue("check_script", FALSE);
+	self->childSetValue("check_sound", FALSE);
+	self->childSetValue("check_texture", FALSE);
+	self->childSetValue("check_snapshot", FALSE);
+}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 759c86f3a0..47e745c9d3 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -67,6 +67,7 @@
 #include "llinventorymodel.h"
 #include "llmenugl.h"
 #include "llmutelist.h"
+#include "llsidepaneltaskinfo.h"
 #include "llslurl.h"
 #include "llstatusbar.h"
 #include "llsurface.h"
@@ -4906,12 +4907,20 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 	}
 	if (mSelectedObjects->getNumNodes())
 	{
-		LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
 		LLUUID inspect_item_id= LLUUID::null;
+#if 0		
+		LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
 		if(inspect_instance)
 		{
 			inspect_item_id = inspect_instance->getSelectedUUID();
 		}
+#endif
+		LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
+		if (panel_task_info)
+		{
+			inspect_item_id = panel_task_info->getSelectedUUID();
+		}
+
 		for (S32 pass = 0; pass < 2; pass++)
 		{
 			for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
@@ -5494,12 +5503,19 @@ void dialog_refresh_all()
 	}
 
 	LLFloaterProperties::dirtyAll();
-	
+
+#if 0	
 	LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
 	if(inspect_instance)
 	{
 		inspect_instance->dirty();
 	}
+#endif
+	LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
+	if (panel_task_info)
+	{
+		panel_task_info->dirty();
+	}
 }
 
 S32 get_family_count(LLViewerObject *parent)
diff --git a/indra/newview/llsidepanelinventorysubpanel.cpp b/indra/newview/llsidepanelinventorysubpanel.cpp
index 8522456777..162198f1c5 100644
--- a/indra/newview/llsidepanelinventorysubpanel.cpp
+++ b/indra/newview/llsidepanelinventorysubpanel.cpp
@@ -87,7 +87,6 @@ void LLSidepanelInventorySubpanel::setVisible(BOOL visible)
 	if (visible)
 	{
 		dirty();
-		setIsEditing(FALSE);
 	}
 	LLPanel::setVisible(visible);
 }
@@ -123,6 +122,7 @@ void LLSidepanelInventorySubpanel::draw()
 void LLSidepanelInventorySubpanel::dirty()
 {
 	mIsDirty = TRUE;
+	setIsEditing(FALSE);
 }
 
 void LLSidepanelInventorySubpanel::updateVerbs()
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 4284c95b13..01c832d7d5 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -71,6 +71,8 @@
 /// Class llsidepaneltaskinfo
 ///----------------------------------------------------------------------------
 
+LLSidepanelTaskInfo* LLSidepanelTaskInfo::sActivePanel = NULL;
+
 static LLRegisterPanelClassWrapper<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info");
 
 // Default constructor
@@ -79,6 +81,14 @@ LLSidepanelTaskInfo::LLSidepanelTaskInfo()
 	setMouseOpaque(FALSE);
 }
 
+
+LLSidepanelTaskInfo::~LLSidepanelTaskInfo()
+{
+	if (sActivePanel == this)
+		sActivePanel = NULL;
+}
+
+// virtual
 BOOL LLSidepanelTaskInfo::postBuild()
 {
 	LLSidepanelInventorySubpanel::postBuild();
@@ -101,12 +111,20 @@ BOOL LLSidepanelTaskInfo::postBuild()
 	return TRUE;
 }
 
-LLSidepanelTaskInfo::~LLSidepanelTaskInfo()
+// virtual
+void LLSidepanelTaskInfo::setVisible(BOOL visible)
 {
-	// base class will take care of everything
+	LLPanel::setVisible(visible);
+	if (visible)
+	{
+		sActivePanel = this;
+	}
+	else
+	{
+		sActivePanel = NULL;
+	}
 }
 
-
 void LLSidepanelTaskInfo::refresh()
 {
 	LLButton*	BtnDeedToGroup = getChild<LLButton>("button deed");
@@ -1037,6 +1055,8 @@ void LLSidepanelTaskInfo::updateVerbs()
 	mBuyBtn->setVisible(!getIsEditing());
 
 	mOpenBtn->setEnabled(enable_object_open());
+	const LLViewerObject *obj = getFirstSelectedObject();
+	mEditBtn->setEnabled(obj && obj->permModify());
 }
 
 void LLSidepanelTaskInfo::onOpenButtonClicked()
@@ -1077,3 +1097,28 @@ void LLSidepanelTaskInfo::setObjectSelection(LLObjectSelectionHandle selection)
 {
 	mObjectSelection = selection;
 }
+
+LLSidepanelTaskInfo* LLSidepanelTaskInfo::getActivePanel()
+{
+	return sActivePanel;
+}
+
+LLViewerObject* LLSidepanelTaskInfo::getFirstSelectedObject()
+{
+	LLSelectNode *node = mObjectSelection->getFirstRootNode();
+	if (node)
+	{
+		return node->getObject();
+	}
+	return NULL;
+}
+
+const LLUUID& LLSidepanelTaskInfo::getSelectedUUID()
+{
+	const LLViewerObject* obj = getFirstSelectedObject();
+	if (obj)
+	{
+		return obj->getID();
+	}
+	return LLUUID::null;
+}
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index 25a9e2d577..b6dd4dfb2c 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -45,6 +45,7 @@
 
 class LLNameBox;
 class LLCheckBoxCtrl;
+class LLViewerObject;
 
 class LLSidepanelTaskInfo : public LLSidepanelInventorySubpanel
 {
@@ -53,9 +54,14 @@ public:
 	virtual ~LLSidepanelTaskInfo();
 
 	/*virtual*/	BOOL postBuild();
+	/*virtual*/ void setVisible(BOOL visible);
 
 	void setObjectSelection(LLObjectSelectionHandle selection);
 
+	const LLUUID& getSelectedUUID();
+	LLViewerObject* getFirstSelectedObject();
+
+	static LLSidepanelTaskInfo *getActivePanel();
 protected:
 	/*virtual*/ void refresh();	// refresh all labels as needed
 	/*virtual*/ void save();
@@ -102,6 +108,7 @@ private:
 	LLButton*					mBuyBtn;
 
 	LLObjectSelectionHandle mObjectSelection;
+	static LLSidepanelTaskInfo* sActivePanel;
 };
 
 
-- 
cgit v1.2.3