diff options
| author | Richard Linden <none@none> | 2012-06-15 09:56:47 -0700 | 
|---|---|---|
| committer | Richard Linden <none@none> | 2012-06-15 09:56:47 -0700 | 
| commit | 86103dd5d40a685c3ba0ad385e6585e005785e50 (patch) | |
| tree | 363d2731af7e73143f54962e8f9fc8f290202ef8 | |
| parent | 569146f27c7350ca2245f1fa7bc4cb9c16a428ea (diff) | |
| parent | 9940ca5ae7698e89c0587733f7ab922027c8ddcc (diff) | |
Automated merge with ssh://hg.lindenlab.com/richard/viewer-chui-folderview
34 files changed, 1379 insertions, 1441 deletions
| diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index fbf23bc3f0..784e20ad46 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -275,6 +275,18 @@ void LLInventoryObject::correctInventoryName(std::string& name)  	LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN);  } +time_t LLInventoryObject::getCreationDate() const +{ +	return mCreationDate; +} + +void LLInventoryObject::setCreationDate(time_t creation_date_utc) +{ +	mCreationDate = creation_date_utc; +} + + +  ///----------------------------------------------------------------------------  /// Class LLInventoryItem @@ -297,9 +309,10 @@ LLInventoryItem::LLInventoryItem(const LLUUID& uuid,  	mDescription(desc),  	mSaleInfo(sale_info),  	mInventoryType(inv_type), -	mFlags(flags), -	mCreationDate(creation_date_utc) +	mFlags(flags)  { +	mCreationDate = creation_date_utc; +  	LLStringUtil::replaceNonstandardASCII(mDescription, ' ');  	LLStringUtil::replaceChar(mDescription, '|', ' ');  	mPermissions.initMasks(inv_type); @@ -312,9 +325,9 @@ LLInventoryItem::LLInventoryItem() :  	mDescription(),  	mSaleInfo(),  	mInventoryType(LLInventoryType::IT_NONE), -	mFlags(0), -	mCreationDate(0) +	mFlags(0)  { +	mCreationDate = 0;  }  LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) : @@ -379,11 +392,6 @@ const std::string& LLInventoryItem::getDescription() const  	return mDescription;  } -time_t LLInventoryItem::getCreationDate() const -{ -	return mCreationDate; -} -  U32 LLInventoryItem::getCRC32() const  {  	// *FIX: Not a real crc - more of a checksum. @@ -440,11 +448,6 @@ void LLInventoryItem::setFlags(U32 flags)  	mFlags = flags;  } -void LLInventoryItem::setCreationDate(time_t creation_date_utc) -{ -	mCreationDate = creation_date_utc; -} -  // Currently only used in the Viewer to handle calling cards  // where the creator is actually used to store the target.  void LLInventoryItem::setCreator(const LLUUID& creator) diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index a5cfe59bda..dc9a09e9d6 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -75,6 +75,7 @@ public:  	virtual LLAssetType::EType getType() const;  	LLAssetType::EType getActualType() const; // bypasses indirection for linked items  	BOOL getIsLinkType() const; +	virtual time_t getCreationDate() const;  	//--------------------------------------------------------------------  	// Mutators @@ -85,6 +86,7 @@ public:  	virtual void rename(const std::string& new_name);  	void setParent(const LLUUID& new_parent);  	void setType(LLAssetType::EType type); +	virtual void setCreationDate(time_t creation_date_utc); // only stored for items  private:  	// in place correction for inventory name string @@ -113,6 +115,7 @@ protected:  	LLUUID mParentUUID; // Parent category.  Root categories have LLUUID::NULL.  	LLAssetType::EType mType;  	std::string mName; +	time_t mCreationDate; // seconds from 1/1/1970, UTC  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -178,7 +181,6 @@ public:  	void setPermissions(const LLPermissions& perm);  	void setInventoryType(LLInventoryType::EType inv_type);  	void setFlags(U32 flags); -	void setCreationDate(time_t creation_date_utc);  	void setCreator(const LLUUID& creator); // only used for calling cards  	// Check for changes in permissions masks and sale info @@ -224,7 +226,6 @@ protected:  	LLSaleInfo mSaleInfo;  	LLInventoryType::EType mInventoryType;  	U32 mFlags; -	time_t mCreationDate; // seconds from 1/1/1970, UTC  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index ce59401e87..d44ccac6e4 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -212,7 +212,7 @@ namespace LLInitParam  		{}  		ParamValue(const default_value_t& other) -			:	T(other), +		:	T(other),  			mValidated(false)  		{} @@ -632,38 +632,38 @@ namespace LLInitParam  		class BaseBlock*				mCurrentBlockPtr;		// pointer to block currently being constructed  	}; -		//TODO: implement in terms of owned_ptr -		template<typename T> +	//TODO: implement in terms of owned_ptr +	template<typename T>  	class LazyValue -		{ +	{  		public:  		LazyValue() -				: mPtr(NULL) -			{} +		: mPtr(NULL) +		{}  		~LazyValue() -			{ -				delete mPtr; -			} +		{ +			delete mPtr; +		}  		LazyValue(const T& value) -			{ +		{  			mPtr = new T(value);  		}  		LazyValue(const LazyValue& other)  		:	mPtr(NULL) -				{ +		{  			*this = other; -				} +		}  		LazyValue& operator = (const LazyValue& other)  		{  			if (!other.mPtr) -				{ +			{  				delete mPtr; -					mPtr = NULL; -				} +				mPtr = NULL; +			}  			else  			{  				if (!mPtr) @@ -674,9 +674,9 @@ namespace LLInitParam  				{  					*mPtr = *(other.mPtr);  				} -				} -				return *this;  			} +			return *this; +		}  		bool operator==(const LazyValue& other) const  		{ @@ -684,13 +684,13 @@ namespace LLInitParam  			return *mPtr == *other.mPtr;  		} -			bool empty() const -			{ -				return mPtr == NULL; -			} +		bool empty() const +		{ +			return mPtr == NULL; +		} -			void set(const T& other) -			{ +		void set(const T& other) +		{  			if (!mPtr)  			{  				mPtr = new T(other); @@ -701,36 +701,36 @@ namespace LLInitParam  			}  		} -			const T& get() const -			{ +		const T& get() const +		{  			return *ensureInstance(); -			} +		} -			T& get() -			{ +		T& get() +		{  			return *ensureInstance();  		}  		operator const T&() const  		{   			return get();  -			} +		} -		private: -			// lazily allocate an instance of T -			T* ensureInstance() const +	private: +		// lazily allocate an instance of T +		T* ensureInstance() const +		{ +			if (mPtr == NULL)  			{ -				if (mPtr == NULL) -				{ -					mPtr = new T(); -				} -				return mPtr; -			} +				mPtr = new T();			 +                        } +			return mPtr; +		} -		private: +	private: -			mutable T* mPtr; -		}; +		mutable T* mPtr; +	};  	// root class of all parameter blocks @@ -2492,10 +2492,10 @@ namespace LLInitParam  		} EValueAge;  		typedef ParamValue<T>			derived_t; -		typedef CustomParamValue<T>				self_t; -		typedef Block<derived_t>				block_t; +		typedef CustomParamValue<T>		self_t; +		typedef Block<derived_t>		block_t;  		typedef T						default_value_t; -		typedef T								value_t; +		typedef T						value_t;  		typedef void					baseblock_base_class_t; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index c9031dd26a..decfef2ae6 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -711,23 +711,30 @@ namespace action_give_inventory  //static  std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()  { -	std::set<LLUUID> inventory_selected_uuids; +	std::set<LLFolderViewItem*> inventory_selected;  	LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();  	if (active_panel)  	{ -		inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +		inventory_selected= active_panel->getRootFolder()->getSelectionList();  	} -	if (inventory_selected_uuids.empty()) +	if (inventory_selected.empty())  	{  		LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");  		if (sidepanel_inventory)  		{ -			inventory_selected_uuids = sidepanel_inventory->getInboxSelectionList(); +			inventory_selected= sidepanel_inventory->getInboxSelectionList();  		}  	} +	std::set<LLUUID> inventory_selected_uuids; +	for (std::set<LLFolderViewItem*>::iterator it = inventory_selected.begin(), end_it = inventory_selected.end(); +		it != end_it; +		++it) +	{ +		inventory_selected_uuids.insert((*it)->getListener()->getUUID()); +	}  	return inventory_selected_uuids;  } @@ -763,15 +770,15 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL  	// check selection in the panel  	LLFolderView* root_folder = inv_panel->getRootFolder(); -	const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList(); -	if (inventory_selected_uuids.empty()) return false; // nothing selected +	const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList(); +	if (inventory_selected.empty()) return false; // nothing selected  	bool can_share = true; -	std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); -	const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end(); +	std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin(); +	const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();  	for (; it != it_end; ++it)  	{ -		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); +		LLViewerInventoryCategory* inv_cat = gInventory.getCategory((*it)->getListener()->getUUID());  		// any category can be offered.  		if (inv_cat)  		{ @@ -779,7 +786,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL  		}  		// check if inventory item can be given -		LLFolderViewItem* item = root_folder->getItemByID(*it); +		LLFolderViewItem* item = *it;  		if (!item) return false;  		LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener());  		if (bridge && bridge->canShare()) diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp index c55970ad69..ba0f51b467 100644 --- a/indra/newview/llfloateroutbox.cpp +++ b/indra/newview/llfloateroutbox.cpp @@ -250,7 +250,8 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)  	mOutboxInventoryPanel->setShape(inventory_placeholder_rect);  	// Set the sort order newest to oldest -	mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);	 + +	mOutboxInventoryPanel->getViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	  	mOutboxInventoryPanel->getFilter()->markDefault();  	fetchOutboxContents(); @@ -386,7 +387,7 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	// Determine if the mouse is inside the inventory panel itself or just within the floater  	bool pointInInventoryPanel = false;  	bool pointInInventoryPanelChild = false; -	LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder(); +	LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();  	if (mOutboxInventoryPanel->getVisible())  	{  		S32 inv_x, inv_y; @@ -443,10 +444,10 @@ void LLFloaterOutbox::onOutboxChanged()  {  	llassert(!mOutboxId.isNull()); -	if (mOutboxInventoryPanel) -	{ -		mOutboxInventoryPanel->requestSort(); -	} +	//if (mOutboxInventoryPanel) +	//{ +	//	mOutboxInventoryPanel->requestSort(); +	//}  	fetchOutboxContents(); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 57fc3f7efd..1f48ef98f6 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -27,6 +27,7 @@  #include "llviewerprecompiledheaders.h"  #include "llfolderview.h" +#include "llfolderview.h"  #include "llcallbacklist.h"  #include "llinventorybridge.h" @@ -94,42 +95,6 @@ enum {  F32 LLFolderView::sAutoOpenTime = 1.f; -void delete_selected_item(void* user_data); -void copy_selected_item(void* user_data); -void open_selected_items(void* user_data); -void properties_selected_items(void* user_data); -void paste_items(void* user_data); - - -//--------------------------------------------------------------------------- - -// Tells all folders in a folderview to sort their items -// (and only their items, not folders) by a certain function. -class LLSetItemSortFunction : public LLFolderViewFunctor -{ -public: -	LLSetItemSortFunction(U32 ordering) -		: mSortOrder(ordering) {} -	virtual ~LLSetItemSortFunction() {} -	virtual void doFolder(LLFolderViewFolder* folder); -	virtual void doItem(LLFolderViewItem* item); - -	U32 mSortOrder; -}; - - -// Set the sort order. -void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder) -{ -	folder->setItemSortOrder(mSortOrder); -} - -// Do nothing. -void LLSetItemSortFunction::doItem(LLFolderViewItem* item) -{ -	return; -} -  //---------------------------------------------------------------------------  // Tells all folders in a folderview to close themselves @@ -154,7 +119,6 @@ public:  }; -// Set the sort order.  void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)  {  	folder->setOpenArrangeRecursively(mOpen); @@ -200,7 +164,6 @@ LLFolderView::Params::Params()  	use_label_suffix("use_label_suffix"),  	allow_multiselect("allow_multiselect", true),  	show_empty_message("show_empty_message", true), -	show_load_status("show_load_status", true),  	use_ellipses("use_ellipses", false)  {  	folder_indentation = -4; @@ -210,7 +173,6 @@ LLFolderView::Params::Params()  // Default constructor  LLFolderView::LLFolderView(const Params& p)  :	LLFolderViewFolder(p), -	mRunningHeight(0),  	mScrollContainer( NULL ),  	mPopupMenuHandle(),  	mAllowMultiSelect(p.allow_multiselect), @@ -237,17 +199,15 @@ LLFolderView::LLFolderView(const Params& p)  	mParentPanel(p.parent_panel),  	mUseEllipses(p.use_ellipses),  	mDraggingOverItem(NULL), -	mStatusTextBox(NULL) +	mStatusTextBox(NULL), +	mViewModel(p.view_model)  {  	mRoot = this; -	mShowLoadStatus = p.show_load_status(); -  	LLRect rect = p.rect;  	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);  	setRect( rect );  	reshape(rect.getWidth(), rect.getHeight()); -	mIsOpen = TRUE; // this view is always open.  	mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);  	mAutoOpenCandidate = NULL;  	mAutoOpenTimer.stop(); @@ -332,8 +292,6 @@ LLFolderView::~LLFolderView( void )  	mItems.clear();  	mFolders.clear(); -	mItemMap.clear(); -  	delete mFilter;  	mFilter = NULL;  } @@ -343,27 +301,6 @@ BOOL LLFolderView::canFocusChildren() const  	return FALSE;  } -static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory"); - -void LLFolderView::setSortOrder(U32 order) -{ -	if (order != mSortOrder) -	{ -		LLFastTimer t(FTM_SORT); -		 -		mSortOrder = order; - -		sortBy(order); -		arrangeAll(); -	} -} - - -U32 LLFolderView::getSortOrder() const -{ -	return mSortOrder; -} -  BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)  {  	// enforce sort order of My Inventory followed by Library @@ -375,7 +312,6 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)  	{  		mFolders.insert(mFolders.begin(), folder);  	} -	folder->setShowLoadStatus(mShowLoadStatus);  	folder->setOrigin(0, 0);  	folder->reshape(getRect().getWidth(), 0);  	folder->setVisible(FALSE); @@ -402,128 +338,32 @@ void LLFolderView::openTopLevelFolders()  	}  } -void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) -{ -	// call base class to do proper recursion -	LLFolderViewFolder::setOpenArrangeRecursively(openitem, recurse); -	// make sure root folder is always open -	mIsOpen = TRUE; -} - -static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange"); -  // This view grows and shrinks to enclose all of its children items and folders. +// mItemHeight = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0; +// *width should be 0 +// conform show folder state works  S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )  { -	if (getListener()->getUUID().notNull()) -	{ -		if (mNeedsSort) -		{ -			mFolders.sort(mSortFunction); -			mItems.sort(mSortFunction); -			mNeedsSort = false; -		} -	} - -	LLFastTimer t2(FTM_ARRANGE); - -	filter_generation = mFilter->getMinRequiredGeneration();  	mMinWidth = 0; +	S32 target_height; -	mHasVisibleChildren = hasFilteredDescendants(filter_generation); -	// arrange always finishes, so optimistically set the arrange generation to the most current -	mLastArrangeGeneration = getRoot()->getArrangeGeneration(); - -	LLInventoryFilter::EFolderShow show_folder_state = -		getRoot()->getFilter()->getShowFolderState(); - -	S32 total_width = LEFT_PAD; -	S32 running_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0; -	S32 target_height = running_height; -	S32 parent_item_height = getRect().getHeight(); - -	for (folders_t::iterator iter = mFolders.begin(); -		 iter != mFolders.end();) -	{ -		folders_t::iterator fit = iter++; -		LLFolderViewFolder* folderp = (*fit); -		if (getDebugFilters()) -		{ -			folderp->setVisible(TRUE); -		} -		else -		{ -			folderp->setVisible((show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? -								 (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation)))); -		} - -		if (folderp->getVisible()) -		{ -			S32 child_height = 0; -			S32 child_width = 0; -			S32 child_top = parent_item_height - running_height; -			 -			target_height += folderp->arrange( &child_width, &child_height, filter_generation ); - -			mMinWidth = llmax(mMinWidth, child_width); -			total_width = llmax( total_width, child_width ); -			running_height += child_height; -			folderp->setOrigin( ICON_PAD, child_top - (*fit)->getRect().getHeight() ); -		} -	} +	LLFolderViewFolder::arrange(&mMinWidth, &target_height, mFilter->getFirstSuccessGeneration()); -	for (items_t::iterator iter = mItems.begin(); -		 iter != mItems.end();) -	{ -		items_t::iterator iit = iter++; -		LLFolderViewItem* itemp = (*iit); -		itemp->setVisible(itemp->getFiltered(filter_generation)); - -		if (itemp->getVisible()) -		{ -			S32 child_width = 0; -			S32 child_height = 0; -			S32 child_top = parent_item_height - running_height; -			 -			target_height += itemp->arrange( &child_width, &child_height, filter_generation ); -			itemp->reshape(itemp->getRect().getWidth(), child_height); - -			mMinWidth = llmax(mMinWidth, child_width); -			total_width = llmax( total_width, child_width ); -			running_height += child_height; -			itemp->setOrigin( ICON_PAD, child_top - itemp->getRect().getHeight() ); -		} -	} - -	if(!mHasVisibleChildren)// is there any filtered items ? -	{ -		//Nope. We need to display status textbox, let's reserve some place for it -		running_height = mStatusTextBox->getTextPixelHeight(); -		target_height = running_height; -	} - -	mRunningHeight = running_height;  	LLRect scroll_rect = mScrollContainer->getContentWindowRect(); -	reshape( llmax(scroll_rect.getWidth(), total_width), running_height ); +	reshape( llmax(scroll_rect.getWidth(), mMinWidth), mCurHeight );  	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();  	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())  	{ -		reshape( llmax(scroll_rect.getWidth(), total_width), running_height ); +		reshape( llmax(scroll_rect.getWidth(), mMinWidth), mCurHeight );  	}  	// move item renamer text field to item's new position  	updateRenamerPosition(); -	mTargetHeight = (F32)target_height;  	return llround(mTargetHeight);  } -const std::string LLFolderView::getFilterSubString(BOOL trim) -{ -	return mFilter->getFilterSubString(trim); -} -  static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");  void LLFolderView::filter( LLInventoryFilter& filter ) @@ -552,7 +392,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)  		scroll_rect = mScrollContainer->getContentWindowRect();  	}  	width = llmax(mMinWidth, scroll_rect.getWidth()); -	height = llmax(mRunningHeight, scroll_rect.getHeight()); +	height = llmax(mCurHeight, scroll_rect.getHeight());  	// Restrict width within scroll container's width  	if (mUseEllipses && mScrollContainer) @@ -651,30 +491,6 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,  	return rv;  } -void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus) -{ -	LLFolderViewItem* itemp = getItemByID(obj_id); -	if(itemp && itemp->getListener()) -	{ -		itemp->arrangeAndSet(TRUE, take_keyboard_focus); -		mSelectThisID.setNull(); -		return; -	} -	else -	{ -		// save the desired item to be selected later (if/when ready) -		mSelectThisID = obj_id; -	} -} - -void LLFolderView::updateSelection() -{ -	if (mSelectThisID.notNull()) -	{ -		setSelectionByID(mSelectThisID, false); -	} -} -  BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)  {  	BOOL rv = FALSE; @@ -725,9 +541,6 @@ void LLFolderView::sanitizeSelection()  	// and we want to preserve context  	LLFolderViewItem* original_selected_item = getCurSelectedItem(); -	// Cache "Show all folders" filter setting -	BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); -  	std::vector<LLFolderViewItem*> items_to_remove;  	selected_items_t::iterator item_iter;  	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter) @@ -738,21 +551,12 @@ void LLFolderView::sanitizeSelection()  		BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item  		// modify with parent open and filters states  		LLFolderViewFolder* parent_folder = item->getParentFolder(); -		if ( parent_folder ) -		{ -			if ( show_all_folders ) -			{	// "Show all folders" is on, so this folder is visible -				visible = TRUE; -			} -			else -			{	// Move up through parent folders and see what's visible +		// Move up through parent folders and see what's visible  				while(parent_folder)  				{  					visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();  					parent_folder = parent_folder->getParentFolder();  				} -			} -		}  		//  deselect item if any ancestor is closed or didn't pass filter requirements.  		if (!visible) @@ -844,15 +648,10 @@ void LLFolderView::clearSelection()  	mSelectThisID.setNull();  } -std::set<LLUUID> LLFolderView::getSelectionList() const -{ -	std::set<LLUUID> selection; -	for (selected_items_t::const_iterator item_it = mSelectedItems.begin();  -		 item_it != mSelectedItems.end();  -		 ++item_it) +std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const  	{ -		selection.insert((*item_it)->getListener()->getUUID()); -	} +	std::set<LLFolderViewItem*> selection; +	std::copy(mSelectedItems.begin(), mSelectedItems.end(), std::inserter(selection, selection.begin()));  	return selection;  } @@ -890,7 +689,7 @@ void LLFolderView::draw()  	if (mDebugFilters)  	{  		std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d", -										mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration()); +										mFilter->getCurrentGeneration(), mFilter->getFirstSuccessGeneration(), mFilter->getFirstRequiredGeneration());  		LLFontGL::getFontMonospace()->renderUTF8(current_filter_string, 0, 2,   			getRect().getHeight() - LLFontGL::getFontMonospace()->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f),   			LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); @@ -929,25 +728,23 @@ void LLFolderView::draw()  		mSearchString.clear();  	} -	if (hasVisibleChildren() -		|| mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) +	if (hasVisibleChildren())  	{  		mStatusText.clear();  		mStatusTextBox->setVisible( FALSE );  	}  	else if (mShowEmptyMessage)  	{ -		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration()) +		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getFirstSuccessGeneration())  		{ +			RN: Get this from filter  			mStatusText = LLTrans::getString("Searching");  		}  		else  		{  			if (getFilter())  			{ -				LLStringUtil::format_map_t args; -				args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig()); -				mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args); +				mStatusText = getFilter()->getEmptyLookupMessage();  			}  		}  		mStatusTextBox->setValue(mStatusText); @@ -994,7 +791,7 @@ void LLFolderView::finishRenamingItem( void )  	closeRenamer(); -	// List is re-sorted alphabeticly, so scroll to make sure the selected item is visible. +	// List is re-sorted alphabetically, so scroll to make sure the selected item is visible.  	scrollToShowSelection();  } @@ -1123,8 +920,8 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL  		}  		else if (count > 1)  		{ -			LLDynamicArray<LLFolderViewEventListener*> listeners; -			LLFolderViewEventListener* listener; +			LLDynamicArray<LLFolderViewModelItem*> listeners; +			LLFolderViewModelItemInventory* listener;  			LLFolderViewItem* last_item = items[count - 1];  			LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);  			while(new_selection && new_selection->isSelected()) @@ -1151,12 +948,12 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL  			for(S32 i = 0; i < count; ++i)  			{  				listener = items[i]->getListener(); -				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL)) +				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItemInventory*>::FAIL))  				{  					listeners.put(listener);  				}  			} -			listener = listeners.get(0); +			listener = static_cast<LLFolderViewModelItemInventory*>(listeners.get(0));  			if(listener)  			{  				listener->removeBatch(listeners); @@ -1187,7 +984,7 @@ void LLFolderView::openSelectedItems( void )  				// IT_{OBJECT,ATTACHMENT} creates LLProperties  				// floaters; others create LLPreviews.  Put  				// each one in the right type of container. -				LLFolderViewEventListener* listener = (*item_it)->getListener(); +				LLFolderViewModelItemInventory* listener = (*item_it)->getListener();  				bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);  				if (is_prop)  					LLFloater::setFloaterHost(multi_propertiesp); @@ -1343,7 +1140,7 @@ void LLFolderView::copy()  	S32 count = mSelectedItems.size();  	if(getVisible() && getEnabled() && (count > 0))  	{ -		LLFolderViewEventListener* listener = NULL; +		LLFolderViewModelItemInventory* listener = NULL;  		selected_items_t::iterator item_it;  		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)  		{ @@ -1367,7 +1164,7 @@ BOOL LLFolderView::canCut() const  	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)  	{  		const LLFolderViewItem* item = *selected_it; -		const LLFolderViewEventListener* listener = item->getListener(); +		const LLFolderViewModelItemInventory* listener = item->getListener();  		if (!listener || !listener->isItemRemovable())  		{ @@ -1384,7 +1181,7 @@ void LLFolderView::cut()  	S32 count = mSelectedItems.size();  	if(getVisible() && getEnabled() && (count > 0))  	{ -		LLFolderViewEventListener* listener = NULL; +		LLFolderViewModelItemInventory* listener = NULL;  		selected_items_t::iterator item_it;  		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)  		{ @@ -1413,7 +1210,7 @@ BOOL LLFolderView::canPaste() const  		{  			// *TODO: only check folders and parent folders of items  			const LLFolderViewItem* item = (*item_it); -			const LLFolderViewEventListener* listener = item->getListener(); +			const LLFolderViewModelItemInventory* listener = item->getListener();  			if(!listener || !listener->isClipboardPasteable())  			{  				const LLFolderViewFolder* folderp = item->getParentFolder(); @@ -1441,7 +1238,7 @@ void LLFolderView::paste()  		for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)  		{  			LLFolderViewItem* item = *selected_it; -			LLFolderViewEventListener* listener = item->getListener(); +			LLFolderViewModelItemInventory* listener = item->getListener();  			if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)  			{  				item = item->getParentFolder(); @@ -1452,7 +1249,7 @@ void LLFolderView::paste()  		std::set<LLFolderViewItem*>::iterator set_iter;  		for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)  		{ -			LLFolderViewEventListener* listener = (*set_iter)->getListener(); +			LLFolderViewModelItemInventory* listener = (*set_iter)->getListener();  			if(listener && listener->isClipboardPasteable())  			{  				listener->pasteFromClipboard(); @@ -1895,7 +1692,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  	S32 count = mSelectedItems.size();  	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();  	if (   handled -		&& ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible +		&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible  		&& menu )  	{  		if (mCallbackRegistrar) @@ -2076,55 +1873,6 @@ void LLFolderView::setShowSingleSelection(BOOL show)  	}  } -void LLFolderView::addItemID(const LLUUID& id, LLFolderViewItem* itemp) -{ -	mItemMap[id] = itemp; -} - -void LLFolderView::removeItemID(const LLUUID& id) -{ -	mItemMap.erase(id); -} - -LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID"); -LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id) -{ -	LLFastTimer _(FTM_GET_ITEM_BY_ID); -	if (id == getListener()->getUUID()) -	{ -		return this; -	} - -	std::map<LLUUID, LLFolderViewItem*>::iterator map_it; -	map_it = mItemMap.find(id); -	if (map_it != mItemMap.end()) -	{ -		return map_it->second; -	} - -	return NULL; -} - -LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id) -{ -	if (id == getListener()->getUUID()) -	{ -		return this; -	} - -	for (folders_t::iterator iter = mFolders.begin(); -		 iter != mFolders.end(); -		 ++iter) -	{ -		LLFolderViewFolder *folder = (*iter); -		if (folder->getListener()->getUUID() == id) -		{ -			return folder; -		} -	} -	return NULL; -} -  bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)  {  	std::string action = userdata.asString(); @@ -2140,7 +1888,7 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)  		return true;  	}  	if (("copy" == action) || ("cut" == action)) -	{ +	{	  		// Clear the clipboard before we start adding things on it  		LLClipboard::instance().reset();  	} @@ -2155,7 +1903,7 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)  	} -	std::set<LLUUID> selected_items = getSelectionList(); +	std::set<LLFolderViewItem*> selected_items = getSelectionList();  	LLMultiPreview* multi_previewp = NULL;  	LLMultiProperties* multi_propertiesp = NULL; @@ -2176,11 +1924,11 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)  		LLFloater::setFloaterHost(multi_propertiesp);  	} -	std::set<LLUUID>::iterator set_iter; +	std::set<LLFolderViewItem*>::iterator set_iter;  	for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)  	{ -		LLFolderViewItem* folder_item = getItemByID(*set_iter); +		LLFolderViewItem* folder_item = *set_iter;  		if(!folder_item) continue;  		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();  		if(!bridge) continue; @@ -2540,72 +2288,18 @@ void LLFolderView::onRenamerLost()  	}  } -LLInventoryFilter* LLFolderView::getFilter() +LLFolderViewFilter* LLFolderView::getFilter()  {  	return mFilter;  } -void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask ) -{ -	mFilter->setFilterPermissions(filter_perm_mask); -} - -U32 LLFolderView::getFilterObjectTypes() const -{ -	return mFilter->getFilterObjectTypes(); -} - -PermissionMask LLFolderView::getFilterPermissions() const -{ -	return mFilter->getFilterPermissions(); -} - -BOOL LLFolderView::isFilterModified() -{ -	return mFilter->isNotDefault(); -} - -void delete_selected_item(void* user_data) -{ -	if(user_data) -	{ -		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); -		fv->removeSelectedItems(); -	} -} - -void copy_selected_item(void* user_data) -{ -	if(user_data) -	{ -		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); -		fv->copy(); -	} -} - -void paste_items(void* user_data) -{ -	if(user_data) -	{ -		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); -		fv->paste(); -	} -} - -void open_selected_items(void* user_data) -{ -	if(user_data) -	{ -		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); -		fv->openSelectedItems(); -	} -} - -void properties_selected_items(void* user_data) +S32 LLFolderView::getItemHeight()  { -	if(user_data) +	S32 debug_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0; +	if(!hasVisibleChildren())  	{ -		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); -		fv->propertiesSelectedItems(); +		//We need to display status textbox, let's reserve some place for it +		return llmax(debug_height, mStatusTextBox->getTextPixelHeight());  	} +	return debug_height;  } diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index dc3d02eac6..37005f080f 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -48,9 +48,10 @@  #include "lltooldraganddrop.h"  #include "llviewertexture.h" -class LLFolderViewEventListener; +class LLFolderViewModelInterface;  class LLFolderViewFolder;  class LLFolderViewItem; +class LLFolderViewFilter;  class LLInventoryModel;  class LLPanel;  class LLLineEditor; @@ -95,8 +96,8 @@ public:  		Optional<bool>			use_label_suffix,  								allow_multiselect,  								show_empty_message, -								show_load_status,  								use_ellipses; +		Mandatory<LLFolderViewModelInterface*>	view_model;  		Params();  	}; @@ -110,9 +111,8 @@ public:  	virtual LLFolderView*	getRoot() { return this; } -	// FolderViews default to sort by name. This will change that, -	// and resort the items if necessary. -	void setSortOrder(U32 order); +	LLFolderViewModelInterface* getViewModel() { return mViewModel; } +  	void setFilterPermMask(PermissionMask filter_perm_mask);  	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t; @@ -120,14 +120,7 @@ public:  	void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }  	// filter is never null -	LLInventoryFilter* getFilter(); -	const std::string getFilterSubString(BOOL trim = FALSE); -	U32 getFilterObjectTypes() const; -	PermissionMask getFilterPermissions() const; -	// *NOTE: use getFilter()->getShowFolderState(); -	//LLInventoryFilter::EFolderShow getShowFolderState(); -	U32 getSortOrder() const; -	BOOL isFilterModified(); +	LLFolderViewFilter* getFilter();  	bool getAllowMultiSelect() { return mAllowMultiSelect; } @@ -135,19 +128,18 @@ public:  	void closeAllFolders();  	void openTopLevelFolders(); -	virtual void toggleOpen() {}; -	virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);  	virtual BOOL addFolder( LLFolderViewFolder* folder);  	// Find width and height of this object and its children. Also  	// makes sure that this view and its children are the right size.  	virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); +	virtual S32 getItemHeight();  	void arrangeAll() { mArrangeGeneration++; }  	S32 getArrangeGeneration() { return mArrangeGeneration; } -	// Apply filters to control visibility of inventory items -	virtual void filter( LLInventoryFilter& filter); +	// applies filters to control visibility of items +	virtual void filter( LLFolderViewFilter& filter);  	// Get the last selected item  	virtual LLFolderViewItem* getCurSelectedItem( void ); @@ -156,21 +148,15 @@ public:  	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,  		BOOL take_keyboard_focus); -	// Used by menu callbacks -	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus); - -	// Called once a frame to update the selection if mSelectThisID has been set -	void updateSelection(); - -	// This method is used to toggle the selection of an item.  -	// Walks children and keeps track of selected objects. +	// This method is used to toggle the selection of an item. Walks +	// children, and keeps track of selected objects.  	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); -	virtual std::set<LLUUID> getSelectionList() const; +	virtual std::set<LLFolderViewItem*> getSelectionList() const;  	// Make sure if ancestor is selected, descendents are not  	void sanitizeSelection(); -	void clearSelection(); +	virtual void clearSelection();  	void addToSelectionList(LLFolderViewItem* item);  	void removeFromSelectionList(LLFolderViewItem* item); @@ -193,6 +179,7 @@ public:  	void autoOpenItem(LLFolderViewFolder* item);  	void closeAutoOpenedFolders();  	BOOL autoOpenTest(LLFolderViewFolder* item); +	BOOL isOpen() const { return TRUE; } // root folder always open  	// Copy & paste  	virtual void	copy(); @@ -241,11 +228,6 @@ public:  	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }  	bool getUseEllipses() { return mUseEllipses; } -	void addItemID(const LLUUID& id, LLFolderViewItem* itemp); -	void removeItemID(const LLUUID& id); -	LLFolderViewItem* getItemByID(const LLUUID& id); -	LLFolderViewFolder* getFolderByID(const LLUUID& id); -	  	bool doToSelected(LLInventoryModel* model, const LLSD& userdata);  	void	doIdle();						// Real idle routine @@ -290,6 +272,8 @@ protected:  	void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response); +	LLInventorySort& getSortFunction() { return mSortFunction; } +  protected:  	LLHandle<LLView>					mPopupMenuHandle; @@ -320,7 +304,7 @@ protected:  	LLFrameTimer					mAutoOpenTimer;  	LLFrameTimer					mSearchTimer;  	std::string						mSearchString; -	LLInventoryFilter*				mFilter; +	LLFolderViewFilter*				mFilter;  	BOOL							mShowSelectionContext;  	BOOL							mShowSingleSelection;  	LLFrameTimer					mMultiSelectionFadeTimer; @@ -330,13 +314,12 @@ protected:  	signal_t						mReshapeSignal;  	S32								mSignalSelectCallback;  	S32								mMinWidth; -	S32								mRunningHeight; -	std::map<LLUUID, LLFolderViewItem*> mItemMap;  	BOOL							mDragAndDropThisFrame; -	LLUUID							mSelectThisID; // if non null, select this item -	  	LLPanel*						mParentPanel; +	 +	LLInventorySort					mSortFunction; +	LLFolderViewModelInterface*		mViewModel;  	/**  	 * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. @@ -357,9 +340,6 @@ public:  }; -bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b); -bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b); -  // Flags for buildContextMenu()  const U32 SUPPRESS_OPEN_ITEM = 0x1;  const U32 FIRST_SELECTED_ITEM = 0x2; diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h index 06682dcbf1..76e051d12f 100644 --- a/indra/newview/llfoldervieweventlistener.h +++ b/indra/newview/llfoldervieweventlistener.h @@ -32,62 +32,157 @@  #include "llpermissionsflags.h"  #include "llpointer.h"  #include "llwearabletype.h" +#include "lltooldraganddrop.h" +// These are grouping of inventory types. +// Order matters when sorting system folders to the top. +enum EInventorySortGroup +{ +	SG_SYSTEM_FOLDER, +	SG_TRASH_FOLDER, +	SG_NORMAL_FOLDER, +	SG_ITEM +}; -class LLFolderViewItem; -class LLFolderView;  class LLFontGL;  class LLInventoryModel;  class LLMenuGL; -class LLScrollContainer;  class LLUIImage;  class LLUUID; +class LLFolderViewItem; +class LLFolderViewFolder; -// This is an abstract base class that users of the folderview classes -// would use to catch the useful events emitted from the folder -// views. -class LLFolderViewEventListener +class LLFolderViewFilter  {  public: -	virtual ~LLFolderViewEventListener( void ) {} +	LLFolderViewFilter() {} +	virtual ~LLFolderViewFilter() {} + +	// +-------------------------------------------------------------------+ +	// + Execution And Results +	// +-------------------------------------------------------------------+ +	virtual bool 				check(const LLFolderViewItem* item) = 0; +	virtual bool				check(const LLInventoryItem* item) = 0; +	virtual bool				checkFolder(const LLFolderViewFolder* folder) const = 0; +	virtual bool				checkFolder(const LLUUID& folder_id) const = 0; + +	virtual void 				setEmptyLookupMessage(const std::string& message) = 0; +	const virtual std::string&	getEmptyLookupMessage() const = 0; + +	// +-------------------------------------------------------------------+ +	// + Status +	// +-------------------------------------------------------------------+ +	virtual bool 				isActive() const = 0; +	virtual bool 				isModified() const = 0; +	virtual bool 				isModifiedAndClear() = 0; +	virtual void 				clearModified() = 0; +	virtual const std::string& 	getName() const = 0; +	virtual const std::string& 	getFilterText() = 0; +	//RN: this is public to allow system to externally force a global refilter +	virtual void 				setModified(EFilterBehavior behavior = FILTER_RESTART) = 0; + +	// +-------------------------------------------------------------------+ +	// + Count +	// +-------------------------------------------------------------------+ +	virtual void 				setFilterCount(S32 count) = 0; +	virtual S32 				getFilterCount() const = 0; +	virtual void 				decrementFilterCount() = 0; + +	// +-------------------------------------------------------------------+ +	// + Default +	// +-------------------------------------------------------------------+ +	virtual BOOL 				isNotDefault() const = 0; +	virtual void 				markDefault() = 0; +	virtual void 				resetDefault() = 0; + +	// +-------------------------------------------------------------------+ +	// + Generation +	// +-------------------------------------------------------------------+ +	virtual S32 				getCurrentGeneration() const = 0; +	virtual S32 				getFirstSuccessGeneration() const = 0; +	virtual S32 				getFirstRequiredGeneration() const = 0; +}; + +struct LLFolderViewModelInterface +{ +	virtual void requestSortAll() = 0; +	virtual void requestSort(class LLFolderViewFolder*) = 0; + +	virtual void sort(class LLFolderViewFolder*) = 0; +	virtual void filter(class LLFolderViewFolder*) = 0; +}; + +struct LLFolderViewModelCommon : public LLFolderViewModelInterface +{ +	LLFolderViewModelCommon() +	:	mTargetSortVersion(0) +	{} + +	virtual void requestSortAll() +	{ +		// sort everything +		mTargetSortVersion++; +	} + +	virtual void requestSort(class LLFolderViewFolder* folder) +	{ +		folder->requestSort(); +	} +	 +protected: +	bool needsSort(class LLFolderViewModelItem* item) +	{ +		return item->getSortVersion() < mTargetSortVersion; +	} + +	S32 mTargetSortVersion; +}; + + +// This is am abstract base class that users of the folderview classes +// would use to bridge the folder view with the underlying data +class LLFolderViewModelItem +{ +public: +	virtual ~LLFolderViewModelItem( void ) {}; + +	virtual void update() {}	//called when drawing  	virtual const std::string& getName() const = 0;  	virtual const std::string& getDisplayName() const = 0; -	virtual const LLUUID& getUUID() const = 0; -	virtual time_t getCreationDate() const = 0;	// UTC seconds -	virtual PermissionMask getPermissionMask() const = 0; -	virtual LLFolderType::EType getPreferredType() const = 0; +  	virtual LLPointer<LLUIImage> getIcon() const = 0;  	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); } +  	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;  	virtual std::string getLabelSuffix() const = 0; +  	virtual void openItem( void ) = 0;  	virtual void closeItem( void ) = 0; -	virtual void previewItem( void ) = 0;  	virtual void selectItem(void) = 0; -	virtual void showProperties(void) = 0; +  	virtual BOOL isItemRenameable() const = 0;  	virtual BOOL renameItem(const std::string& new_name) = 0; +  	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder +	virtual void move( LLFolderViewModelItem* parent_listener ) = 0; +  	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed -	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.  	virtual BOOL removeItem() = 0; -	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0; -	virtual void move( LLFolderViewEventListener* parent_listener ) = 0; +	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0; +  	virtual BOOL isItemCopyable() const = 0;  	virtual BOOL copyToClipboard() const = 0;  	virtual BOOL cutToClipboard() const = 0; +  	virtual BOOL isClipboardPasteable() const = 0;  	virtual void pasteFromClipboard() = 0;  	virtual void pasteLinkFromClipboard() = 0; +  	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; -	virtual BOOL isUpToDate() const = 0; -	virtual BOOL hasChildren() const = 0; -	virtual LLInventoryType::EType getInventoryType() const = 0; -	virtual void performAction(LLInventoryModel* model, std::string action) = 0; -	virtual LLWearableType::EType getWearableType() const = 0;  	// This method should be called when a drag begins. returns TRUE  	// if the drag can begin, otherwise FALSE. +	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;  	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;  	// This method will be called to determine if a drop can be @@ -98,6 +193,102 @@ public:  							EDragAndDropType cargo_type,  							void* cargo_data,  							std::string& tooltip_msg) = 0; + +	virtual void requestSort() = 0; +	virtual S32 getSortVersion() = 0; +	virtual void setSortVersion(S32 version) = 0; +}; + +class LLFolderViewModelItemCommon : public LLFolderViewModelItem +{ +public: +	LLFolderViewModelItemCommon() +	:	mSortVersion(-1) +	{} + +	void requestSort() { mSortVersion = -1; } +	S32 getSortVersion() { return mSortVersion; } +	void setSortVersion(S32 version) { mSortVersion = VERSION;} + +protected: +	S32 mSortVersion; +}; + +template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE> +class LLFolderViewModel : public LLFolderViewModelCommon +{ +protected: +	LLFolderViewModel() {} +	 +	typedef SORT_TYPE		SortType; +	typedef ITEM_TYPE		ItemType; +	typedef FOLDER_TYPE		FolderType; +	typedef FILTER_TYPE		FilterType; +	 +	virtual const SortType& getSorter() const 		 { return mSorter; } +	virtual void setSorter(const SortType& type) 	 { mSorter = sorter; requestSortAll(); } +	virtual FilterType& getFilter() const 			 { return mFilter; } +	virtual void setFilter(const FilterType& filter) { mFilter = filter; } + +public: + +	struct ViewModelCompare() +	{ +		ViewModelCompare(const SortType& sorter) +		:	mSorter(sorter) +		{} +		 +		int operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) +		{ +			return mSorter(static_cast<const ItemType*>(a->getListener()), static_cast<const ItemType*>(b->getListener())); +		} + +		int operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) +		{ +			return mSorter(static_cast<const ItemType*>(a->getListener()), static_cast<const ItemType*>(b->getListener())); +		} + +		const SortType& mSorter; +	} + +	void sort(LLFolderViewFolder* folder) +	{ +		if (needsSort(folder)) +		{ +			std::sort(folder->getFoldersBegin(), folder->getFoldersEnd(), ViewModelCompare(getSorter())); +			std::sort(folder->getItemsBegin(), folder->getItemsEnd(), ViewModelCompare(getSorter())); +			folder->getListener()->setSortVersion(mTargetSortVersion); +			folder->requestArrange(); +		} +	} + +	void filter(LLFolderViewFolder* folder) +	{ +		FilterType& filter = getFilter(); +		for (std::list<LLFolderViewItem*>::iterator it = folder->getItemsBegin(), end_it = folder->getItemsEnd(); +			it != end_it; +			++it) +		{ +			LLFolderViewItem* child_item = *it; +			child_item->setFiltered(filter(static_cast<ItemType*>(child_item->getListener())), filter.getCurrentGeneration()) +		} + +		for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd(); +			it != end_it; +			++it) +		{ +			LLFolderViewItem* child_folder = *it; +			child_folder->setFiltered(filter(static_cast<ItemType*>(child_folder->getListener())), filter.getCurrentGeneration()) +		} +	} + +protected: +	SortType	mSorter; +	FilterType	mFilter;  }; + + + +  #endif diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index f40f051537..13b721fa23 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -29,6 +29,7 @@  // viewer includes  #include "llfolderview.h"		// Items depend extensively on LLFolderViews +#include "llfolderview.h"  #include "llfoldervieweventlistener.h"  #include "llviewerfoldertype.h"  #include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator() @@ -122,15 +123,12 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  	mStringMatchOffset(std::string::npos),  	mControlLabelRotation(0.f),  	mDragAndDropTarget(FALSE), -	mIsLoading(FALSE),  	mLabel(p.name),  	mRoot(p.root), -	mCreationDate(p.creation_date),  	mIcon(p.icon),  	mIconOpen(p.icon_open),  	mIconOverlay(p.icon_overlay),  	mListener(p.listener), -	mShowLoadStatus(false),  	mIsMouseOverTitle(false)  {  } @@ -219,19 +217,13 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)  // until we find out otherwise  BOOL LLFolderViewItem::potentiallyVisible()  { -	// we haven't been checked against min required filter -	// or we have and we passed -	return potentiallyFiltered(); -} - -BOOL LLFolderViewItem::potentiallyFiltered() -{ -	return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered(); +	return getFiltered() // we've passed the filter +		||	getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration()); // or we don't know yet  }  BOOL LLFolderViewItem::getFiltered()   {  -	return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();  +	return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();  }  BOOL LLFolderViewItem::getFiltered(S32 filter_generation)  @@ -250,13 +242,12 @@ void LLFolderViewItem::setIcon(LLUIImagePtr icon)  	mIcon = icon;  } -// refresh information from the listener -void LLFolderViewItem::refreshFromListener() +void LLFolderViewItem::refresh()  { -	if(mListener) -	{ -		mLabel = mListener->getDisplayName(); -		LLFolderType::EType preferred_type = mListener->getPreferredType(); +	if(!getListener()) return; + +	mLabel = getListener()->getDisplayName(); +	LLFolderType::EType preferred_type = getListener()->getPreferredType();  		// *TODO: to be removed when database supports multi language. This is a  		// temporary attempt to display the inventory folder in the user locale. @@ -270,7 +261,7 @@ void LLFolderViewItem::refreshFromListener()  		{  			//To ensure that Accessories folder is in Library we have to check its parent folder.  			//Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model -			LLInventoryCategory* cat = gInventory.getCategory(mListener->getUUID()); +		LLInventoryCategory* cat = gInventory.getCategory(getListener()->getUUID());  			if(cat)  			{  				const LLUUID& parent_folder_id = cat->getParentUUID(); @@ -286,25 +277,13 @@ void LLFolderViewItem::refreshFromListener()  		};  		setToolTip(mLabel); -		setIcon(mListener->getIcon()); -		time_t creation_date = mListener->getCreationDate(); -		if ((creation_date > 0) && (mCreationDate != creation_date)) -		{ -			setCreationDate(creation_date); -			dirtyFilter(); -		} +	setIcon(getListener()->getIcon());  		if (mRoot->useLabelSuffix())  		{ -			mLabelStyle = mListener->getLabelStyle(); -			mLabelSuffix = mListener->getLabelSuffix(); -		} -	} +		mLabelStyle = getListener()->getLabelStyle(); +		mLabelSuffix = getListener()->getLabelSuffix();  } -void LLFolderViewItem::refresh() -{ -	refreshFromListener(); -  	std::string searchable_label(mLabel);  	searchable_label.append(mLabelSuffix);  	LLStringUtil::toUpper(searchable_label); @@ -322,11 +301,7 @@ void LLFolderViewItem::refresh()  	}  	mLabelWidthDirty = true; -} - -void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ -	functor(mListener); +	dirtyFilter();  }  // This function is called when items are added or view filters change. It's @@ -392,19 +367,14 @@ void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL  	getRoot()->changeSelection(selection, selected);  } -std::set<LLUUID> LLFolderViewItem::getSelectionList() const +std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const  { -	std::set<LLUUID> selection; +	std::set<LLFolderViewItem*> selection;  	return selection;  } -EInventorySortGroup LLFolderViewItem::getSortGroup()  const -{  -	return SG_ITEM;  -} -  // addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)  {  	if (!folder)  	{ @@ -465,7 +435,7 @@ void LLFolderViewItem::filter( LLInventoryFilter& filter)  	}  	setFiltered(passed_filter, filter.getCurrentGeneration()); -	mStringMatchOffset = filter.getStringMatchOffset(); +	mStringMatchOffset = filter.getStringMatchOffset(this);  	filter.decrementFilterCount();  	if (getRoot()->getDebugFilters()) @@ -528,9 +498,9 @@ void LLFolderViewItem::selectItem(void)  {  	if (mIsSelected == FALSE)  	{ -		if (mListener) +		if (getListener())  		{ -			mListener->selectItem(); +			getListener()->selectItem();  		}  		mIsSelected = TRUE;  	} @@ -538,9 +508,9 @@ void LLFolderViewItem::selectItem(void)  BOOL LLFolderViewItem::isMovable()  { -	if( mListener ) +	if( getListener() )  	{ -		return mListener->isItemMovable(); +		return getListener()->isItemMovable();  	}  	else  	{ @@ -550,9 +520,9 @@ BOOL LLFolderViewItem::isMovable()  BOOL LLFolderViewItem::isRemovable()  { -	if( mListener ) +	if( getListener() )  	{ -		return mListener->isItemRemovable(); +		return getListener()->isItemRemovable();  	}  	else  	{ @@ -578,9 +548,9 @@ BOOL LLFolderViewItem::remove()  	{  		return FALSE;  	} -	if(mListener) +	if(getListener())  	{ -		return mListener->removeItem(); +		return getListener()->removeItem();  	}  	return TRUE;  } @@ -588,25 +558,25 @@ BOOL LLFolderViewItem::remove()  // Build an appropriate context menu for the item.  void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)  { -	if(mListener) +	if(getListener())  	{ -		mListener->buildContextMenu(menu, flags); +		getListener()->buildContextMenu(menu, flags);  	}  }  void LLFolderViewItem::openItem( void )  { -	if( mListener ) +	if( getListener() )  	{ -		mListener->openItem(); +		getListener()->openItem();  	}  }  void LLFolderViewItem::preview( void )  { -	if (mListener) +	if (getListener())  	{ -		mListener->previewItem(); +		getListener()->previewItem();  	}  } @@ -614,9 +584,9 @@ void LLFolderViewItem::rename(const std::string& new_name)  {  	if( !new_name.empty() )  	{ -		if( mListener ) +		if( getListener() )  		{ -			mListener->renameItem(new_name); +			getListener()->renameItem(new_name);  			if(mParentFolder)  			{ @@ -639,11 +609,11 @@ LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)  const std::string& LLFolderViewItem::getName( void ) const  { -	if(mListener) +	if(getListener())  	{ -		return mListener->getName(); +		return getListener()->getName();  	} -	return mLabel; +	return z;  }  // LLView functionality @@ -719,21 +689,19 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )  				// *TODO: push this into listener and remove  				// dependency on llagent -				if (mListener -					&& gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID())) +				if (getListener())  				{ -					src = LLToolDragAndDrop::SOURCE_AGENT; +					src = getListener()->getDragSource();  				} -				else if (mListener -					&& gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID())) +				else  				{ -					src = LLToolDragAndDrop::SOURCE_LIBRARY; +					src = LLToolDragAndDrop::SOURCE_VIEWER;  				}  				can_drag = root->startDrag(src);  				if (can_drag)  				{ -					// if (mListener) mListener->startDrag(); +					// if (getListener()) getListener()->startDrag();  					// RN: when starting drag and drop, clear out last auto-open  					root->autoOpenTest(NULL);  					root->setShowSelectionContext(TRUE); @@ -822,9 +790,9 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  {  	BOOL accepted = FALSE;  	BOOL handled = FALSE; -	if(mListener) +	if(getListener())  	{ -		accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg); +		accepted = getListener()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);  		handled = accepted;  		if (accepted)  		{ @@ -870,15 +838,14 @@ void LLFolderViewItem::draw()  	const S32 FOCUS_LEFT = 1;  	const LLFontGL* font = getLabelFontForStyle(mLabelStyle); -	const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID()); -	const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID()); +	getListener()->update();  	//--------------------------------------------------------------------------------//  	// Draw open folder arrow  	// -	const bool up_to_date = mListener && mListener->isUpToDate(); +	const bool up_to_date = getListener() && getListener()->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) +										|| (!up_to_date && getListener() && getListener()->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; @@ -1007,7 +974,7 @@ void LLFolderViewItem::draw()  	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;  	if (highlight_link) color = sLinkColor;  	if (in_library) color = sLibraryColor; -	 +  	F32 right_x  = 0;  	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;  	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); @@ -1037,30 +1004,6 @@ void LLFolderViewItem::draw()  					 S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);  	//--------------------------------------------------------------------------------// -	// Draw "Loading..." text -	// -	bool root_is_loading = false; -	if (in_inventory) -	{ -		root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();  -	} -	if (in_library) -	{ -		root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress(); -	} -	if ((mIsLoading -		&&	mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) -			||	(LLInventoryModelBackgroundFetch::instance().folderFetchActive() -				&&	root_is_loading -				&&	mShowLoadStatus)) -	{ -		std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) "; -		font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor, -						 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,  -						 S32_MAX, S32_MAX, &right_x, FALSE); -	} - -	//--------------------------------------------------------------------------------//  	// Draw label suffix  	//  	if (!mLabelSuffix.empty()) @@ -1073,28 +1016,29 @@ void LLFolderViewItem::draw()  	//--------------------------------------------------------------------------------//  	// Highlight string match  	// -	if (mStringMatchOffset != std::string::npos) -	{ -		// don't draw backgrounds for zero-length strings -		S32 filter_string_length = getRoot()->getFilterSubString().size(); -		if (filter_string_length > 0) -		{ -			std::string combined_string = mLabel + mLabelSuffix; -			S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1; -			S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; -			S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD); -			S32 top = getRect().getHeight() - TOP_PAD; -		 -			LLUIImage* box_image = default_params.selection_image; -			LLRect box_rect(left, top, right, bottom); -			box_image->draw(box_rect, sFilterBGColor); -			F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset); -			F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; -			font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy, -							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -							  filter_string_length, S32_MAX, &right_x, FALSE ); -		} -	} +	RN: expose interface for highlighting +	//if (mStringMatchOffset != std::string::npos) +	//{ +	//	// don't draw backgrounds for zero-length strings +	//	S32 filter_string_length = getRoot()->getFilterSubString().size(); +	//	if (filter_string_length > 0) +	//	{ +	//		std::string combined_string = mLabel + mLabelSuffix; +	//		S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1; +	//		S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; +	//		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD); +	//		S32 top = getRect().getHeight() - TOP_PAD; +	//	 +	//		LLUIImage* box_image = default_params.selection_image; +	//		LLRect box_rect(left, top, right, bottom); +	//		box_image->draw(box_rect, sFilterBGColor); +	//		F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset); +	//		F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; +	//		font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy, +	//						  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, +	//						  filter_string_length, S32_MAX, &right_x, FALSE ); +	//	} +	//}  } @@ -1103,19 +1047,16 @@ void LLFolderViewItem::draw()  ///----------------------------------------------------------------------------  LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):  -	LLFolderViewItem( p ),	// 0 = no create time +	LLFolderViewItem( p ),  	mIsOpen(FALSE),  	mExpanderHighlighted(FALSE),  	mCurHeight(0.f),  	mTargetHeight(0.f),  	mAutoOpenCountdown(0.f), -	mSubtreeCreationDate(0), -	mAmTrash(LLFolderViewFolder::UNKNOWN),  	mLastArrangeGeneration( -1 ),  	mLastCalculatedWidth(0),  	mCompletedFilterGeneration(-1),  	mMostFilteredDescendantGeneration(-1), -	mNeedsSort(false),  	mPassedFolderFilter(FALSE)  {  } @@ -1136,32 +1077,30 @@ void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)  bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)  { -	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); +	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();  }  // addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)  {  	if (!folder)  	{  		return FALSE;  	}  	mParentFolder = folder; -	root->addItemID(getListener()->getUUID(), this);  	return folder->addFolder(this);  } +static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange"); +  // Finds width and height of this object and its children. Also  // makes sure that this view and its children are the right size.  S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  {  	// sort before laying out contents -	if (mNeedsSort) -	{ -		mFolders.sort(mSortFunction); -		mItems.sort(mSortFunction); -		mNeedsSort = false; -	} +	getRoot->getViewModel()->sort(this); + +	LLFastTimer t2(FTM_ARRANGE);  	// evaluate mHasVisibleChildren  	mHasVisibleChildren = false; @@ -1202,7 +1141,6 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  	mCurHeight = llmax((F32)*height, mCurHeight);  	// initialize running height value as height of single item in case we have no children -	*height = getItemHeight();  	F32 running_height = (F32)*height;  	F32 target_height = (F32)*height; @@ -1212,7 +1150,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  		// set last arrange generation first, in case children are animating  		// and need to be arranged again  		mLastArrangeGeneration = getRoot()->getArrangeGeneration(); -		if (mIsOpen) +		if (isOpen())  		{  			// Add sizes of children  			S32 parent_item_height = getRect().getHeight(); @@ -1288,7 +1226,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  	// animate current height towards target height  	if (llabs(mCurHeight - mTargetHeight) > 1.f)  	{ -		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); +		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));  		requestArrange(); @@ -1339,9 +1277,7 @@ BOOL LLFolderViewFolder::needsArrange()  void LLFolderViewFolder::requestSort()  { -	mNeedsSort = true; -	// whenever item order changes, we need to lay things out again -	requestArrange(); +	getRoot()->getViewModel()->requestSort(this);  }  void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up) @@ -1363,7 +1299,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	// if failed to pass filter newer than must_pass_generation  	// you will automatically fail this time, so we only  	// check against items that have passed the filter -	S32 must_pass_generation = filter.getMustPassGeneration(); +	S32 must_pass_generation = filter.getFirstRequiredGeneration();  	bool autoopen_folders = (filter.hasFilterString()); @@ -1380,7 +1316,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  			&& !mPassedFilter)									// and did not pass the filter  		{  			// go ahead and flag this folder as done -			mLastFilterGeneration = filter_generation; +			mLastFilterGeneration = filter_generation;			  			mStringMatchOffset = std::string::npos;  		}  		else // filter self only on first pass through @@ -1417,11 +1353,11 @@ 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()))) +		&& getFiltered(filter.getFirstSuccessGeneration()) +		&&	(getListener() +			&& !gInventory.isCategoryComplete(getListener()->getUUID())))  	{ -		LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID()); +		LLInventoryModelBackgroundFetch::instance().start(getListener()->getUUID());  	}  	// now query children @@ -1442,7 +1378,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  		if (folder->getCompletedFilterGeneration() >= filter_generation)  		{  			// track latest generation to pass any child items -			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration())) +			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getFirstSuccessGeneration()))  			{  				mMostFilteredDescendantGeneration = filter_generation;  				requestArrange(); @@ -1496,7 +1432,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  		item->filter( filter ); -		if (item->getFiltered(filter.getMinRequiredGeneration())) +		if (item->getFiltered(filter.getFirstSuccessGeneration()))  		{  			mMostFilteredDescendantGeneration = filter_generation;  			requestArrange(); @@ -1561,7 +1497,7 @@ void LLFolderViewFolder::dirtyFilter()  BOOL LLFolderViewFolder::getFiltered()   {  -	return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration())  +	return getFilteredFolder(getRoot()->getFilter()->getFirstSuccessGeneration())  		&& LLFolderViewItem::getFiltered();   } @@ -1578,7 +1514,7 @@ BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)  BOOL LLFolderViewFolder::hasFilteredDescendants()  { -	return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); +	return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();  }  // Passes selection information on to children and record selection @@ -1933,14 +1869,6 @@ void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)  void LLFolderViewFolder::destroyView()  { -	for (items_t::iterator iter = mItems.begin(); -		iter != mItems.end();) -	{ -		items_t::iterator iit = iter++; -		LLFolderViewItem* item = (*iit); -		getRoot()->removeItemID(item->getListener()->getUUID()); -	} -  	std::for_each(mItems.begin(), mItems.end(), DeletePointer());  	mItems.clear(); @@ -1950,8 +1878,6 @@ void LLFolderViewFolder::destroyView()  		folderp->destroyView(); // removes entry from mFolders  	} -	//deleteAllChildren(); -  	if (mParentFolder)  	{  		mParentFolder->removeView(this); @@ -2013,103 +1939,14 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )  	dirtyFilter();  	//because an item is going away regardless of filter status, force rearrange  	requestArrange(); -	getRoot()->removeItemID(item->getListener()->getUUID());  	removeChild(item);  } -bool LLFolderViewFolder::isTrash() const -{ -	if (mAmTrash == LLFolderViewFolder::UNKNOWN) -	{ -		mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH; -	} -	return mAmTrash == LLFolderViewFolder::TRASH; -} - -void LLFolderViewFolder::sortBy(U32 order) -{ -	if (!mSortFunction.updateSort(order)) -	{ -		// No changes. -		return; -	} - -	// Propagate this change to sub folders -	for (folders_t::iterator iter = mFolders.begin(); -		iter != mFolders.end();) -	{ -		folders_t::iterator fit = iter++; -		(*fit)->sortBy(order); -	} - -	// Don't sort the topmost folders (My Inventory and Library) -	if (mListener->getUUID().notNull()) -	{ -		mFolders.sort(mSortFunction); -		mItems.sort(mSortFunction); -	} - -	if (order & LLInventoryFilter::SO_DATE) -	{ -		time_t latest = 0; - -		if (!mItems.empty()) -		{ -			LLFolderViewItem* item = *(mItems.begin()); -			latest = item->getCreationDate(); -		} - -		if (!mFolders.empty()) -		{ -			LLFolderViewFolder* folder = *(mFolders.begin()); -			if (folder->getCreationDate() > latest) -			{ -				latest = folder->getCreationDate(); -			} -		} -		mSubtreeCreationDate = latest; -	} -} - -void LLFolderViewFolder::setItemSortOrder(U32 ordering) -{ -	if (mSortFunction.updateSort(ordering)) -	{ -		for (folders_t::iterator iter = mFolders.begin(); -			iter != mFolders.end();) -		{ -			folders_t::iterator fit = iter++; -			(*fit)->setItemSortOrder(ordering); -		} - -		mFolders.sort(mSortFunction); -		mItems.sort(mSortFunction); -	} -} - -EInventorySortGroup LLFolderViewFolder::getSortGroup() const -{ -	if (isTrash()) -	{ -		return SG_TRASH_FOLDER; -	} - -	if( mListener ) -	{ -		if(LLFolderType::lookupIsProtectedType(mListener->getPreferredType())) -		{ -			return SG_SYSTEM_FOLDER; -		} -	} - -	return SG_NORMAL_FOLDER; -} -  BOOL LLFolderViewFolder::isMovable()  { -	if( mListener ) +	if( getListener() )  	{ -		if( !(mListener->isItemMovable()) ) +		if( !(getListener()->isItemMovable()) )  		{  			return FALSE;  		} @@ -2140,9 +1977,9 @@ BOOL LLFolderViewFolder::isMovable()  BOOL LLFolderViewFolder::isRemovable()  { -	if( mListener ) +	if( getListener() )  	{ -		if( !(mListener->isItemRemovable()) ) +		if( !(getListener()->isItemRemovable()) )  		{  			return FALSE;  		} @@ -2182,37 +2019,23 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)  	item->dirtyFilter(); -	// Update the folder creation date if the folder has no creation date -	bool setting_date = false; -	const time_t item_creation_date = item->getCreationDate(); -	if ((item_creation_date > 0) && (mCreationDate == 0)) -	{ -		setCreationDate(item_creation_date); -		setting_date = true; -	} -  	// Handle sorting  	requestArrange();  	requestSort(); -	// Traverse parent folders and update creation date and resort, if necessary -	LLFolderViewFolder* parentp = getParentFolder(); -	while (parentp) -	{ -		// Update the parent folder creation date -		if (setting_date && (parentp->mCreationDate == 0)) -		{ -			parentp->setCreationDate(item_creation_date); -		} +	FIXME: RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria +	//// Traverse parent folders and update creation date and resort, if necessary +	//LLFolderViewFolder* parentp = this; +	//while (parentp) +	//{ +	//	if (parentp->mSortFunction.isByDate()) +	//	{ +	//		// parent folder doesn't have a time stamp yet, so get it from us +	//		parentp->requestSort(); +	//	} -		if (parentp->mSortFunction.isByDate()) -		{ -			// parent folder doesn't have a time stamp yet, so get it from us -			parentp->requestSort(); -		} - -		parentp = parentp->getParentFolder(); -	} +	//	parentp = parentp->getParentFolder(); +	//}  	return TRUE;  } @@ -2229,13 +2052,16 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)  	// rearrange all descendants too, as our indentation level might have changed  	folder->requestArrange(TRUE);  	requestSort(); +	if (getRoot()->getSortFunction().isByDate()) +	{  	LLFolderViewFolder* parentp = getParentFolder(); -	while (parentp && !parentp->mSortFunction.isByDate()) +		while(parentp)  	{  		// parent folder doesn't have a time stamp yet, so get it from us  		parentp->requestSort();  		parentp = parentp->getParentFolder();  	} +	}  	return TRUE;  } @@ -2261,7 +2087,7 @@ void LLFolderViewFolder::requestArrange(BOOL include_descendants)  void LLFolderViewFolder::toggleOpen()  { -	setOpen(!mIsOpen); +	setOpen(!isOpen());  }  // Force a folder open or closed @@ -2272,17 +2098,17 @@ void LLFolderViewFolder::setOpen(BOOL openitem)  void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)  { -	BOOL was_open = mIsOpen; +	BOOL was_open = isOpen();  	mIsOpen = openitem; -	if (mListener) +	if (getListener())  	{  		if(!was_open && openitem)  		{ -			mListener->openItem(); +			getListener()->openItem();  		}  		else if(was_open && !openitem)  		{ -			mListener->closeItem(); +			getListener()->closeItem();  		}  	} @@ -2302,7 +2128,7 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r  		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);  	} -	if (was_open != mIsOpen) +	if (was_open != isOpen())  	{  		requestArrange();  	} @@ -2371,23 +2197,6 @@ void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)  	}  } -void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ -	functor(mListener); -	for (folders_t::iterator iter = mFolders.begin(); -		iter != mFolders.end();) -	{ -		folders_t::iterator fit = iter++; -		(*fit)->applyListenerFunctorRecursively(functor); -	} -	for (items_t::iterator iter = mItems.begin(); -		iter != mItems.end();) -	{ -		items_t::iterator iit = iter++; -		(*iit)->applyListenerFunctorRecursively(functor); -	} -} -  // LLView functionality  BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,  										   BOOL drop, @@ -2398,7 +2207,7 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,  {  	BOOL handled = FALSE; -	if (mIsOpen) +	if (isOpen())  	{  		handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);  	} @@ -2420,7 +2229,7 @@ BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,  													   EAcceptance* accept,  													   std::string& tooltip_msg)  { -	BOOL accepted = mListener && mListener->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg); +	BOOL accepted = getListener() && getListener()->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);  	if (accepted)   	{ @@ -2446,9 +2255,9 @@ BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )  	BOOL handled = FALSE;  	// fetch contents of this folder, as context menu can depend on contents  	// still, user would have to open context menu again to see the changes -	gInventory.fetchDescendentsOf(mListener->getUUID()); +	gInventory.fetchDescendentsOf(getListener()->getUUID()); -	if( mIsOpen ) +	if( isOpen() )  	{  		handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;  	} @@ -2478,7 +2287,7 @@ BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)  BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )  {  	BOOL handled = FALSE; -	if( mIsOpen ) +	if( isOpen() )  	{  		handled = childrenHandleMouseDown(x,y,mask) != NULL;  	} @@ -2512,7 +2321,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )  	*/  	BOOL handled = FALSE; -	if( mIsOpen ) +	if( isOpen() )  	{  		handled = childrenHandleDoubleClick( x, y, mask ) != NULL;  	} @@ -2540,7 +2349,7 @@ void LLFolderViewFolder::draw()  	{  		mControlLabelRotation = mAutoOpenCountdown * -90.f;  	} -	else if (mIsOpen) +	else if (isOpen())  	{  		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));  	} @@ -2549,31 +2358,10 @@ void LLFolderViewFolder::draw()  		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));  	} -	bool possibly_has_children = false; -	bool up_to_date = mListener && mListener->isUpToDate(); -	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 ); - -	if ( loading && !mIsLoading ) -	{ -		// Measure how long we've been in the loading state -		mTimeSinceRequestStart.reset(); -	} - -	mIsLoading = loading; -  	LLFolderViewItem::draw();  	// draw children if root folder, or any other folder that is open or animating to closed state -	if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight )) +	if( getRoot() == this || (isOpen() || mCurHeight != mTargetHeight ))  	{  		LLView::draw();  	} @@ -2581,20 +2369,14 @@ void LLFolderViewFolder::draw()  	mExpanderHighlighted = FALSE;  } -time_t LLFolderViewFolder::getCreationDate() const -{ -	return llmax<time_t>(mCreationDate, mSubtreeCreationDate); -} - -  BOOL	LLFolderViewFolder::potentiallyVisible()  {  	// folder should be visible by it's own filter status  	return LLFolderViewItem::potentiallyVisible() 	  		// or one or more of its descendants have passed the minimum filter requirement -		|| hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration()) +		|| hasFilteredDescendants()  		// or not all of its descendants have been checked against minimum filter requirement -		|| getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration();  +		|| getCompletedFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration();  }  // this does prefix traversal, as folders are listed above their contents @@ -2808,41 +2590,27 @@ LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* it  	return result;  } - -bool LLInventorySort::updateSort(U32 order) -{ -	if (order != mSortOrder) -	{ -		mSortOrder = order; -		mByDate = (order & LLInventoryFilter::SO_DATE); -		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); -		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); -		return true; -	} -	return false; -} - -bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) +bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b)  {  	// 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 -		&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK -		&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) +		&& a->getInventoryType() == LLInventoryType::IT_LANDMARK +		&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)  	{  		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); -		LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID(); -		LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID(); +		LLUUID a_uuid = a->getParentFolder()->getUUID(); +		LLUUID b_uuid = b->getParentFolder()->getUUID();  		if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))  		{  			// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem  			// or to LLInvFVBridge -			LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a->getListener()))->getItem(); -			LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b->getListener()))->getItem(); +			LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem(); +			LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();  			if (!aitem || !bitem)  				return false;  			S32 a_sort = aitem->getSortField(); @@ -2889,8 +2657,6 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde  	}  	else  	{ -		// BUG: This is very very slow.  The getCreationDate() is log n in number -		// of inventory items.  		time_t first_create = a->getCreationDate();  		time_t second_create = b->getCreationDate();  		if (first_create == second_create) @@ -2903,3 +2669,4 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde  		}  	}  } + diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 3c7592046a..b7588223da 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -30,52 +30,13 @@  #include "lldarray.h"  // *TODO: Eliminate, forward declare  #include "lluiimage.h" -class LLFontGL;  class LLFolderView; -class LLFolderViewEventListener; +class LLFolderViewModelItemInventory;  class LLFolderViewFolder;  class LLFolderViewFunctor; -class LLFolderViewItem; -class LLFolderViewListenerFunctor;  class LLInventoryFilter; -class LLMenuGL; -class LLUIImage;  class LLViewerInventoryItem; -// These are grouping of inventory types. -// Order matters when sorting system folders to the top. -enum EInventorySortGroup -{  -	SG_SYSTEM_FOLDER,  -	SG_TRASH_FOLDER,  -	SG_NORMAL_FOLDER,  -	SG_ITEM  -}; - -// *TODO: do we really need one sort object per folder? -// can we just have one of these per LLFolderView ? -class LLInventorySort -{ -public: -	LLInventorySort()  -		: mSortOrder(0), -		mByDate(false), -		mSystemToTop(false), -		mFoldersByName(false) { } - -	// Returns true if order has changed -	bool updateSort(U32 order); -	U32 getSort() { return mSortOrder; } -	bool isByDate() { return mByDate; } - -	bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b); -private: -	U32  mSortOrder; -	bool mByDate; -	bool mSystemToTop; -	bool mFoldersByName; -}; -  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLFolderViewItem  // @@ -91,19 +52,19 @@ public:  	struct Params : public LLInitParam::Block<Params, LLView::Params>  	{ -		Optional<LLUIImage*>					icon; -		Optional<LLUIImage*>					icon_open;  // used for folders -		Optional<LLUIImage*>					icon_overlay;  // for links +		Optional<LLUIImage*>						icon, +													icon_open,     // used for folders +													icon_overlay,  // for links +													folder_arrow_image, +													selection_image;  		Optional<LLFolderView*>					root; -		Mandatory<LLFolderViewEventListener*>	listener; +		Mandatory<LLFolderViewModelItemInventory*>	listener; -		Optional<LLUIImage*>					folder_arrow_image; -		Optional<S32>							folder_indentation; // pixels -		Optional<LLUIImage*>					selection_image; -		Optional<S32>							item_height; // pixels -		Optional<S32>							item_top_pad; // pixels +		Optional<S32>								folder_indentation, // pixels +													item_height, +													item_top_pad; -		Optional<S32>							creation_date; //UTC seconds +		Optional<time_t>							creation_date;  		Params();  	}; @@ -121,17 +82,14 @@ public:  	static const F32 FOLDER_CLOSE_TIME_CONSTANT;  	static const F32 FOLDER_OPEN_TIME_CONSTANT; -	// Mostly for debugging printout purposes.  	const std::string& getSearchableLabel() { return mSearchableLabel; } -	BOOL isLoading() const { return mIsLoading; } -  private:  	BOOL						mIsSelected;  protected:  	friend class LLUICtrlFactory; -	friend class LLFolderViewEventListener; +	friend class LLFolderViewModelItem;  	LLFolderViewItem(const Params& p); @@ -139,9 +97,8 @@ protected:  	std::string					mSearchableLabel;  	S32							mLabelWidth;  	bool						mLabelWidthDirty; -	time_t						mCreationDate;  	LLFolderViewFolder*			mParentFolder; -	LLFolderViewEventListener*	mListener; +	LLFolderViewModelItemInventory*	mListener;  	BOOL						mIsCurSelection;  	BOOL						mSelectPending;  	LLFontGL::StyleFlags		mLabelStyle; @@ -159,9 +116,6 @@ protected:  	F32							mControlLabelRotation;  	LLFolderView*				mRoot;  	BOOL						mDragAndDropTarget; -	BOOL                        mIsLoading; -	LLTimer                     mTimeSinceRequestStart; -	bool						mShowLoadStatus;  	bool						mIsMouseOverTitle;  	// helper function to change the selection from the root. @@ -174,11 +128,11 @@ protected:  	static LLFontGL* getLabelFontForStyle(U8 style); -	virtual void setCreationDate(time_t creation_date_utc)	{ mCreationDate = creation_date_utc; } -  public:  	BOOL postBuild(); +	virtual void openItem( void ); +  	// 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 @@ -198,9 +152,7 @@ public:  	// addToFolder() returns TRUE if it succeeds. FALSE otherwise  	enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE }; -	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); - -	virtual EInventorySortGroup getSortGroup() const; +	virtual BOOL addToFolder(LLFolderViewFolder* folder);  	// Finds width and height of this object and it's children.  Also  	// makes sure that this view and it's children are the right size. @@ -231,7 +183,7 @@ public:  	virtual void selectItem();  	// gets multiple-element selection -	virtual std::set<LLUUID> getSelectionList() const; +	virtual std::set<LLFolderViewItem*> getSelectionList() const;  	// Returns true is this object and all of its children can be removed (deleted by user)  	virtual BOOL isRemovable(); @@ -252,15 +204,13 @@ public:  	BOOL hasVisibleChildren() { return mHasVisibleChildren; } -	void setShowLoadStatus(bool status) { mShowLoadStatus = status; } -  	// Call through to the viewed object and return true if it can be  	// removed. Returns true if it's removed.  	//virtual BOOL removeRecursively(BOOL single_item);  	BOOL remove();  	// Build an appropriate context menu for the item.	Flags unused. -	void buildContextMenu(LLMenuGL& menu, U32 flags); +	void buildContextMenu(class LLMenuGL& menu, U32 flags);  	// This method returns the actual name of the thing being  	// viewed. This method will ask the viewed object itself. @@ -273,8 +223,6 @@ public:  	// contents possible before the entire view has been constructed.  	const std::string& getLabel() const { return mLabel; } -	// Used for sorting, like getLabel() above. -	virtual time_t getCreationDate() const { return mCreationDate; }  	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }  	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; } @@ -282,22 +230,15 @@ public:  	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );  	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); -	const LLFolderViewEventListener* getListener( void ) const { return mListener; } -	LLFolderViewEventListener* getListener( void ) { return mListener; } -	 -	// Gets the inventory item if it exists (null otherwise) -	LLViewerInventoryItem * getInventoryItem(void); +	const LLFolderViewModelItemInventory* getListener( void ) const { return mListener; } +	LLFolderViewModelItemInventory* getListener( void ) { return mListener; }  	// just rename the object.  	void rename(const std::string& new_name); -	// open -	virtual void openItem( void ); -	virtual void preview(void);  	// Show children (unfortunate that this is called "open")  	virtual void setOpen(BOOL open = TRUE) {}; -  	virtual BOOL isOpen() const { return FALSE; }  	virtual LLFolderView*	getRoot(); @@ -315,11 +256,8 @@ public:  	void setIcon(LLUIImagePtr icon);  	// refresh information from the object being viewed. -	void refreshFromListener();  	virtual void refresh(); -	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); -  	// LLView functionality  	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );  	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); @@ -339,14 +277,40 @@ public:  		EAcceptance* accept,  		std::string& tooltip_msg); +	// Gets the inventory item if it exists (null otherwise) +	LLViewerInventoryItem * getInventoryItem(void); +	// open +	virtual void preview(void); +  private:  	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts  }; +class LLInventorySort +{ +public: +	LLInventorySort(U32 order) +	:	mSortOrder(0), +		mByDate(false), +		mSystemToTop(false), +		mFoldersByName(false) +	{ +		mSortOrder = order; +		mByDate = (order & LLInventoryFilter::SO_DATE); +		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); +		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); +	} -// function used for sorting. -typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b); +	bool isByDate() { return mByDate; } +	U32 getSortOrder() { return mSortOrder; } +	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b); +private: +	U32  mSortOrder; +	bool mByDate; +	bool mSystemToTop; +	bool mFoldersByName; +};  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLFolderViewFolder @@ -363,10 +327,6 @@ protected:  	friend class LLUICtrlFactory;  public: -	typedef enum e_trash -	{ -		UNKNOWN, TRASH, NOT_TRASH -	} ETrash;  	typedef std::list<LLFolderViewItem*> items_t;  	typedef std::list<LLFolderViewFolder*> folders_t; @@ -374,15 +334,12 @@ public:  protected:  	items_t mItems;  	folders_t mFolders; -	LLInventorySort	mSortFunction;  	BOOL		mIsOpen;  	BOOL		mExpanderHighlighted;  	F32			mCurHeight;  	F32			mTargetHeight;  	F32			mAutoOpenCountdown; -	time_t		mSubtreeCreationDate; -	mutable ETrash mAmTrash;  	S32			mLastArrangeGeneration;  	S32			mLastCalculatedWidth;  	S32			mCompletedFilterGeneration; @@ -408,17 +365,13 @@ public:  	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );  	// addToFolder() returns TRUE if it succeeds. FALSE otherwise -	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); +	virtual BOOL addToFolder(LLFolderViewFolder* folder);  	// Finds width and height of this object and it's children.  Also  	// makes sure that this view and it's children are the right size.  	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );  	BOOL needsArrange(); -	void requestSort(); - -	// Returns the sort group (system, trash, folder) for this folder. -	virtual EInventorySortGroup getSortGroup() const;  	virtual void	setCompletedFilterGeneration(S32 generation, BOOL recurse_up);  	virtual S32		getCompletedFilterGeneration() { return mCompletedFilterGeneration; } @@ -479,15 +432,11 @@ public:  	// extractItem() removes the specified item from the folder, but  	// doesn't delete it. -	void extractItem( LLFolderViewItem* item ); +	virtual void extractItem( LLFolderViewItem* item );  	// This function is called by a child that needs to be resorted.  	void resort(LLFolderViewItem* item); -	void setItemSortOrder(U32 ordering); -	void sortBy(U32); -	//BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b)); -  	void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }  	// folders can be opened. This will usually be called by internal @@ -501,6 +450,8 @@ public:  	// don't rearrange child folder contents unless explicitly requested  	virtual void requestArrange(BOOL include_descendants = FALSE); +	virtual void requestSort(); +  	// internal method which doesn't update the entire view. This  	// method was written because the list iterators destroy the state  	// of other iterations, thus, we can't arrange while iterating @@ -519,7 +470,6 @@ public:  		std::string& tooltip_msg);  	void applyFunctorRecursively(LLFolderViewFunctor& functor); -	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);  	// Just apply this functor to the folder's immediate children.  	void applyFunctorToChildren(LLFolderViewFunctor& functor); @@ -545,32 +495,18 @@ public:  									   std::string& tooltip_msg);  	virtual void draw(); -	time_t getCreationDate() const; -	bool isTrash() const; -	folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); } -	folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); } +	folders_t::iterator getFoldersBegin() const { return mFolders.begin(); } +	folders_t::iterator getFoldersEnd() const { return mFolders.end(); }  	folders_t::size_type getFoldersCount() const { return mFolders.size(); } -	items_t::const_iterator getItemsBegin() const { return mItems.begin(); } -	items_t::const_iterator getItemsEnd() const { return mItems.end(); } +	items_t::iterator getItemsBegin() const { return mItems.begin(); } +	items_t::iterator getItemsEnd() const { return mItems.end(); }  	items_t::size_type getItemsCount() const { return mItems.size(); } +  	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);  	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);  }; -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewListenerFunctor -// -// This simple abstract base class can be used to applied to all -// listeners in a hierarchy. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewListenerFunctor -{ -public: -	virtual ~LLFolderViewListenerFunctor() {} -	virtual void operator()(LLFolderViewEventListener* listener) = 0; -};  #endif  // LLFOLDERVIEWITEM_H diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 11401d6c68..a64ddd185d 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -47,13 +47,13 @@ static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All";  // helper functions  // NOTE: For now Friends & All folders are created as protected folders of the LLFolderType::FT_CALLINGCARD type. -// So, their names will be processed in the LLFolderViewItem::refreshFromListener() to be localized +// So, their names will be processed in the LLFolderViewItem::refresh() to be localized  // using "InvFolder LABEL_NAME" as LLTrans::findString argument.  // We must use in this file their hard-coded names to ensure found them on different locales. EXT-5829.  // These hard-coded names will be stored in InventoryItems but shown localized in FolderViewItems -// If hack in the LLFolderViewItem::refreshFromListener() to localize protected folder is removed +// If hack in the LLFolderViewItem::refresh() to localize protected folder is removed  // or these folders are not protected these names should be localized in another place/way.  inline const std::string get_friend_folder_name()  { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b86c453d61..d0d2215361 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -115,10 +115,10 @@ void teleport_via_landmark(const LLUUID& asset_id);  static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);  static bool check_category(LLInventoryModel* model,  						   const LLUUID& cat_id, -						   LLFolderView* active_folder_view, +						   LLInventoryPanel* active_panel,  						   LLInventoryFilter* filter);  static bool check_item(const LLUUID& item_id, -					   LLFolderView* active_folder_view, +					   LLInventoryPanel* active_panel,  					   LLInventoryFilter* filter);  // Helper functions @@ -227,9 +227,24 @@ LLFolderType::EType LLInvFVBridge::getPreferredType() const  // Folders don't have creation dates.  time_t LLInvFVBridge::getCreationDate() const  { -	return 0; +	LLInventoryObject* objectp = getInventoryObject(); +	if (objectp) +	{ +		return objectp->getCreationDate(); +	} +	return (time_t)0; +} + +void LLInvFVBridge::setCreationDate(time_t creation_date_utc) +{ +	LLInventoryObject* objectp = getInventoryObject(); +	if (objectp) +	{ +		objectp->setCreationDate(creation_date_utc); +	}  } +  // Can be destroyed (or moved to trash)  BOOL LLInvFVBridge::isItemRemovable() const  { @@ -283,7 +298,7 @@ void LLInvFVBridge::showProperties()  	*/  } -void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) +void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)  {  	// Deactivate gestures when moving them into Trash  	LLInvFVBridge* bridge; @@ -292,11 +307,11 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc  	LLViewerInventoryCategory* cat = NULL;  	LLInventoryModel::cat_array_t	descendent_categories;  	LLInventoryModel::item_array_t	descendent_items; -	S32 count = batch.count(); +	S32 count = batch.size();  	S32 i,j;  	for(i = 0; i < count; ++i)  	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); +		bridge = (LLInvFVBridge*)(batch[i]);  		if(!bridge || !bridge->isItemRemovable()) continue;  		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());  		if (item) @@ -309,7 +324,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc  	}  	for(i = 0; i < count; ++i)  	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); +		bridge = (LLInvFVBridge*)(batch[i]);  		if(!bridge || !bridge->isItemRemovable()) continue;  		cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());  		if (cat) @@ -327,7 +342,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc  	removeBatchNoCheck(batch);  } -void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch) +void  LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>&  batch)  {  	// this method moves a bunch of items and folders to the trash. As  	// per design guidelines for the inventory model, the message is @@ -343,14 +358,14 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*  	uuid_vec_t move_ids;  	LLInventoryModel::update_map_t update;  	bool start_new_message = true; -	S32 count = batch.count(); +	S32 count = batch.size();  	S32 i;  	// first, hide any 'preview' floaters that correspond to the items  	// being deleted.  	for(i = 0; i < count; ++i)  	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); +		bridge = (LLInvFVBridge*)(batch[i]);  		if(!bridge || !bridge->isItemRemovable()) continue;  		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());  		if(item) @@ -363,7 +378,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*  	for(i = 0; i < count; ++i)  	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); +		bridge = (LLInvFVBridge*)(batch[i]);  		if(!bridge || !bridge->isItemRemovable()) continue;  		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());  		if(item) @@ -876,6 +891,12 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const  	return panel ? panel->getModel() : NULL;  } +LLInventoryFilter* getInventoryFilter() const +{ +	LLInventoryPanel* panel = mInventoryPanel.get(); +	return panel ? panel->getFilter() : NULL; +} +  BOOL LLInvFVBridge::isItemInTrash() const  {  	LLInventoryModel* model = getInventoryModel(); @@ -1250,7 +1271,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const  		if (can_list)  		{ -			LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id); +			LLFolderViewFolder * object_folderp =   mInventoryPanel->getFolderByID(object_id);  			if (object_folderp)  			{  				can_list = !object_folderp->isLoading(); @@ -1261,7 +1282,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const  		{  			// Get outbox id  			const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); -			LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id); +			LLFolderViewItem * outbox_itemp =   mInventoryPanel->getItemByID(outbox_id);  			if (outbox_itemp)  			{ @@ -1283,6 +1304,21 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const  #endif  } +LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const +{ +	if (gInventory.isObjectDescendentOf(getUUID(),   gInventory.getRootFolderID())) +	{ +		return LLToolDragAndDrop::SOURCE_AGENT; +	} +	else if (gInventory.isObjectDescendentOf(getUUID(),   gInventory.getLibraryRootFolderID())) +	{ +		return LLToolDragAndDrop::SOURCE_LIBRARY; +	} + +	return SOURCE_VIEWER; +} + +  // +=================================================+  // |        InventoryFVBridgeBuilder                 | @@ -1368,7 +1404,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)  		LLInventoryItem* itemp = model->getItem(mUUID);  		if (!itemp) return; -		LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); +		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());  		if (!folder_view_itemp) return;  		folder_view_itemp->getListener()->pasteFromClipboard(); @@ -1380,7 +1416,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)  		LLInventoryItem* itemp = model->getItem(mUUID);  		if (!itemp) return; -		LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); +		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());  		if (!folder_view_itemp) return;  		folder_view_itemp->getListener()->pasteLinkFromClipboard(); @@ -1785,6 +1821,60 @@ void LLFolderBridge::selectItem()  	// Have no fear: the first thing start() does is to test if everything for that folder has been fetched...  	LLInventoryModelBackgroundFetch::instance().start(getUUID(), true);  } +std::string& LLFolderBridge::getDisplayName() const +{ +	return mDisplayName; +} + + +void LLFolderBridge::update() +{ +	bool possibly_has_children = false; +	bool up_to_date = isUpToDate(); +	if(!up_to_date && hasChildren()) // we know we have children but  haven't  fetched them (doesn't obey filter) +	{ +		possibly_has_children = true; +	} + +	BOOL loading = (possibly_has_children +		&& !up_to_date ); + +	if (loading != mIsLoading) +	{ +		if ( loading && !mIsLoading ) +		{ +			// Measure how long we've been in the loading state +			mTimeSinceRequestStart.reset(); +		} + +		const BOOL in_inventory = gInventory.isObjectDescendentOf(getUUID(),   gInventory.getRootFolderID()); +		const BOOL in_library = gInventory.isObjectDescendentOf(getUUID(),   gInventory.getLibraryRootFolderID()); + +		bool root_is_loading = false; +		if (in_inventory) +		{ +			root_is_loading =   LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress(); +		} +		if (in_library) +		{ +			root_is_loading =   LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress(); +		} +		if ((mIsLoading +				&&	mTimeSinceRequestStart.getElapsedTimeF32() >=   gSavedSettings.getF32("FolderLoadingMessageWaitTime")) +			||	(LLInventoryModelBackgroundFetch::instance().folderFetchActive() +				&&	root_is_loading)) +		{ +			mDisplayName = LLInvFVBridge::getDisplayName() + " ( " +   LLTrans::getString("LoadingData") + " ) "; +			mIsLoading = true; +		} +		else +		{ +			mDisplayName = LLInvFVBridge::getDisplayName(); +			mIsLoading = false; +		} +	} +} +  // Iterate through a folder's children to determine if  // all the children are removable. @@ -1812,7 +1902,7 @@ BOOL LLFolderBridge::isItemRemovable() const  	}  	LLInventoryPanel* panel = mInventoryPanel.get(); -	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL); +	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ?   panel->getItemByID(mUUID) : NULL);  	if (folderp)  	{  		LLIsItemRemovable folder_test; @@ -2051,7 +2141,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  	LLInventoryPanel* destination_panel = mInventoryPanel.get();  	if (!destination_panel) return false; -	LLInventoryFilter* filter = destination_panel->getFilter(); +	LLInventoryFilter* filter = getInventoryFilter();  	if (!filter) return false;  	const LLUUID &cat_id = inv_cat->getUUID(); @@ -2270,7 +2360,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  				{  					// Check whether the folder being dragged from active inventory panel  					// passes the filter of the destination panel. -					is_movable = check_category(model, cat_id, active_folder_view, filter); +					is_movable = check_category(model, cat_id, active_panel, filter);  				}  			}  		} @@ -2696,7 +2786,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)  {  	if ("open" == action)  	{ -		LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mRoot->getItemByID(mUUID)); +		LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder   *>(mInventoryPanel.get()->getItemByID(mUUID));  		if (f)  		{  			f->setOpen(TRUE); @@ -2971,7 +3061,7 @@ void LLFolderBridge::pasteFromClipboard()  		if (move_is_into_outbox)  		{ -			LLFolderViewItem * outbox_itemp = mRoot->getItemByID(mUUID); +			LLFolderViewItem * outbox_itemp =   mInventoryPanel.get()->getItemByID(mUUID);  			if (outbox_itemp)  			{ @@ -3166,7 +3256,7 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv  	return ((item_array.count() > 0) ? TRUE : FALSE );  } -void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) +void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items, menuentry_vec_t& disabled_items)  {  	LLInventoryModel* model = getInventoryModel();  	llassert(model != NULL); @@ -3177,30 +3267,30 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)  	if (lost_and_found_id == mUUID)  	{  		// This is the lost+found folder. -		mItems.push_back(std::string("Empty Lost And Found")); +		items.push_back(std::string("Empty Lost And Found")); -		mDisabledItems.push_back(std::string("New Folder")); -		mDisabledItems.push_back(std::string("New Script")); -		mDisabledItems.push_back(std::string("New Note")); -		mDisabledItems.push_back(std::string("New Gesture")); -		mDisabledItems.push_back(std::string("New Clothes")); -		mDisabledItems.push_back(std::string("New Body Parts")); +		disabled_items.push_back(std::string("New Folder")); +		disabled_items.push_back(std::string("New Script")); +		disabled_items.push_back(std::string("New Note")); +		disabled_items.push_back(std::string("New Gesture")); +		disabled_items.push_back(std::string("New Clothes")); +		disabled_items.push_back(std::string("New Body Parts"));  	}  	if(trash_id == mUUID)  	{  		// This is the trash. -		mItems.push_back(std::string("Empty Trash")); +		items.push_back(std::string("Empty Trash"));  	}  	else if(isItemInTrash())  	{  		// This is a folder in the trash. -		mItems.clear(); // clear any items that used to exist -		addTrashContextMenuOptions(mItems, mDisabledItems); +		items.clear(); // clear any items that used to exist +		addTrashContextMenuOptions(items, disabled_items);  	}  	else if(isOutboxFolder())  	{ -		addOutboxContextMenuOptions(flags, mItems, mDisabledItems); +		addOutboxContextMenuOptions(flags, items, disabled_items);  	}  	else if(isAgentInventory()) // do not allow creating in library  	{ @@ -3214,40 +3304,40 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)  				// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.  				if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))  				{ -					mItems.push_back(std::string("New Folder")); +					items.push_back(std::string("New Folder"));  				} -				mItems.push_back(std::string("New Script")); -				mItems.push_back(std::string("New Note")); -				mItems.push_back(std::string("New Gesture")); -				mItems.push_back(std::string("New Clothes")); -				mItems.push_back(std::string("New Body Parts")); +				items.push_back(std::string("New Script")); +				items.push_back(std::string("New Note")); +				items.push_back(std::string("New Gesture")); +				items.push_back(std::string("New Clothes")); +				items.push_back(std::string("New Body Parts"));  			}  #if SUPPORT_ENSEMBLES  			// Changing folder types is an unfinished unsupported feature  			// and can lead to unexpected behavior if enabled. -			mItems.push_back(std::string("Change Type")); +			items.push_back(std::string("Change Type"));  			const LLViewerInventoryCategory *cat = getCategory();  			if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))  			{ -				mDisabledItems.push_back(std::string("Change Type")); +				disabled_items.push_back(std::string("Change Type"));  			}  #endif -			getClipboardEntries(false, mItems, mDisabledItems, flags); +			getClipboardEntries(false, items, disabled_items, flags);  		}  		else  		{  			// Want some but not all of the items from getClipboardEntries for outfits.  			if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))  			{ -				mItems.push_back(std::string("Rename")); +				items.push_back(std::string("Rename")); -				addDeleteContextMenuOptions(mItems, mDisabledItems); +				addDeleteContextMenuOptions(items, disabled_items);  				// EXT-4030: disallow deletion of currently worn outfit  				const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();  				if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory()))  				{ -					mDisabledItems.push_back(std::string("Delete")); +					disabled_items.push_back(std::string("Delete"));  				}  			}  		} @@ -3276,20 +3366,44 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)  	// Preemptively disable system folder removal if more than one item selected.  	if ((flags & FIRST_SELECTED_ITEM) == 0)  	{ -		mDisabledItems.push_back(std::string("Delete System Folder")); +		disabled_items.push_back(std::string("Delete System Folder"));  	}  	if (!isOutboxFolder())  	{ -		mItems.push_back(std::string("Share")); +		items.push_back(std::string("Share"));  		if (!canShare())  		{ -			mDisabledItems.push_back(std::string("Share")); +			disabled_items.push_back(std::string("Share")); +		} +	} +	// Add menu items that are dependent on the contents of the folder. +	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID); +	if (category) +	{ +		uuid_vec_t folders; +		folders.push_back(category->getUUID()); + +		sSelf = getHandle(); +		LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders); +		fetch->startFetch(); +		if (fetch->isFinished()) +		{ +			// Do not call execute() or done() here as if the folder is here, there's likely no point drilling down  +			// This saves lots of time as buildContextMenu() is called a lot +			delete fetch; +			buildContextMenuFolderOptions(flags); +		} +		else +		{ +			// it's all on its way - add an observer, and the inventory will call done for us when everything is here. +			inc_busy_count(); +			gInventory.addObserver(fetch);  		}  	}  } -void LLFolderBridge::buildContextMenuFolderOptions(U32 flags) +void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t& items, menuentry_vec_t& disabled_items)  {  	// Build folder specific options back up  	LLInventoryModel* model = getInventoryModel(); @@ -3316,21 +3430,21 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)  		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);  		if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))  		{ -			mItems.push_back(std::string("Calling Card Separator")); -			mItems.push_back(std::string("Conference Chat Folder")); -			mItems.push_back(std::string("IM All Contacts In Folder")); +			items.push_back(std::string("Calling Card Separator")); +			items.push_back(std::string("Conference Chat Folder")); +			items.push_back(std::string("IM All Contacts In Folder"));  		}  	}  	if (!isItemRemovable())  	{ -		mDisabledItems.push_back(std::string("Delete")); +		disabled_items.push_back(std::string("Delete"));  	}  #ifndef LL_RELEASE_FOR_DOWNLOAD  	if (LLFolderType::lookupIsProtectedType(type))  	{ -		mItems.push_back(std::string("Delete System Folder")); +		items.push_back(std::string("Delete System Folder"));  	}  #endif @@ -3345,7 +3459,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)  		checkFolderForContentsOfType(model, is_object) ||  		checkFolderForContentsOfType(model, is_gesture) )  	{ -		mItems.push_back(std::string("Folder Wearables Separator")); +		items.push_back(std::string("Folder Wearables Separator"));  		// Only enable add/replace outfit for non-system folders.  		if (!is_system_folder) @@ -3353,25 +3467,25 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)  			// Adding an outfit onto another (versus replacing) doesn't make sense.  			if (type != LLFolderType::FT_OUTFIT)  			{ -				mItems.push_back(std::string("Add To Outfit")); +				items.push_back(std::string("Add To Outfit"));  			} -			mItems.push_back(std::string("Replace Outfit")); +			items.push_back(std::string("Replace Outfit"));  		}  		if (is_ensemble)  		{ -			mItems.push_back(std::string("Wear As Ensemble")); +			items.push_back(std::string("Wear As Ensemble"));  		} -		mItems.push_back(std::string("Remove From Outfit")); +		items.push_back(std::string("Remove From Outfit"));  		if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))  		{ -			mDisabledItems.push_back(std::string("Remove From Outfit")); +			disabled_items.push_back(std::string("Remove From Outfit"));  		}  		if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))  		{ -			mDisabledItems.push_back(std::string("Replace Outfit")); +			disabled_items.push_back(std::string("Replace Outfit"));  		} -		mItems.push_back(std::string("Outfit Separator")); +		items.push_back(std::string("Outfit Separator"));  	}  } @@ -3380,42 +3494,16 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  {  	sSelf.markDead(); -	mItems.clear(); -	mDisabledItems.clear(); +	menuentry_vec_t items; +	menuentry_vec_t disabled_items;  	lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;  	LLInventoryModel* model = getInventoryModel();  	if(!model) return; -	buildContextMenuBaseOptions(flags); - -	// Add menu items that are dependent on the contents of the folder. -	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID); -	if (category) -	{ -		uuid_vec_t folders; -		folders.push_back(category->getUUID()); - -		sSelf = getHandle(); -		LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders); -		fetch->startFetch(); -		if (fetch->isFinished()) -		{ -			// Do not call execute() or done() here as if the folder is here, there's likely no point drilling down  -			// This saves lots of time as buildContextMenu() is called a lot -			delete fetch; -			buildContextMenuFolderOptions(flags); -		} -		else -		{ -			// it's all on its way - add an observer, and the inventory will call done for us when everything is here. -			inc_busy_count(); -			gInventory.addObserver(fetch); -		} -	} - -	hide_context_entries(menu, mItems, mDisabledItems); +	buildContextMenuOptions(flags, items, disabled_items); +        hide_context_entries(menu, items, disabled_items);  	// Reposition the menu, in case we're adding items to an existing menu.  	menu.needsArrange(); @@ -3516,9 +3604,7 @@ void LLFolderBridge::createNewCategory(void* user_data)  {  	LLFolderBridge* bridge = (LLFolderBridge*)user_data;  	if(!bridge) return; -	LLInventoryPanel* panel = bridge->mInventoryPanel.get(); -	if (!panel) return; -	LLInventoryModel* model = panel->getModel(); +	LLInventoryModel* model = bridge->getInventoryModel();  	if(!model) return;  	LLUUID id;  	id = model->createNewCategory(bridge->getUUID(), @@ -3596,6 +3682,24 @@ void LLFolderBridge::createNewEyes(void* user_data)  	LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_EYES);  } +EInventorySortGroup LLFolderBridge::getSortGroup() const +{ +	LLFolderType::EType preferred_type = getPreferredType(); + +	if (preferred_type == LLFolderType::FT_TRASH) +	{ +		return SG_TRASH_FOLDER; +	} + +	if(LLFolderType::lookupIsProtectedType(preferred_type)) +	{ +		return SG_SYSTEM_FOLDER; +	} + +	return SG_NORMAL_FOLDER; +} + +  // static  void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::EType type)  { @@ -3749,7 +3853,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  	LLInventoryPanel* destination_panel = mInventoryPanel.get();  	if (!destination_panel) return false; -	LLInventoryFilter* filter = destination_panel->getFilter(); +	LLInventoryFilter* filter = getInventoryFilter();  	if (!filter) return false;  	const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); @@ -3866,10 +3970,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  		// passes the filter of the destination panel.  		if (accept && active_panel)  		{ -			LLFolderView* active_folder_view = active_panel->getRootFolder(); -			if (!active_folder_view) return false; - -			LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID()); +			LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());  			if (!fv_item) return false;  			accept = filter->check(fv_item); @@ -3884,6 +3985,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  			}  			// If an item is being dragged between windows, unselect everything in the active window   			// so that we don't follow the selection to its new location (which is very annoying). +                        // RN: a better solution would be to deselect automatically when an   item is moved +			// and then select any item that is dropped only in the panel that it   is dropped in  			if (active_panel && (destination_panel != active_panel))  				{  					active_panel->unSelectAll(); @@ -4089,10 +4192,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  			// passes the filter of the destination panel.  			if (accept && active_panel)  			{ -				LLFolderView* active_folder_view = active_panel->getRootFolder(); -				if (!active_folder_view) return false; - -				LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID()); +				LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());  				if (!fv_item) return false;  				accept = filter->check(fv_item); @@ -4135,10 +4235,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  // static  bool check_category(LLInventoryModel* model,  					const LLUUID& cat_id, -					LLFolderView* active_folder_view, +					LLInventoryPanel* active_panel,  					LLInventoryFilter* filter)  { -	if (!model || !active_folder_view || !filter) +	if (!model || !active_panel || !filter)  		return false;  	if (!filter->checkFolder(cat_id)) @@ -4158,13 +4258,13 @@ bool check_category(LLInventoryModel* model,  		// Empty folder should be checked as any other folder view item.  		// If we are filtering by date the folder should not pass because  		// it doesn't have its own creation date. See LLInvFVBridge::getCreationDate(). -		return check_item(cat_id, active_folder_view, filter); +		return check_item(cat_id, active_panel, filter);  	}  	for (S32 i = 0; i < num_descendent_categories; ++i)  	{  		LLInventoryCategory* category = descendent_categories[i]; -		if(!check_category(model, category->getUUID(), active_folder_view, filter)) +		if(!check_category(model, category->getUUID(), active_panel, filter))  		{  			return false;  		} @@ -4173,7 +4273,7 @@ bool check_category(LLInventoryModel* model,  	for (S32 i = 0; i < num_descendent_items; ++i)  	{  		LLViewerInventoryItem* item = descendent_items[i]; -		if(!check_item(item->getUUID(), active_folder_view, filter)) +		if(!check_item(item->getUUID(), active_panel, filter))  		{  			return false;  		} @@ -4184,12 +4284,12 @@ bool check_category(LLInventoryModel* model,  // static  bool check_item(const LLUUID& item_id, -				LLFolderView* active_folder_view, +				LLInventoryPanel* active_panel,  				LLInventoryFilter* filter)  { -	if (!active_folder_view || !filter) return false; +	if (!active_panel || !filter) return false; -	LLFolderViewItem* fv_item = active_folder_view->getItemByID(item_id); +	LLFolderViewItem* fv_item = active_panel->getItemByID(item_id);  	if (!fv_item) return false;  	return filter->check(fv_item); @@ -4518,7 +4618,7 @@ LLCallingCardBridge::~LLCallingCardBridge()  void LLCallingCardBridge::refreshFolderViewItem()  {  	LLInventoryPanel* panel = mInventoryPanel.get(); -	LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL; +	LLFolderViewItem* itemp = panel ? panel->getItemByID(mUUID) : NULL;  	if (itemp)  	{  		itemp->refresh(); @@ -6011,7 +6111,8 @@ void LLLinkFolderBridge::gotoItem()  	const LLUUID &cat_uuid = getFolderID();  	if (!cat_uuid.isNull())  	{ -		if (LLFolderViewItem *base_folder = mRoot->getItemByID(cat_uuid)) +                LLFolderViewItem *base_folder =   mInventoryPanel.get()->getItemByID(cat_uuid) +		if (base_folder)  		{  			if (LLInventoryModel* model = getInventoryModel())  			{ @@ -6349,9 +6450,8 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_  /************************************************************************/  void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  { -	LLFolderBridge::buildContextMenu(menu, flags); - -	menuentry_vec_t disabled_items, items = getMenuItems(); +	menuentry_vec_t disabled_items, items; +        buildContextMenuOptions(flags, items, disabled_items);  	items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end()); @@ -6400,5 +6500,4 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(  } -  // EOF diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index dc9e88d54d..114144c8a4 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -32,6 +32,7 @@  #include "llfoldervieweventlistener.h"  #include "llinventorymodel.h"  #include "llinventoryobserver.h" +#include "llinventorypanel.h"  #include "llviewercontrol.h"  #include "llwearable.h" @@ -41,7 +42,7 @@ class LLInventoryModel;  class LLMenuGL;  class LLCallingCardObserver;  class LLViewerJointAttachment; - +class LLFolderView;  typedef std::vector<std::string> menuentry_vec_t; @@ -56,7 +57,7 @@ typedef std::vector<std::string> menuentry_vec_t;  // functionality a bit. (except for folders, you can create those  // manually...)  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInvFVBridge : public LLFolderViewEventListener +class LLInvFVBridge : public LLFolderViewModelItemInventory  {  public:  	// This method is a convenience function which creates the correct @@ -83,13 +84,14 @@ public:  	virtual void restoreToWorld() {}  	//-------------------------------------------------------------------- -	// Inherited LLFolderViewEventListener functions +	// Inherited LLFolderViewModelItemInventory functions  	//--------------------------------------------------------------------  	virtual const std::string& getName() const;  	virtual const std::string& getDisplayName() const;  	virtual PermissionMask getPermissionMask() const;  	virtual LLFolderType::EType getPreferredType() const;  	virtual time_t getCreationDate() const; +        virtual void setCreationDate(time_t creation_date_utc);  	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }  	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }  	virtual void openItem() {} @@ -103,8 +105,8 @@ public:  	virtual BOOL isItemInTrash() const;  	virtual BOOL isLink() const;  	//virtual BOOL removeItem() = 0; -	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch); -	virtual void move(LLFolderViewEventListener* new_parent_bridge) {} +	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); +	virtual void move(LLFolderViewModelItem* new_parent_bridge) {}  	virtual BOOL isItemCopyable() const { return FALSE; }  	virtual BOOL copyToClipboard() const;  	virtual BOOL cutToClipboard() const; @@ -115,6 +117,7 @@ public:  	void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items,   							 menuentry_vec_t &disabled_items, U32 flags);  	virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +        virtual LLToolDragAndDrop::ESource getDragSource() const;  	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;  	virtual BOOL dragOrDrop(MASK mask, BOOL drop,  							EDragAndDropType cargo_type, @@ -122,6 +125,7 @@ public:  							std::string& tooltip_msg) { return FALSE; }  	virtual LLInventoryType::EType getInventoryType() const { return mInvType; }  	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; } +        EInventorySortGroup getSortGroup()  const { return SG_ITEM; }  	//--------------------------------------------------------------------  	// Convenience functions for adding various common menu options. @@ -140,14 +144,15 @@ protected:  	LLInventoryObject* getInventoryObject() const;  	LLInventoryModel* getInventoryModel() const; +	LLInventoryFilter* getInventoryFilter() const;  	BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?  	BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory?  	BOOL isAgentInventory() const; // false if lost or in the inventory library -	BOOL isCOFFolder() const; // true if COF or descendent of -	BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox -	BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox +	BOOL isCOFFolder() const;       // true if COF or descendant of +	BOOL isInboxFolder() const;     // true if COF or descendant of   marketplace inbox +	BOOL isOutboxFolder() const;    // true if COF or descendant of   marketplace outbox  	BOOL isOutboxFolderDirectParent() const;  	const LLUUID getOutboxFolder() const; @@ -160,13 +165,14 @@ protected:  									 LLViewerInventoryCategory* item,  									 const LLUUID& new_parent,  									 BOOL restamp); -	void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch); +	void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch);  protected:  	LLHandle<LLInventoryPanel> mInventoryPanel;  	LLFolderView* mRoot;  	const LLUUID mUUID;	// item id  	LLInventoryType::EType mInvType; -	BOOL mIsLink; +	bool						mIsLink; +	LLTimer						mTimeSinceRequestStart;  	void purgeItem(LLInventoryModel *model, const LLUUID &uuid);  }; @@ -232,15 +238,18 @@ class LLFolderBridge : public LLInvFVBridge  public:  	LLFolderBridge(LLInventoryPanel* inventory,   				   LLFolderView* root, -				   const LLUUID& uuid) : -		LLInvFVBridge(inventory, root, uuid), +				   const LLUUID& uuid)  +        :       LLInvFVBridge(inventory, root, uuid),  		mCallingCards(FALSE), -		mWearables(FALSE) +		mWearables(FALSE), +		mIsLoading(false)  	{}  	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);  	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg); +        const std::string& getDisplayName() const; +  	virtual void performAction(LLInventoryModel* model, std::string action);  	virtual void openItem();  	virtual void closeItem(); @@ -275,14 +284,17 @@ public:  	virtual BOOL isClipboardPasteable() const;  	virtual BOOL isClipboardPasteableAsLink() const; +	EInventorySortGroup getSortGroup()  const; +	virtual void update(); +  	static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);  	LLViewerInventoryCategory* getCategory() const;  	LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }  protected: -	void buildContextMenuBaseOptions(U32 flags); -	void buildContextMenuFolderOptions(U32 flags); +	void buildContextMenuOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items); +	void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items);  	//--------------------------------------------------------------------  	// Menu callbacks @@ -308,8 +320,6 @@ protected:  	void modifyOutfit(BOOL append);  	void determineFolderType(); -	menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items -  	void dropToFavorites(LLInventoryItem* inv_item);  	void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit); @@ -321,10 +331,11 @@ public:  	static void staticFolderOptionsMenu();  private: -	BOOL				mCallingCards; -	BOOL				mWearables; -	menuentry_vec_t		mItems; -	menuentry_vec_t		mDisabledItems; +	bool							mCallingCards; +	bool							mWearables; +	bool							mIsLoading; +	LLTimer							mTimeSinceRequestStart; +	std::string						mDisplayName;  	LLRootHandle<LLFolderBridge> mHandle;  }; diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 4d0af94f9f..5de3f0cb4e 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -44,39 +44,39 @@  LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard"); -LLInventoryFilter::FilterOps::FilterOps() : -	mFilterObjectTypes(0xffffffffffffffffULL), -	mFilterCategoryTypes(0xffffffffffffffffULL), -	mFilterWearableTypes(0xffffffffffffffffULL), -	mMinDate(time_min()), -	mMaxDate(time_max()), -	mHoursAgo(0), -	mShowFolderState(SHOW_NON_EMPTY_FOLDERS), -	mPermissions(PERM_NONE), -	mFilterTypes(FILTERTYPE_OBJECT), -	mFilterUUID(LLUUID::null), -	mFilterLinks(FILTERLINK_INCLUDE_LINKS) +LLInventoryFilter::FilterOps::FilterOps(const Params& p) +:	mFilterObjectTypes(p.object_types), +	mFilterCategoryTypes(p.category_types), +	mFilterWearableTypes(p.wearable_types), +	mMinDate(p.date_range.min_date), +	mMaxDate(p.date_range.max_date), +	mHoursAgo(p.hours_ago), +	mShowFolderState(p.show_folder_state), +	mPermissions(p.permissions), +	mFilterTypes(p.types), +	mFilterUUID(p.uuid), +	mFilterLinks(p.links)  {  }  ///----------------------------------------------------------------------------  /// Class LLInventoryFilter  ///---------------------------------------------------------------------------- -LLInventoryFilter::LLInventoryFilter(const std::string& name) +LLInventoryFilter::LLInventoryFilter(const std::string& name, const   Params& p)  :	mName(name),  	mModified(FALSE),  	mNeedTextRebuild(TRUE), -	mEmptyLookupMessage("InventoryNoMatchingItems") +	mEmptyLookupMessage("InventoryNoMatchingItems"), +        mFilterOps(p.filter_ops)  { -	mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately +	mOrder = p.sort_order; // This gets overridden by a pref immediately -	mSubStringMatchOffset = 0; -	mFilterSubString.clear(); -	mFilterGeneration = 0; -	mMustPassGeneration = S32_MAX; -	mMinRequiredGeneration = 0; +	mFilterSubString(p.substring); +	mLastSuccessGeneration = 0; +	mLastFailGeneration = S32_MAX; +	getFirstSuccessGeneration = 0;  	mFilterCount = 0; -	mNextFilterGeneration = mFilterGeneration + 1; +	mNextFilterGeneration = mLastSuccessGeneration + 1;  	mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");  	mFilterBehavior = FILTER_NONE; @@ -102,7 +102,7 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)  		return passed_clipboard;  	} -	mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; +	std::string::size_type string_offset = mFilterSubString.size() ?   item->getSearchableLabel().find(mFilterSubString) : std::string::npos;  	const BOOL passed_filtertype = checkAgainstFilterType(item);  	const BOOL passed_permissions = checkAgainstPermissions(item); @@ -111,22 +111,22 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)  						 passed_permissions &&  						 passed_filterlink &&  						 passed_clipboard && -						 (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)); +						 (mFilterSubString.size() == 0 || string_offset !=  std::string::npos));  	return passed;  }  bool LLInventoryFilter::check(const LLInventoryItem* item)  { -	mSubStringMatchOffset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos; +	std::string::size_type string_offset = mFilterSubString.size() ?   item->getName().find(mFilterSubString) : std::string::npos;  	const bool passed_filtertype = checkAgainstFilterType(item);  	const bool passed_permissions = checkAgainstPermissions(item);  	const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID()); -	const bool passed = (passed_filtertype && -						 passed_permissions && -						 passed_clipboard && -						 (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)); +	const bool passed = (passed_filtertype  +						&& passed_permissions +						&& passed_clipboard  +						&&	(mFilterSubString.size() == 0 || string_offset !=  std::string::npos));  	return passed;  } @@ -140,7 +140,7 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const  		return false;  	} -	const LLFolderViewEventListener* listener = folder->getListener(); +	const LLFolderViewModelItemInventory* listener = folder->getListener();  	if (!listener)  	{  		llwarns << "Folder view event listener not found." << llendl; @@ -163,7 +163,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const  	{  		return passed_clipboard;  	} - +	  	if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)  	{  		// Can only filter categories for items in your inventory @@ -181,7 +181,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const  BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const  { -	const LLFolderViewEventListener* listener = item->getListener(); +	const LLFolderViewModelItemInventory* listener = item->getListener();  	if (!listener) return FALSE;  	LLInventoryType::EType object_type = listener->getInventoryType(); @@ -268,7 +268,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  			}  		}  	} - +	  	return TRUE;  } @@ -349,7 +349,7 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const  BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const  { -	const LLFolderViewEventListener* listener = item->getListener(); +	const LLFolderViewModelItemInventory* listener = item->getListener();  	if (!listener) return FALSE;  	PermissionMask perm = listener->getPermissionMask(); @@ -377,7 +377,7 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con  BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const  { -	const LLFolderViewEventListener* listener = item->getListener(); +	const LLFolderViewModelItemInventory* listener = item->getListener();  	if (!listener) return TRUE;  	const LLUUID object_id = listener->getUUID(); @@ -397,9 +397,9 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const  	return mFilterSubString;  } -std::string::size_type LLInventoryFilter::getStringMatchOffset() const +std::string::size_type   LLInventoryFilter::getStringMatchOffset(LLFolderViewItem* item) const  { -	return mSubStringMatchOffset; +	return mFilterSubString.size() ? item->getName().find(mFilterSubString)   : std::string::npos;  }  BOOL LLInventoryFilter::isDefault() const @@ -422,7 +422,7 @@ BOOL LLInventoryFilter::isNotDefault() const  	not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);  	not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);  	not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo); -	 +  	return not_default;  } @@ -746,7 +746,7 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)  {  	mModified = TRUE;  	mNeedTextRebuild = TRUE; -	mFilterGeneration = mNextFilterGeneration++; +	mLastSuccessGeneration = mNextFilterGeneration++;  	if (mFilterBehavior == FILTER_NONE)  	{ @@ -765,17 +765,17 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)  		switch(mFilterBehavior)  		{  			case FILTER_RESTART: -				mMustPassGeneration = mFilterGeneration; -				mMinRequiredGeneration = mFilterGeneration; +				mLastFailGeneration = mLastSuccessGeneration; +				mFirstSuccessGeneration = mLastSuccessGeneration;  				break;  			case FILTER_LESS_RESTRICTIVE: -				mMustPassGeneration = mFilterGeneration; +				mLastFailGeneration = mLastSuccessGeneration;  				break;  			case FILTER_MORE_RESTRICTIVE: -				mMinRequiredGeneration = mFilterGeneration; +				mFirstSuccessGeneration = mLastSuccessGeneration;  				// must have passed either current filter generation (meaningless, as it hasn't been run yet)  				// or some older generation, so keep the value -				mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration); +				mLastFailGeneration = llmin(mLastFailGeneration,  mLastSuccessGeneration);  				break;  			default:  				llerrs << "Bad filter behavior specified" << llendl; @@ -991,60 +991,34 @@ const std::string& LLInventoryFilter::getFilterText()  	return mFilterText;  } -void LLInventoryFilter::toLLSD(LLSD& data) const -{ -	data["filter_types"] = (LLSD::Integer)getFilterObjectTypes(); -	data["min_date"] = (LLSD::Integer)getMinDate(); -	data["max_date"] = (LLSD::Integer)getMaxDate(); -	data["hours_ago"] = (LLSD::Integer)getHoursAgo(); -	data["show_folder_state"] = (LLSD::Integer)getShowFolderState(); -	data["permissions"] = (LLSD::Integer)getFilterPermissions(); -	data["substring"] = (LLSD::String)getFilterSubString(); -	data["sort_order"] = (LLSD::Integer)getSortOrder(); -	data["since_logoff"] = (LLSD::Boolean)isSinceLogoff(); -} - -void LLInventoryFilter::fromLLSD(LLSD& data) -{ -	if(data.has("filter_types")) +void LLInventoryFilter::toParams(Params& params) const  	{ -		setFilterObjectTypes((U64)data["filter_types"].asInteger()); +	params.filter_ops.types = getFilterObjectTypes(); +	params.filter_ops.date_range.min_date = getMinDate(); +	params.filter_ops.date_range.max_date = getMaxDate(); +	params.filter_ops.hours_ago = getHoursAgo(); +	params.filter_ops.show_folder_state = getShowFolderState(); +	params.filter_ops.permissions = getFilterPermissions(); +	params.substring = getFilterSubString(); +	params.sort_order = getSortOrder(); +	params.since_logoff = isSinceLogoff();  	} -	if(data.has("min_date") && data.has("max_date")) +void LLInventoryFilter::fromParams(const Params& data)  	{ -		setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger()); -	} - -	if(data.has("hours_ago")) +	if (!params.validateBlock())  	{ -		setHoursAgo((U32)data["hours_ago"].asInteger()); +		return;  	} -	if(data.has("show_folder_state")) -	{ -		setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); -	} - -	if(data.has("permissions")) -	{ -		setFilterPermissions((PermissionMask)data["permissions"].asInteger()); -	} - -	if(data.has("substring")) -	{ -		setFilterSubString(std::string(data["substring"].asString())); -	} - -	if(data.has("sort_order")) -	{ -		setSortOrder((U32)data["sort_order"].asInteger()); -	} - -	if(data.has("since_logoff")) -	{ -		setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean()); -	} +	setFilterObjectTypes(params.filter_ops.types); +	setDateRange(params.filter_ops.date_range.min_date,   params.filter_ops.date_range.max_date); +	setHoursAgo(params.filter_ops.hours_ago); +	setShowFolderState(params.filter_ops.show_folder_state); +	setFilterPermissions(params.filter_ops.permissions); +	setFilterSubString(params.substring); +	setSortOrder(params.sort_order); +	setDateRangeLastLogoff(params.since_logoff);  }  U64 LLInventoryFilter::getFilterObjectTypes() const @@ -1113,15 +1087,15 @@ void LLInventoryFilter::decrementFilterCount()  S32 LLInventoryFilter::getCurrentGeneration() const   {  -	return mFilterGeneration;  +	return mLastSuccessGeneration;  } -S32 LLInventoryFilter::getMinRequiredGeneration() const  +S32 LLInventoryFilter::getFirstSuccessGeneration() const  {  -	return mMinRequiredGeneration;  +	return mFirstSuccessGeneration;   } -S32 LLInventoryFilter::getMustPassGeneration() const  +S32 LLInventoryFilter::getFirstRequiredGeneration() const  {  -	return mMustPassGeneration;  +	return mLastFailGeneration;   }  void LLInventoryFilter::setEmptyLookupMessage(const std::string& message) @@ -1129,9 +1103,13 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)  	mEmptyLookupMessage = message;  } +RN: turn this into a param  const std::string& LLInventoryFilter::getEmptyLookupMessage() const  { -	return mEmptyLookupMessage; +	LLStringUtil::format_map_t args; +	args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); + +	return LLTrans::getString(mEmptyLookupMessage, args);  } @@ -1141,3 +1119,26 @@ bool LLInventoryFilter::areDateLimitsSet()  			|| mFilterOps.mMaxDate != time_max()  			|| mFilterOps.mHoursAgo != 0;  } + +LLInventoryFilter& LLInventoryFilter::operator=( const  LLInventoryFilter&  other ) +{ +	fromParams(other.toParams()); +} + + +bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool   emit_errors /*= true*/ ) +{ +	bool valid = LLInitParam::Block<DateRange>::validateBlock(emit_errors); +	if (valid) +	{ +		if (max_date() < min_date()) +		{ +			if (emit_errors) +			{ +				llwarns << "max_date should be greater or equal to min_date" <<   llendl; +			} +			valid = false; +		} +	} +	return valid; +} diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 9e600c036f..4434008958 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -34,7 +34,7 @@ class LLFolderViewItem;  class LLFolderViewFolder;  class LLInventoryItem; -class LLInventoryFilter +class LLInventoryFilter : public LLFolderViewFilter  {  public:  	enum EFolderShow @@ -59,7 +59,7 @@ public:  		FILTERTYPE_UUID	= 0x1 << 2,		// find the object with UUID and any links to it  		FILTERTYPE_DATE = 0x1 << 3,		// search by date range  		FILTERTYPE_WEARABLE = 0x1 << 4,	// search by wearable type -		FILTERTYPE_EMPTYFOLDERS = 0x1 << 5	// pass if folder is not a system folder to be hidden if empty +		FILTERTYPE_EMPTYFOLDERS = 0x1 << 5		// pass if folder is not a system   folder to be hidden if  	};  	enum EFilterLink @@ -77,7 +77,81 @@ public:  		SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2	// Force system folders to be on top  	}; -	LLInventoryFilter(const std::string& name); +	struct FilterOps +	{ +		struct DateRange : public LLInitParam::Block<DateRange> +		{ +			Optional<time_t> min_date; +			Optional<time_t> max_date; + +			DateRange() +			:	min_date("min_date", time_min()), +				max_date("max_date", time_max()) +			{} + +			bool validateBlock(bool emit_errors = true); +		}; + +		struct Params : public LLInitParam::Block<Params> +		{ +			Optional<U32>				types; +			Optional<U64>				object_types, +										wearable_types, +										category_types; +			Optional<EFilterLink>		links; +			Optional<LLUUID>			uuid; +			Optional<DateRange>			date_range; +			Optional<S32>				hours_ago; +			Optional<EFolderShow>		show_folder_state; +			Optional<PermissionMask>	permissions; + +			Params() +			:	types("filter_types", FILTERTYPE_OBJECT), +				object_types("object_types", 0xffffFFFFffffFFFFULL), +				wearable_types("wearable_types", 0xffffFFFFffffFFFFULL), +				category_types("category_types", 0xffffFFFFffffFFFFULL), +				links("links", FILTERLINK_INCLUDE_LINKS), +				uuid("uuid"), +				date_range("date_range"), +				hours_ago("hours_ago", 0), +				show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS), +				permissions("permissions", PERM_NONE) +			{} +		}; + +		FilterOps(const Params& = Params()); + +		U32 			mFilterTypes; + +		U64				mFilterObjectTypes;   // For _OBJECT +		U64				mFilterWearableTypes; +		U64				mFilterCategoryTypes; // For _CATEGORY +		LLUUID      	mFilterUUID; 		  // for UUID + +		time_t			mMinDate; +		time_t			mMaxDate; +		U32				mHoursAgo; +		EFolderShow		mShowFolderState; +		PermissionMask	mPermissions; +		U64				mFilterLinks; +	}; +							 +	struct Params : public LLInitParam::Block<Params> +	{ +		Optional<FilterOps::Params>	filter_ops; +		Optional<std::string>		substring; +		Optional<U32>				sort_order; +		Optional<bool>				since_logoff; + +		Params() +		:	filter_ops(""), +			substring("substring"), +			sort_order("sort_order"), +			since_logoff("since_logoff") +		{} +	}; +									 +	LLInventoryFilter(const std::string& name, const Params& p);  	virtual ~LLInventoryFilter();  	// +-------------------------------------------------------------------+ @@ -86,7 +160,7 @@ public:  	void 				setFilterObjectTypes(U64 types);  	U64 				getFilterObjectTypes() const;  	U64					getFilterCategoryTypes() const; -	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const; +	bool 				isFilterObjectTypesWith(LLInventoryType::EType t) const;  	void 				setFilterCategoryTypes(U64 types);  	void 				setFilterUUID(const LLUUID &object_id);  	void				setFilterWearableTypes(U64 types); @@ -96,7 +170,7 @@ public:  	void 				setFilterSubString(const std::string& string);  	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;  	const std::string& 	getFilterSubStringOrig() const { return mFilterSubStringOrig; }  -	BOOL 				hasFilterString() const; +	bool 				hasFilterString() const;  	void 				setFilterPermissions(PermissionMask perms);  	PermissionMask 		getFilterPermissions() const; @@ -115,19 +189,20 @@ public:  	// +-------------------------------------------------------------------+  	// + Execution And Results  	// +-------------------------------------------------------------------+ -	BOOL 				check(const LLFolderViewItem* item); +	bool 				check(const LLFolderViewItem* item);  	bool				check(const LLInventoryItem* item);  	bool				checkFolder(const LLFolderViewFolder* folder) const;  	bool				checkFolder(const LLUUID& folder_id) const; -	BOOL 				checkAgainstFilterType(const LLFolderViewItem* item) const; +	bool 				checkAgainstFilterType(const LLFolderViewItem* item) const;  	bool 				checkAgainstFilterType(const LLInventoryItem* item) const; -	BOOL 				checkAgainstPermissions(const LLFolderViewItem* item) const; +	bool 				checkAgainstPermissions(const LLFolderViewItem* item) const;  	bool 				checkAgainstPermissions(const LLInventoryItem* item) const; -	BOOL 				checkAgainstFilterLinks(const LLFolderViewItem* item) const; +	bool 				checkAgainstFilterLinks(const LLFolderViewItem* item) const;  	bool				checkAgainstClipboard(const LLUUID& object_id) const;  	std::string::size_type getStringMatchOffset() const; +	std::string::size_type getStringMatchOffset(LLFolderViewItem* item)   const;  	// +-------------------------------------------------------------------+  	// + Presentation  	// +-------------------------------------------------------------------+ @@ -143,10 +218,10 @@ public:  	// +-------------------------------------------------------------------+  	// + Status  	// +-------------------------------------------------------------------+ -	BOOL 				isActive() const; -	BOOL 				isModified() const; -	BOOL 				isModifiedAndClear(); -	BOOL 				isSinceLogoff() const; +	bool 				isActive() const; +	bool 				isModified() const; +	bool 				isModifiedAndClear(); +	bool 				isSinceLogoff() const;  	void 				clearModified();  	const std::string& 	getName() const;  	const std::string& 	getFilterText(); @@ -163,8 +238,8 @@ public:  	// +-------------------------------------------------------------------+  	// + Default  	// +-------------------------------------------------------------------+ -	BOOL 				isDefault() const; -	BOOL 				isNotDefault() const; +	bool 				isDefault() const; +	bool 				isNotDefault() const;  	void 				markDefault();  	void 				resetDefault(); @@ -172,14 +247,17 @@ public:  	// + Generation  	// +-------------------------------------------------------------------+  	S32 				getCurrentGeneration() const; -	S32 				getMinRequiredGeneration() const; -	S32 				getMustPassGeneration() const; +	S32 				getFirstSuccessGeneration() const; +	S32 				getFirstRequiredGeneration() const; +  	// +-------------------------------------------------------------------+  	// + Conversion  	// +-------------------------------------------------------------------+ -	void 				toLLSD(LLSD& data) const; -	void 				fromLLSD(LLSD& data); +	void 				toParams(Params& params) const; +	void 				fromParams(const Params& p); + +	LLInventoryFilter& operator =(const LLInventoryFilter& other);  private:  	bool				areDateLimitsSet(); @@ -205,6 +283,7 @@ private:  	U32						mOrder;  	U32 					mLastLogoff; +	std::string::size_type	mSubStringMatchOffset;  	FilterOps				mFilterOps;  	FilterOps				mDefaultFilterOps; @@ -213,9 +292,9 @@ private:  	std::string				mFilterSubStringOrig;  	const std::string		mName; -	S32						mFilterGeneration; -	S32						mMustPassGeneration; -	S32						mMinRequiredGeneration; +	S32						mLastSuccessGeneration; +	S32						mLastFailGeneration; +	S32						mFirstSuccessGeneration;  	S32						mNextFilterGeneration;  	S32						mFilterCount; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 71dd963f28..d60b819da8 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -38,6 +38,7 @@  #include "llfloaterreg.h"  #include "llfloatersidepanelcontainer.h"  #include "llfolderview.h" +#include "llfolderviewitem.h"  #include "llimfloater.h"  #include "llimview.h"  #include "llinventorybridge.h" @@ -55,6 +56,62 @@ const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("Recent  const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");  static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER; +// +// class LLFolderViewModelInventory +// +void LLFolderViewModelInventory::requestSort(class LLFolderViewFolder*   folder) +{ +	base_t::requestSort(folder); +	if (getSorter().isByDate()) +	{ +		// sort by date potentially affects parent folders which use a date +		// derived from newest item in them +		requestSort(folder->getParentFolder()); +	} +} + +static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort"); + +void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) +{ +	LLFastTimer _(FTM_INVENTORY_SORT); + +	if (!needsSort(folder)) return; + +	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getListener()); +	if (modelp->getUUID().isNull()) return; + +	for (std::list<LLFolderViewFolder*>::iterator it =   folder->getFoldersBegin(), end_it = folder->getFoldersEnd(); +		it != end_it; +		++it) +	{ +		LLFolderViewFolder* child_folderp = *it; +		sort(child_folderp); + +		if (child_folderp->getFoldersCount() > 0) +		{ +			time_t most_recent_folder_time = +				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getFoldersBegin()->getListener())->getCreationDate(); +			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getListener()); +			if (most_recent_folder_time > modelp->getCreationDate()) +			{ +				modelp->setCreationDate(most_recent_folder_time); +			} +		} +		if (child_folderp->getItemsCount() > 0)			 +		{ +			time_t most_recent_item_time = +				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getItemsBegin()->getListener())->getCreationDate(); + +			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getListener()); +			if (most_recent_item_time > modelp->getCreationDate()) +			{ +				modelp->setCreationDate(most_recent_item_time); +			} +		} +	} +	base_t::sort(folder); +}  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLInventoryPanelObserver @@ -134,7 +191,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mAllowMultiSelect(p.allow_multi_select),  	mShowItemLinkOverlays(p.show_item_link_overlays),  	mShowEmptyMessage(p.show_empty_message), -	mShowLoadStatus(p.show_load_status),  	mViewsInitialized(false),  	mInvFVBridgeBuilder(NULL)  { @@ -258,14 +314,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  LLInventoryPanel::~LLInventoryPanel()  { -	if (mFolderRoot) -	{ -		U32 sort_order = mFolderRoot->getSortOrder(); +        U32 sort_order = getViewModel()->getSortOrder();  		if (mSortOrderSetting != INHERIT_SORT_ORDER)  		{  			gSavedSettings.setU32(mSortOrderSetting, sort_order);  		} -	}  	gIdleCallbacks.deleteFunction(onIdle, this); @@ -281,7 +334,7 @@ LLInventoryPanel::~LLInventoryPanel()  void LLInventoryPanel::draw()  {  	// Select the desired item (in case it wasn't loaded when the selection was requested) -	mFolderRoot->updateSelection(); +	updateSelection();  	// Nudge the filter if the clipboard state changed  	if (mClipboardState != LLClipboard::instance().getGeneration()) @@ -295,20 +348,12 @@ void LLInventoryPanel::draw()  LLInventoryFilter* LLInventoryPanel::getFilter()  { -	if (mFolderRoot)  -	{ -		return mFolderRoot->getFilter(); -	} -	return NULL; +	return getViewModel()->getFilter();  }  const LLInventoryFilter* LLInventoryPanel::getFilter() const  { -	if (mFolderRoot) -	{ -		return mFolderRoot->getFilter(); -	} -	return NULL; +	return getViewModel()->getFilter();  }  void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type) @@ -321,12 +366,12 @@ void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType  U32 LLInventoryPanel::getFilterObjectTypes() const   {  -	return mFolderRoot->getFilterObjectTypes();  +	return getFilter()->getFilterObjectTypes();  }  U32 LLInventoryPanel::getFilterPermMask() const   {  -	return mFolderRoot->getFilterPermissions();  +	return getFilter()->getFilterPermissions();  } @@ -347,16 +392,17 @@ void LLInventoryPanel::setFilterSubString(const std::string& string)  const std::string LLInventoryPanel::getFilterSubString()   {  -	return mFolderRoot->getFilterSubString();  +	return getFilter()->getFilterSubString();  }  void LLInventoryPanel::setSortOrder(U32 order)  { +        LLInventorySort sorter(order);  	getFilter()->setSortOrder(order); -	if (getFilter()->isModified()) +	if (order != getViewModel()->getSortOrder())  	{ -		mFolderRoot->setSortOrder(order); +		getViewModel()->setSorter(LLInventorySort(order));  		// try to keep selection onscreen, even if it wasn't to start with  		mFolderRoot->scrollToShowSelection();  	} @@ -364,12 +410,7 @@ void LLInventoryPanel::setSortOrder(U32 order)  U32 LLInventoryPanel::getSortOrder() const   {  -	return mFolderRoot->getSortOrder();  -} - -void LLInventoryPanel::requestSort() -{ -	mFolderRoot->requestSort(); +	return getViewModel()->getSortOrder();  }  void LLInventoryPanel::setSinceLogoff(BOOL sl) @@ -418,7 +459,7 @@ void LLInventoryPanel::modelChanged(U32 mask)  	{  		const LLUUID& item_id = (*items_iter);  		const LLInventoryObject* model_item = model->getObject(item_id); -		LLFolderViewItem* view_item = mFolderRoot->getItemByID(item_id); +		LLFolderViewItem* view_item = getItemByID(item_id);  		// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item  		// to folder is the fast way to get a folder without searching through folders tree. @@ -452,6 +493,7 @@ void LLInventoryPanel::modelChanged(U32 mask)  			if (model_item && view_item)  			{  				view_item->destroyView(); +                                removeItemID(view_item->getListener()->getUUID());  			}  			view_item = buildNewViews(item_id);  			view_folder = dynamic_cast<LLFolderViewFolder *>(view_item); @@ -510,9 +552,9 @@ void LLInventoryPanel::modelChanged(U32 mask)  			else if (model_item && view_item)  			{  				// Don't process the item if it is the root -				if (view_item->getRoot() != view_item) +				if (view_item->getParentFolder())  				{ -					LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID()); +					LLFolderViewFolder* new_parent =   (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());  					// Item has been moved.  					if (view_item->getParentFolder() != new_parent)  					{ @@ -520,13 +562,15 @@ void LLInventoryPanel::modelChanged(U32 mask)  						{  							// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.  							view_item->getParentFolder()->extractItem(view_item); -							view_item->addToFolder(new_parent, mFolderRoot); +							view_item->addToFolder(new_parent); +							addItemID(view_item->getListener()->getUUID(), view_item);  						}  						else   						{  							// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that   							// doesn't include trash).  Just remove the item's UI.  							view_item->destroyView(); +                                                        removeItemID(view_item->getListener()->getUUID());  						}  					}  				} @@ -539,6 +583,7 @@ void LLInventoryPanel::modelChanged(U32 mask)  			{  				// Remove the item's UI.  				view_item->destroyView(); +                                removeItemID(view_item->getListener()->getUUID());  			}  		}  	} @@ -587,14 +632,14 @@ void LLInventoryPanel::initializeViews()  	if (gAgent.isFirstLogin())  	{  		// Auto open the user's library -		LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID()); +		LLFolderViewFolder* lib_folder =   getFolderByID(gInventory.getLibraryRootFolderID());  		if (lib_folder)  		{  			lib_folder->setOpen(TRUE);  		}  		// Auto close the user's my inventory folder -		LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID()); +		LLFolderViewFolder* my_inv_folder =   getFolderByID(gInventory.getRootFolderID());  		if (my_inv_folder)  		{  			my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); @@ -605,10 +650,11 @@ void LLInventoryPanel::initializeViews()  LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)  {  	// Destroy the old view for this ID so we can rebuild it. -	LLFolderViewItem* old_view = mFolderRoot->getItemByID(id); +	LLFolderViewItem* old_view = getItemByID(id);  	if (old_view)  	{  		old_view->destroyView(); +                removeItemID(old_view->getListener()->getUUID());  	}  	return buildNewViews(id); @@ -632,7 +678,6 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u  	p.use_label_suffix = useLabelSuffix;  	p.allow_multiselect = mAllowMultiSelect;  	p.show_empty_message = mShowEmptyMessage; -	p.show_load_status = mShowLoadStatus;  	return LLUICtrlFactory::create<LLFolderView>(p);  } @@ -693,7 +738,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)   	else if (objectp)   	{   		const LLUUID &parent_id = objectp->getParentUUID(); - 		parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); + 		parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);    		if (parent_folder)    		{ @@ -717,12 +762,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)    																				objectp->getUUID());    				if (new_listener)    				{ -					LLFolderViewFolder* folderp = createFolderViewFolder(new_listener); -					if (folderp) -					{ -						folderp->setItemSortOrder(mFolderRoot->getSortOrder()); -					} -  					itemp = folderp; +					itemp = createFolderViewFolder(new_listener);    				}    			}    			else @@ -745,7 +785,8 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)    			if (itemp)    			{ -  				itemp->addToFolder(parent_folder, mFolderRoot); +  				itemp->addToFolder(parent_folder); +				addItemID(itemp->getListener()->getUUID(), itemp);     			}  		}  	} @@ -917,7 +958,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc  	{  		return;  	} -	mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus); +	setSelectionByID(obj_id, take_keyboard_focus);  }  void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)  @@ -930,7 +971,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::  void LLInventoryPanel::clearSelection()  { -	mFolderRoot->clearSelection(); +	mSelectThisID.setNull();  }  void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action) @@ -966,12 +1007,12 @@ void LLInventoryPanel::doToSelected(const LLSD& userdata)  void LLInventoryPanel::doCreate(const LLSD& userdata)  { -	menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata); +	menu_create_inventory_item(this, LLFolderBridge::sSelf.get(), userdata);  }  bool LLInventoryPanel::beginIMSession()  { -	std::set<LLUUID> selected_items = mFolderRoot->getSelectionList(); +	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList();  	std::string name;  	static int session_num = 1; @@ -979,12 +1020,11 @@ bool LLInventoryPanel::beginIMSession()  	LLDynamicArray<LLUUID> members;  	EInstantMessage type = IM_SESSION_CONFERENCE_START; -	std::set<LLUUID>::const_iterator iter; +	std::set<LLFolderViewItem*>::const_iterator iter;  	for (iter = selected_items.begin(); iter != selected_items.end(); iter++)  	{ -		LLUUID item = *iter; -		LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item); +		LLFolderViewItem* folder_item = (*iter);  		if(folder_item)   		{ @@ -1026,8 +1066,6 @@ bool LLInventoryPanel::beginIMSession()  			}  			else  			{ -				LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item); -				if(!folder_item) return true;  				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();  				if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) @@ -1069,13 +1107,13 @@ bool LLInventoryPanel::beginIMSession()  bool LLInventoryPanel::attachObject(const LLSD& userdata)  {  	// Copy selected item UUIDs to a vector. -	std::set<LLUUID> selected_items = mFolderRoot->getSelectionList(); +	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList();  	uuid_vec_t items; -	for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin();  +	for (std::set<LLFolderViewItem*>::const_iterator set_iter =   selected_items.begin();  		 set_iter != selected_items.end();   		 ++set_iter)  	{ -		items.push_back(*set_iter); +		items.push_back((*set_iter)->getListener()->getUUID());  	}  	// Attach selected items. @@ -1222,6 +1260,84 @@ BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) co  	return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));  } +void LLInventoryPanel::addItemID( const LLUUID& id, LLFolderViewItem*   itemp ) +{ +	mItemMap[id] = itemp; +} + +void LLInventoryPanel::removeItemID(const LLUUID& id) +{ +	LLInventoryModel::cat_array_t categories; +	LLInventoryModel::item_array_t items; +	gInventory.collectDescendents(id, categories, items, TRUE); + +	mItemMap.erase(id); + +	for (LLInventoryModel::cat_array_t::iterator it = categories.begin(),    end_it = categories.end(); +		it != end_it; +		++it) +	{ +		mItemMap.erase((*it)->getUUID()); +	} + +	for (LLInventoryModel::item_array_t::iterator it = items.begin(),   end_it  = items.end(); +		it != end_it; +		++it) +	{ +		mItemMap.erase((*it)->getUUID()); +	} +} + +LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID"); +LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id) +{ +	LLFastTimer _(FTM_GET_ITEM_BY_ID); +	if (id == mFolderRoot->getListener()->getUUID()) +	{ +		return mFolderRoot; +	} + +	std::map<LLUUID, LLFolderViewItem*>::iterator map_it; +	map_it = mItemMap.find(id); +	if (map_it != mItemMap.end()) +	{ +		return map_it->second; +	} + +	return NULL; +} + +LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id) +{ +	LLFolderViewItem* item = getItemByID(id); +	return dynamic_cast<LLFolderViewFolder*>(item); +} + + +void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL    take_keyboard_focus ) +{ +	LLFolderViewItem* itemp = getItemByID(obj_id); +	if(itemp && itemp->getListener()) +	{ +		itemp->arrangeAndSet(TRUE, take_keyboard_focus); +		mSelectThisID.setNull(); +		return; +	} +	else +	{ +		// save the desired item to be selected later (if/when ready) +		mSelectThisID = obj_id; +	} +} + +void LLInventoryPanel::updateSelection() +{ +	if (mSelectThisID.notNull()) +	{ +		setSelectionByID(mSelectThisID, false); +	} +} +  /************************************************************************/  /* Recent Inventory Panel related class                                 */ diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 6db59afb9b..7cf82bf268 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -30,6 +30,7 @@  #include "llassetstorage.h"  #include "lldarray.h" +#include "llfolderviewitem.h"  #include "llfloater.h"  #include "llinventory.h"  #include "llinventoryfilter.h" @@ -55,6 +56,18 @@ class LLFilterEditor;  class LLTabContainer;  class LLInvPanelComplObserver; +class LLFolderViewModelInventory +:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> +{ +	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t; + +	virtual ~LLFolderViewModelInventory() {} + +	void sort(LLFolderViewFolder* folder); +	void requestSort(LLFolderViewFolder* folder); +}; + +  class LLInventoryPanel : public LLPanel  {  	//-------------------------------------------------------------------- @@ -85,7 +98,6 @@ public:  		Optional<std::string>               start_folder;  		Optional<bool>						use_label_suffix;  		Optional<bool>						show_empty_message; -		Optional<bool>						show_load_status;  		Optional<LLScrollContainer::Params>	scroll;  		Optional<bool>						accepts_drag_and_drop; @@ -98,7 +110,6 @@ public:  			start_folder("start_folder"),  			use_label_suffix("use_label_suffix", true),  			show_empty_message("show_empty_message", true), -			show_load_status("show_load_status"),  			scroll("scroll"),  			accepts_drag_and_drop("accepts_drag_and_drop")  		{} @@ -182,10 +193,21 @@ public:  	static void openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id); +	void addItemID(const LLUUID& id, LLFolderViewItem* itemp); +	void removeItemID(const LLUUID& id); +	LLFolderViewItem* getItemByID(const LLUUID& id); +	LLFolderViewFolder* getFolderByID(const LLUUID& id); +	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus); +	void updateSelection(); +	 	 +	LLFolderViewModelInventory* getViewModel() { return &mViewModel; } +	const LLFolderViewModelInventory* getViewModel() const { return   &mViewModel; } +  protected:  	void openStartFolderOrMyInventory(); // open the first level of inventory  	void onItemsCompletion();			// called when selected items are complete +        LLUUID						mSelectThisID;	  	LLInventoryModel*			mInventory;  	LLInventoryObserver*		mInventoryObserver;  	LLInvPanelComplObserver*	mCompletionObserver; @@ -193,11 +215,13 @@ protected:  	BOOL 						mAllowMultiSelect;  	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons  	BOOL						mShowEmptyMessage; -	BOOL						mShowLoadStatus;  	LLFolderView*				mFolderRoot;  	LLScrollContainer*			mScroller; +	LLFolderViewModelInventory	mViewModel; +	 +	std::map<LLUUID, LLFolderViewItem*> mItemMap;  	/**  	 * Pointer to LLInventoryFVBridgeBuilder.  	 * @@ -218,7 +242,6 @@ public:  	void setSortOrder(U32 order);  	U32 getSortOrder() const; -	void requestSort();  private:  	std::string					mSortOrderSetting; @@ -253,4 +276,25 @@ private:  	LLUUID				mStartFolderID;  }; +class LLFolderViewModelItemInventory +	:	public LLFolderViewModelItemCommon +{ +public: +	virtual const LLUUID& getUUID() const = 0; +	virtual time_t getCreationDate() const = 0;	// UTC seconds +	virtual void setCreationDate(time_t creation_date_utc) = 0; +	virtual PermissionMask getPermissionMask() const = 0; +	virtual LLFolderType::EType getPreferredType() const = 0; +	virtual void previewItem( void ) = 0; +	virtual void showProperties(void) = 0; +	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual. +	virtual BOOL isUpToDate() const = 0; +	virtual BOOL hasChildren() const = 0; +	virtual LLInventoryType::EType getInventoryType() const = 0; +	virtual void performAction(LLInventoryModel* model, std::string action)   = 0; +	virtual LLWearableType::EType getWearableType() const = 0; +	virtual EInventorySortGroup getSortGroup() const; +	virtual void requestSort(const LLInventorySort& sorter); +}; +  #endif // LL_LLINVENTORYPANEL_H diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 68a3b6d1cd..234fa7590d 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -299,7 +299,7 @@ void LLLandmarksPanel::onTeleport()  		return;  	} -	LLFolderViewEventListener* listenerp = current_item->getListener(); +	LLFolderViewModelItem* listenerp = current_item->getListener();  	if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)  	{  		listenerp->openItem(); @@ -360,7 +360,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()  	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();  	if (!cur_item) return; -	LLFolderViewEventListener* listenerp = cur_item->getListener(); +	LLFolderViewModelItem* listenerp = cur_item->getListener();  	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)  	{  		LLSD key; @@ -376,7 +376,7 @@ void LLLandmarksPanel::updateShowFolderState()  	if (!mLandmarksInventoryPanel->getFilter())  		return; -	bool show_all_folders = mLandmarksInventoryPanel->getRootFolder()->getFilterSubString().empty(); +	bool show_all_folders =   mLandmarksInventoryPanel->getFilterSubString().empty();  	if (show_all_folders)  	{  		show_all_folders = category_has_descendents(mLandmarksInventoryPanel); @@ -466,7 +466,7 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa  	LLFolderView* root = inventory_list->getRootFolder(); -	LLFolderViewItem* item = root->getItemByID(obj_id); +	LLFolderViewItem* item = inventory_list->getItemByID(obj_id);  	if (!item)  		return NULL; @@ -665,20 +665,20 @@ void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory  {  	if (inventory_list != mFavoritesInventoryPanel)  	{ -		mFavoritesInventoryPanel->getRootFolder()->clearSelection(); +		mFavoritesInventoryPanel->clearSelection();  	}  	if (inventory_list != mLandmarksInventoryPanel)  	{ -		mLandmarksInventoryPanel->getRootFolder()->clearSelection(); +		mLandmarksInventoryPanel->clearSelection();  	}  	if (inventory_list != mMyInventoryPanel)  	{ -		mMyInventoryPanel->getRootFolder()->clearSelection(); +		mMyInventoryPanel->clearSelection();  	}  	if (inventory_list != mLibraryInventoryPanel)  	{ -		mLibraryInventoryPanel->getRootFolder()->clearSelection(); +		mLibraryInventoryPanel->clearSelection();  	}  } @@ -738,7 +738,7 @@ void LLLandmarksPanel::onActionsButtonClick()  		if(!cur_item)  			return; -		LLFolderViewEventListener* listenerp = cur_item->getListener(); +		LLFolderViewModelItem* listenerp = cur_item->getListener();  		if(!listenerp)  			return; @@ -794,7 +794,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const  		LLFolderViewItem* item = getCurSelectedItem();  		if (item && mCurrentSelectedList == mLandmarksInventoryPanel)  		{ -			LLFolderViewEventListener* folder_bridge = NULL; +			LLFolderViewModelItem* folder_bridge = NULL;  			if (item-> getListener()->getInventoryType()  					== LLInventoryType::IT_LANDMARK)  			{ @@ -808,7 +808,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const  				folder_bridge = item->getListener();  			} -			menu_create_inventory_item(mCurrentSelectedList->getRootFolder(), +			menu_create_inventory_item(mCurrentSelectedList,  					dynamic_cast<LLFolderBridge*> (folder_bridge), LLSD(  							"category"), gInventory.findCategoryUUIDForType(  							LLFolderType::FT_LANDMARK)); @@ -816,7 +816,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const  		else  		{  			//in case My Landmarks tab is completely empty (thus cannot be determined as being selected) -			menu_create_inventory_item(mLandmarksInventoryPanel->getRootFolder(), NULL, LLSD("category"),  +			menu_create_inventory_item(mLandmarksInventoryPanel, NULL,  LLSD("category"),   				gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));  			if (mMyLandmarksAccordionTab) @@ -977,12 +977,12 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  	{  		if (!root_folder_view) return false; -		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); +		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();  		// Allow to execute the command only if it can be applied to all selected items. -		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) +		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)  		{ -			LLFolderViewItem* item = root_folder_view->getItemByID(*iter); +			LLFolderViewItem* item = *iter;  			// If no item is found it might be a folder id.  			if (!item) @@ -1049,7 +1049,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  	{  		if (mCurrentSelectedList)  		{ -			std::set<LLUUID> selection = mCurrentSelectedList->getRootFolder()->getSelectionList(); +			std::set<LLFolderViewItem*> selection =    mCurrentSelectedList->getRootFolder()->getSelectionList();  			if (!selection.empty())  			{  				return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() ); @@ -1105,27 +1105,23 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)  	{  		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); -		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); +		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();  		// Iterate through selected items to find out if any of these items are in Trash  		// or all the items are in Trash category. -		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) +		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)  		{ -			LLFolderViewItem* item = root_folder_view->getItemByID(*iter); +			LLFolderViewItem* item = *iter;  			// If no item is found it might be a folder id. -			if (!item) -			{ -				item = root_folder_view->getFolderByID(*iter); -			}  			if (!item) continue; -			LLFolderViewEventListener* listenerp = item->getListener(); +			LLFolderViewModelItem* listenerp = item->getListener();  			if(!listenerp) continue;  			// Trash category itself should not be included because it can't be  			// actually restored from trash. -			are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id; +			are_all_items_in_trash &= listenerp->isItemInTrash() &&    (*iter)->getListener()->getUUID() != trash_id;  			// If there are any selected items in Trash including the Trash category itself  			// we show "Restore Item" in context menu and hide other irrelevant items. @@ -1202,7 +1198,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold  	if (can_be_modified)  	{ -		LLFolderViewEventListener* listenerp = item->getListener(); +		LLFolderViewModelItemInventory* listenerp = item->getListener();  		if ("cut" == command_name)  		{ @@ -1262,8 +1258,9 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg  				LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data);  				if (item)  				{ -					LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ? -						mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL; +					LLFolderViewItem* fv_item = mCurrentSelectedList +						? mCurrentSelectedList->getItemByID(item->getUUID()) +						: NULL;  					if (fv_item)  					{ @@ -1391,7 +1388,7 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)  static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string)  {  	// When search is cleared, restore the old folder state. -	if (!inventory_list->getRootFolder()->getFilterSubString().empty() && string == "") +	if (!inventory_list->getFilterSubString().empty() && string == "")  	{  		inventory_list->setFilterSubString(LLStringUtil::null);  		// Re-open folders that were open before @@ -1405,7 +1402,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin  	}  	// save current folder open state if no filter currently applied -	if (inventory_list->getRootFolder()->getFilterSubString().empty()) +	if (inventory_list->getFilterSubString().empty())  	{  		inventory_list->saveFolderState();  	} diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index c11597f532..a7970bde24 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -53,6 +53,7 @@  #include "llviewermenu.h"  #include "llviewertexturelist.h"  #include "llsidepanelinventory.h" +#include "llfolderview.h"  const std::string FILTERS_FILENAME("filters.xml"); @@ -171,7 +172,10 @@ BOOL LLPanelMainInventory::postBuild()  			{  				LLSD recent_items = savedFilterState.get(  					recent_items_panel->getFilter()->getName()); -				recent_items_panel->getFilter()->fromLLSD(recent_items); +				LLInventoryFilter::Params p; +				LLParamSDParser parser; +				parser.readSD(recent_items, p); +				recent_items_panel->getFilter()->fromParams(p);  			}  		} @@ -212,22 +216,23 @@ LLPanelMainInventory::~LLPanelMainInventory( void )  		if (filter)  		{  			LLSD filterState; -			filter->toLLSD(filterState); +			LLInventoryFilter::Params p; +			filter->toParams(p); +			if (p.validateBlock(false)) +			{ +				LLParamSDParser().writeSD(filterState, p);  			filterRoot[filter->getName()] = filterState;  		}  	} +	} -	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items"); -	if (recent_items_panel) -	{ -		LLInventoryFilter* filter = recent_items_panel->getFilter(); +        LLInventoryFilter* filter = getChild<LLInventoryPanel>("Recent   Items")->getFilter();  		if (filter)  		{  			LLSD filterState;  			filter->toLLSD(filterState);  			filterRoot[filter->getName()] = filterState;  		} -	}  	std::ostringstream filterSaveName;  	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME); @@ -306,7 +311,7 @@ void LLPanelMainInventory::newWindow()  void LLPanelMainInventory::doCreate(const LLSD& userdata)  { -	menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata); +	menu_create_inventory_item(getPanel(), NULL, userdata);  }  void LLPanelMainInventory::resetFilters() @@ -417,7 +422,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )  	}  	// save current folder open state if no filter currently applied -	if (!mActivePanel->getRootFolder()->isFilterModified()) +	if (!mActivePanel->getFilter()->isNotDefault())  	{  		mSavedFolderState->setApply(FALSE);  		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -1110,15 +1115,15 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)  		if (root)  		{  			can_delete = TRUE; -			std::set<LLUUID> selection_set = root->getSelectionList(); +			std::set<LLFolderViewItem*> selection_set = root->getSelectionList();  			if (selection_set.empty()) return FALSE; -			for (std::set<LLUUID>::iterator iter = selection_set.begin(); +			for (std::set<LLFolderViewItem*>::iterator iter =    selection_set.begin();  				 iter != selection_set.end();  				 ++iter)  			{  				const LLUUID &item_id = (*iter); -				LLFolderViewItem *item = root->getItemByID(item_id); -				const LLFolderViewEventListener *listener = item->getListener(); +				LLFolderViewItem *item = *iter; +				const LLFolderViewModelItemInventory *listener = item->getListener();  				llassert(listener);  				if (!listener) return FALSE;  				can_delete &= listener->isItemRemovable(); @@ -1148,7 +1153,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)  	if (command_name == "find_links")  	{  		LLFolderView* root = getActivePanel()->getRootFolder(); -		std::set<LLUUID> selection_set = root->getSelectionList(); +		std::set<LLFolderViewItem*> selection_set = root->getSelectionList();  		if (selection_set.size() != 1) return FALSE;  		LLFolderViewItem* current_item = root->getCurSelectedItem();  		if (!current_item) return FALSE; diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp index 66c9c323cb..6804342106 100644 --- a/indra/newview/llpanelmarketplaceinbox.cpp +++ b/indra/newview/llpanelmarketplaceinbox.cpp @@ -94,7 +94,7 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()  	mInventoryPanel->setShape(inventory_placeholder_rect);  	// Set the sort order newest to oldest -	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	 +	mInventoryPanel->getViewModel()->setSorter(LLInventoryFilter::SO_DATE);  	mInventoryPanel->getFilter()->markDefault();  	// Set selection callback for proper update of inventory status buttons @@ -139,12 +139,12 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const  	if (mInventoryPanel)  	{ -		const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder(); +		LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();  		if (inbox_folder)  		{ -			LLFolderViewFolder::folders_t::const_iterator folders_it = inbox_folder->getFoldersBegin(); -			LLFolderViewFolder::folders_t::const_iterator folders_end = inbox_folder->getFoldersEnd(); +			LLFolderViewFolder::folders_t::iterator folders_it = inbox_folder->getFoldersBegin(); +			LLFolderViewFolder::folders_t::iterator folders_end = inbox_folder->getFoldersEnd();  			for (; folders_it != folders_end; ++folders_it)  			{ @@ -157,8 +157,8 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const  				}  			} -			LLFolderViewFolder::items_t::const_iterator items_it = inbox_folder->getItemsBegin(); -			LLFolderViewFolder::items_t::const_iterator items_end = inbox_folder->getItemsEnd(); +			LLFolderViewFolder::items_t::iterator items_it = inbox_folder->getItemsBegin(); +			LLFolderViewFolder::items_t::iterator items_end = inbox_folder->getItemsEnd();  			for (; items_it != items_end; ++items_it)  			{ diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp index 678e4f2843..1d079adfd3 100644 --- a/indra/newview/llpanelmarketplaceinboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -29,6 +29,7 @@  #include "llpanelmarketplaceinboxinventory.h"  #include "llfolderview.h" +#include "llfolderviewitem.h"  #include "llfoldervieweventlistener.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h" @@ -253,9 +254,9 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p)  #endif  } -BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)  { -	BOOL retval = LLFolderViewItem::addToFolder(folder, root); +	BOOL retval = LLFolderViewItem::addToFolder(folder);  #if SUPPORTING_FRESH_ITEM_COUNT  	// Compute freshness if our parent is the root folder for the inbox diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h index d6b827ee3e..209f3a4098 100644 --- a/indra/newview/llpanelmarketplaceinboxinventory.h +++ b/indra/newview/llpanelmarketplaceinboxinventory.h @@ -81,8 +81,6 @@ public:  	bool isFresh() const { return mFresh; }  protected: -	void setCreationDate(time_t creation_date_utc); -  	bool mFresh;  }; @@ -102,7 +100,7 @@ public:  	LLInboxFolderViewItem(const Params& p); -	BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); +	BOOL addToFolder(LLFolderViewFolder* folder);  	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);  	void draw(); diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp index ff62cb23db..b5c7c4ca88 100644 --- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp @@ -28,7 +28,7 @@  #include "llpanelmarketplaceoutboxinventory.h" -#include "llfolderview.h" +#include "llfolderviewitem.h"  #include "llfoldervieweventlistener.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h" diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index f84d6e5cc1..3d7d9d573e 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -71,7 +71,7 @@  /// Class LLTaskInvFVBridge  ///---------------------------------------------------------------------------- -class LLTaskInvFVBridge : public LLFolderViewEventListener +class LLTaskInvFVBridge : public LLFolderViewModelItemInventory  {  protected:  	LLUUID mUUID; @@ -102,7 +102,7 @@ public:  	S32 getPrice();  	static bool commitBuyItem(const LLSD& notification, const LLSD& response); -	// LLFolderViewEventListener functionality +	// LLFolderViewModelItemInventory functionality  	virtual const std::string& getName() const;  	virtual const std::string& getDisplayName() const;  	virtual PermissionMask getPermissionMask() const { return PERM_NONE; } @@ -120,8 +120,8 @@ public:  	virtual BOOL isItemMovable() const;  	virtual BOOL isItemRemovable() const;  	virtual BOOL removeItem(); -	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch); -	virtual void move(LLFolderViewEventListener* parent_listener); +	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); +	virtual void move(LLFolderViewModelItem* parent_listener);	  	virtual BOOL isItemCopyable() const;  	virtual BOOL copyToClipboard() const;  	virtual BOOL cutToClipboard() const; @@ -467,7 +467,7 @@ BOOL LLTaskInvFVBridge::removeItem()  	return FALSE;  } -void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) +void   LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewModelItem*>&   batch)  {  	if (!mPanel)  	{ @@ -507,7 +507,7 @@ void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>&  	}  } -void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener) +void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)  {  } @@ -1548,7 +1548,8 @@ void LLPanelObjectInventory::reset()  	p.folder_indentation = -14; // subtract space normally reserved for folder expanders  	mFolders = LLUICtrlFactory::create<LLFolderView>(p);  	// this ensures that we never say "searching..." or "no items found" -	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); +	RN: make this happen by manipulating filter object directly +	//mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);  	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);  	if (hasFocus()) @@ -1608,7 +1609,7 @@ void LLPanelObjectInventory::updateInventory()  	//		<< " panel UUID: " << panel->mTaskUUID << "\n"  	//		<< " task  UUID: " << object->mID << llendl;  	// We're still interested in this task's inventory. -	std::set<LLUUID> selected_items; +	std::set<LLFolderViewItem*> selected_items;  	BOOL inventory_has_focus = FALSE;  	if (mHaveInventory)  	{ @@ -1646,11 +1647,11 @@ void LLPanelObjectInventory::updateInventory()  	}  	// restore previous selection -	std::set<LLUUID>::iterator selection_it; +	std::set<LLFolderViewItem*>::iterator selection_it;  	BOOL first_item = TRUE;  	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)  	{ -		LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it); +		LLFolderViewItem* selected_item = (*selection_it);  		if (selected_item)  		{  			//HACK: "set" first item then "change" each other one to get keyboard focus right @@ -1752,7 +1753,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li  				params.tool_tip = params.name;  				view = LLUICtrlFactory::create<LLFolderViewItem> (params);  			} -			view->addToFolder(folder, mFolders); +			view->addToFolder(folder); +                        addItemID(view->getListener()->getUUID(), view);  		}  	} diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 35e2e96bab..4abc7fea0e 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -270,7 +270,7 @@ private:  		if (inventory_panel->getVisible())  		{ -			inventory_panel->setSortOrder(sort_order); +			inventory_panel->getViewModel()->setSorter(sort_order);  		}  		else  		{ @@ -738,7 +738,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)  	}  	// save current folder open state if no filter currently applied -	if (mInventoryItemsPanel->getRootFolder()->getFilterSubString().empty()) +	if (mInventoryItemsPanel->getFilterSubString().empty())  	{  		mSavedFolderState->setApply(FALSE);  		mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -885,13 +885,13 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT  	{  		if (mInventoryItemsPanel != NULL && mInventoryItemsPanel->getVisible())  		{ -			std::set<LLUUID> selected_uuids = mInventoryItemsPanel->getRootFolder()->getSelectionList(); +			std::set<LLFolderViewItem*> selected_items =    mInventoryItemsPanel->getRootFolder()->getSelectionList(); -			result.second = selected_uuids.size(); +			result.second = selected_items.size();  			if (result.second == 1)  			{ -				result.first = getWearableTypeByItemUUID(*(selected_uuids.begin())); +				result.first =    getWearableTypeByItemUUID((*selected_items.begin())->getListener()->getUUID());  			}  		}  		else if (mWearableItemsList != NULL && mWearableItemsList->getVisible()) @@ -1310,7 +1310,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id)  		LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();  		if (!curr_item) return; -		LLFolderViewEventListener* listenerp  = curr_item->getListener(); +		LLFolderViewModelItemInventory* listenerp  = curr_item->getListener();  		if (!listenerp) return;  		selected_id = listenerp->getUUID(); @@ -1327,9 +1327,13 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)  	void (uuid_vec_t::* tmp)(LLUUID const &) = &uuid_vec_t::push_back;  	if (mInventoryItemsPanel->getVisible())  	{ -		std::set<LLUUID> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList(); - -		std::for_each(item_set.begin(), item_set.end(), boost::bind( tmp, &uuid_list, _1)); +		std::set<LLFolderViewItem*> item_set =    mInventoryItemsPanel->getRootFolder()->getSelectionList(); +		for (std::set<LLFolderViewItem*>::iterator it = item_set.begin(),    end_it = item_set.end(); +			it != end_it; +			++it) +		{ +			uuid_list.push_back((*it)->getListener()->getUUID()); +		}  	}  	else if (mWearablesListViewPanel->getVisible())  	{ @@ -1374,13 +1378,13 @@ void LLPanelOutfitEdit::saveListSelection()  {  	if(mWearablesListViewPanel->getVisible())  	{ -		std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList(); +		std::set<LLFolderViewItem*> selected_ids =    mInventoryItemsPanel->getRootFolder()->getSelectionList();  		if(!selected_ids.size()) return; -		for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id) +		for (std::set<LLFolderViewItem*>::const_iterator item_id =    selected_ids.begin(); item_id != selected_ids.end(); ++item_id)  		{ -			mWearableItemsList->selectItemByUUID(*item_id, true); +			mWearableItemsList->selectItemByUUID((*item_id)->getListener()->getUUID(),    true);  		}  		mWearableItemsList->scrollToShowFirstSelectedItem();  	} @@ -1398,7 +1402,7 @@ void LLPanelOutfitEdit::saveListSelection()  		for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)  		{ -			LLFolderViewItem* item = root->getItemByID(*item_id); +			LLFolderViewItem* item = mInventoryItemsPanel->getItemByID(*item_id);  			if (!item) continue;  			LLFolderViewFolder* parent = item->getParentFolder(); diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp index fe4cc0f55f..97c5d531d2 100644 --- a/indra/newview/llplacesinventorybridge.cpp +++ b/indra/newview/llplacesinventorybridge.cpp @@ -85,34 +85,33 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  { +	std::vector<std::string> items; +	std::vector<std::string> disabled_items; + +	LLInventoryPanel* inv_panel = mInventoryPanel.get(); +	bool is_open = false; +	if (inv_panel)  	{ -		std::vector<std::string> items; -		std::vector<std::string> disabled_items; +		LLFolderViewFolder* folder =  dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID)); +		is_open = (NULL != folder) && folder->isOpen(); +	} -		LLInventoryPanel* inv_panel = mInventoryPanel.get(); -		bool is_open = false; -		if (inv_panel) -		{ -			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID)); -			is_open = (NULL != folder) && folder->isOpen(); -		} +	// collect all items' names +	fill_items_with_menu_items(items, menu); -		// collect all items' names -		fill_items_with_menu_items(items, menu); +	// remove expand or collapse menu item depend on folder state +	std::string collapse_expand_item_to_hide(is_open ? "expand" :  "collapse"); +	std::vector<std::string>::iterator it = std::find(items.begin(),  items.end(), collapse_expand_item_to_hide); +	if (it != items.end())	items.erase(it); -		// remove expand or collapse menu item depend on folder state -		std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse"); -		std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide); -		if (it != items.end())	items.erase(it); -		// Disabled items are processed via LLLandmarksPanel::isActionEnabled() -		// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601  +	// Disabled items are processed via LLLandmarksPanel::isActionEnabled() +	// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601  -		// repeat parent functionality - 		sSelf = getHandle(); // necessary for "New Folder" functionality +	// repeat parent functionality + 	sSelf = getHandle(); // necessary for "New Folder" functionality -		hide_context_entries(menu, items, disabled_items); -	} +	hide_context_entries(menu, items, disabled_items);  }  //virtual @@ -140,7 +139,7 @@ LLFolderViewFolder* LLPlacesFolderBridge::getFolder()  	LLInventoryPanel* inv_panel = mInventoryPanel.get();  	if (inv_panel)  	{ -		folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID)); +		folder =    dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));  	}  	return folder; diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp index f7823f4fe8..1de26660bc 100644 --- a/indra/newview/llplacesinventorypanel.cpp +++ b/indra/newview/llplacesinventorypanel.cpp @@ -31,6 +31,7 @@  #include "llplacesinventorypanel.h"  #include "llfoldervieweventlistener.h" +#include "llfolderview.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h"  #include "llpanellandmarks.h" @@ -91,7 +92,7 @@ void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par  	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); +	mFolderRoot = LLUICtrlFactory::create<LLPlacesFolderView>(p);  } diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 853656905c..f069da5869 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -267,7 +267,7 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()  		if (inventory_panel)  		{  			LLFolderView* root = inventory_panel->getRootFolder(); -			LLFolderViewItem *outfit_folder = root->getItemByID(outfit_link->getLinkedUUID()); +			LLFolderViewItem *outfit_folder =    inventory_panel->getItemByID(outfit_link->getLinkedUUID());  			if (outfit_folder)  			{  				outfit_folder->setOpen(!outfit_folder->isOpen()); diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 4f9ab318a5..cc578b5799 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -36,6 +36,7 @@  #include "llfirstuse.h"  #include "llfloatersidepanelcontainer.h"  #include "llfoldertype.h" +#include "llfolderview.h"  #include "llhttpclient.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h" @@ -383,10 +384,10 @@ void LLSidepanelInventory::onToggleInboxBtn()  	{  		inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));  		if (inboxPanel->isInVisibleChain()) -		{ -			gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); -		} +	{ +		gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());  	} +}  	else  	{  		gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim()); @@ -671,7 +672,7 @@ U32 LLSidepanelInventory::getSelectedCount()  {  	int count = 0; -	std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList(); +	std::set<LLFolderViewItem*> selection_list =    mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();  	count += selection_list.size();  	if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL)) @@ -722,9 +723,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)  	updateVerbs();  } -std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList() +std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()  { -	std::set<LLUUID> inventory_selected_uuids; +	std::set<LLFolderViewItem*> inventory_selected_uuids;  	if (mInboxEnabled && (mInventoryPanelInbox != NULL))  	{ diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index a33607f50d..6aa349f0f3 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -63,6 +63,7 @@ public:  	BOOL isMainInventoryPanelActive() const;  	void clearSelections(bool clearMain, bool clearInbox); +        std::set<LLFolderViewItem*> getInboxSelectionList();  	std::set<LLUUID> getInboxSelectionList();  	void showItemInfoPanel(); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ed9faa0706..ad2db966bd 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -181,7 +181,7 @@ protected:  	F32					mContextConeOpacity;  	LLSaveFolderState	mSavedFolderState;  	BOOL				mSelectedItemPinned; -	 +  	LLRadioGroup*		mModeSelector;  	LLScrollListCtrl*	mLocalScrollCtrl;  }; @@ -358,7 +358,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)  		{  			if (!root_folder->getCurSelectedItem())  			{ -				LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID()); +				LLFolderViewItem* itemp =    mInventoryPanel->getItemByID(gInventory.getRootFolderID());  				if (itemp)  				{  					root_folder->setSelection(itemp, FALSE, FALSE); @@ -982,7 +982,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )  	else if (mInventoryPanel->getFilterSubString().empty())  	{  		// first letter in search term, save existing folder open state -		if (!mInventoryPanel->getRootFolder()->isFilterModified()) +		if (!mInventoryPanel->getFilter()->isNotDefault())  		{  			mSavedFolderState.setApply(FALSE);  			mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState); @@ -1280,7 +1280,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)  		// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.  		else if (mCommitOnSelection || op == TEXTURE_SELECT)  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - +			  		if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.  		{  			setTentative( FALSE ); @@ -1292,10 +1292,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)  			}  			else  			{ -				mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE); -				lldebugs << "mImageItemID: " << mImageItemID << llendl; -				mImageAssetID = floaterp->getAssetID(); -				lldebugs << "mImageAssetID: " << mImageAssetID << llendl; +			mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE); +			lldebugs << "mImageItemID: " << mImageItemID << llendl; +			mImageAssetID = floaterp->getAssetID(); +			lldebugs << "mImageAssetID: " << mImageAssetID << llendl;  			}  			if (op == TEXTURE_SELECT && mOnSelectCallback) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 45ca23cdfe..d827b2b8aa 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1308,7 +1308,7 @@ const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably  const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)  // ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements... -void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid) +void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)  {  	std::string type_name = userdata.asString(); @@ -1332,7 +1332,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons  		LLUUID category = gInventory.createNewCategory(parent_id, preferred_type, LLStringUtil::null);  		gInventory.notifyObservers(); -		root->setSelectionByID(category, TRUE); +		panel->setSelectionByID(category, TRUE);  	}  	else if ("lsl" == type_name)  	{ @@ -1375,7 +1375,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons  			llwarns << "Can't create unrecognized type " << type_name << llendl;  		}  	} -	root->setNeedsAutoRename(TRUE);	 +	panel->getRoot()->->setNeedsAutoRename(TRUE);	  }  LLAssetType::EType LLViewerInventoryItem::getType() const @@ -1785,12 +1785,6 @@ void LLViewerInventoryItem::getSLURL()  	LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID);  } -const LLPermissions& LLViewerInventoryItem::getPermissions() const -{ -	// Use the actual permissions of the symlink, not its parent. -	return LLInventoryItem::getPermissions();	 -} -  const LLUUID& LLViewerInventoryItem::getCreatorUUID() const  {  	if (const LLViewerInventoryItem *linked_item = getLinkedItem()) @@ -1861,17 +1855,6 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const  	return LLWearableType::EType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);  } - -time_t LLViewerInventoryItem::getCreationDate() const -{ -	return LLInventoryItem::getCreationDate(); -} - -U32 LLViewerInventoryItem::getCRC32() const -{ -	return LLInventoryItem::getCRC32();	 -} -  // *TODO: mantipov: should be removed with LMSortPrefix patch in llinventorymodel.cpp, EXT-3985  static char getSeparator() { return '@'; }  BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName) diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 7822ef4da6..d66362d544 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -34,7 +34,7 @@  #include <boost/signals2.hpp>	// boost::signals2::trackable -class LLFolderView; +class LLInventoryPanel;  class LLFolderBridge;  class LLViewerInventoryCategory; @@ -63,7 +63,6 @@ public:  	virtual S32 getSortField() const;  	virtual void setSortField(S32 sortField);  	virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here. -	virtual const LLPermissions& getPermissions() const;  	virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied  	virtual const LLUUID& getCreatorUUID() const;  	virtual const std::string& getDescription() const; @@ -72,8 +71,11 @@ public:  	virtual bool isWearableType() const;  	virtual LLWearableType::EType getWearableType() const;  	virtual U32 getFlags() const; -	virtual time_t getCreationDate() const; -	virtual U32 getCRC32() const; // really more of a checksum. + +        using LLInventoryItem::getPermissions; +	using LLInventoryItem::getCreationDate; +	using LLInventoryItem::setCreationDate; +	using LLInventoryItem::getCRC32;  	static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName); @@ -372,7 +374,7 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,  								  U32 callback_id = 0); -void menu_create_inventory_item(LLFolderView* root, +void menu_create_inventory_item(LLInventoryPanel* root,  								LLFolderBridge* bridge,  								const LLSD& userdata,  								const LLUUID& default_parent_uuid = LLUUID::null); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index dd78bbd491..90d144b458 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -728,7 +728,7 @@ static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& item  		LLFolderView* fv = inventory_panel->getRootFolder();  		if (fv)  		{ -			LLFolderViewItem* fv_item = fv->getItemByID(item_id); +			LLFolderViewItem* fv_item = inventory_panel->getItemByID(item_id);  			if (fv_item)  			{  				LLFolderViewItem* fv_folder = fv_item->getParentFolder(); @@ -816,7 +816,13 @@ private:  		mSelectedItems.clear();  		if (LLInventoryPanel::getActiveInventoryPanel())  		{ -			mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(); +			std::set<LLFolderViewItem*> selection =    LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(); +			for (std::set<LLFolderViewItem*>::iterator it = selection.begin(),    end_it = selection.end(); +				it != end_it; +				++it) +			{ +				mSelectedItems.insert((*it)->getListener()->getUUID()); +			}  		}  		mSelectedItems.erase(mMoveIntoFolderID);  	} @@ -851,7 +857,15 @@ private:  		}  		// get selected items (without destination folder) -		selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList(); +		selected_items_t selected_items; + 		 + 		std::set<LLFolderViewItem*> selection =    LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(); +		for (std::set<LLFolderViewItem*>::iterator it = selection.begin(),    end_it = selection.end(); +			it != end_it; +			++it) +		{ +			selected_items.insert((*it)->getListener()->getUUID()); +		}  		selected_items.erase(mMoveIntoFolderID);  		// compare stored & current sets of selected items | 
