From 353da63a07b07b75ad73b9f5cb8e463d07ebea3a Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 17 Jun 2011 15:24:24 -0700
Subject: [PATCH] EXP-915 FIX remove mHidden and mStartFolderID from
 LLFolderView* cleaned up and refactored inventory code a bit

reviewed by Leyla
---
 indra/newview/llfolderview.cpp           |  49 ++--
 indra/newview/llfolderview.h             |   9 +-
 indra/newview/llfolderviewitem.cpp       | 119 ++++++---
 indra/newview/llfolderviewitem.h         |  14 +-
 indra/newview/llinventoryfilter.cpp      | 122 +++------
 indra/newview/llinventoryfilter.h        |   6 +-
 indra/newview/llinventorypanel.cpp       | 324 +++++++++++------------
 indra/newview/llinventorypanel.h         |  19 +-
 indra/newview/llpanellandmarks.cpp       |   4 +-
 indra/newview/llplacesinventorypanel.cpp |  85 ++----
 indra/newview/lltexturectrl.cpp          |   1 -
 11 files changed, 370 insertions(+), 382 deletions(-)

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 3884b94b60e..260693ebc7e 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -167,13 +167,22 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
 ///----------------------------------------------------------------------------
 /// Class LLFolderView
 ///----------------------------------------------------------------------------
+LLFolderView::Params::Params()
+:	task_id("task_id"),
+	title("title"),
+	use_label_suffix("use_label_suffix"),
+	allow_multiselect("allow_multiselect", true),
+	use_ellipses("use_ellipses", false)
+{
+}
+
 
 // Default constructor
 LLFolderView::LLFolderView(const Params& p)
 :	LLFolderViewFolder(p),
 	mScrollContainer( NULL ),
 	mPopupMenuHandle(),
-	mAllowMultiSelect(TRUE),
+	mAllowMultiSelect(p.allow_multiselect),
 	mShowFolderHierarchy(FALSE),
 	mSourceID(p.task_id),
 	mRenameItem( NULL ),
@@ -194,10 +203,12 @@ LLFolderView::LLFolderView(const Params& p)
 	mDragAndDropThisFrame(FALSE),
 	mCallbackRegistrar(NULL),
 	mParentPanel(p.parent_panel),
-	mUseEllipses(false),
+	mUseEllipses(p.use_ellipses),
 	mDraggingOverItem(NULL),
 	mStatusTextBox(NULL)
 {
+	mRoot = this;
+
 	LLRect rect = p.rect;
 	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
 	setRect( rect );
@@ -424,11 +435,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
 									(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
 		}
 
-		// Need to call arrange regardless of visibility, since children's visibility
-		// might need to be changed too (e.g. even though a folder is invisible, its
-		// children also need to be set invisible for state-tracking purposes, e.g.
-		// llfolderviewitem::filter).
-		// if (folderp->getVisible())
+		if (folderp->getVisible())
 		{
 			S32 child_height = 0;
 			S32 child_width = 0;
@@ -764,7 +771,7 @@ void LLFolderView::sanitizeSelection()
 		}
 
 		// Don't allow invisible items (such as root folders) to be selected.
-		if (item->getHidden())
+		if (item == getRoot())
 		{
 			items_to_remove.push_back(item);
 		}
@@ -787,7 +794,7 @@ void LLFolderView::sanitizeSelection()
 				parent_folder;
 				parent_folder = parent_folder->getParentFolder())
 			{
-				if (parent_folder->potentiallyVisible() && !parent_folder->getHidden())
+				if (parent_folder->potentiallyVisible())
 				{
 					// give initial selection to first ancestor folder that potentially passes the filter
 					if (!new_selection)
@@ -808,11 +815,6 @@ void LLFolderView::sanitizeSelection()
 		{
 			// nothing selected to start with, so pick "My Inventory" as best guess
 			new_selection = getItemByID(gInventory.getRootFolderID());
-			// ... except if it's hidden from the UI.
-			if (new_selection && new_selection->getHidden())
-			{
-				new_selection = NULL;
-			}
 		}
 
 		if (new_selection)
@@ -962,7 +964,9 @@ void LLFolderView::draw()
 		
 	}
 
-	LLFolderViewFolder::draw();
+	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label, 
+	// and arrow for the root folder
+	LLView::draw();
 
 	mDragAndDropThisFrame = FALSE;
 }
@@ -1642,11 +1646,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 			LLFolderViewItem* parent_folder = last_selected->getParentFolder();
 			if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
 			{
-				// Don't change selectin to hidden folder. See EXT-5328.
-				if (!parent_folder->getHidden())
-				{
-					setSelection(parent_folder, FALSE, TRUE);
-				}
+				setSelection(parent_folder, FALSE, TRUE);
 			}
 			else
 			{
@@ -2031,7 +2031,7 @@ void LLFolderView::removeItemID(const LLUUID& id)
 
 LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
 {
-	if (id.isNull())
+	if (id == getListener()->getUUID())
 	{
 		return this;
 	}
@@ -2048,7 +2048,7 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
 
 LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
 {
-	if (id.isNull())
+	if (id == getListener()->getUUID())
 	{
 		return this;
 	}
@@ -2496,11 +2496,6 @@ BOOL LLFolderView::isFilterModified()
 	return mFilter->isNotDefault();
 }
 
-BOOL LLFolderView::getAllowMultiSelect()
-{
-	return mAllowMultiSelect;
-}
-
 void delete_selected_item(void* user_data)
 {
 	if(user_data)
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 1464a058d8c..12f6170a7da 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -89,7 +89,11 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 		Mandatory<LLPanel*>	    parent_panel;
 		Optional<LLUUID>        task_id;
 		Optional<std::string>   title;
-		Optional<bool>			use_label_suffix;
+		Optional<bool>			use_label_suffix,
+								allow_multiselect,
+								use_ellipses;
+
+		Params();
 	};
 	LLFolderView(const Params&);
 	virtual ~LLFolderView( void );
@@ -102,7 +106,6 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	// and resort the items if necessary.
 	void setSortOrder(U32 order);
 	void setFilterPermMask(PermissionMask filter_perm_mask);
-	void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }
 	
 	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
 	void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
@@ -117,7 +120,6 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	//LLInventoryFilter::EFolderShow getShowFolderState();
 	U32 getSortOrder() const;
 	BOOL isFilterModified();
-	BOOL getAllowMultiSelect();
 
 	// Close all folders in the view
 	void closeAllFolders();
@@ -238,7 +240,6 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	void setShowSingleSelection(BOOL show);
 	BOOL getShowSingleSelection() { return mShowSingleSelection; }
 	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
-	void setUseEllipses(bool use_ellipses) { mUseEllipses = use_ellipses; }
 	bool getUseEllipses() { return mUseEllipses; }
 
 	void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index e9d1ad3a9e3..904c233850f 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -132,8 +132,13 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mListener(p.listener),
 	mHidden(false),
 	mShowLoadStatus(false)
+{
+}
+
+BOOL LLFolderViewItem::postBuild()
 {
 	refresh();
+	return TRUE;
 }
 
 // Destroys the object
@@ -195,7 +200,7 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
 	LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
 
 	// Skip over items that are invisible or are hidden from the UI.
-	while(itemp && (!itemp->getVisible() || itemp->getHidden()))
+	while(itemp && !itemp->getVisible())
 	{
 		LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
 		if (itemp == next_itemp) 
@@ -351,7 +356,10 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
 									 BOOL take_keyboard_focus)
 {
 	LLFolderView* root = getRoot();
-	getParentFolder()->requestArrange();
+	if (getParentFolder())
+	{
+		getParentFolder()->requestArrange();
+	}
 	if(set_selection)
 	{
 		setSelectionFromRoot(this, TRUE, take_keyboard_focus);
@@ -442,23 +450,20 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
 
 S32 LLFolderViewItem::getItemHeight()
 {
-	if (getHidden()) return 0;
-
 	return mItemHeight;
 }
 
 void LLFolderViewItem::filter( LLInventoryFilter& filter)
 {
 	const BOOL previous_passed_filter = mPassedFilter;
-	const BOOL passed_filter = mListener && filter.check(this);
+	const BOOL passed_filter = filter.check(this);
 
 	// If our visibility will change as a result of this filter, then
 	// we need to be rearranged in our parent folder
 	if (mParentFolder)
 	{
-		if (getVisible() != passed_filter)
-			mParentFolder->requestArrange();
-		if (passed_filter != previous_passed_filter)
+		if (getVisible() != passed_filter
+			||	previous_passed_filter != passed_filter )
 			mParentFolder->requestArrange();
 	}
 
@@ -863,11 +868,6 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 
 void LLFolderViewItem::draw()
 {
-	if (getHidden())
-	{
-		return;
-	}
-
 	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
 	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
 	static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
@@ -891,8 +891,8 @@ void LLFolderViewItem::draw()
 	// Draw open folder arrow
 	//
 	const bool up_to_date = mListener && mListener->isUpToDate();
-	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) || // we fetched our children and some of them have passed the filter...
-										(!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
+	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
+										|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
 	if (possibly_has_children)
 	{
 		LLUIImage* arrow_image = default_params.folder_arrow_image;
@@ -1054,8 +1054,11 @@ void LLFolderViewItem::draw()
 	{
 		root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
 	}
-	if ((mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) ||
-		(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && root_is_loading && (mShowLoadStatus || mHidden)))
+	if ((mIsLoading
+		&&	mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
+			||	(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()
+				&&	root_is_loading
+				&&	(mShowLoadStatus || mHidden)))
 	{
 		std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";
 		font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
@@ -1119,7 +1122,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
 	mLastCalculatedWidth(0),
 	mCompletedFilterGeneration(-1),
 	mMostFilteredDescendantGeneration(-1),
-	mNeedsSort(false)
+	mNeedsSort(false),
+	mPassedFolderFilter(FALSE)
 {
 }
 
@@ -1131,6 +1135,17 @@ LLFolderViewFolder::~LLFolderViewFolder( void )
 	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
 }
 
+void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
+{
+	mPassedFolderFilter = filtered;
+	mLastFilterGeneration = filter_generation;
+}
+
+bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
+{
+	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
+}
+
 // addToFolder() returns TRUE if it succeeds. FALSE otherwise
 BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
 {
@@ -1190,8 +1205,10 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 				}
 				else
 				{
-					folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
-						(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
+					folderp->setVisible(
+						folderp->getFilteredFolder(filter_generation)					// folder must pass folder filters
+						&&	(folderp->getFiltered(filter_generation)
+							||	folderp->hasFilteredDescendants(filter_generation)));	// passed item filter or has descendants that passed filter
 				}
 
 				if (folderp->getVisible())
@@ -1311,7 +1328,9 @@ void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recur
 	mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
 	mCompletedFilterGeneration = generation;
 	// only aggregate up if we are a lower (older) value
-	if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration())
+	if (recurse_up
+		&& mParentFolder
+		&& generation < mParentFolder->getCompletedFilterGeneration())
 	{
 		mParentFolder->setCompletedFilterGeneration(generation, TRUE);
 	}
@@ -1336,15 +1355,17 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 	// filter folder itself
 	if (getLastFilterGeneration() < filter_generation)
 	{
-		if (getLastFilterGeneration() >= must_pass_generation &&		// folder has been compared to a valid precursor filter
-			!mPassedFilter)													// and did not pass the filter
+		if (getLastFilterGeneration() >= must_pass_generation	// folder has been compared to a valid precursor filter
+			&& !mPassedFilter)									// and did not pass the filter
 		{
 			// go ahead and flag this folder as done
 			mLastFilterGeneration = filter_generation;			
 		}
-		else
+		else // filter self only on first pass through
 		{
-			// filter self only on first pass through
+			// filter against folder rules
+			filterFolder(filter);
+			// and then item rules
 			LLFolderViewItem::filter( filter );
 		}
 		if (mHidden)
@@ -1377,7 +1398,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 	}
 
 	// when applying a filter, matching folders get their contents downloaded first
-	if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID())))
+	if (filter.isNotDefault()
+		&& getFiltered(filter.getMinRequiredGeneration())
+		&&	(mListener
+			&& !gInventory.isCategoryComplete(mListener->getUUID())))
 	{
 		LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());
 	}
@@ -1467,6 +1491,31 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 	}
 }
 
+void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter)
+{
+	const BOOL previous_passed_filter = mPassedFolderFilter;
+	const BOOL passed_filter = filter.checkFolder(this);
+
+	// If our visibility will change as a result of this filter, then
+	// we need to be rearranged in our parent folder
+	if (mParentFolder)
+	{
+		if (getVisible() != passed_filter
+			|| previous_passed_filter != passed_filter )
+		{
+			mParentFolder->requestArrange();
+		}
+	}
+
+	setFilteredFolder(passed_filter, filter.getCurrentGeneration());
+	filter.decrementFilterCount();
+
+	if (getRoot()->getDebugFilters())
+	{
+		mStatusText = llformat("%d", mLastFilterGeneration);
+	}
+}
+
 void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
 {
 	// if this folder is now filtered, but wasn't before
@@ -2059,7 +2108,9 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
 			(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN);		/* Flawfinder: ignore */
 		}
 	}
-	if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN))
+	if (mParentFolder
+		&&	(recurse == RECURSE_UP
+			|| recurse == RECURSE_UP_DOWN))
 	{
 		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
 	}
@@ -2301,13 +2352,16 @@ void LLFolderViewFolder::draw()
 
 	bool possibly_has_children = false;
 	bool up_to_date = mListener && mListener->isUpToDate();
-	if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
+	if(!up_to_date
+		&& mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
 	{
 		possibly_has_children = true;
 	}
 
 
-	BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date );
+	BOOL loading = (mIsOpen
+					&& possibly_has_children
+					&& !up_to_date );
 
 	if ( loading && !mIsLoading )
 	{
@@ -2573,7 +2627,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde
 {
 	// ignore sort order for landmarks in the Favorites folder.
 	// they should be always sorted as in Favorites bar. See EXT-719
-	if (a->getSortGroup() == SG_ITEM && b->getSortGroup() == SG_ITEM
+	if (a->getSortGroup() == SG_ITEM
+		&& b->getSortGroup() == SG_ITEM
 		&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK
 		&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
@@ -2600,8 +2655,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde
 	// We sort by name if we aren't sorting by date
 	// OR if these are folders and we are sorting folders by name.
 	bool by_name = (!mByDate 
-		|| (mFoldersByName 
-		&& (a->getSortGroup() != SG_ITEM)));
+					|| (mFoldersByName 
+						&& (a->getSortGroup() != SG_ITEM)));
 
 	if (a->getSortGroup() != b->getSortGroup())
 	{
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index fc941510ab2..c48e568b301 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -174,6 +174,8 @@ class LLFolderViewItem : public LLView
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
 public:
+	BOOL postBuild();
+
 	// This function clears the currently selected item, and records
 	// the specified selected item appropriately for display and use
 	// in the UI. If open is TRUE, then folders are opened up along
@@ -202,11 +204,6 @@ class LLFolderViewItem : public LLView
 	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
 	virtual S32 getItemHeight();
 
-	// Hide the folder from the UI, such as if you want to hide the root
-	// folder in an inventory panel.
-	void setHidden(bool hidden) { mHidden = hidden; }
-	bool getHidden() const { return mHidden; }
-
 	// applies filters to control visibility of inventory items
 	virtual void filter( LLInventoryFilter& filter);
 
@@ -392,6 +389,8 @@ class LLFolderViewFolder : public LLFolderViewItem
 	S32			mCompletedFilterGeneration;
 	S32			mMostFilteredDescendantGeneration;
 	bool		mNeedsSort;
+	bool		mPassedFolderFilter;
+
 public:
 	typedef enum e_recurse_type
 	{
@@ -432,6 +431,11 @@ class LLFolderViewFolder : public LLFolderViewItem
 	virtual void filter( LLInventoryFilter& filter);
 	virtual void setFiltered(BOOL filtered, S32 filter_generation);
 	virtual void dirtyFilter();
+	
+	// folder-specific filtering (filter status propagates top down instead of bottom up)
+	void filterFolder(LLInventoryFilter& filter);
+	void setFilteredFolder(bool filtered, S32 filter_generation);
+	bool getFilteredFolder(S32 filter_generation);
 
 	// Passes selection information on to children and record
 	// selection information if necessary.
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index dee15a1efdc..49e0ab33e5d 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -107,6 +107,31 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
 	return passed;
 }
 
+bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
+{
+	// we're showing all folders, overriding filter
+	if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
+	{
+		return true;
+	}
+
+	const LLFolderViewEventListener* listener = folder->getListener();
+	const LLUUID folder_id = listener->getUUID();
+
+	if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
+	{
+		// Can only filter categories for items in your inventory
+		// (e.g. versus in-world object contents).
+		const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
+		if (!cat)
+			return false;
+		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
+			return false;
+	}
+
+	return true;
+}
+
 BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
 {
 	const LLFolderViewEventListener* listener = item->getListener();
@@ -137,30 +162,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
 		}
 	}
 	
-	
-	////////////////////////////////////////////////////////////////////////////////
-	// FILTERTYPE_CATEGORY
-	// Pass if this item is a category of the filter type, or
-	// if its parent is a category of the filter type.
-	if (filterTypes & FILTERTYPE_CATEGORY)
-	{
-		// Can only filter categories for items in your inventory 
-		// (e.g. versus in-world object contents).
-		if (!object) return FALSE;
-
-		LLUUID cat_id = object_id;
-		if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
-		{
-			cat_id = object->getParentUUID();
-		}
-		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
-		if (!cat) 
-			return FALSE;
-		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
-			return FALSE;
-	}
-
-
 	////////////////////////////////////////////////////////////////////////////////
 	// FILTERTYPE_UUID
 	// Pass if this item is the target UUID or if it links to the target UUID
@@ -172,7 +173,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
 			return FALSE;
 	}
 
-
 	////////////////////////////////////////////////////////////////////////////////
 	// FILTERTYPE_DATE
 	// Pass if this item is within the date range.
@@ -293,15 +293,15 @@ BOOL LLInventoryFilter::isModifiedAndClear()
 	return ret;
 }
 
-void LLInventoryFilter::setFilterObjectTypes(U64 types)
+void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
 {
-	if (mFilterOps.mFilterObjectTypes != types)
+	if (current_types != types)
 	{
 		// keep current items only if no type bits getting turned off
-		BOOL fewer_bits_set = (mFilterOps.mFilterObjectTypes & ~types);
-		BOOL more_bits_set = (~mFilterOps.mFilterObjectTypes & types);
+		BOOL fewer_bits_set = (current_types & ~types);
+		BOOL more_bits_set = (~current_types & types);
 
-		mFilterOps.mFilterObjectTypes = types;
+		current_types = types;
 		if (more_bits_set && fewer_bits_set)
 		{
 			// neither less or more restrive, both simultaneously
@@ -318,62 +318,23 @@ void LLInventoryFilter::setFilterObjectTypes(U64 types)
 			setModified(FILTER_MORE_RESTRICTIVE);
 		}
 	}
+}
+
+void LLInventoryFilter::setFilterObjectTypes(U64 types)
+{
+	updateFilterTypes(types, mFilterOps.mFilterObjectTypes);
 	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
 }
 
 void LLInventoryFilter::setFilterCategoryTypes(U64 types)
 {
-	if (mFilterOps.mFilterCategoryTypes != types)
-	{
-		// keep current items only if no type bits getting turned off
-		BOOL fewer_bits_set = (mFilterOps.mFilterCategoryTypes & ~types);
-		BOOL more_bits_set = (~mFilterOps.mFilterCategoryTypes & types);
-
-		mFilterOps.mFilterCategoryTypes = types;
-		if (more_bits_set && fewer_bits_set)
-		{
-			// neither less or more restrive, both simultaneously
-			// so we need to filter from scratch
-			setModified(FILTER_RESTART);
-		}
-		else if (more_bits_set)
-		{
-			// target is only one of all requested types so more type bits == less restrictive
-			setModified(FILTER_LESS_RESTRICTIVE);
-		}
-		else if (fewer_bits_set)
-		{
-			setModified(FILTER_MORE_RESTRICTIVE);
-		}
-	}
-	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
+	updateFilterTypes(types, mFilterOps.mFilterCategoryTypes);
+	mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
 }
 
 void LLInventoryFilter::setFilterWearableTypes(U64 types)
 {
-	if (mFilterOps.mFilterWearableTypes != types)
-	{
-		// keep current items only if no type bits getting turned off
-		BOOL fewer_bits_set = (mFilterOps.mFilterWearableTypes & ~types);
-		BOOL more_bits_set = (~mFilterOps.mFilterWearableTypes & types);
-
-		mFilterOps.mFilterWearableTypes = types;
-		if (more_bits_set && fewer_bits_set)
-		{
-			// neither less or more restrive, both simultaneously
-			// so we need to filter from scratch
-			setModified(FILTER_RESTART);
-		}
-		else if (more_bits_set)
-		{
-			// target is only one of all requested types so more type bits == less restrictive
-			setModified(FILTER_LESS_RESTRICTIVE);
-		}
-		else if (fewer_bits_set)
-		{
-			setModified(FILTER_MORE_RESTRICTIVE);
-		}
-	}
+	updateFilterTypes(types, mFilterOps.mFilterWearableTypes);
 	mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
 }
 
@@ -898,11 +859,16 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
 	}
 }
 
-U32 LLInventoryFilter::getFilterObjectTypes() const
+U64 LLInventoryFilter::getFilterObjectTypes() const
 {
 	return mFilterOps.mFilterObjectTypes;
 }
 
+U64 LLInventoryFilter::getFilterCategoryTypes() const
+{
+	return mFilterOps.mFilterCategoryTypes;
+}
+
 BOOL LLInventoryFilter::hasFilterString() const
 {
 	return mFilterSubString.size() > 0;
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 39e6f797a24..f9460822f7d 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -31,6 +31,7 @@
 #include "llpermissionsflags.h"
 
 class LLFolderViewItem;
+class LLFolderViewFolder;
 
 class LLInventoryFilter
 {
@@ -81,11 +82,13 @@ class LLInventoryFilter
 	// + Parameters
 	// +-------------------------------------------------------------------+
 	void 				setFilterObjectTypes(U64 types);
-	U32 				getFilterObjectTypes() const;
+	U64 				getFilterObjectTypes() const;
+	U64					getFilterCategoryTypes() const;
 	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
 	void 				setFilterCategoryTypes(U64 types);
 	void 				setFilterUUID(const LLUUID &object_id);
 	void				setFilterWearableTypes(U64 types);
+	void				updateFilterTypes(U64 types, U64& current_types);
 
 	void 				setFilterSubString(const std::string& string);
 	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;
@@ -110,6 +113,7 @@ class LLInventoryFilter
 	// + Execution And Results
 	// +-------------------------------------------------------------------+
 	BOOL 				check(const LLFolderViewItem* item);
+	bool				checkFolder(const LLFolderViewFolder* folder);
 	BOOL 				checkAgainstFilterType(const LLFolderViewItem* item) const;
 	BOOL 				checkAgainstPermissions(const LLFolderViewItem* item) const;
 	BOOL 				checkAgainstFilterLinks(const LLFolderViewItem* item) const;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 1dcb91ad4d2..1ff423056a2 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -132,8 +132,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mAllowMultiSelect(p.allow_multi_select),
 	mShowItemLinkOverlays(p.show_item_link_overlays),
 	mViewsInitialized(false),
-	mStartFolderString(p.start_folder),	
-	mBuildDefaultHierarchy(true),
 	mInvFVBridgeBuilder(NULL)
 {
 	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@@ -146,11 +144,48 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
 	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
-	
-	if (mStartFolderString != "")
+
+}
+
+void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
+{
+	// Determine the root folder in case specified, and
+	// build the views starting with that folder.
+	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
+
+	LLUUID root_id;
+
+	if ("LIBRARY" == params.start_folder())
 	{
-		mBuildDefaultHierarchy = false;
+		root_id = gInventory.getLibraryRootFolderID();
 	}
+	else
+	{
+		root_id = (preferred_type != LLFolderType::FT_NONE)
+				? gInventory.findCategoryUUIDForType(preferred_type) 
+				: LLUUID::null;
+	}
+
+	LLRect folder_rect(0,
+						0,
+						getRect().getWidth(),
+						0);
+	LLFolderView::Params p;
+	p.name = getName();
+	p.title = getLabel();
+	p.rect = folder_rect;
+	p.parent_panel = this;
+	p.tool_tip = p.name;
+	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
+													LLAssetType::AT_CATEGORY,
+													LLInventoryType::IT_CATEGORY,
+													this,
+													NULL,
+													root_id);
+	p.use_label_suffix = params.use_label_suffix;
+	p.allow_multiselect = mAllowMultiSelect;
+	mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
+	
 }
 
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
@@ -159,22 +194,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 
 	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
 	
-	// Create root folder
-	{
-		LLRect folder_rect(0,
-						   0,
-						   getRect().getWidth(),
-						   0);
-		LLFolderView::Params p;
-		p.name = getName();
-		p.title = getLabel();
-		p.rect = folder_rect;
-		p.parent_panel = this;
-		p.tool_tip = p.name;
-		p.use_label_suffix = params.use_label_suffix;
-		mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
-		mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
-	}
+	buildFolderView(params);
 
 	mCommitCallbackRegistrar.popScope();
 	
@@ -206,7 +226,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 
 	// Build view of inventory if we need default full hierarchy and inventory ready,
 	// otherwise wait for idle callback.
-	if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized)
+	if (mInventory->isInventoryUsable() && !mViewsInitialized)
 	{
 		initializeViews();
 	}
@@ -264,6 +284,15 @@ LLInventoryFilter* LLInventoryPanel::getFilter()
 	return NULL;
 }
 
+const LLInventoryFilter* LLInventoryPanel::getFilter() const
+{
+	if (mFolderRoot)
+	{
+		return mFolderRoot->getFilter();
+	}
+	return NULL;
+}
+
 void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
 {
 	if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
@@ -488,23 +517,16 @@ void LLInventoryPanel::onIdle(void *userdata)
 	}
 }
 
+const LLUUID& LLInventoryPanel::getRootFolderID() const
+{
+	return mFolderRoot->getListener()->getUUID();
+}
+
 void LLInventoryPanel::initializeViews()
 {
 	if (!gInventory.isInventoryUsable()) return;
 
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
-
-	if ("LIBRARY" == mStartFolderString)
-	{
-		mStartFolderID = gInventory.getLibraryRootFolderID();
-	}
-	else
-	{
-		mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
-	}
-	rebuildViewsFor(mStartFolderID);
+	rebuildViewsFor(getRootFolderID());
 
 	mViewsInitialized = true;
 	
@@ -533,7 +555,7 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
 {
 	// Destroy the old view for this ID so we can rebuild it.
 	LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
-	if (old_view && id.notNull())
+	if (old_view && old_view != mFolderRoot)
 	{
 		old_view->destroyView();
 	}
@@ -543,118 +565,101 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
 
 void LLInventoryPanel::buildNewViews(const LLUUID& id)
 {
-	LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS);
-	LLFolderViewItem* itemp = NULL;
-	LLInventoryObject* objectp = gInventory.getObject(id);
-	if (objectp)
-	{
-		const LLUUID &parent_id = objectp->getParentUUID();
-		LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
-		if (id == mStartFolderID)
-		{
-			parent_folder = mFolderRoot;
-		}
-		else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
-		{
-			// This item exists outside the inventory's hierarchy, so don't add it.
-			return;
-		}
-		
-		if (objectp->getType() <= LLAssetType::AT_NONE ||
-			objectp->getType() >= LLAssetType::AT_COUNT)
-		{
-			llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
-					<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() 
-					<< llendl;
-			return;
-		}
-		
-		if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
-			(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
-		{
-			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
-																			objectp->getType(),
-																			LLInventoryType::IT_CATEGORY,
-																			this,
-																			mFolderRoot,
-																			objectp->getUUID());
-			if (new_listener)
-			{
-				LLFolderViewFolder::Params params;
-				params.name = new_listener->getDisplayName();
-				params.icon = new_listener->getIcon();
-				params.icon_open = new_listener->getOpenIcon();
-				if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-				{
-					params.icon_overlay = LLUI::getUIImage("Inv_Link");
-				}
-				params.root = mFolderRoot;
-				params.listener = new_listener;
-				params.tool_tip = params.name;
-				LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);
-				folderp->setItemSortOrder(mFolderRoot->getSortOrder());
-				itemp = folderp;
-
-				// Hide the root folder, so we can show the contents of a folder flat
-				// but still have the parent folder present for listener-related operations.
-				if (id == mStartFolderID)
-				{
-					folderp->setHidden(TRUE);
-				}
-				const LLViewerInventoryCategory *cat = dynamic_cast<LLViewerInventoryCategory *>(objectp);
-				if (cat && getIsHiddenFolderType(cat->getPreferredType()))
-				{
-					folderp->setHidden(TRUE);
-				}
-			}
-		}
-		else 
-		{
-			// Build new view for item.
-			LLInventoryItem* item = (LLInventoryItem*)objectp;
-			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
-																			item->getActualType(),
-																			item->getInventoryType(),
-																			this,
-																			mFolderRoot,
-																			item->getUUID(),
-																			item->getFlags());
-
-			if (new_listener)
-			{
-				LLFolderViewItem::Params params;
-				params.name = new_listener->getDisplayName();
-				params.icon = new_listener->getIcon();
-				params.icon_open = new_listener->getOpenIcon();
-				if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-				{
-					params.icon_overlay = LLUI::getUIImage("Inv_Link");
-				}
-				params.creation_date = new_listener->getCreationDate();
-				params.root = mFolderRoot;
-				params.listener = new_listener;
-				params.rect = LLRect (0, 0, 0, 0);
-				params.tool_tip = params.name;
-				itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
-			}
-		}
-
-		if (itemp)
-		{
-			itemp->addToFolder(parent_folder, mFolderRoot);
-
-			// Don't add children of hidden folders unless this is the panel's root folder.
-			if (itemp->getHidden() && (id != mStartFolderID))
-			{
-				return;
-			}
+ 	LLInventoryObject const* objectp = gInventory.getObject(id);
+ 	LLUUID root_id = mFolderRoot->getListener()->getUUID();
+ 	LLFolderViewFolder* parent_folder = NULL;
+ 
+ 	if (id == root_id)
+ 	{
+ 		parent_folder = mFolderRoot;
+ 	}
+ 	else if (objectp)
+ 	{
+ 		LLFolderViewItem* itemp = NULL;
+ 		const LLUUID &parent_id = objectp->getParentUUID();
+ 		parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
+  		
+  		if (parent_folder)
+  		{
+  			if (objectp->getType() <= LLAssetType::AT_NONE ||
+  				objectp->getType() >= LLAssetType::AT_COUNT)
+  			{
+  				llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
+  						<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
+  						<< llendl;
+  				return;
+  			}
+  		
+  			if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
+  				(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
+  			{
+  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
+  																				objectp->getType(),
+  																				LLInventoryType::IT_CATEGORY,
+  																				this,
+  																				mFolderRoot,
+  																				objectp->getUUID());
+  				if (new_listener)
+  				{
+  					LLFolderViewFolder::Params params;
+  					params.name = new_listener->getDisplayName();
+  					params.icon = new_listener->getIcon();
+  					params.icon_open = new_listener->getOpenIcon();
+  					if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+  					{
+  						params.icon_overlay = LLUI::getUIImage("Inv_Link");
+  					}
+  					params.root = mFolderRoot;
+  					params.listener = new_listener;
+  					params.tool_tip = params.name;
+  					LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);
+  					folderp->setItemSortOrder(mFolderRoot->getSortOrder());
+  					itemp = folderp;
+  				}
+  			}
+  			else
+  			{
+  				// Build new view for item.
+  				LLInventoryItem* item = (LLInventoryItem*)objectp;
+  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
+  																				item->getActualType(),
+  																				item->getInventoryType(),
+  																				this,
+  																				mFolderRoot,
+  																				item->getUUID(),
+  																				item->getFlags());
+ 
+  				if (new_listener)
+  				{
+  					LLFolderViewItem::Params params;
+  					params.name = new_listener->getDisplayName();
+  					params.icon = new_listener->getIcon();
+  					params.icon_open = new_listener->getOpenIcon();
+  					if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+  					{
+  						params.icon_overlay = LLUI::getUIImage("Inv_Link");
+  					}
+  					params.creation_date = new_listener->getCreationDate();
+  					params.root = mFolderRoot;
+  					params.listener = new_listener;
+  					params.rect = LLRect (0, 0, 0, 0);
+  					params.tool_tip = params.name;
+  					itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
+  				}
+  			}
+ 
+  			if (itemp)
+  			{
+  				itemp->addToFolder(parent_folder, mFolderRoot);
+   			}
 		}
 	}
 
 	// If this is a folder, add the children of the folder and recursively add any 
 	// child folders.
-	if ((id == mStartFolderID) ||
-		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY))
+	if (id.isNull()
+		||	(objectp
+			&& objectp->getType() == LLAssetType::AT_CATEGORY))
 	{
 		LLViewerInventoryCategory::cat_array_t* categories;
 		LLViewerInventoryItem::item_array_t* items;
@@ -671,7 +676,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
 			}
 		}
 		
-		if(items)
+		if(items && parent_folder)
 		{
 			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
 				 item_iter != items->end();
@@ -688,23 +693,17 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
 // bit of a hack to make sure the inventory is open.
 void LLInventoryPanel::openStartFolderOrMyInventory()
 {
-	if (mStartFolderString != "")
-	{
-		mFolderRoot->openFolder(mStartFolderString);
-	}
-	else
+	// Find My Inventory folder and open it up by name
+	for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
 	{
-		// Find My Inventory folder and open it up by name
-		for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
+		LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
+		if (fchild
+			&& fchild->getListener()
+				&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
 		{
-			LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
-			if (fchild && fchild->getListener() &&
-				(fchild->getListener()->getUUID() == gInventory.getRootFolderID()))
-			{
-				const std::string& child_name = child->getName();
-				mFolderRoot->openFolder(child_name);
-				break;
-			}
+			const std::string& child_name = child->getName();
+			mFolderRoot->openFolder(child_name);
+			break;
 		}
 	}
 }
@@ -1067,15 +1066,12 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
 
 void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
 {
-	if (!getIsHiddenFolderType(folder_type))
-	{
-		mHiddenFolderTypes.push_back(folder_type);
-	}
+	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
 }
 
 BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
 {
-	return (std::find(mHiddenFolderTypes.begin(), mHiddenFolderTypes.end(), folder_type) != mHiddenFolderTypes.end());
+	return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
 }
 
 
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 9da9f7d8ba9..da67da13b2d 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -126,6 +126,7 @@ class LLInventoryPanel : public LLPanel
 	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
 	void clearSelection();
 	LLInventoryFilter* getFilter();
+	const LLInventoryFilter* getFilter() const;
 	void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
 	U32 getFilterObjectTypes() const { return mFolderRoot->getFilterObjectTypes(); }
 	void setFilterPermMask(PermissionMask filter_perm_mask);
@@ -140,7 +141,6 @@ class LLInventoryPanel : public LLPanel
 
 	void setShowFolderState(LLInventoryFilter::EFolderShow show);
 	LLInventoryFilter::EFolderShow getShowFolderState();
-	void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); }
 	// This method is called when something has changed about the inventory.
 	void modelChanged(U32 mask);
 	LLFolderView* getRootFolder() { return mFolderRoot; }
@@ -207,23 +207,18 @@ class LLInventoryPanel : public LLPanel
 	//--------------------------------------------------------------------
 public:
 	void addHideFolderType(LLFolderType::EType folder_type);
-protected:
-	BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
-private:
-	std::vector<LLFolderType::EType> mHiddenFolderTypes;
 
-	//--------------------------------------------------------------------
-	// Initialization routines for building up the UI ("views")
-	//--------------------------------------------------------------------
 public:
 	BOOL 				getIsViewsInitialized() const { return mViewsInitialized; }
-	const LLUUID&		getStartFolderID() const { return mStartFolderID; }
-	const std::string&  getStartFolderString() { return mStartFolderString; }
+	const LLUUID&		getRootFolderID() const;
 protected:
 	// Builds the UI.  Call this once the inventory is usable.
 	void 				initializeViews();
-	void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
-	virtual void buildNewViews(const LLUUID& id);
+	void				rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
+
+	virtual void		buildFolderView(const LLInventoryPanel::Params& params);
+	virtual void		buildNewViews(const LLUUID& id);
+	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;
 private:
 	BOOL				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
 	BOOL				mViewsInitialized; // Views have been generated
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 80f68621697..f09f675b75e 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -645,7 +645,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI
 	// Start background fetch, mostly for My Inventory and Library
 	if (expanded)
 	{
-		const LLUUID &cat_id = inventory_list->getStartFolderID();
+		const LLUUID &cat_id = inventory_list->getRootFolderID();
 		// Just because the category itself has been fetched, doesn't mean its child folders have.
 		/*
 		  if (!gInventory.isCategoryComplete(cat_id))
@@ -1414,7 +1414,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
 
 static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)
 {
-	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getStartFolderID());
+	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());
 	if (category)
 	{
 		return category->getDescendentCount() > 0;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 29e262199e3..f7823f4fe86 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -35,6 +35,7 @@
 #include "llinventoryfunctions.h"
 #include "llpanellandmarks.h"
 #include "llplacesinventorybridge.h"
+#include "llviewerfoldertype.h"
 
 static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_inventory_panel");
 
@@ -56,72 +57,44 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
 	delete mSavedFolderState;
 }
 
-BOOL LLPlacesInventoryPanel::postBuild()
+void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
 {
-	LLInventoryPanel::postBuild();
+	// Determine the root folder in case specified, and
+	// build the views starting with that folder.
+	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
 
-	// clear Contents();
-	{
-		mFolderRoot->destroyView();
-		mFolderRoot->getParent()->removeChild(mFolderRoot);
-		mFolderRoot->die();
-
-		if( mScroller )
-		{
-			removeChild( mScroller );
-			mScroller->die();
-			mScroller = NULL;
-		}
-		mFolderRoot = NULL;
-	}
-
-
-	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
+	LLUUID root_id;
 
-	// create root folder
+	if ("LIBRARY" == params.start_folder())
 	{
-		LLRect folder_rect(0,
-			0,
-			getRect().getWidth(),
-			0);
-		LLPlacesFolderView::Params p;
-		p.name = getName();
-		p.title = getLabel();
-		p.rect = folder_rect;
-		p.parent_panel = this;
-		mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
-		mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
+		root_id = gInventory.getLibraryRootFolderID();
 	}
-
-	mCommitCallbackRegistrar.popScope();
-
-	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
-
-	// scroller
+	else
 	{
-		LLRect scroller_view_rect = getRect();
-		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
-		LLScrollContainer::Params p;
-		p.name("Inventory Scroller");
-		p.rect(scroller_view_rect);
-		p.follows.flags(FOLLOWS_ALL);
-		p.reserve_scroll_corner(true);
-		p.tab_stop(true);
-		mScroller = LLUICtrlFactory::create<LLScrollContainer>(p);
+		root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
 	}
-	addChild(mScroller);
-	mScroller->addChild(mFolderRoot);
-
-	mFolderRoot->setScrollContainer(mScroller);
-	mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
 
-
-	// cut subitems
-	mFolderRoot->setUseEllipses(true);
-
-	return TRUE;
+	LLRect folder_rect(0,
+		0,
+		getRect().getWidth(),
+		0);
+	LLPlacesFolderView::Params p;
+	p.name = getName();
+	p.title = getLabel();
+	p.rect = folder_rect;
+	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
+													LLAssetType::AT_CATEGORY,
+													LLInventoryType::IT_CATEGORY,
+													this,
+													NULL,
+													root_id);
+	p.parent_panel = this;
+	p.allow_multiselect = mAllowMultiSelect;
+	p.use_ellipses = true;	// truncate inventory item text so remove horizontal scroller
+	mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
 }
 
+
 // save current folder open state
 void LLPlacesInventoryPanel::saveFolderState()
 {
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 1023a4339b2..b182c15dd0b 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -420,7 +420,6 @@ BOOL LLFloaterTexturePicker::postBuild()
 		mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
 		mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
 		mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
-		mInventoryPanel->setAllowMultiSelect(FALSE);
 
 		// Disable auto selecting first filtered item because it takes away
 		// selection from the item set by LLTextureCtrl owning this floater.
-- 
GitLab