diff options
Diffstat (limited to 'indra/newview')
55 files changed, 6044 insertions, 5529 deletions
| diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index eb5d172ff7..2644235114 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -734,6 +734,10 @@ BOOL LLAgent::canFly()  	return parcel->getAllowFly();  } +BOOL LLAgent::getFlying() const +{  +	return mControlFlags & AGENT_CONTROL_FLY;  +}  //-----------------------------------------------------------------------------  // setFlying() @@ -791,7 +795,7 @@ void LLAgent::setFlying(BOOL fly)  // static  void LLAgent::toggleFlying()  { -	BOOL fly = !(gAgent.mControlFlags & AGENT_CONTROL_FLY); +	BOOL fly = !gAgent.getFlying();  	gAgent.setFlying( fly );  	gAgent.resetView(); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 4162dfce1e..2e95dc72be 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -310,7 +310,7 @@ private:  	// Fly  	//--------------------------------------------------------------------  public: -	BOOL			getFlying() const	{ return mControlFlags & AGENT_CONTROL_FLY; } +	BOOL			getFlying() const;  	void			setFlying(BOOL fly);  	static void		toggleFlying();  	static bool		enableFlying(); diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 538dcb6f3d..475f34dc2b 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -675,7 +675,7 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab  	{  		wearable_vec[index] = wearable;  		old_wearable->setLabelUpdated(); -		mAvatarObject->wearableUpdated(wearable->getType()); +		wearableUpdated(wearable);  	}  } @@ -690,13 +690,32 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl  	if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE)  	{  		mWearableDatas[type].push_back(wearable); -		mAvatarObject->wearableUpdated(wearable->getType()); -		wearable->setLabelUpdated(); +		wearableUpdated(wearable);  		return mWearableDatas[type].size()-1;  	}  	return MAX_WEARABLES_PER_TYPE;  } +void LLAgentWearables::wearableUpdated(LLWearable *wearable) +{ +	mAvatarObject->wearableUpdated(wearable->getType()); +	wearable->setLabelUpdated(); + +	// Hack pt 2. If the wearable we just loaded has definition version 24, +	// then force a re-save of this wearable after slamming the version number to 22. +	// This number was incorrectly incremented for internal builds before release, and +	// this fix will ensure that the affected wearables are re-saved with the right version number. +	// the versions themselves are compatible. This code can be removed before release. +	if( wearable->getDefinitionVersion() == 24 ) +	{ +		wearable->setDefinitionVersion(22); +		U32 index = getWearableIndex(wearable); +		llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl; +		saveWearable(wearable->getType(),index,TRUE); +	} + +} +  void LLAgentWearables::popWearable(LLWearable *wearable)  {  	if (wearable == NULL) @@ -1528,7 +1547,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	gInventory.notifyObservers(); -	queryWearableCache();  	std::vector<LLWearable*>::iterator wearable_iter; @@ -1551,6 +1569,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	// Start rendering & update the server  	mWearablesLoaded = TRUE;   	checkWearablesLoaded(); +	queryWearableCache();  	updateServer();  	lldebugs << "setWearableOutfit() end" << llendl; @@ -2155,7 +2174,6 @@ void LLLibraryOutfitsFetch::contentsDone(void)  LLInitialWearablesFetch::~LLInitialWearablesFetch()  { -	llinfos << "~LLInitialWearablesFetch" << llendl;  }  // virtual @@ -2185,17 +2203,50 @@ void LLInitialWearablesFetch::processContents()  	else  	{  		processWearablesMessage(); -		// Create links for attachments that may have arrived before the COF existed. -		LLAppearanceManager::instance().linkRegisteredAttachments();  	}  	delete this;  } +class LLFetchAndLinkObserver: public LLInventoryFetchObserver +{ +public: +	LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids): +		m_ids(ids), +		LLInventoryFetchObserver(true) +	{ +	} +	~LLFetchAndLinkObserver() +	{ +	} +	virtual void done() +	{ +		gInventory.removeObserver(this); +		// Link to all fetched items in COF. +		for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin(); +			 it != m_ids.end(); +			 ++it) +		{ +			LLUUID id = *it; +			LLViewerInventoryItem *item = gInventory.getItem(*it); +			if (!item) +			{ +				llwarns << "fetch failed!" << llendl; +				continue; +			} +			link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(), +								LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); +		} +	} +private: +	LLInventoryFetchObserver::item_ref_t m_ids; +}; +  void LLInitialWearablesFetch::processWearablesMessage()  {  	if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.  	{ -		const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); +		const LLUUID current_outfit_id = LLAppearanceManager::instance().getCOF(); +		LLInventoryFetchObserver::item_ref_t ids;  		for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)  		{  			// Populate the current outfit folder with links to the wearables passed in the message @@ -2204,9 +2255,7 @@ void LLInitialWearablesFetch::processWearablesMessage()  			if (wearable_data->mAssetID.notNull())  			{  #ifdef USE_CURRENT_OUTFIT_FOLDER -				const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed. -				link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name, -									LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); +				ids.push_back(wearable_data->mItemID);  #endif  				// Fetch the wearables  				LLWearableList::instance().getAsset(wearable_data->mAssetID, @@ -2220,6 +2269,42 @@ void LLInitialWearablesFetch::processWearablesMessage()  				<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;  			}  		} + +		// Add all current attachments to the requested items as well. +		LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); +		if( avatar ) +		{ +			for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin();  +				 iter != avatar->mAttachmentPoints.end(); ++iter) +			{ +				LLViewerJointAttachment* attachment = iter->second; +				if (!attachment) continue; +				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					 attachment_iter != attachment->mAttachedObjects.end(); +					 ++attachment_iter) +				{ +					LLViewerObject* attached_object = (*attachment_iter); +					if (!attached_object) continue; +					const LLUUID& item_id = attached_object->getItemID(); +					if (item_id.isNull()) continue; +					ids.push_back(item_id); +				} +			} +		} + +		// Need to fetch the inventory items for ids, then create links to them after they arrive. +		LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids); +		fetcher->fetchItems(ids); +		// If no items to be fetched, done will never be triggered. +		// TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition. +		if (fetcher->isEverythingComplete()) +		{ +			fetcher->done(); +		} +		else +		{ +			gInventory.addObserver(fetcher); +		}  	}  	else  	{ diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 8f3a16501e..b4f58674af 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -107,6 +107,7 @@ private:  	// Low-level data structure setter - public access is via setWearableItem, etc.  	void 			setWearable(const EWearableType type, U32 index, LLWearable *wearable);  	U32 			pushWearable(const EWearableType type, LLWearable *wearable); +	void			wearableUpdated(LLWearable *wearable);  	void 			popWearable(LLWearable *wearable);  	void			popWearable(const EWearableType type, U32 index); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 1050deaa27..6288088210 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -559,10 +559,9 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)  	linkAll(cof, obj_items, link_waiter);  	linkAll(cof, gest_items, link_waiter); -	// Add link to outfit if category is an outfit.  -	const LLViewerInventoryCategory* catp = gInventory.getCategory(category);  	LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance")); -	 +	// Add link to outfit if category is an outfit.  +	LLViewerInventoryCategory* catp = gInventory.getCategory(category);  	if (!append && catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)  	{  		link_inventory_item(gAgent.getID(), category, cof, catp->getName(), @@ -576,10 +575,9 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)  	}  	else  	{ -		// Update the current outfit name of the appearance sidepanel.  		if (panel_appearance)  		{ -			panel_appearance->refreshCurrentOutfitName(); +			panel_appearance->refreshCurrentOutfitName("");  		}  	}  } @@ -858,7 +856,7 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor  void LLAppearanceManager::addCOFItemLink(const LLUUID &item_id, bool do_update )  {  	const LLInventoryItem *item = gInventory.getItem(item_id); -	addCOFItemLink(item); +	addCOFItemLink(item, do_update);  }  void LLAppearanceManager::addCOFItemLink(const LLInventoryItem *item, bool do_update ) @@ -1029,7 +1027,6 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)  	   if (mAttachmentInvLinkEnabled)  	   { -		   //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");  		   LLAppearanceManager::addCOFItemLink(item_id, false);  // Add COF link for item.  	   }  	   else diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index edad76a072..3e10c4b2b0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3546,7 +3546,7 @@ void LLAppViewer::idle()  		gEventNotifier.update();  		gIdleCallbacks.callFunctions(); -		gInventory.notifyObservers(); +		gInventory.idleNotifyObservers();  	}  	if (gDisconnected) diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 839a84f2d2..b08191ce15 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -324,6 +324,27 @@ void LLAvatarActions::pay(const LLUUID& id)  	}  } +//static  +void LLAvatarActions::share(const LLUUID& id) +{ +	LLSD key; +	LLSideTray::getInstance()->showPanel("sidepanel_inventory", key); + + +	LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,id); + +	if (!gIMMgr->hasSession(session_id)) +	{ +		startIM(id); +	} + +	if (gIMMgr->hasSession(session_id)) +	{ +		// we should always get here, but check to verify anyways +		LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, LLTrans::getString("share_alert"), false); +	} +} +  // static  void LLAvatarActions::toggleBlock(const LLUUID& id)  { diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index d9dab95a77..4c9851a48d 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -104,6 +104,11 @@ public:  	static void pay(const LLUUID& id);  	/** +	 * Share items with the avatar. +	 */ +	static void share(const LLUUID& id); + +	/**  	 * Block/unblock the avatar.  	 */  	static void toggleBlock(const LLUUID& id); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 88a98c3350..dbd3643742 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -564,7 +564,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)  	mBtnEdit	->setToggleState( edit_visible );  	mRadioGroupEdit->setVisible( edit_visible ); -	childSetVisible("RenderingCost", edit_visible || focus_visible || move_visible); +	bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts"); +	childSetVisible("RenderingCost", !linked_parts && (edit_visible || focus_visible || move_visible));  	if (mCheckSelectIndividual)  	{ @@ -976,6 +977,8 @@ void LLFloaterTools::onClickGridOptions()  S32 LLFloaterTools::calcRenderCost()  {  	S32 cost = 0; +	std::set<LLUUID> textures; +  	for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin();  		  selection_iter != LLSelectMgr::getInstance()->getSelection()->end();  		  ++selection_iter) @@ -986,11 +989,14 @@ S32 LLFloaterTools::calcRenderCost()  			LLVOVolume *viewer_volume = (LLVOVolume*)select_node->getObject();  			if (viewer_volume)  			{ -				cost += viewer_volume->getRenderCost(); +				cost += viewer_volume->getRenderCost(textures); +				cost += textures.size() * 5; +				textures.clear();  			}  		}  	} +  	return cost;  } diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 955bc64e05..ab49739d58 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -39,11 +39,13 @@  #include "llinventoryclipboard.h" // *TODO: remove this once hack below gone.  #include "llinventoryfilter.h"  #include "llinventoryfunctions.h" +#include "llinventorypanel.h"  #include "llfoldertype.h"  #include "llfloaterinventory.h"// hacked in for the bonus context menu items.  #include "llkeyboard.h"  #include "lllineeditor.h"  #include "llmenugl.h" +#include "llpanel.h"  #include "llpreview.h"  #include "llscrollcontainer.h" // hack to allow scrolling  #include "lltooldraganddrop.h" @@ -2014,6 +2016,14 @@ static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");  // Main idle routine  void LLFolderView::doIdle()  { +	// If this is associated with the user's inventory, don't do anything +	// until that inventory is loaded up. +	const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel); +	if (inventory_panel && !inventory_panel->getIsViewsInitialized()) +	{ +		return; +	} +	  	LLFastTimer t2(FTM_INVENTORY);  	BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters"); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 0bd65b5f90..a0e252ae88 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -41,25 +41,27 @@  #ifndef LL_LLFOLDERVIEW_H  #define LL_LLFOLDERVIEW_H -// JAMESDEBUG - trim this list -#include <vector> -#include <map> -#include <deque> -#include <boost/function.hpp> -#include <boost/signals2.hpp> +#include "llfolderviewitem.h"	// because LLFolderView is-a LLFolderViewFolder  #include "lluictrl.h"  #include "v4color.h"  #include "lldarray.h" -//#include "llviewermenu.h"  #include "stdenums.h" -#include "llfontgl.h" -#include "lleditmenuhandler.h" -#include "llviewertexture.h"  #include "lldepthstack.h" +#include "lleditmenuhandler.h" +#include "llfontgl.h"  #include "lltooldraganddrop.h" -// JAMESDEBUG - move this up -#include "llfolderviewitem.h"	// because LLFolderView is-a LLFolderViewFolder +#include "llviewertexture.h" + +class LLFolderViewEventListener; +class LLFolderViewFolder; +class LLFolderViewItem; +class LLInventoryModel; +class LLPanel; +class LLLineEditor; +class LLMenuGL; +class LLScrollContainer; +class LLUICtrl;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLFolderViewFunctor @@ -70,8 +72,7 @@  // that later when it's determined to be too slow.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFolderViewItem; -class LLFolderViewFolder; +  class LLFolderViewFunctor  { @@ -89,13 +90,6 @@ public:  // manages the screen region of the folder view.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFolderViewEventListener; -class LLInventoryModel; -class LLLineEditor; -class LLMenuGL; -class LLScrollContainer; -class LLUICtrl; -  class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler  {  public: @@ -330,7 +324,7 @@ protected:  	LLUUID							mSelectThisID; // if non null, select this item -	LLPanel*						mParentPanel; +	LLPanel*				mParentPanel;  	/**  	 * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index a1260d1156..63511301b3 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -38,12 +38,12 @@  #include "llfoldervieweventlistener.h"  #include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator()  #include "llinventoryfilter.h" +#include "llpanel.h"  #include "llviewercontrol.h"	// gSavedSettings  #include "llviewerwindow.h"		// Argh, only for setCursor()  // linden library includes  #include "llfocusmgr.h"		// gFocusMgr -#include "llpanel.h"		// panel->hasFocus()  #include "lltrans.h"  ///---------------------------------------------------------------------------- @@ -1290,9 +1290,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	// now query children  	for (folders_t::iterator iter = mFolders.begin(); -		iter != mFolders.end();) +		 iter != mFolders.end(); +		 ++iter)  	{ -		folders_t::iterator fit = iter++; +		LLFolderViewFolder* folder = (*iter);  		// have we run out of iterations this frame?  		if (filter.getFilterCount() < 0)  		{ @@ -1302,15 +1303,15 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  		// mMostFilteredDescendantGeneration might have been reset  		// in which case we need to update it even for folders that  		// don't need to be filtered anymore -		if ((*fit)->getCompletedFilterGeneration() >= filter_generation) +		if (folder->getCompletedFilterGeneration() >= filter_generation)  		{  			// track latest generation to pass any child items -			if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration())) +			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))  			{  				mMostFilteredDescendantGeneration = filter_generation;  				if (getRoot()->needsAutoSelect() && autoopen_folders)  				{ -					(*fit)->setOpenArrangeRecursively(TRUE); +					folder->setOpenArrangeRecursively(TRUE);  				}  			}  			// just skip it, it has already been filtered @@ -1318,48 +1319,49 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  		}  		// update this folders filter status (and children) -		(*fit)->filter( filter ); +		folder->filter( filter );  		// track latest generation to pass any child items -		if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation)) +		if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))  		{  			mMostFilteredDescendantGeneration = filter_generation;  			if (getRoot()->needsAutoSelect() && autoopen_folders)  			{ -				(*fit)->setOpenArrangeRecursively(TRUE); +				folder->setOpenArrangeRecursively(TRUE);  			}  		}  	}  	for (items_t::iterator iter = mItems.begin(); -		iter != mItems.end();) +		 iter != mItems.end(); +		 ++iter)  	{ -		items_t::iterator iit = iter++; +		LLFolderViewItem* item = (*iter);  		if (filter.getFilterCount() < 0)  		{  			break;  		} -		if ((*iit)->getLastFilterGeneration() >= filter_generation) +		if (item->getLastFilterGeneration() >= filter_generation)  		{ -			if ((*iit)->getFiltered()) +			if (item->getFiltered())  			{  				mMostFilteredDescendantGeneration = filter_generation;  			}  			continue;  		} -		if ((*iit)->getLastFilterGeneration() >= must_pass_generation &&  -			!(*iit)->getFiltered(must_pass_generation)) +		if (item->getLastFilterGeneration() >= must_pass_generation &&  +			!item->getFiltered(must_pass_generation))  		{  			// failed to pass an earlier filter that was a subset of the current one  			// go ahead and flag this item as done -			(*iit)->setFiltered(FALSE, filter_generation); +			item->setFiltered(FALSE, filter_generation);  			continue;  		} -		(*iit)->filter( filter ); +		item->filter( filter ); -		if ((*iit)->getFiltered(filter.getMinRequiredGeneration())) +		if (item->getFiltered(filter.getMinRequiredGeneration()))  		{  			mMostFilteredDescendantGeneration = filter_generation;  		} @@ -2028,6 +2030,22 @@ void LLFolderViewFolder::openItem( void )  	toggleOpen();  } +void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor) +{ +	for (folders_t::iterator iter = mFolders.begin(); +		iter != mFolders.end();) +	{ +		folders_t::iterator fit = iter++; +		functor.doItem((*fit)); +	} +	for (items_t::iterator iter = mItems.begin(); +		iter != mItems.end();) +	{ +		items_t::iterator iit = iter++; +		functor.doItem((*iit)); +	} +} +  void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)  {  	functor.doFolder(this); diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 30387812a6..f6264ec968 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -501,6 +501,9 @@ public:  	void applyFunctorRecursively(LLFolderViewFunctor& functor);  	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); +	// Just apply this functor to the folder's immediate children. +	void applyFunctorToChildren(LLFolderViewFunctor& functor); +  	virtual void openItem( void );  	virtual BOOL addItem(LLFolderViewItem* item);  	virtual BOOL addFolder( LLFolderViewFolder* folder); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a6a5ecb8e7..aa71904595 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1,5146 +1,5203 @@ -/** - * @file llinventorybridge.cpp - * @brief Implementation of the Inventory-Folder-View-Bridge classes. - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab.  Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llinventorybridge.h" - -#include "llagent.h" -#include "llagentwearables.h" -#include "llappearancemgr.h" -#include "llavataractions.h" -#include "llfloatercustomize.h" -#include "llfloaterinventory.h" -#include "llfloateropenobject.h" -#include "llfloaterreg.h" -#include "llfloaterworldmap.h" -#include "llfriendcard.h" -#include "llgesturemgr.h" -#include "llimfloater.h" -#include "llimview.h" -#include "llinventoryclipboard.h" -#include "llinventoryfunctions.h" -#include "llinventorymodel.h" -#include "llinventorypanel.h" -#include "llpreviewanim.h" -#include "llpreviewgesture.h" -#include "llpreviewtexture.h" -#include "llselectmgr.h" -#include "llsidetray.h" -#include "lltrans.h" -#include "llviewerassettype.h" -#include "llviewermessage.h" -#include "llviewerobjectlist.h" -#include "llviewerwindow.h" -#include "llvoavatarself.h" -#include "llwearablelist.h" - -using namespace LLOldEvents; - -// Helpers -// bug in busy count inc/dec right now, logic is complex... do we really need it? -void inc_busy_count() -{ -// 	gViewerWindow->getWindow()->incBusyCount(); -//  check balance of these calls if this code is changed to ever actually -//  *do* something! -} -void dec_busy_count() -{ -// 	gViewerWindow->getWindow()->decBusyCount(); -//  check balance of these calls if this code is changed to ever actually -//  *do* something! -} - -// Function declarations -void wear_add_inventory_item_on_avatar(LLInventoryItem* item); -void remove_inventory_category_from_avatar(LLInventoryCategory* category); -void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id); -bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*); -bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response); - -std::string ICON_NAME[ICON_NAME_COUNT] = -{ -	"Inv_Texture", -	"Inv_Sound", -	"Inv_CallingCard", -	"Inv_CallingCard", -	"Inv_Landmark", -	"Inv_Landmark", -	"Inv_Script", -	"Inv_Clothing", -	"Inv_Object", -	"Inv_Object", -	"Inv_Notecard", -	"Inv_Skin", -	"Inv_Snapshot", - -	"Inv_BodyShape", -	"Inv_Skin", -	"Inv_Hair", -	"Inv_Eye", -	"Inv_Shirt", -	"Inv_Pants", -	"Inv_Shoe", -	"Inv_Socks", -	"Inv_Jacket", -	"Inv_Gloves", -	"Inv_Undershirt", -	"Inv_Underpants", -	"Inv_Skirt", -	"Inv_Alpha", -	"Inv_Tattoo", - -	"Inv_Animation", -	"Inv_Gesture", - -	"inv_item_linkitem.tga", -	"inv_item_linkfolder.tga" -}; - -// +=================================================+ -// |        LLInvFVBridge                            | -// +=================================================+ - -LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid) : -mUUID(uuid), mInvType(LLInventoryType::IT_NONE) -{ -	mInventoryPanel = inventory->getHandle(); -} - -const std::string& LLInvFVBridge::getName() const -{ -	LLInventoryObject* obj = getInventoryObject(); -	if(obj) -	{ -		return obj->getName(); -	} -	return LLStringUtil::null; -} - -const std::string& LLInvFVBridge::getDisplayName() const -{ -	return getName(); -} - -// Folders have full perms -PermissionMask LLInvFVBridge::getPermissionMask() const -{ - -	return PERM_ALL; -} - -// virtual -LLFolderType::EType LLInvFVBridge::getPreferredType() const -{ -	return LLFolderType::FT_NONE; -} - - -// Folders don't have creation dates. -time_t LLInvFVBridge::getCreationDate() const -{ -	return 0; -} - -// Can be destoryed (or moved to trash) -BOOL LLInvFVBridge::isItemRemovable() -{ -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; -	if(model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) -	{ -		return TRUE; -	} -	return FALSE; -} - -// Can be moved to another folder -BOOL LLInvFVBridge::isItemMovable() const -{ -	return TRUE; -} - -/*virtual*/ -/** - * @brief Adds this item into clipboard storage - */ -void LLInvFVBridge::cutToClipboard() -{ -	if(isItemMovable()) -	{ -		LLInventoryClipboard::instance().cut(mUUID); -	} -} -// *TODO: make sure this does the right thing -void LLInvFVBridge::showProperties() -{ -	LLSD key; -	key["id"] = mUUID; -	LLSideTray::getInstance()->showPanel("sidepanel_inventory", key); - -	// Disable old properties floater; this is replaced by the sidepanel. -	/* -	LLFloaterReg::showInstance("properties", mUUID); -	*/ -} - -void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) -{ -	// Deactivate gestures when moving them into Trash -	LLInvFVBridge* bridge; -	LLInventoryModel* model = getInventoryModel(); -	LLViewerInventoryItem* item = NULL; -	LLViewerInventoryCategory* cat = NULL; -	LLInventoryModel::cat_array_t	descendent_categories; -	LLInventoryModel::item_array_t	descendent_items; -	S32 count = batch.count(); -	S32 i,j; -	for(i = 0; i < count; ++i) -	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); -		if(!bridge || !bridge->isItemRemovable()) continue; -		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); -		if (item) -		{ -			if(LLAssetType::AT_GESTURE == item->getType()) -			{ -				LLGestureManager::instance().deactivateGesture(item->getUUID()); -			} -		} -	} -	for(i = 0; i < count; ++i) -	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); -		if(!bridge || !bridge->isItemRemovable()) continue; -		cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); -		if (cat) -		{ -			gInventory.collectDescendents( cat->getUUID(), descendent_categories, descendent_items, FALSE ); -			for (j=0; j<descendent_items.count(); j++) -			{ -				if(LLAssetType::AT_GESTURE == descendent_items[j]->getType()) -				{ -					LLGestureManager::instance().deactivateGesture(descendent_items[j]->getUUID()); -				} -			} -		} -	} -	removeBatchNoCheck(batch); -} - -void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch) -{ -	// this method moves a bunch of items and folders to the trash. As -	// per design guidelines for the inventory model, the message is -	// built and the accounting is performed first. After all of that, -	// we call LLInventoryModel::moveObject() to move everything -	// around. -	LLInvFVBridge* bridge; -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return; -	LLMessageSystem* msg = gMessageSystem; -	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); -	LLViewerInventoryItem* item = NULL; -	LLViewerInventoryCategory* cat = NULL; -	std::vector<LLUUID> move_ids; -	LLInventoryModel::update_map_t update; -	bool start_new_message = true; -	S32 count = batch.count(); -	S32 i; -	for(i = 0; i < count; ++i) -	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); -		if(!bridge || !bridge->isItemRemovable()) continue; -		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); -		if(item) -		{ -			if(item->getParentUUID() == trash_id) continue; -			move_ids.push_back(item->getUUID()); -			LLPreview::hide(item->getUUID()); -			--update[item->getParentUUID()]; -			++update[trash_id]; -			if(start_new_message) -			{ -				start_new_message = false; -				msg->newMessageFast(_PREHASH_MoveInventoryItem); -				msg->nextBlockFast(_PREHASH_AgentData); -				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -				msg->addBOOLFast(_PREHASH_Stamp, TRUE); -			} -			msg->nextBlockFast(_PREHASH_InventoryData); -			msg->addUUIDFast(_PREHASH_ItemID, item->getUUID()); -			msg->addUUIDFast(_PREHASH_FolderID, trash_id); -			msg->addString("NewName", NULL); -			if(msg->isSendFullFast(_PREHASH_InventoryData)) -			{ -				start_new_message = true; -				gAgent.sendReliableMessage(); -				gInventory.accountForUpdate(update); -				update.clear(); -			} -		} -	} -	if(!start_new_message) -	{ -		start_new_message = true; -		gAgent.sendReliableMessage(); -		gInventory.accountForUpdate(update); -		update.clear(); -	} -	for(i = 0; i < count; ++i) -	{ -		bridge = (LLInvFVBridge*)(batch.get(i)); -		if(!bridge || !bridge->isItemRemovable()) continue; -		cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); -		if(cat) -		{ -			if(cat->getParentUUID() == trash_id) continue; -			move_ids.push_back(cat->getUUID()); -			--update[cat->getParentUUID()]; -			++update[trash_id]; -			if(start_new_message) -			{ -				start_new_message = false; -				msg->newMessageFast(_PREHASH_MoveInventoryFolder); -				msg->nextBlockFast(_PREHASH_AgentData); -				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -				msg->addBOOL("Stamp", TRUE); -			} -			msg->nextBlockFast(_PREHASH_InventoryData); -			msg->addUUIDFast(_PREHASH_FolderID, cat->getUUID()); -			msg->addUUIDFast(_PREHASH_ParentID, trash_id); -			if(msg->isSendFullFast(_PREHASH_InventoryData)) -			{ -				start_new_message = true; -				gAgent.sendReliableMessage(); -				gInventory.accountForUpdate(update); -				update.clear(); -			} -		} -	} -	if(!start_new_message) -	{ -		gAgent.sendReliableMessage(); -		gInventory.accountForUpdate(update); -	} - -	// move everything. -	std::vector<LLUUID>::iterator it = move_ids.begin(); -	std::vector<LLUUID>::iterator end = move_ids.end(); -	for(; it != end; ++it) -	{ -		gInventory.moveObject((*it), trash_id); -	} - -	// notify inventory observers. -	model->notifyObservers(); -} - -BOOL LLInvFVBridge::isClipboardPasteable() const -{ -	if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory()) -	{ -		return FALSE; -	} -	LLInventoryModel* model = getInventoryModel(); -	if (!model) -	{ -		return FALSE; -	} - -	const LLUUID &agent_id = gAgent.getID(); - -	LLDynamicArray<LLUUID> objects; -	LLInventoryClipboard::instance().retrieve(objects); -	S32 count = objects.count(); -	for(S32 i = 0; i < count; i++) -	{ -		const LLUUID &item_id = objects.get(i); - -		// Can't paste folders -		const LLInventoryCategory *cat = model->getCategory(item_id); -		if (cat) -		{ -			return FALSE; -		} - -		const LLInventoryItem *item = model->getItem(item_id); -		if (item) -		{ -			if (!item->getPermissions().allowCopyBy(agent_id)) -			{ -				return FALSE; -			} -		} -	} -	return TRUE; -} - -BOOL LLInvFVBridge::isClipboardPasteableAsLink() const -{ -	if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory()) -	{ -		return FALSE; -	} -	const LLInventoryModel* model = getInventoryModel(); -	if (!model) -	{ -		return FALSE; -	} - -	LLDynamicArray<LLUUID> objects; -	LLInventoryClipboard::instance().retrieve(objects); -	S32 count = objects.count(); -	for(S32 i = 0; i < count; i++) -	{ -		const LLInventoryItem *item = model->getItem(objects.get(i)); -		if (item) -		{ -			if (!LLAssetType::lookupCanLink(item->getActualType())) -			{ -				return FALSE; -			} -		} -		const LLViewerInventoryCategory *cat = model->getCategory(objects.get(i)); -		if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType())) -		{ -			return FALSE; -		} -	} -	return TRUE; -} - -void hide_context_entries(LLMenuGL& menu,  -						const std::vector<std::string> &entries_to_show, -						const std::vector<std::string> &disabled_entries) -{ -	const LLView::child_list_t *list = menu.getChildList(); - -	LLView::child_list_t::const_iterator itor; -	for (itor = list->begin(); itor != list->end(); ++itor) -	{ -		std::string name = (*itor)->getName(); - -		// descend into split menus: -		LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(*itor); -		if ((name == "More") && branchp) -		{ -			hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries); -		} - - -		bool found = false; -		std::vector<std::string>::const_iterator itor2; -		for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2) -		{ -			if (*itor2 == name) -			{ -				found = true; -			} -		} -		if (!found) -		{ -			(*itor)->setVisible(FALSE); -		} -		else -		{ -			for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2) -			{ -				if (*itor2 == name) -				{ -					(*itor)->setEnabled(FALSE); -				} -			} -		} -	} -} - -// Helper for commonly-used entries -void LLInvFVBridge::getClipboardEntries(bool show_asset_id, -										std::vector<std::string> &items, -										std::vector<std::string> &disabled_items, U32 flags) -{ -	items.push_back(std::string("Rename")); -	if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0) -	{ -		disabled_items.push_back(std::string("Rename")); -	} - -	if (show_asset_id) -	{ -		items.push_back(std::string("Copy Asset UUID")); -		if ( (! ( isItemPermissive() || gAgent.isGodlike() ) ) -			  || (flags & FIRST_SELECTED_ITEM) == 0) -		{ -			disabled_items.push_back(std::string("Copy Asset UUID")); -		} -	} - -	items.push_back(std::string("Copy Separator")); - -	items.push_back(std::string("Copy")); -	if (!isItemCopyable()) -	{ -		disabled_items.push_back(std::string("Copy")); -	} - -	items.push_back(std::string("Paste")); -	if (!isClipboardPasteable() || (flags & FIRST_SELECTED_ITEM) == 0) -	{ -		disabled_items.push_back(std::string("Paste")); -	} - -	items.push_back(std::string("Paste As Link")); -	if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) -	{ -		disabled_items.push_back(std::string("Paste As Link")); -	} -	items.push_back(std::string("Paste Separator")); - -	items.push_back(std::string("Delete")); -	if (!isItemRemovable()) -	{ -		disabled_items.push_back(std::string("Delete")); -	} - -	// If multiple items are selected, disable properties (if it exists). -	if ((flags & FIRST_SELECTED_ITEM) == 0) -	{ -		disabled_items.push_back(std::string("Properties")); -	} -} - -void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	lldebugs << "LLInvFVBridge::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; -	if(isInTrash()) -	{ -		items.push_back(std::string("PurgeItem")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("PurgeItem")); -		} -		items.push_back(std::string("RestoreItem")); -	} -	else -	{ -		items.push_back(std::string("Open")); -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); -	} -	hide_context_entries(menu, items, disabled_items); -} - -// *TODO: remove this -BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const -{ -	BOOL rv = FALSE; - -	const LLInventoryObject* obj = getInventoryObject(); - -	if(obj) -	{ -		*type = LLViewerAssetType::lookupDragAndDropType(obj->getActualType()); -		if(*type == DAD_NONE) -		{ -			return FALSE; -		} - -		*id = obj->getUUID(); -		//object_ids.put(obj->getUUID()); - -		if (*type == DAD_CATEGORY) -		{ -			gInventory.startBackgroundFetch(obj->getUUID()); -		} - -		rv = TRUE; -	} - -	return rv; -} - -LLInventoryObject* LLInvFVBridge::getInventoryObject() const -{ -	LLInventoryObject* obj = NULL; -	LLInventoryModel* model = getInventoryModel(); -	if(model) -	{ -		obj = (LLInventoryObject*)model->getObject(mUUID); -	} -	return obj; -} - -LLInventoryModel* LLInvFVBridge::getInventoryModel() const -{ -	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); -	return panel ? panel->getModel() : NULL; -} - -BOOL LLInvFVBridge::isInTrash() const -{ -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; -	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); -	return model->isObjectDescendentOf(mUUID, trash_id); -} - -BOOL LLInvFVBridge::isLinkedObjectInTrash() const -{ -	if (isInTrash()) return TRUE; - -	const LLInventoryObject *obj = getInventoryObject(); -	if (obj && obj->getIsLinkType()) -	{ -		LLInventoryModel* model = getInventoryModel(); -		if(!model) return FALSE; -		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); -		return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id); -	} -	return FALSE; -} - -BOOL LLInvFVBridge::isAgentInventory() const -{ -	const LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; -	if(gInventory.getRootFolderID() == mUUID) return TRUE; -	return model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); -} - -BOOL LLInvFVBridge::isCOFFolder() const -{ -	const LLInventoryModel* model = getInventoryModel(); -	if(!model) return TRUE; -	const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); -	if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id)) -	{ -		return TRUE; -	} -	return FALSE; -} - -BOOL LLInvFVBridge::isItemPermissive() const -{ -	return FALSE; -} - -// static -void LLInvFVBridge::changeItemParent(LLInventoryModel* model, -									 LLViewerInventoryItem* item, -									 const LLUUID& new_parent, -									 BOOL restamp) -{ -	if(item->getParentUUID() != new_parent) -	{ -		LLInventoryModel::update_list_t update; -		LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); -		update.push_back(old_folder); -		LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1); -		update.push_back(new_folder); -		gInventory.accountForUpdate(update); - -		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); -		new_item->setParent(new_parent); -		new_item->updateParentOnServer(restamp); -		model->updateItem(new_item); -		model->notifyObservers(); -	} -} - -// static -void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model, -										 LLViewerInventoryCategory* cat, -										 const LLUUID& new_parent, -										 BOOL restamp) -{ -	if(cat->getParentUUID() != new_parent) -	{ -		LLInventoryModel::update_list_t update; -		LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); -		update.push_back(old_folder); -		LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1); -		update.push_back(new_folder); -		gInventory.accountForUpdate(update); - -		LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); -		new_cat->setParent(new_parent); -		new_cat->updateParentOnServer(restamp); -		model->updateCategory(new_cat); -		model->notifyObservers(); -	} -} - - -const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type) -{ -	const std::string rv= LLInventoryType::lookup(inv_type); -	if(rv.empty()) -	{ -		return std::string("<invalid>"); -	} -	return rv; -} - -LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, -										   LLAssetType::EType actual_asset_type, -										   LLInventoryType::EType inv_type, -										   LLInventoryPanel* inventory, -										   const LLUUID& uuid, -										   U32 flags) -{ -	LLInvFVBridge* new_listener = NULL; -	switch(asset_type) -	{ -		case LLAssetType::AT_TEXTURE: -			if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLTextureBridge(inventory, uuid, inv_type); -			break; - -		case LLAssetType::AT_SOUND: -			if(!(inv_type == LLInventoryType::IT_SOUND)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLSoundBridge(inventory, uuid); -			break; - -		case LLAssetType::AT_LANDMARK: -			if(!(inv_type == LLInventoryType::IT_LANDMARK)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLLandmarkBridge(inventory, uuid, flags); -			break; - -		case LLAssetType::AT_CALLINGCARD: -			if(!(inv_type == LLInventoryType::IT_CALLINGCARD)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLCallingCardBridge(inventory, uuid); -			break; - -		case LLAssetType::AT_SCRIPT: -			if(!(inv_type == LLInventoryType::IT_LSL)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLScriptBridge(inventory, uuid); -			break; - -		case LLAssetType::AT_OBJECT: -			if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags); -			break; - -		case LLAssetType::AT_NOTECARD: -			if(!(inv_type == LLInventoryType::IT_NOTECARD)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLNotecardBridge(inventory, uuid); -			break; - -		case LLAssetType::AT_ANIMATION: -			if(!(inv_type == LLInventoryType::IT_ANIMATION)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLAnimationBridge(inventory, uuid); -			break; - -		case LLAssetType::AT_GESTURE: -			if(!(inv_type == LLInventoryType::IT_GESTURE)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLGestureBridge(inventory, uuid); -			break; - -		case LLAssetType::AT_LSL_TEXT: -			if(!(inv_type == LLInventoryType::IT_LSL)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLLSLTextBridge(inventory, uuid); -			break; - -		case LLAssetType::AT_CLOTHING: -		case LLAssetType::AT_BODYPART: -			if(!(inv_type == LLInventoryType::IT_WEARABLE)) -			{ -				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; -			} -			new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags); -			break; -		case LLAssetType::AT_CATEGORY: -			if (actual_asset_type == LLAssetType::AT_LINK_FOLDER) -			{ -				// Create a link folder handler instead. -				new_listener = new LLLinkFolderBridge(inventory, uuid); -				break; -			} -			new_listener = new LLFolderBridge(inventory, uuid); -			break; -		case LLAssetType::AT_LINK: -			// Only should happen for broken links. -			new_listener = new LLLinkItemBridge(inventory, uuid); -			break; -		case LLAssetType::AT_LINK_FOLDER: -			// Only should happen for broken links. -			new_listener = new LLLinkItemBridge(inventory, uuid); -			break; -		default: -			llinfos << "Unhandled asset type (llassetstorage.h): " -					<< (S32)asset_type << llendl; -			break; -	} - -	if (new_listener) -	{ -		new_listener->mInvType = inv_type; -	} - -	return new_listener; -} - -void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) -{ -	LLInventoryCategory* cat = model->getCategory(uuid); -	if (cat) -	{ -		model->purgeDescendentsOf(uuid); -		model->notifyObservers(); -	} -	LLInventoryObject* obj = model->getObject(uuid); -	if (obj) -	{ -		model->purgeObject(uuid); -		model->notifyObservers(); -	} -} - -// +=================================================+ -// |        InventoryFVBridgeBuilder                 | -// +=================================================+ -LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type, -														LLAssetType::EType actual_asset_type, -														LLInventoryType::EType inv_type, -														LLInventoryPanel* inventory, -														const LLUUID& uuid, -														U32 flags /* = 0x00 */) const -{ -	return LLInvFVBridge::createBridge(asset_type, -		actual_asset_type, -		inv_type, -		inventory, -		uuid, -		flags); -} - -// +=================================================+ -// |        LLItemBridge                             | -// +=================================================+ - -void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("goto" == action) -	{ -		gotoItem(folder); -	} -	if ("open" == action) -	{ -		openItem(); -		return; -	} -	else if ("properties" == action) -	{ -		showProperties(); -		return; -	} -	else if ("purge" == action) -	{ -		purgeItem(model, mUUID); -		return; -	} -	else if ("restoreToWorld" == action) -	{ -		restoreToWorld(); -		return; -	} -	else if ("restore" == action) -	{ -		restoreItem(); -		return; -	} -	else if ("copy_uuid" == action) -	{ -		// Single item only -		LLInventoryItem* item = model->getItem(mUUID); -		if(!item) return; -		LLUUID asset_id = item->getAssetUUID(); -		std::string buffer; -		asset_id.toString(buffer); - -		gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); -		return; -	} -	else if ("copy" == action) -	{ -		copyToClipboard(); -		return; -	} -	else if ("paste" == action) -	{ -		// Single item only -		LLInventoryItem* itemp = model->getItem(mUUID); -		if (!itemp) return; - -		LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID()); -		if (!folder_view_itemp) return; - -		folder_view_itemp->getListener()->pasteFromClipboard(); -		return; -	} -	else if ("paste_link" == action) -	{ -		// Single item only -		LLInventoryItem* itemp = model->getItem(mUUID); -		if (!itemp) return; - -		LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID()); -		if (!folder_view_itemp) return; - -		folder_view_itemp->getListener()->pasteLinkFromClipboard(); -		return; -	} -} - -void LLItemBridge::selectItem() -{ -	LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); -	if(item && !item->isComplete()) -	{ -		item->fetchFromServer(); -	} -} - -void LLItemBridge::restoreItem() -{ -	LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); -	if(item) -	{ -		LLInventoryModel* model = getInventoryModel(); -		const LLUUID new_parent = model->findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(item->getType())); -		// do not restamp on restore. -		LLInvFVBridge::changeItemParent(model, item, new_parent, FALSE); -	} -} - -void LLItemBridge::restoreToWorld() -{ -	LLViewerInventoryItem* itemp = (LLViewerInventoryItem*)getItem(); -	if (itemp) -	{ -		LLMessageSystem* msg = gMessageSystem; -		msg->newMessage("RezRestoreToWorld"); -		msg->nextBlockFast(_PREHASH_AgentData); -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - -		msg->nextBlockFast(_PREHASH_InventoryData); -		itemp->packMessage(msg); -		msg->sendReliable(gAgent.getRegion()->getHost()); -	} - -	//Similar functionality to the drag and drop rez logic -	BOOL remove_from_inventory = FALSE; - -	//remove local inventory copy, sim will deal with permissions and removing the item -	//from the actual inventory if its a no-copy etc -	if(!itemp->getPermissions().allowCopyBy(gAgent.getID())) -	{ -		remove_from_inventory = TRUE; -	} - -	// Check if it's in the trash. (again similar to the normal rez logic) -	const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); -	if(gInventory.isObjectDescendentOf(itemp->getUUID(), trash_id)) -	{ -		remove_from_inventory = TRUE; -	} - -	if(remove_from_inventory) -	{ -		gInventory.deleteObject(itemp->getUUID()); -		gInventory.notifyObservers(); -	} -} - -void LLItemBridge::gotoItem(LLFolderView *folder) -{ -	LLInventoryObject *obj = getInventoryObject(); -	if (obj && obj->getIsLinkType()) -	{ -		LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); -		if (active_panel) -		{ -			active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); -		} -	} -} - -LLUIImagePtr LLItemBridge::getIcon() const -{ -	return LLUI::getUIImage(ICON_NAME[OBJECT_ICON_NAME]); -} - -PermissionMask LLItemBridge::getPermissionMask() const -{ -	LLViewerInventoryItem* item = getItem(); -	PermissionMask perm_mask = 0; -	if(item) -	{ -		BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); -		BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); -		BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, -															gAgent.getID()); - -		if (copy) perm_mask |= PERM_COPY; -		if (mod)  perm_mask |= PERM_MODIFY; -		if (xfer) perm_mask |= PERM_TRANSFER; - -	} -	return perm_mask; -} - -const std::string& LLItemBridge::getDisplayName() const -{ -	if(mDisplayName.empty()) -	{ -		buildDisplayName(getItem(), mDisplayName); -	} -	return mDisplayName; -} - -void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name) -{ -	if(item) -	{ -		name.assign(item->getName()); -	} -	else -	{ -		name.assign(LLStringUtil::null); -	} -} - -LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const -{ -	U8 font = LLFontGL::NORMAL; - -	if( gAgentWearables.isWearingItem( mUUID ) ) -	{ -		// llinfos << "BOLD" << llendl; -		font |= LLFontGL::BOLD; -	} - -	const LLViewerInventoryItem* item = getItem(); -	if (item && item->getIsLinkType()) -	{ -		font |= LLFontGL::ITALIC; -	} -	return (LLFontGL::StyleFlags)font; -} - -std::string LLItemBridge::getLabelSuffix() const -{ -	// String table is loaded before login screen and inventory items are -	// loaded after login, so LLTrans should be ready. -	static std::string NO_COPY =LLTrans::getString("no_copy"); -	static std::string NO_MOD = LLTrans::getString("no_modify"); -	static std::string NO_XFER = LLTrans::getString("no_transfer"); -	static std::string LINK = LLTrans::getString("link"); -	static std::string BROKEN_LINK = LLTrans::getString("broken_link"); -	std::string suffix; -	LLInventoryItem* item = getItem(); -	if(item) -	{ -		// it's a bit confusing to put nocopy/nomod/etc on calling cards. -		if(LLAssetType::AT_CALLINGCARD != item->getType() -		   && item->getPermissions().getOwner() == gAgent.getID()) -		{ -			BOOL broken_link = LLAssetType::lookupIsLinkType(item->getType()); -			if (broken_link) return BROKEN_LINK; - -			BOOL link = item->getIsLinkType(); -			if (link) return LINK; - -			BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); -			if (!copy) -			{ -				suffix += NO_COPY; -			} -			BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); -			if (!mod) -			{ -				suffix += NO_MOD; -			} -			BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, -																gAgent.getID()); -			if (!xfer) -			{ -				suffix += NO_XFER; -			} -		} -	} -	return suffix; -} - -time_t LLItemBridge::getCreationDate() const -{ -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		return item->getCreationDate(); -	} -	return 0; -} - - -BOOL LLItemBridge::isItemRenameable() const -{ -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		// (For now) Don't allow calling card rename since that may confuse users as to -		// what the calling card points to. -		if (item->getInventoryType() == LLInventoryType::IT_CALLINGCARD) -		{ -			return FALSE; -		} -		return (item->getPermissions().allowModifyBy(gAgent.getID())); -	} -	return FALSE; -} - -BOOL LLItemBridge::renameItem(const std::string& new_name) -{ -	if(!isItemRenameable()) -		return FALSE; -	LLPreview::dirty(mUUID); -	LLInventoryModel* model = getInventoryModel(); -	if(!model) -		return FALSE; -	LLViewerInventoryItem* item = getItem(); -	if(item && (item->getName() != new_name)) -	{ -		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); -		new_item->rename(new_name); -		buildDisplayName(new_item, mDisplayName); -		new_item->updateServer(FALSE); -		model->updateItem(new_item); - -		model->notifyObservers(); -	} -	// return FALSE because we either notified observers (& therefore -	// rebuilt) or we didn't update. -	return FALSE; -} - - -BOOL LLItemBridge::removeItem() -{ -	if(!isItemRemovable()) -	{ -		return FALSE; -	} -	// move it to the trash -	LLPreview::hide(mUUID, TRUE); -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; -	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); -	LLViewerInventoryItem* item = getItem(); - -	// if item is not already in trash -	if(item && !model->isObjectDescendentOf(mUUID, trash_id)) -	{ -		// move to trash, and restamp -		LLInvFVBridge::changeItemParent(model, item, trash_id, TRUE); -		// delete was successful -		return TRUE; -	} -	else -	{ -		// tried to delete already item in trash (should purge?) -		return FALSE; -	} -} - -BOOL LLItemBridge::isItemCopyable() const -{ -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		// can't copy worn objects. DEV-15183 -		LLVOAvatarSelf *avatarp = gAgent.getAvatarObject(); -		if( !avatarp ) -		{ -			return FALSE; -		} - -		if(avatarp->isWearingAttachment(mUUID)) -		{ -			return FALSE; -		} - -		// All items can be copied, not all can be pasted. -		// The only time an item can't be copied is if it's a link -		// return (item->getPermissions().allowCopyBy(gAgent.getID())); -		if (item->getIsLinkType()) -		{ -			return FALSE; -		} -		return TRUE; -	} -	return FALSE; -} -BOOL LLItemBridge::copyToClipboard() const -{ -	if(isItemCopyable()) -	{ -		LLInventoryClipboard::instance().add(mUUID); -		return TRUE; -	} -	return FALSE; -} - -LLViewerInventoryItem* LLItemBridge::getItem() const -{ -	LLViewerInventoryItem* item = NULL; -	LLInventoryModel* model = getInventoryModel(); -	if(model) -	{ -		item = (LLViewerInventoryItem*)model->getItem(mUUID); -	} -	return item; -} - -BOOL LLItemBridge::isItemPermissive() const -{ -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		U32 mask = item->getPermissions().getMaskBase(); -		if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) -		{ -			return TRUE; -		} -	} -	return FALSE; -} - -// +=================================================+ -// |        LLFolderBridge                           | -// +=================================================+ - -LLFolderBridge* LLFolderBridge::sSelf=NULL; - -// Can be moved to another folder -BOOL LLFolderBridge::isItemMovable() const -{ -	LLInventoryObject* obj = getInventoryObject(); -	if(obj) -	{ -		return (!LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType())); -	} -	return FALSE; -} - -void LLFolderBridge::selectItem() -{ -} - - -// Can be destroyed (or moved to trash) -BOOL LLFolderBridge::isItemRemovable() -{ -	LLInventoryModel* model = getInventoryModel(); -	if(!model) -	{ -		return FALSE; -	} - -	if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) -	{ -		return FALSE; -	} - -	LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); -	if( !avatar ) -	{ -		return FALSE; -	} - -	LLInventoryCategory* category = model->getCategory(mUUID); -	if( !category ) -	{ -		return FALSE; -	} - -	if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) -	{ -		return FALSE; -	} - -	LLInventoryModel::cat_array_t	descendent_categories; -	LLInventoryModel::item_array_t	descendent_items; -	gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE ); - -	S32 i; -	for( i = 0; i < descendent_categories.count(); i++ ) -	{ -		LLInventoryCategory* category = descendent_categories[i]; -		if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) -		{ -			return FALSE; -		} -	} - -	for( i = 0; i < descendent_items.count(); i++ ) -	{ -		LLInventoryItem* item = descendent_items[i]; -		if( (item->getType() == LLAssetType::AT_CLOTHING) || -			(item->getType() == LLAssetType::AT_BODYPART) ) -		{ -			if(gAgentWearables.isWearingItem(item->getUUID())) -			{ -				return FALSE; -			} -		} -		else -		if( item->getType() == LLAssetType::AT_OBJECT ) -		{ -			if(avatar->isWearingAttachment(item->getUUID())) -			{ -				return FALSE; -			} -		} -	} - -	return TRUE; -} - -BOOL LLFolderBridge::isUpToDate() const -{ -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; -	LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); -	if( !category ) -	{ -		return FALSE; -	} - -	return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN; -} - -BOOL LLFolderBridge::isItemCopyable() const -{ -	return TRUE; -} - -BOOL LLFolderBridge::copyToClipboard() const -{ -	if(isItemCopyable()) -	{ -		LLInventoryClipboard::instance().add(mUUID); -		return TRUE; -	} -	return FALSE; -} - -BOOL LLFolderBridge::isClipboardPasteable() const -{ -	if ( ! LLInvFVBridge::isClipboardPasteable() ) -		return FALSE; - -	// Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599 -	if ( LLFriendCardsManager::instance().isCategoryInFriendFolder( getCategory() ) ) -	{ -		LLInventoryModel* model = getInventoryModel(); -		if ( !model ) -		{ -			return FALSE; -		} - -		LLDynamicArray<LLUUID> objects; -		LLInventoryClipboard::instance().retrieve(objects); -		const LLViewerInventoryCategory *current_cat = getCategory(); - -		// Search for the direct descendent of current Friends subfolder among all pasted items, -		// and return false if is found. -		for(S32 i = objects.count() - 1; i >= 0; --i) -		{ -			const LLUUID &obj_id = objects.get(i); -			if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) ) -			{ -				return FALSE; -			} -		} - -	} -	return TRUE; -} - -BOOL LLFolderBridge::isClipboardPasteableAsLink() const -{ -	// Check normal paste-as-link permissions -	if (!LLInvFVBridge::isClipboardPasteableAsLink()) -	{ -		return FALSE; -	} - -	const LLInventoryModel* model = getInventoryModel(); -	if (!model) -	{ -		return FALSE; -	} - -	const LLViewerInventoryCategory *current_cat = getCategory(); -	if (current_cat) -	{ -		const BOOL is_in_friend_folder = LLFriendCardsManager::instance().isCategoryInFriendFolder( current_cat ); -		const LLUUID ¤t_cat_id = current_cat->getUUID(); -		LLDynamicArray<LLUUID> objects; -		LLInventoryClipboard::instance().retrieve(objects); -		S32 count = objects.count(); -		for(S32 i = 0; i < count; i++) -		{ -			const LLUUID &obj_id = objects.get(i); -			const LLInventoryCategory *cat = model->getCategory(obj_id); -			if (cat) -			{ -				const LLUUID &cat_id = cat->getUUID(); -				// Don't allow recursive pasting -				if ((cat_id == current_cat_id) || -					model->isObjectDescendentOf(current_cat_id, cat_id)) -				{ -					return FALSE; -				} -			} -			// Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599 -			if ( is_in_friend_folder ) -			{ -				// If object is direct descendent of current Friends subfolder than return false. -				// Note: We can't use 'const LLInventoryCategory *cat', because it may be null -				// in case type of obj_id is LLInventoryItem. -				if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) ) -				{ -					return FALSE; -				} -			} -		} -	} -	return TRUE; - -} - -BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, -											BOOL drop) -{ -	// This should never happen, but if an inventory item is incorrectly parented, -	// the UI will get confused and pass in a NULL. -	if(!inv_cat) return FALSE; - -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; - -	LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); -	if(!avatar) return FALSE; - -	// cannot drag categories into library -	if(!isAgentInventory()) -	{ -		return FALSE; -	} - -	// check to make sure source is agent inventory, and is represented there. -	LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); -	BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL) -		&& (LLToolDragAndDrop::SOURCE_AGENT == source); - -	BOOL accept = FALSE; -	S32 i; -	LLInventoryModel::cat_array_t	descendent_categories; -	LLInventoryModel::item_array_t	descendent_items; -	if(is_agent_inventory) -	{ -		const LLUUID& cat_id = inv_cat->getUUID(); - -		// Is the destination the trash? -		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); -		BOOL move_is_into_trash = (mUUID == trash_id) -				|| model->isObjectDescendentOf(mUUID, trash_id); -		BOOL is_movable = (!LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())); -		const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); -		BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); -		BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); -		if (move_is_into_current_outfit || move_is_into_outfit) -		{ -			// BAP - restrictions? -			is_movable = true; -		} - -		if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)) -		{ -			is_movable = FALSE; // It's generally movable but not into Favorites folder. EXT-1604 -		} - -		if( is_movable ) -		{ -			gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE ); - -			for( i = 0; i < descendent_categories.count(); i++ ) -			{ -				LLInventoryCategory* category = descendent_categories[i]; -				if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) -				{ -					// ...can't move "special folders" like Textures -					is_movable = FALSE; -					break; -				} -			} - -			if( is_movable ) -			{ -				if( move_is_into_trash ) -				{ -					for( i = 0; i < descendent_items.count(); i++ ) -					{ -						LLInventoryItem* item = descendent_items[i]; -						if( (item->getType() == LLAssetType::AT_CLOTHING) || -							(item->getType() == LLAssetType::AT_BODYPART) ) -						{ -							if( gAgentWearables.isWearingItem( item->getUUID() ) ) -							{ -								is_movable = FALSE;  // It's generally movable, but not into the trash! -								break; -							} -						} -						else -						if( item->getType() == LLAssetType::AT_OBJECT ) -						{ -							if( avatar->isWearingAttachment( item->getUUID() ) ) -							{ -								is_movable = FALSE;  // It's generally movable, but not into the trash! -								break; -							} -						} -					} -				} -			} -		} - - -		accept =	is_movable -					&& (mUUID != cat_id)								// Can't move a folder into itself -					&& (mUUID != inv_cat->getParentUUID())				// Avoid moves that would change nothing -					&& !(model->isObjectDescendentOf(mUUID, cat_id));	// Avoid circularity -		if(accept && drop) -		{ -			// Look for any gestures and deactivate them -			if (move_is_into_trash) -			{ -				for (i = 0; i < descendent_items.count(); i++) -				{ -					LLInventoryItem* item = descendent_items[i]; -					if (item->getType() == LLAssetType::AT_GESTURE -						&& LLGestureManager::instance().isGestureActive(item->getUUID())) -					{ -						LLGestureManager::instance().deactivateGesture(item->getUUID()); -					} -				} -			} -			// if target is an outfit or current outfit folder we use link -			if (move_is_into_current_outfit || move_is_into_outfit) -			{ -				if (inv_cat->getPreferredType() == LLFolderType::FT_NONE) -				{ -					if (move_is_into_current_outfit) -					{ -						// traverse category and add all contents to currently worn. -						BOOL append = true; -						LLAppearanceManager::instance().wearInventoryCategory(inv_cat, false, append); -					} -					else -					{ -						// Recursively create links in target outfit. -						LLInventoryModel::cat_array_t cats; -						LLInventoryModel::item_array_t items; -						gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH); -						LLAppearanceManager::instance().linkAll(mUUID,items,NULL); -					} -				} -				else -				{ -#if SUPPORT_ENSEMBLES -				// BAP - should skip if dup. -				if (move_is_into_current_outfit) -				{ -					LLAppearanceManager::instance().addEnsembleLink(inv_cat); -				} -				else -				{ -					LLPointer<LLInventoryCallback> cb = NULL; -					link_inventory_item( -						gAgent.getID(), -						inv_cat->getUUID(), -						mUUID, -						inv_cat->getName(), -						LLAssetType::AT_LINK_FOLDER, -						cb); -				} -#endif -				} -			} -			else -			{ - -				// Reparent the folder and restamp children if it's moving -				// into trash. -				LLInvFVBridge::changeCategoryParent( -					model, -					(LLViewerInventoryCategory*)inv_cat, -					mUUID, -					move_is_into_trash); -			} -		} -	} -	else if(LLToolDragAndDrop::SOURCE_WORLD == source) -	{ -		// content category has same ID as object itself -		LLUUID object_id = inv_cat->getUUID(); -		LLUUID category_id = mUUID; -		accept = move_inv_category_world_to_agent(object_id, category_id, drop); -	} -	return accept; -} - -void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv) -{ -	const char* dialog = NULL; -	if (object->flagScripted()) -	{ -		dialog = "MoveInventoryFromScriptedObject"; -	} -	else -	{ -		dialog = "MoveInventoryFromObject"; -	} -	LLNotifications::instance().add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv)); -} - -// Move/copy all inventory items from the Contents folder of an in-world -// object to the agent's inventory, inside a given category. -BOOL move_inv_category_world_to_agent(const LLUUID& object_id, -									  const LLUUID& category_id, -									  BOOL drop, -									  void (*callback)(S32, void*), -									  void* user_data) -{ -	// Make sure the object exists. If we allowed dragging from -	// anonymous objects, it would be possible to bypass -	// permissions. -	// content category has same ID as object itself -	LLViewerObject* object = gObjectList.findObject(object_id); -	if(!object) -	{ -		llinfos << "Object not found for drop." << llendl; -		return FALSE; -	} - -	// this folder is coming from an object, as there is only one folder in an object, the root, -	// we need to collect the entire contents and handle them as a group -	InventoryObjectList inventory_objects; -	object->getInventoryContents(inventory_objects); - -	if (inventory_objects.empty()) -	{ -		llinfos << "Object contents not found for drop." << llendl; -		return FALSE; -	} - -	BOOL accept = TRUE; -	BOOL is_move = FALSE; - -	// coming from a task. Need to figure out if the person can -	// move/copy this item. -	InventoryObjectList::iterator it = inventory_objects.begin(); -	InventoryObjectList::iterator end = inventory_objects.end(); -	for ( ; it != end; ++it) -	{ -		// coming from a task. Need to figure out if the person can -		// move/copy this item. -		LLPermissions perm(((LLInventoryItem*)((LLInventoryObject*)(*it)))->getPermissions()); -		if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) -			&& perm.allowTransferTo(gAgent.getID()))) -//			|| gAgent.isGodlike()) -		{ -			accept = TRUE; -		} -		else if(object->permYouOwner()) -		{ -			// If the object cannot be copied, but the object the -			// inventory is owned by the agent, then the item can be -			// moved from the task to agent inventory. -			is_move = TRUE; -			accept = TRUE; -		} -		else -		{ -			accept = FALSE; -			break; -		} -	} - -	if(drop && accept) -	{ -		it = inventory_objects.begin(); -		InventoryObjectList::iterator first_it = inventory_objects.begin(); -		LLMoveInv* move_inv = new LLMoveInv; -		move_inv->mObjectID = object_id; -		move_inv->mCategoryID = category_id; -		move_inv->mCallback = callback; -		move_inv->mUserData = user_data; - -		for ( ; it != end; ++it) -		{ -			two_uuids_t two(category_id, (*it)->getUUID()); -			move_inv->mMoveList.push_back(two); -		} - -		if(is_move) -		{ -			// Callback called from within here. -			warn_move_inventory(object, move_inv); -		} -		else -		{ -			LLNotification::Params params("MoveInventoryFromObject"); -			params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv)); -			LLNotifications::instance().forceResponse(params, 0); -		} -	} -	return accept; -} - -bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, -									 LLInventoryItem* item) -{ -	// Valid COF items are: -	// - links to wearables (body parts or clothing) -	// - links to attachments -	// - links to gestures -	// - links to ensemble folders -	LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); // BAP - safe? -	if (linked_item) -	{ -		LLAssetType::EType type = linked_item->getType(); -		return (type == LLAssetType::AT_CLOTHING || -				type == LLAssetType::AT_BODYPART || -				type == LLAssetType::AT_GESTURE || -				type == LLAssetType::AT_OBJECT); -	} -	else -	{ -		LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); // BAP - safe? -		// BAP remove AT_NONE support after ensembles are fully working? -		return (linked_category && -				((linked_category->getPreferredType() == LLFolderType::FT_NONE) || -				 (LLFolderType::lookupIsEnsembleType(linked_category->getPreferredType())))); -	} -} - - -bool LLFindWearables::operator()(LLInventoryCategory* cat, -								 LLInventoryItem* item) -{ -	if(item) -	{ -		if((item->getType() == LLAssetType::AT_CLOTHING) -		   || (item->getType() == LLAssetType::AT_BODYPART)) -		{ -			return TRUE; -		} -	} -	return FALSE; -} - - - -//Used by LLFolderBridge as callback for directory recursion. -class LLRightClickInventoryFetchObserver : public LLInventoryFetchObserver -{ -public: -	LLRightClickInventoryFetchObserver() : -		mCopyItems(false) -	{ }; -	LLRightClickInventoryFetchObserver(const LLUUID& cat_id, bool copy_items) : -		mCatID(cat_id), -		mCopyItems(copy_items) -		{ }; -	virtual void done() -	{ -		// we've downloaded all the items, so repaint the dialog -		LLFolderBridge::staticFolderOptionsMenu(); - -		gInventory.removeObserver(this); -		delete this; -	} - - -protected: -	LLUUID mCatID; -	bool mCopyItems; - -}; - -//Used by LLFolderBridge as callback for directory recursion. -class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver -{ -public: -	LLRightClickInventoryFetchDescendentsObserver(bool copy_items) : mCopyItems(copy_items) {} -	~LLRightClickInventoryFetchDescendentsObserver() {} -	virtual void done(); -protected: -	bool mCopyItems; -}; - -void LLRightClickInventoryFetchDescendentsObserver::done() -{ -	// Avoid passing a NULL-ref as mCompleteFolders.front() down to -	// gInventory.collectDescendents() -	if( mCompleteFolders.empty() ) -	{ -		llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl; -		dec_busy_count(); -		gInventory.removeObserver(this); -		delete this; -		return; -	} - -	// What we do here is get the complete information on the items in -	// the library, and set up an observer that will wait for that to -	// happen. -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t item_array; -	gInventory.collectDescendents(mCompleteFolders.front(), -								  cat_array, -								  item_array, -								  LLInventoryModel::EXCLUDE_TRASH); -	S32 count = item_array.count(); -#if 0 // HACK/TODO: Why? -	// This early causes a giant menu to get produced, and doesn't seem to be needed. -	if(!count) -	{ -		llwarns << "Nothing fetched in category " << mCompleteFolders.front() -				<< llendl; -		dec_busy_count(); -		gInventory.removeObserver(this); -		delete this; -		return; -	} -#endif - -	LLRightClickInventoryFetchObserver* outfit; -	outfit = new LLRightClickInventoryFetchObserver(mCompleteFolders.front(), mCopyItems); -	LLInventoryFetchObserver::item_ref_t ids; -	for(S32 i = 0; i < count; ++i) -	{ -		ids.push_back(item_array.get(i)->getUUID()); -	} - -	// clean up, and remove this as an observer since the call to the -	// outfit could notify observers and throw us into an infinite -	// loop. -	dec_busy_count(); -	gInventory.removeObserver(this); -	delete this; - -	// increment busy count and either tell the inventory to check & -	// call done, or add this object to the inventory for observation. -	inc_busy_count(); - -	// do the fetch -	outfit->fetchItems(ids); -	outfit->done();				//Not interested in waiting and this will be right 99% of the time. -//Uncomment the following code for laggy Inventory UI. -/*	if(outfit->isEverythingComplete()) -	{ -		// everything is already here - call done. -		outfit->done(); -	} -	else -	{ -		// it's all on it's way - add an observer, and the inventory -		// will call done for us when everything is here. -		gInventory.addObserver(outfit); -	}*/ -} - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLInventoryWearObserver -// -// Observer for "copy and wear" operation to support knowing -// when the all of the contents have been added to inventory. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInventoryCopyAndWearObserver : public LLInventoryObserver -{ -public: -	LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) :mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {} -	virtual ~LLInventoryCopyAndWearObserver() {} -	virtual void changed(U32 mask); - -protected: -	LLUUID mCatID; -	int    mContentsCount; -	BOOL   mFolderAdded; -}; - - - -void LLInventoryCopyAndWearObserver::changed(U32 mask) -{ -	if((mask & (LLInventoryObserver::ADD)) != 0) -	{ -		if (!mFolderAdded) -		{ -			const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); - -			std::set<LLUUID>::const_iterator id_it = changed_items.begin(); -			std::set<LLUUID>::const_iterator id_end = changed_items.end(); -			for (;id_it != id_end; ++id_it) -			{ -				if ((*id_it) == mCatID) -				{ -					mFolderAdded = TRUE; -					break; -				} -			} -		} - -		if (mFolderAdded) -		{ -			LLViewerInventoryCategory* category = gInventory.getCategory(mCatID); - -			if (NULL == category) -			{ -				llwarns << "gInventory.getCategory(" << mCatID -					<< ") was NULL" << llendl; -			} -			else -			{ -				if (category->getDescendentCount() == -				    mContentsCount) -				{ -					gInventory.removeObserver(this); -					LLAppearanceManager::instance().wearInventoryCategory(category, FALSE, TRUE); -					delete this; -				} -			} -		} - -	} -} - - - -void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("open" == action) -	{ -		openItem(); -		return; -	} -	else if ("paste" == action) -	{ -		pasteFromClipboard(); -		return; -	} -	else if ("paste_link" == action) -	{ -		pasteLinkFromClipboard(); -		return; -	} -	else if ("properties" == action) -	{ -		showProperties(); -		return; -	} -	else if ("replaceoutfit" == action) -	{ -		modifyOutfit(FALSE); -		return; -	} -#if SUPPORT_ENSEMBLES -	else if ("wearasensemble" == action) -	{ -		LLInventoryModel* model = getInventoryModel(); -		if(!model) return; -		LLViewerInventoryCategory* cat = getCategory(); -		if(!cat) return; -		LLAppearanceManager::instance().addEnsembleLink(cat,true); -		return; -	} -#endif -	else if ("addtooutfit" == action) -	{ -		modifyOutfit(TRUE); -		return; -	} -	else if ("copy" == action) -	{ -		copyToClipboard(); -		return; -	} -	else if ("removefromoutfit" == action) -	{ -		LLInventoryModel* model = getInventoryModel(); -		if(!model) return; -		LLViewerInventoryCategory* cat = getCategory(); -		if(!cat) return; - -		remove_inventory_category_from_avatar ( cat ); -		return; -	} -	else if ("purge" == action) -	{ -		purgeItem(model, mUUID); -		return; -	} -	else if ("restore" == action) -	{ -		restoreItem(); -		return; -	} -} - -void LLFolderBridge::openItem() -{ -	lldebugs << "LLFolderBridge::openItem()" << llendl; -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return; -	if(mUUID.isNull()) return; -	bool fetching_inventory = model->fetchDescendentsOf(mUUID); -	// Only change folder type if we have the folder contents. -	if (!fetching_inventory) -	{ -		// Disabling this for now, it's causing crash when new items are added to folders -		// since folder type may change before new item item has finished processing. -		// determineFolderType(); -	} -} - -void LLFolderBridge::closeItem() -{ -	determineFolderType(); -} - -void LLFolderBridge::determineFolderType() -{ -	if (isUpToDate()) -	{ -		LLInventoryModel* model = getInventoryModel(); -		LLViewerInventoryCategory* category = model->getCategory(mUUID); -		category->determineFolderType(); -	} -} - -BOOL LLFolderBridge::isItemRenameable() const -{ -	LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory(); -	if(cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) -	   && (cat->getOwnerID() == gAgent.getID())) -	{ -		return TRUE; -	} -	return FALSE; -} - -void LLFolderBridge::restoreItem() -{ -	LLViewerInventoryCategory* cat; -	cat = (LLViewerInventoryCategory*)getCategory(); -	if(cat) -	{ -		LLInventoryModel* model = getInventoryModel(); -		const LLUUID new_parent = model->findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(cat->getType())); -		// do not restamp children on restore -		LLInvFVBridge::changeCategoryParent(model, cat, new_parent, FALSE); -	} -} - -LLFolderType::EType LLFolderBridge::getPreferredType() const -{ -	LLFolderType::EType preferred_type = LLFolderType::FT_NONE; -	LLViewerInventoryCategory* cat = getCategory(); -	if(cat) -	{ -		preferred_type = cat->getPreferredType(); -	} - -	return preferred_type; -} - -// Icons for folders are based on the preferred type -LLUIImagePtr LLFolderBridge::getIcon() const -{ -	LLFolderType::EType preferred_type = LLFolderType::FT_NONE; -	LLViewerInventoryCategory* cat = getCategory(); -	if(cat) -	{ -		preferred_type = cat->getPreferredType(); -	} -	return getIcon(preferred_type); -} - -LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type) -{ -	// we only have one folder image now -	return LLUI::getUIImage("Inv_FolderClosed"); -} - -BOOL LLFolderBridge::renameItem(const std::string& new_name) -{ -	if(!isItemRenameable()) -		return FALSE; -	LLInventoryModel* model = getInventoryModel(); -	if(!model) -		return FALSE; -	LLViewerInventoryCategory* cat = getCategory(); -	if(cat && (cat->getName() != new_name)) -	{ -		LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); -		new_cat->rename(new_name); -		new_cat->updateServer(FALSE); -		model->updateCategory(new_cat); - -		model->notifyObservers(); -	} -	// return FALSE because we either notified observers (& therefore -	// rebuilt) or we didn't update. -	return FALSE; -} - -BOOL LLFolderBridge::removeItem() -{ -	if(!isItemRemovable()) -	{ -		return FALSE; -	} -	// move it to the trash -	LLPreview::hide(mUUID); -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; - -	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); - -	// Look for any gestures and deactivate them -	LLInventoryModel::cat_array_t	descendent_categories; -	LLInventoryModel::item_array_t	descendent_items; -	gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE ); - -	S32 i; -	for (i = 0; i < descendent_items.count(); i++) -	{ -		LLInventoryItem* item = descendent_items[i]; -		if (item->getType() == LLAssetType::AT_GESTURE -			&& LLGestureManager::instance().isGestureActive(item->getUUID())) -		{ -			LLGestureManager::instance().deactivateGesture(item->getUUID()); -		} -	} - -	// go ahead and do the normal remove if no 'last calling -	// cards' are being removed. -	LLViewerInventoryCategory* cat = getCategory(); -	if(cat) -	{ -		LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE); -	} - -	return TRUE; -} - -void LLFolderBridge::pasteFromClipboard() -{ -	LLInventoryModel* model = getInventoryModel(); -	if(model && isClipboardPasteable()) -	{ -		LLInventoryItem* item = NULL; -		LLDynamicArray<LLUUID> objects; -		LLInventoryClipboard::instance().retrieve(objects); -		S32 count = objects.count(); -		const LLUUID parent_id(mUUID); -		for(S32 i = 0; i < count; i++) -		{ -			item = model->getItem(objects.get(i)); -			if (item) -			{ -				if(LLInventoryClipboard::instance().isCutMode()) -				{ -					// move_inventory_item() is not enough, -					//we have to update inventory locally too -					changeItemParent(model, dynamic_cast<LLViewerInventoryItem*>(item), parent_id, FALSE); -				} -				else -				{ -					copy_inventory_item( -						gAgent.getID(), -						item->getPermissions().getOwner(), -						item->getUUID(), -						parent_id, -						std::string(), -						LLPointer<LLInventoryCallback>(NULL)); -				} -			} -		} -	} -} - -void LLFolderBridge::pasteLinkFromClipboard() -{ -	const LLInventoryModel* model = getInventoryModel(); -	if(model) -	{ -		LLDynamicArray<LLUUID> objects; -		LLInventoryClipboard::instance().retrieve(objects); -		S32 count = objects.count(); -		LLUUID parent_id(mUUID); -		for(S32 i = 0; i < count; i++) -		{ -			const LLUUID &object_id = objects.get(i); -#if SUPPORT_ENSEMBLES -			if (LLInventoryCategory *cat = model->getCategory(object_id)) -			{ -				link_inventory_item( -					gAgent.getID(), -					cat->getUUID(), -					parent_id, -					cat->getName(), -					LLAssetType::AT_LINK_FOLDER, -					LLPointer<LLInventoryCallback>(NULL)); -			} -			else -#endif -			if (LLInventoryItem *item = model->getItem(object_id)) -			{ -				link_inventory_item( -					gAgent.getID(), -					item->getLinkedUUID(), -					parent_id, -					item->getName(), -					LLAssetType::AT_LINK, -					LLPointer<LLInventoryCallback>(NULL)); -			} -		} -	} -} - -void LLFolderBridge::staticFolderOptionsMenu() -{ -	if (!sSelf) return; -	sSelf->folderOptionsMenu(); -} - -void LLFolderBridge::folderOptionsMenu() -{ -	std::vector<std::string> disabled_items; - -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return; - -	const LLInventoryCategory* category = model->getCategory(mUUID); -	LLFolderType::EType type = category->getPreferredType(); -	const bool is_default_folder = category && LLFolderType::lookupIsProtectedType(type); -	// BAP change once we're no longer treating regular categories as ensembles. -	const bool is_ensemble = category && (type == LLFolderType::FT_NONE || -										  LLFolderType::lookupIsEnsembleType(type)); - -	// calling card related functionality for folders. - -	// Only enable calling-card related options for non-default folders. -	if (!is_default_folder) -	{ -		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")); -		} -	} - -	// wearables related functionality for folders. -	//is_wearable -	LLFindWearables is_wearable; -	LLIsType is_object( LLAssetType::AT_OBJECT ); -	LLIsType is_gesture( LLAssetType::AT_GESTURE ); - -	if (mWearables || -		checkFolderForContentsOfType(model, is_wearable)  || -		checkFolderForContentsOfType(model, is_object) || -		checkFolderForContentsOfType(model, is_gesture) ) -	{ -		mItems.push_back(std::string("Folder Wearables Separator")); - -		// Only enable add/replace outfit for non-default folders. -		if (!is_default_folder) -		{ -			mItems.push_back(std::string("Add To Outfit")); -			mItems.push_back(std::string("Replace Outfit")); -		} -		if (is_ensemble) -		{ -			mItems.push_back(std::string("Wear As Ensemble")); -		} -		mItems.push_back(std::string("Remove From Outfit")); -	} -	hide_context_entries(*mMenu, mItems, disabled_items); -} - -BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type) -{ -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t item_array; -	model->collectDescendentsIf(mUUID, -								cat_array, -								item_array, -								LLInventoryModel::EXCLUDE_TRASH, -								is_type); -	return ((item_array.count() > 0) ? TRUE : FALSE ); -} - -// Flags unused -void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	mItems.clear(); -	mDisabledItems.clear(); - -	lldebugs << "LLFolderBridge::buildContextMenu()" << llendl; -//	std::vector<std::string> disabled_items; -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return; -	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); -	const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - -	mItems.clear(); //adding code to clear out member Items (which means Items should not have other data here at this point) -	mDisabledItems.clear(); //adding code to clear out disabled members from previous -	if (lost_and_found_id == mUUID) -	  { -		// This is the lost+found folder. -		  mItems.push_back(std::string("Empty Lost And Found")); -	  } - -	if(trash_id == mUUID) -	{ -		// This is the trash. -		mItems.push_back(std::string("Empty Trash")); -	} -	else if(model->isObjectDescendentOf(mUUID, trash_id)) -	{ -		// This is a folder in the trash. -		mItems.clear(); // clear any items that used to exist -		mItems.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			mDisabledItems.push_back(std::string("Purge Item")); -		} - -		mItems.push_back(std::string("Restore Item")); -	} -	else if(isAgentInventory()) // do not allow creating in library -	{ -		LLViewerInventoryCategory *cat =  getCategory(); -		// BAP removed protected check to re-enable standard ops in untyped folders. -		// Not sure what the right thing is to do here. -		if (!isCOFFolder() && cat /*&& -			LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())*/) -		{ -			// 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")); -			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")); -			mItems.push_back(std::string("Change Type")); - -			LLViewerInventoryCategory *cat = getCategory(); -			if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) -			{ -				mDisabledItems.push_back(std::string("Change Type")); -			} - -			getClipboardEntries(false, mItems, mDisabledItems, 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")); -				mItems.push_back(std::string("Delete")); -			} -		} - -		//Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06 -		mCallingCards = mWearables = FALSE; - -		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); -		if (checkFolderForContentsOfType(model, is_callingcard)) -		{ -			mCallingCards=TRUE; -		} - -		LLFindWearables is_wearable; -		LLIsType is_object( LLAssetType::AT_OBJECT ); -		LLIsType is_gesture( LLAssetType::AT_GESTURE ); - -		if (checkFolderForContentsOfType(model, is_wearable)  || -			checkFolderForContentsOfType(model, is_object) || -			checkFolderForContentsOfType(model, is_gesture) ) -		{ -			mWearables=TRUE; -		} - -		mMenu = &menu; -		sSelf = this; -		LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(FALSE); - -		LLInventoryFetchDescendentsObserver::folder_ref_t folders; -		LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); -		if (category) -		{ -			folders.push_back(category->getUUID()); -		} -		fetch->fetchDescendents(folders); -		inc_busy_count(); -		if(fetch->isEverythingComplete()) -		{ -			// everything is already here - call done. -			fetch->done(); -		} -		else -		{ -			// it's all on it's way - add an observer, and the inventory -			// will call done for us when everything is here. -			gInventory.addObserver(fetch); -		} -	} -	else -	{ -		mItems.push_back(std::string("--no options--")); -		mDisabledItems.push_back(std::string("--no options--")); -	} -	hide_context_entries(menu, mItems, mDisabledItems); -} - -BOOL LLFolderBridge::hasChildren() const -{ -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; -	LLInventoryModel::EHasChildren has_children; -	has_children = gInventory.categoryHasChildren(mUUID); -	return has_children != LLInventoryModel::CHILDREN_NO; -} - -BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, -								EDragAndDropType cargo_type, -								void* cargo_data) -{ -	//llinfos << "LLFolderBridge::dragOrDrop()" << llendl; -	BOOL accept = FALSE; -	switch(cargo_type) -	{ -		case DAD_TEXTURE: -		case DAD_SOUND: -		case DAD_CALLINGCARD: -		case DAD_LANDMARK: -		case DAD_SCRIPT: -		case DAD_OBJECT: -		case DAD_NOTECARD: -		case DAD_CLOTHING: -		case DAD_BODYPART: -		case DAD_ANIMATION: -		case DAD_GESTURE: -		case DAD_LINK: -			accept = dragItemIntoFolder((LLInventoryItem*)cargo_data, -										drop); -			break; -		case DAD_CATEGORY: -			if (LLFriendCardsManager::instance().isAnyFriendCategory(mUUID)) -			{ -				accept = FALSE; -			} -			else -			{ -				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop); -			} -			break; -		default: -			break; -	} -	return accept; -} - -LLViewerInventoryCategory* LLFolderBridge::getCategory() const -{ -	LLViewerInventoryCategory* cat = NULL; -	LLInventoryModel* model = getInventoryModel(); -	if(model) -	{ -		cat = (LLViewerInventoryCategory*)model->getCategory(mUUID); -	} -	return cat; -} - - -// static -void LLFolderBridge::pasteClipboard(void* user_data) -{ -	LLFolderBridge* self = (LLFolderBridge*)user_data; -	if(self) self->pasteFromClipboard(); -} - -void LLFolderBridge::createNewCategory(void* user_data) -{ -	LLFolderBridge* bridge = (LLFolderBridge*)user_data; -	if(!bridge) return; -	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(bridge->mInventoryPanel.get()); -	if (!panel) return; -	LLInventoryModel* model = panel->getModel(); -	if(!model) return; -	LLUUID id; -	id = model->createNewCategory(bridge->getUUID(), -								  LLFolderType::FT_NONE, -								  LLStringUtil::null); -	model->notifyObservers(); - -	// At this point, the bridge has probably been deleted, but the -	// view is still there. -	panel->setSelection(id, TAKE_FOCUS_YES); -} - -void LLFolderBridge::createNewShirt(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHIRT); -} - -void LLFolderBridge::createNewPants(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_PANTS); -} - -void LLFolderBridge::createNewShoes(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHOES); -} - -void LLFolderBridge::createNewSocks(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SOCKS); -} - -void LLFolderBridge::createNewJacket(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_JACKET); -} - -void LLFolderBridge::createNewSkirt(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SKIRT); -} - -void LLFolderBridge::createNewGloves(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_GLOVES); -} - -void LLFolderBridge::createNewUndershirt(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERSHIRT); -} - -void LLFolderBridge::createNewUnderpants(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERPANTS); -} - -void LLFolderBridge::createNewShape(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHAPE); -} - -void LLFolderBridge::createNewSkin(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SKIN); -} - -void LLFolderBridge::createNewHair(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_HAIR); -} - -void LLFolderBridge::createNewEyes(void* user_data) -{ -	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_EYES); -} - -// static -void LLFolderBridge::createWearable(LLFolderBridge* bridge, EWearableType type) -{ -	if(!bridge) return; -	LLUUID parent_id = bridge->getUUID(); -	createWearable(parent_id, type); -} - -// Separate function so can be called by global menu as well as right-click -// menu. -// static -void LLFolderBridge::createWearable(const LLUUID &parent_id, EWearableType type) -{ -	LLWearable* wearable = LLWearableList::instance().createNewWearable(type); -	LLAssetType::EType asset_type = wearable->getAssetType(); -	LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; -	create_inventory_item(gAgent.getID(), gAgent.getSessionID(), -		parent_id, wearable->getTransactionID(), wearable->getName(), -		wearable->getDescription(), asset_type, inv_type, wearable->getType(), -		wearable->getPermissions().getMaskNextOwner(), -		LLPointer<LLInventoryCallback>(NULL)); -} - -void LLFolderBridge::modifyOutfit(BOOL append) -{ -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return; -	LLViewerInventoryCategory* cat = getCategory(); -	if(!cat) return; - -	// BAP - was: -	// wear_inventory_category_on_avatar( cat, append ); -	LLAppearanceManager::instance().wearInventoryCategory( cat, FALSE, append ); -} - -// helper stuff -bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv* move_inv) -{ -	LLFloaterOpenObject::LLCatAndWear* cat_and_wear = (LLFloaterOpenObject::LLCatAndWear* )move_inv->mUserData; -	LLViewerObject* object = gObjectList.findObject(move_inv->mObjectID); -	S32 option = LLNotification::getSelectedOption(notification, response); - -	if(option == 0 && object) -	{ -		if (cat_and_wear && cat_and_wear->mWear) -		{ -			InventoryObjectList inventory_objects; -			object->getInventoryContents(inventory_objects); -			int contents_count = inventory_objects.size()-1; //subtract one for containing folder - -			LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count); -			gInventory.addObserver(inventoryObserver); -		} - -		two_uuids_list_t::iterator move_it; -		for (move_it = move_inv->mMoveList.begin(); -			move_it != move_inv->mMoveList.end(); -			++move_it) -		{ -			object->moveInventory(move_it->first, move_it->second); -		} - -		// update the UI. -		dialog_refresh_all(); -	} - -	if (move_inv->mCallback) -	{ -		move_inv->mCallback(option, move_inv->mUserData); -	} - -	delete move_inv; -	return false; -} - -/* -Next functions intended to reorder items in the inventory folder and save order on server -Is now used for Favorites folder. - -*TODO: refactoring is needed with Favorites Bar functionality. Probably should be moved in LLInventoryModel -*/ -void saveItemsOrder(LLInventoryModel::item_array_t& items) -{ -	int sortField = 0; - -	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field -	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) -	{ -		LLViewerInventoryItem* item = *i; - -		item->setSortField(++sortField); -		item->setComplete(TRUE); -		item->updateServer(FALSE); - -		gInventory.updateItem(item); -	} - -	gInventory.notifyObservers(); -} - -LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id) -{ -	LLInventoryModel::item_array_t::iterator result = items.end(); - -	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) -	{ -		if ((*i)->getUUID() == id) -		{ -			result = i; -			break; -		} -	} - -	return result; -} - -void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId) -{ -	LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId); -	LLViewerInventoryItem* destItem = gInventory.getItem(destItemId); - -	items.erase(findItemByUUID(items, srcItem->getUUID())); -	items.insert(findItemByUUID(items, destItem->getUUID()), srcItem); -} - -BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, -										BOOL drop) -{ -	LLInventoryModel* model = getInventoryModel(); -	if(!model) return FALSE; - -	// cannot drag into library -	if(!isAgentInventory()) -	{ -		return FALSE; -	} - -	LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); -	if(!avatar) return FALSE; - -	LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); -	BOOL accept = FALSE; -	LLViewerObject* object = NULL; -	if(LLToolDragAndDrop::SOURCE_AGENT == source) -	{ - -		BOOL is_movable = TRUE; -		switch( inv_item->getActualType() ) -		{ -		case LLAssetType::AT_CATEGORY: -			is_movable = !LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)inv_item)->getPreferredType()); -			break; -		default: -			break; -		} - -		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); -		BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); -		const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); -		BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); -		BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); - -		if(is_movable && move_is_into_trash) -		{ -			switch(inv_item->getType()) -			{ -			case LLAssetType::AT_CLOTHING: -			case LLAssetType::AT_BODYPART: -				is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID()); -				break; - -			case LLAssetType::AT_OBJECT: -				is_movable = !avatar->isWearingAttachment(inv_item->getUUID()); -				break; -			default: -				break; -			} -		} - -		if ( is_movable ) -		{ -			// Don't allow creating duplicates in the Calling Card/Friends -			// subfolders, see bug EXT-1599. Check is item direct descendent -			// of target folder and forbid item's movement if it so. -			// Note: isItemDirectDescendentOfCategory checks if -			// passed category is in the Calling Card/Friends folder -			is_movable = ! LLFriendCardsManager::instance() -				.isObjDirectDescendentOfCategory (inv_item, getCategory()); -		} - -		const LLUUID& favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE); -		const LLUUID& landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK); -		const BOOL folder_allows_reorder = ((mUUID == landmarks_id) || (mUUID == favorites_id)); -	    -		// we can move item inside a folder only if this folder is Favorites. See EXT-719 -		accept = is_movable && ((mUUID != inv_item->getParentUUID()) || folder_allows_reorder); -		if(accept && drop) -		{ -			if (inv_item->getType() == LLAssetType::AT_GESTURE -				&& LLGestureManager::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) -			{ -				LLGestureManager::instance().deactivateGesture(inv_item->getUUID()); -			} -			// 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). -			if (LLFloaterInventory::getActiveInventory()) -			{ -				LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); -				LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); -				if (active_panel && (panel != active_panel)) -				{ -					active_panel->unSelectAll(); -				} -			} - -			// if dragging from/into favorites folder only reorder items -			if ((mUUID == inv_item->getParentUUID()) && folder_allows_reorder) -			{ -				LLInventoryModel::cat_array_t cats; -				LLInventoryModel::item_array_t items; -				LLIsType is_type(LLAssetType::AT_LANDMARK); -				model->collectDescendentsIf(mUUID, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); - -				LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); -				LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; -				if (itemp) -				{ -					LLUUID srcItemId = inv_item->getUUID(); -					LLUUID destItemId = itemp->getListener()->getUUID(); - -					// update order -					updateItemsOrder(items, srcItemId, destItemId); - -					saveItemsOrder(items); -				} -			} -			else if (favorites_id == mUUID) // if target is the favorites folder we use copy -			{ -				copy_inventory_item( -					gAgent.getID(), -					inv_item->getPermissions().getOwner(), -					inv_item->getUUID(), -					mUUID, -					std::string(), -					LLPointer<LLInventoryCallback>(NULL)); -			} -			else if (move_is_into_current_outfit || move_is_into_outfit) -			{ -				// BAP - should skip if dup. -				if (move_is_into_current_outfit) -				{ -					LLAppearanceManager::instance().addCOFItemLink(inv_item); -				} -				else -				{ -					LLPointer<LLInventoryCallback> cb = NULL; -					link_inventory_item( -						gAgent.getID(), -						inv_item->getLinkedUUID(), -						mUUID, -						inv_item->getName(), -						LLAssetType::AT_LINK, -						cb); -				} -			} -			else -			{ -				// restamp if the move is into the trash. -				LLInvFVBridge::changeItemParent( -					model, -					(LLViewerInventoryItem*)inv_item, -					mUUID, -					move_is_into_trash); -			} -		} -	} -	else if(LLToolDragAndDrop::SOURCE_WORLD == source) -	{ -		// Make sure the object exists. If we allowed dragging from -		// anonymous objects, it would be possible to bypass -		// permissions. -		object = gObjectList.findObject(inv_item->getParentUUID()); -		if(!object) -		{ -			llinfos << "Object not found for drop." << llendl; -			return FALSE; -		} - -		// coming from a task. Need to figure out if the person can -		// move/copy this item. -		LLPermissions perm(inv_item->getPermissions()); -		BOOL is_move = FALSE; -		if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) -			&& perm.allowTransferTo(gAgent.getID()))) -//		   || gAgent.isGodlike()) - -		{ -			accept = TRUE; -		} -		else if(object->permYouOwner()) -		{ -			// If the object cannot be copied, but the object the -			// inventory is owned by the agent, then the item can be -			// moved from the task to agent inventory. -			is_move = TRUE; -			accept = TRUE; -		} -		if(drop && accept) -		{ -			LLMoveInv* move_inv = new LLMoveInv; -			move_inv->mObjectID = inv_item->getParentUUID(); -			two_uuids_t item_pair(mUUID, inv_item->getUUID()); -			move_inv->mMoveList.push_back(item_pair); -			move_inv->mCallback = NULL; -			move_inv->mUserData = NULL; -			if(is_move) -			{ -				warn_move_inventory(object, move_inv); -			} -			else -			{ -				LLNotification::Params params("MoveInventoryFromObject"); -				params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv)); -				LLNotifications::instance().forceResponse(params, 0); -			} -		} - -	} -	else if(LLToolDragAndDrop::SOURCE_NOTECARD == source) -	{ -		accept = TRUE; -		if(drop) -		{ -			copy_inventory_from_notecard(LLToolDragAndDrop::getInstance()->getObjectID(), -				LLToolDragAndDrop::getInstance()->getSourceID(), inv_item); -		} -	} -	else if(LLToolDragAndDrop::SOURCE_LIBRARY == source) -	{ -		LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_item; -		if(item && item->isComplete()) -		{ -			accept = TRUE; -			if(drop) -			{ -				copy_inventory_item( -					gAgent.getID(), -					inv_item->getPermissions().getOwner(), -					inv_item->getUUID(), -					mUUID, -					std::string(), -					LLPointer<LLInventoryCallback>(NULL)); -			} -		} -	} -	else -	{ -		llwarns << "unhandled drag source" << llendl; -	} -	return accept; -} - -// +=================================================+ -// |        LLScriptBridge (DEPRECTED)               | -// +=================================================+ - -LLUIImagePtr LLScriptBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE); -} - -// +=================================================+ -// |        LLTextureBridge                          | -// +=================================================+ - -LLUIImagePtr LLTextureBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_TEXTURE, mInvType, 0, FALSE); -} - -void LLTextureBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -} - -void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	lldebugs << "LLTextureBridge::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		items.push_back(std::string("Open")); -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); - -		items.push_back(std::string("Texture Separator")); -		items.push_back(std::string("Save As")); -	} -	hide_context_entries(menu, items, disabled_items);	 -} - -// virtual -void LLTextureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("save_as" == action) -	{ -		LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES); -		LLPreviewTexture* preview_texture = LLFloaterReg::findTypedInstance<LLPreviewTexture>("preview_texture", mUUID); -		if (preview_texture) -		{ -			preview_texture->openToSave(); -		} -	} -	else LLItemBridge::performAction(folder, model, action); -} - -// +=================================================+ -// |        LLSoundBridge                            | -// +=================================================+ - -LLUIImagePtr LLSoundBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE); -} - -void LLSoundBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -/* -// Changed this back to the way it USED to work: -// only open the preview dialog through the contextual right-click menu -// double-click just plays the sound - -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		openSoundPreview((void*)this); -		//send_uuid_sound_trigger(item->getAssetUUID(), 1.0); -	} -*/ -} - -void LLSoundBridge::previewItem() -{ -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		send_sound_trigger(item->getAssetUUID(), 1.0); -	} -} - -void LLSoundBridge::openSoundPreview(void* which) -{ -	LLSoundBridge *me = (LLSoundBridge *)which; -	LLFloaterReg::showInstance("preview_sound", LLSD(me->mUUID), TAKE_FOCUS_YES); -} - -void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	lldebugs << "LLSoundBridge::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; - -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		items.push_back(std::string("Sound Open")); -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); -	} - -	items.push_back(std::string("Sound Separator")); -	items.push_back(std::string("Sound Play")); - -	hide_context_entries(menu, items, disabled_items); -} - -// +=================================================+ -// |        LLLandmarkBridge                         | -// +=================================================+ - -LLLandmarkBridge::LLLandmarkBridge(LLInventoryPanel* inventory, const LLUUID& uuid, U32 flags/* = 0x00*/) : -LLItemBridge(inventory, uuid) -{ -	mVisited = FALSE; -	if (flags & LLInventoryItem::II_FLAGS_LANDMARK_VISITED) -	{ -		mVisited = TRUE; -	} -} - -LLUIImagePtr LLLandmarkBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mVisited, FALSE); -} - -void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; - -	lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl; -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		items.push_back(std::string("Landmark Open")); -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); -	} - -	items.push_back(std::string("Landmark Separator")); -	items.push_back(std::string("About Landmark")); - -	// Disable "About Landmark" menu item for -	// multiple landmarks selected. Only one landmark -	// info panel can be shown at a time. -	if ((flags & FIRST_SELECTED_ITEM) == 0) -	{ -		disabled_items.push_back(std::string("About Landmark")); -	} - -	hide_context_entries(menu, items, disabled_items); -} - -// Convenience function for the two functions below. -void teleport_via_landmark(const LLUUID& asset_id) -{ -	gAgent.teleportViaLandmark( asset_id ); - -	// we now automatically track the landmark you're teleporting to -	// because you'll probably arrive at a telehub instead -	LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); -	if( floater_world_map ) -	{ -		floater_world_map->trackLandmark( asset_id ); -	} -} - -// virtual -void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("teleport" == action) -	{ -		LLViewerInventoryItem* item = getItem(); -		if(item) -		{ -			teleport_via_landmark(item->getAssetUUID()); -		} -	} -	else if ("about" == action) -	{ -		LLViewerInventoryItem* item = getItem(); -		if(item) -		{ -			LLSD key; -			key["type"] = "landmark"; -			key["id"] = item->getUUID(); - -			LLSideTray::getInstance()->showPanel("panel_places", key); -		} -	} -	else -	{ -		LLItemBridge::performAction(folder, model, action); -	} -} - -static bool open_landmark_callback(const LLSD& notification, const LLSD& response) -{ -	S32 option = LLNotification::getSelectedOption(notification, response); - -	LLUUID asset_id = notification["payload"]["asset_id"].asUUID(); -	if (option == 0) -	{ -		teleport_via_landmark(asset_id); -	} - -	return false; -} -static LLNotificationFunctorRegistration open_landmark_callback_reg("TeleportFromLandmark", open_landmark_callback); - - -void LLLandmarkBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -/* -	LLViewerInventoryItem* item = getItem(); -	if( item ) -	{ -		// Opening (double-clicking) a landmark immediately teleports, -		// but warns you the first time. -		// open_landmark(item); -		LLSD payload; -		payload["asset_id"] = item->getAssetUUID(); -		LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload); -	} -*/ -} - - -// +=================================================+ -// |        LLCallingCardObserver                    | -// +=================================================+ -void LLCallingCardObserver::changed(U32 mask) -{ -	mBridgep->refreshFolderViewItem(); -} - -// +=================================================+ -// |        LLCallingCardBridge                      | -// +=================================================+ - -LLCallingCardBridge::LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid ) : -	LLItemBridge(inventory, uuid) -{ -	mObserver = new LLCallingCardObserver(this); -	LLAvatarTracker::instance().addObserver(mObserver); -} - -LLCallingCardBridge::~LLCallingCardBridge() -{ -	LLAvatarTracker::instance().removeObserver(mObserver); -	delete mObserver; -} - -void LLCallingCardBridge::refreshFolderViewItem() -{ -	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); -	LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL; -	if (itemp) -	{ -		itemp->refresh(); -	} -} - -// virtual -void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("begin_im" == action) -	{ -		LLViewerInventoryItem *item = getItem(); -		if (item && (item->getCreatorUUID() != gAgent.getID()) && -			(!item->getCreatorUUID().isNull())) -		{ -			std::string callingcard_name; -			gCacheName->getFullName(item->getCreatorUUID(), callingcard_name); -			LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID()); -			if (session_id != LLUUID::null) -			{ -				LLIMFloater::show(session_id); -			} -		} -	} -	else if ("lure" == action) -	{ -		LLViewerInventoryItem *item = getItem(); -		if (item && (item->getCreatorUUID() != gAgent.getID()) && -			(!item->getCreatorUUID().isNull())) -		{ -			LLAvatarActions::offerTeleport(item->getCreatorUUID()); -		} -	} -	else LLItemBridge::performAction(folder, model, action); -} - -LLUIImagePtr LLCallingCardBridge::getIcon() const -{ -	BOOL online = FALSE; -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()); -	} -	return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, online, FALSE); -} - -std::string LLCallingCardBridge::getLabelSuffix() const -{ -	LLViewerInventoryItem* item = getItem(); -	if( item && LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()) ) -	{ -		return LLItemBridge::getLabelSuffix() + " (online)"; -	} -	else -	{ -		return LLItemBridge::getLabelSuffix(); -	} -} - -void LLCallingCardBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -/* -	LLViewerInventoryItem* item = getItem(); -	if(item && !item->getCreatorUUID().isNull()) -	{ -		LLAvatarActions::showProfile(item->getCreatorUUID()); -	} -*/ -} - -void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	lldebugs << "LLCallingCardBridge::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; - -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		items.push_back(std::string("Open")); -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); - -		LLInventoryItem* item = getItem(); -		BOOL good_card = (item -						  && (LLUUID::null != item->getCreatorUUID()) -						  && (item->getCreatorUUID() != gAgent.getID())); -		BOOL user_online = (LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID())); -		items.push_back(std::string("Send Instant Message Separator")); -		items.push_back(std::string("Send Instant Message")); -		items.push_back(std::string("Offer Teleport...")); -		items.push_back(std::string("Conference Chat")); - -		if (!good_card) -		{ -			disabled_items.push_back(std::string("Send Instant Message")); -		} -		if (!good_card || !user_online) -		{ -			disabled_items.push_back(std::string("Offer Teleport...")); -			disabled_items.push_back(std::string("Conference Chat")); -		} -	} -	hide_context_entries(menu, items, disabled_items); -} - -BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, -									 EDragAndDropType cargo_type, -									 void* cargo_data) -{ -	LLViewerInventoryItem* item = getItem(); -	BOOL rv = FALSE; -	if(item) -	{ -		// check the type -		switch(cargo_type) -		{ -		case DAD_TEXTURE: -		case DAD_SOUND: -		case DAD_LANDMARK: -		case DAD_SCRIPT: -		case DAD_CLOTHING: -		case DAD_OBJECT: -		case DAD_NOTECARD: -		case DAD_BODYPART: -		case DAD_ANIMATION: -		case DAD_GESTURE: -			{ -				LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; -				const LLPermissions& perm = inv_item->getPermissions(); -				if(gInventory.getItem(inv_item->getUUID()) -				   && perm.allowOperationBy(PERM_TRANSFER, gAgent.getID())) -				{ -					rv = TRUE; -					if(drop) -					{ -						LLToolDragAndDrop::giveInventory(item->getCreatorUUID(), -														 (LLInventoryItem*)cargo_data); -					} -				} -				else -				{ -					// It's not in the user's inventory (it's probably in -					// an object's contents), so disallow dragging it here. -					// You can't give something you don't yet have. -					rv = FALSE; -				} -				break; -			} -		case DAD_CATEGORY: -			{ -				LLInventoryCategory* inv_cat = (LLInventoryCategory*)cargo_data; -				if( gInventory.getCategory( inv_cat->getUUID() ) ) -				{ -					rv = TRUE; -					if(drop) -					{ -						LLToolDragAndDrop::giveInventoryCategory( -							item->getCreatorUUID(), -							inv_cat); -					} -				} -				else -				{ -					// It's not in the user's inventory (it's probably in -					// an object's contents), so disallow dragging it here. -					// You can't give something you don't yet have. -					rv = FALSE; -				} -				break; -			} -		default: -			break; -		} -	} -	return rv; -} - -BOOL LLCallingCardBridge::removeItem() -{ -	if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem())) -	{ -		LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID()); -		return FALSE; -	} -	else -	{ -		return LLItemBridge::removeItem(); -	} -} -// +=================================================+ -// |        LLNotecardBridge                         | -// +=================================================+ - -LLUIImagePtr LLNotecardBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE); -} - -void LLNotecardBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} - -/* -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); -	} -*/ -} - - -// +=================================================+ -// |        LLGestureBridge                          | -// +=================================================+ - -LLUIImagePtr LLGestureBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE); -} - -LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const -{ -	if( LLGestureManager::instance().isGestureActive(mUUID) ) -	{ -		return LLFontGL::BOLD; -	} -	else -	{ -		return LLFontGL::NORMAL; -	} -} - -std::string LLGestureBridge::getLabelSuffix() const -{ -	if( LLGestureManager::instance().isGestureActive(mUUID) ) -	{ -		return LLItemBridge::getLabelSuffix() + " (active)"; -	} -	else -	{ -		return LLItemBridge::getLabelSuffix(); -	} -} - -// virtual -void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("activate" == action) -	{ -		LLGestureManager::instance().activateGesture(mUUID); - -		LLViewerInventoryItem* item = gInventory.getItem(mUUID); -		if (!item) return; - -		// Since we just changed the suffix to indicate (active) -		// the server doesn't need to know, just the viewer. -		gInventory.updateItem(item); -		gInventory.notifyObservers(); -	} -	else if ("deactivate" == action) -	{ -		LLGestureManager::instance().deactivateGesture(mUUID); - -		LLViewerInventoryItem* item = gInventory.getItem(mUUID); -		if (!item) return; - -		// Since we just changed the suffix to indicate (active) -		// the server doesn't need to know, just the viewer. -		gInventory.updateItem(item); -		gInventory.notifyObservers(); -	} -	else LLItemBridge::performAction(folder, model, action); -} - -void LLGestureBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -/* -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null); -		preview->setFocus(TRUE); -	} -*/ -} - -BOOL LLGestureBridge::removeItem() -{ -	// Force close the preview window, if it exists -	LLGestureManager::instance().deactivateGesture(mUUID); -	return LLItemBridge::removeItem(); -} - -void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	lldebugs << "LLGestureBridge::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		LLInventoryItem* item = getItem(); -		if (item && item->getIsLinkType()) -		{ -			items.push_back(std::string("Find Original")); -		} -		items.push_back(std::string("Open")); -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); - -		items.push_back(std::string("Gesture Separator")); -		items.push_back(std::string("Activate")); -		items.push_back(std::string("Deactivate")); -	} -	hide_context_entries(menu, items, disabled_items); -} - -// +=================================================+ -// |        LLAnimationBridge                        | -// +=================================================+ - -LLUIImagePtr LLAnimationBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE); -} - -void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; - -	lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl; -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		items.push_back(std::string("Animation Open")); -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); -	} - -	items.push_back(std::string("Animation Separator")); -	items.push_back(std::string("Animation Play")); -	items.push_back(std::string("Animation Audition")); - -	hide_context_entries(menu, items, disabled_items); - -} - -// virtual -void LLAnimationBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ((action == "playworld") || (action == "playlocal")) -	{ -		if (getItem()) -		{ -			LLPreviewAnim::e_activation_type activate = LLPreviewAnim::NONE; -			if ("playworld" == action) activate = LLPreviewAnim::PLAY; -			if ("playlocal" == action) activate = LLPreviewAnim::AUDITION; - -			LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID)); -			if (preview) -			{ -				preview->activate(activate); -			} -		} -	} -	else -	{ -		LLItemBridge::performAction(folder, model, action); -	} -} - -void LLAnimationBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -/* -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); -	} -*/ -} - -// +=================================================+ -// |        LLObjectBridge                           | -// +=================================================+ - -// static -LLUUID LLObjectBridge::sContextMenuItemID; - -LLObjectBridge::LLObjectBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type, U32 flags) : -LLItemBridge(inventory, uuid), mInvType(type) -{ -	mAttachPt = (flags & 0xff); // low bye of inventory flags - -	mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ?  TRUE: FALSE; -} - -BOOL LLObjectBridge::isItemRemovable() -{ -	LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); -	if(!avatar) return FALSE; -	if(avatar->isWearingAttachment(mUUID)) return FALSE; -	return LLInvFVBridge::isItemRemovable(); -} - -LLUIImagePtr LLObjectBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject ); -} - -LLInventoryObject* LLObjectBridge::getObject() const -{ -	LLInventoryObject* object = NULL; -	LLInventoryModel* model = getInventoryModel(); -	if(model) -	{ -		object = (LLInventoryObject*)model->getObject(mUUID); -	} -	return object; -} - -// virtual -void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("attach" == action) -	{ -		LLUUID object_id = mUUID; -		LLViewerInventoryItem* item; -		item = (LLViewerInventoryItem*)gInventory.getItem(object_id); -		if(item && gInventory.isObjectDescendentOf(object_id, gInventory.getRootFolderID())) -		{ -			rez_attachment(item, NULL); -		} -		else if(item && item->isComplete()) -		{ -			// must be in library. copy it to our inventory and put it on. -			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0); -			copy_inventory_item( -				gAgent.getID(), -				item->getPermissions().getOwner(), -				item->getUUID(), -				LLUUID::null, -				std::string(), -				cb); -		} -		gFocusMgr.setKeyboardFocus(NULL); -	} -	else if ("detach" == action) -	{ -		LLInventoryItem* item = gInventory.getItem(mUUID); -		if(item) -		{ -			gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); -			gMessageSystem->nextBlockFast(_PREHASH_ObjectData); -			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -			gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); -			gMessageSystem->sendReliable( gAgent.getRegion()->getHost()); -		} -		// this object might have been selected, so let the selection manager know it's gone now -		LLViewerObject *found_obj = gObjectList.findObject(item->getLinkedUUID()); -		if (found_obj) -		{ -			LLSelectMgr::getInstance()->remove(found_obj); -		} -	} -	else LLItemBridge::performAction(folder, model, action); -} - -void LLObjectBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} - -	LLSD key; -	key["id"] = mUUID; -	LLSideTray::getInstance()->showPanel("sidepanel_inventory", key); - -	// Disable old properties floater; this is replaced by the sidepanel. -	/* -	LLFloaterReg::showInstance("properties", mUUID); -	*/ -} - -LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const -{ -	U8 font = LLFontGL::NORMAL; - -	LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); -	if( avatar && avatar->isWearingAttachment( mUUID ) ) -	{ -		font |= LLFontGL::BOLD; -	} - -	LLInventoryItem* item = getItem(); -	if (item && item->getIsLinkType()) -	{ -		font |= LLFontGL::ITALIC; -	} - -	return (LLFontGL::StyleFlags)font; -} - -std::string LLObjectBridge::getLabelSuffix() const -{ -	LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); -	if( avatar && avatar->isWearingAttachment( mUUID ) ) -	{ -		std::string attachment_point_name = avatar->getAttachedPointName(mUUID); - -		// e.g. "(worn on ...)" / "(attached to ...)" -		LLStringUtil::format_map_t args; -		args["[ATTACHMENT_POINT]"] =  attachment_point_name.c_str(); -		return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); -	} -	else -	{ -		return LLItemBridge::getLabelSuffix(); -	} -} - -void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment) -{ -	LLSD payload; -	payload["item_id"] = item->getLinkedUUID(); // Wear the base object in case this is a link. - -	S32 attach_pt = 0; -	if (gAgent.getAvatarObject() && attachment) -	{ -		for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin(); -			 iter != gAgent.getAvatarObject()->mAttachmentPoints.end(); ++iter) -		{ -			if (iter->second == attachment) -			{ -				attach_pt = iter->first; -				break; -			} -		} -	} - -	payload["attachment_point"] = attach_pt; - -#if !ENABLE_MULTIATTACHMENTS -	if (attachment && attachment->getNumObjects() > 0) -	{ -		LLNotifications::instance().add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez); -	} -	else -#endif -	{ -		LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); -	} -} - -bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response) -{ -	LLVOAvatar *avatarp = gAgent.getAvatarObject(); - -	if (!avatarp->canAttachMoreObjects()) -	{ -		LLSD args; -		args["MAX_ATTACHMENTS"] = llformat("%d", MAX_AGENT_ATTACHMENTS); -		LLNotifications::instance().add("MaxAttachmentsOnOutfit", args); -		return false; -	} - -	S32 option = LLNotification::getSelectedOption(notification, response); -	if (option == 0/*YES*/) -	{ -		LLViewerInventoryItem* itemp = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - -		if (itemp) -		{ -			LLMessageSystem* msg = gMessageSystem; -			msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv); -			msg->nextBlockFast(_PREHASH_AgentData); -			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -			msg->nextBlockFast(_PREHASH_ObjectData); -			msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID()); -			msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner()); -			U8 attachment_pt = notification["payload"]["attachment_point"].asInteger(); -#if ENABLE_MULTIATTACHMENTS -			attachment_pt |= ATTACHMENT_ADD; -#endif -			msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt); -			pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions()); -			msg->addStringFast(_PREHASH_Name, itemp->getName()); -			msg->addStringFast(_PREHASH_Description, itemp->getDescription()); -			msg->sendReliable(gAgent.getRegion()->getHost()); -		} -	} -	return false; -} -static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_replace_attachment_rez); - -void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		LLInventoryItem* item = getItem(); -		if (item && item->getIsLinkType()) -		{ -			items.push_back(std::string("Find Original")); -		} - -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); - -		LLObjectBridge::sContextMenuItemID = mUUID; - -		if(item) -		{ -			LLVOAvatarSelf* avatarp = gAgent.getAvatarObject(); -			if( !avatarp ) -			{ -				return; -			} - -			if( avatarp->isWearingAttachment( mUUID ) ) -			{ -				items.push_back(std::string("Detach From Yourself")); -			} -			else -			if( !isInTrash() && !isLinkedObjectInTrash() ) -			{ -				items.push_back(std::string("Attach Separator")); -				items.push_back(std::string("Object Wear")); -				items.push_back(std::string("Attach To")); -				items.push_back(std::string("Attach To HUD")); -				// commented out for DEV-32347 -				//items.push_back(std::string("Restore to Last Position")); - -				if (!avatarp->canAttachMoreObjects()) -				{ -					disabled_items.push_back(std::string("Object Wear")); -					disabled_items.push_back(std::string("Attach To")); -					disabled_items.push_back(std::string("Attach To HUD")); -				} -				LLMenuGL* attach_menu = menu.findChildMenuByName("Attach To", TRUE); -				LLMenuGL* attach_hud_menu = menu.findChildMenuByName("Attach To HUD", TRUE); -				LLVOAvatar *avatarp = gAgent.getAvatarObject(); -				if (attach_menu -					&& (attach_menu->getChildCount() == 0) -					&& attach_hud_menu -					&& (attach_hud_menu->getChildCount() == 0) -					&& avatarp) -				{ -					for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); -						 iter != avatarp->mAttachmentPoints.end(); ) -					{ -						LLVOAvatar::attachment_map_t::iterator curiter = iter++; -						LLViewerJointAttachment* attachment = curiter->second; -						LLMenuItemCallGL::Params p; -						std::string submenu_name = attachment->getName(); -						if (LLTrans::getString(submenu_name) != "") -						{ -						    p.name = (" ")+LLTrans::getString(submenu_name)+" "; -						} -						else -						{ -							p.name = submenu_name; -						} -						LLSD cbparams; -						cbparams["index"] = curiter->first; -						cbparams["label"] = attachment->getName(); -						p.on_click.function_name = "Inventory.AttachObject"; -						p.on_click.parameter = LLSD(attachment->getName()); -						p.on_enable.function_name = "Attachment.Label"; -						p.on_enable.parameter = cbparams; -						LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu; -						LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent); -					} -				} -			} -		} -	} -	hide_context_entries(menu, items, disabled_items); -} - -BOOL LLObjectBridge::renameItem(const std::string& new_name) -{ -	if(!isItemRenameable()) -		return FALSE; -	LLPreview::dirty(mUUID); -	LLInventoryModel* model = getInventoryModel(); -	if(!model) -		return FALSE; -	LLViewerInventoryItem* item = getItem(); -	if(item && (item->getName() != new_name)) -	{ -		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); -		new_item->rename(new_name); -		buildDisplayName(new_item, mDisplayName); -		new_item->updateServer(FALSE); -		model->updateItem(new_item); - -		model->notifyObservers(); - -		LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); -		if( avatar ) -		{ -			LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() ); -			if( obj ) -			{ -				LLSelectMgr::getInstance()->deselectAll(); -				LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, FALSE ); -				LLSelectMgr::getInstance()->selectionSetObjectName( new_name ); -				LLSelectMgr::getInstance()->deselectAll(); -			} -		} -	} -	// return FALSE because we either notified observers (& therefore -	// rebuilt) or we didn't update. -	return FALSE; -} - -// +=================================================+ -// |        LLLSLTextBridge                          | -// +=================================================+ - -LLUIImagePtr LLLSLTextBridge::getIcon() const -{ -	return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE); -} - -void LLLSLTextBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -	/* -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES); -	} -	*/ -} - -// +=================================================+ -// |        LLWearableBridge                         | -// +=================================================+ - -// *NOTE: hack to get from avatar inventory to avatar -void wear_inventory_item_on_avatar( LLInventoryItem* item ) -{ -	if(item) -	{ -		lldebugs << "wear_inventory_item_on_avatar( " << item->getName() -				 << " )" << llendl; - -		LLAppearanceManager::instance().addCOFItemLink(item); -	} -} - -void wear_add_inventory_item_on_avatar( LLInventoryItem* item ) -{ -	if(item) -	{ -		lldebugs << "wear_add_inventory_item_on_avatar( " << item->getName() -				 << " )" << llendl; - -		LLWearableList::instance().getAsset(item->getAssetUUID(), -							   item->getName(), -							   item->getType(), -							   LLWearableBridge::onWearAddOnAvatarArrived, -							   new LLUUID(item->getUUID())); -	} -} - -void remove_inventory_category_from_avatar( LLInventoryCategory* category ) -{ -	if(!category) return; -	lldebugs << "remove_inventory_category_from_avatar( " << category->getName() -			 << " )" << llendl; - - -	if( gFloaterCustomize ) -	{ -		gFloaterCustomize->askToSaveIfDirty( -			boost::bind(remove_inventory_category_from_avatar_step2, _1, category->getUUID())); -	} -	else -	{ -		remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() ); -	} -} - -struct OnRemoveStruct -{ -	LLUUID mUUID; -	OnRemoveStruct(const LLUUID& uuid): -		mUUID(uuid) -	{ -	} -}; - -void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id) -{ - -	// Find all the wearables that are in the category's subtree. -	lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl; -	if(proceed) -	{ -		LLInventoryModel::cat_array_t cat_array; -		LLInventoryModel::item_array_t item_array; -		LLFindWearables is_wearable; -		gInventory.collectDescendentsIf(category_id, -										cat_array, -										item_array, -										LLInventoryModel::EXCLUDE_TRASH, -										is_wearable); -		S32 i; -		S32 wearable_count = item_array.count(); - -		LLInventoryModel::cat_array_t	obj_cat_array; -		LLInventoryModel::item_array_t	obj_item_array; -		LLIsType is_object( LLAssetType::AT_OBJECT ); -		gInventory.collectDescendentsIf(category_id, -										obj_cat_array, -										obj_item_array, -										LLInventoryModel::EXCLUDE_TRASH, -										is_object); -		S32 obj_count = obj_item_array.count(); - -		// Find all gestures in this folder -		LLInventoryModel::cat_array_t	gest_cat_array; -		LLInventoryModel::item_array_t	gest_item_array; -		LLIsType is_gesture( LLAssetType::AT_GESTURE ); -		gInventory.collectDescendentsIf(category_id, -										gest_cat_array, -										gest_item_array, -										LLInventoryModel::EXCLUDE_TRASH, -										is_gesture); -		S32 gest_count = gest_item_array.count(); - -		if (wearable_count > 0)	//Loop through wearables.  If worn, remove. -		{ -			for(i = 0; i  < wearable_count; ++i) -			{ -				if( gAgentWearables.isWearingItem (item_array.get(i)->getUUID()) ) -				{ -					LLWearableList::instance().getAsset(item_array.get(i)->getAssetUUID(), -														item_array.get(i)->getName(), -														item_array.get(i)->getType(), -														LLWearableBridge::onRemoveFromAvatarArrived, -														new OnRemoveStruct(item_array.get(i)->getUUID())); - -				} -			} -		} - - -		if (obj_count > 0) -		{ -			for(i = 0; i  < obj_count; ++i) -			{ -				gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); -				gMessageSystem->nextBlockFast(_PREHASH_ObjectData ); -				gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); -				gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item_array.get(i)->getUUID() ); - -				gMessageSystem->sendReliable( gAgent.getRegion()->getHost() ); - -				// this object might have been selected, so let the selection manager know it's gone now -				LLViewerObject *found_obj = gObjectList.findObject( obj_item_array.get(i)->getUUID()); -				if (found_obj) -				{ -					LLSelectMgr::getInstance()->remove(found_obj); -				} -			} -		} - -		if (gest_count > 0) -		{ -			for(i = 0; i  < gest_count; ++i) -			{ -				if ( LLGestureManager::instance().isGestureActive( gest_item_array.get(i)->getUUID()) ) -				{ -					LLGestureManager::instance().deactivateGesture( gest_item_array.get(i)->getUUID() ); -					gInventory.updateItem( gest_item_array.get(i) ); -					gInventory.notifyObservers(); -				} - -			} -		} -	} -} - -BOOL LLWearableBridge::renameItem(const std::string& new_name) -{ -	if( gAgentWearables.isWearingItem( mUUID ) ) -	{ -		gAgentWearables.setWearableName( mUUID, new_name ); -	} -	return LLItemBridge::renameItem(new_name); -} - -BOOL LLWearableBridge::isItemRemovable() -{ -	if (gAgentWearables.isWearingItem(mUUID)) return FALSE; -	return LLInvFVBridge::isItemRemovable(); -} - -std::string LLWearableBridge::getLabelSuffix() const -{ -	if( gAgentWearables.isWearingItem( mUUID ) ) -	{ -		// e.g. "(worn)"  -		return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn"); -	} -	else -	{ -		return LLItemBridge::getLabelSuffix(); -	} -} - -LLUIImagePtr LLWearableBridge::getIcon() const -{ -	return get_item_icon(mAssetType, mInvType, mWearableType, FALSE); -} - -// virtual -void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("wear" == action) -	{ -		wearOnAvatar(); -	} -	else if ("wear_add" == action) -	{ -		wearAddOnAvatar(); -	} -	else if ("edit" == action) -	{ -		editOnAvatar(); -		return; -	} -	else if ("take_off" == action) -	{ -		if(gAgentWearables.isWearingItem(mUUID)) -		{ -			LLViewerInventoryItem* item = getItem(); -			if (item) -			{ -				LLWearableList::instance().getAsset(item->getAssetUUID(), -													item->getName(), -													item->getType(), -													LLWearableBridge::onRemoveFromAvatarArrived, -													new OnRemoveStruct(mUUID)); -			} -		} -	} -	else LLItemBridge::performAction(folder, model, action); -} - -void LLWearableBridge::openItem() -{ -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} -	/* -	if( isInTrash() ) -	{ -		LLNotifications::instance().add("CannotWearTrash"); -	} -	else if(isAgentInventory()) -	{ -		if( !gAgentWearables.isWearingItem( mUUID ) ) -		{ -			wearOnAvatar(); -		} -	} -	else -	{ -		// must be in the inventory library. copy it to our inventory -		// and put it on right away. -		LLViewerInventoryItem* item = getItem(); -		if(item && item->isComplete()) -		{ -			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); -			copy_inventory_item( -				gAgent.getID(), -				item->getPermissions().getOwner(), -				item->getUUID(), -				LLUUID::null, -				std::string(), -				cb); -		} -		else if(item) -		{ -			// *TODO: We should fetch the item details, and then do -			// the operation above. -			LLNotifications::instance().add("CannotWearInfoNotComplete"); -		} -	} -	*/ -} - -void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	lldebugs << "LLWearableBridge::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{	// FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere -		BOOL no_open = ((flags & SUPPRESS_OPEN_ITEM) == SUPPRESS_OPEN_ITEM); - -		// If we have clothing, don't add "Open" as it's the same action as "Wear"   SL-18976 -		LLViewerInventoryItem* item = getItem(); -		if( !no_open && item ) -		{ -			no_open = (item->getType() == LLAssetType::AT_CLOTHING) || -					  (item->getType() == LLAssetType::AT_BODYPART); -		} -		if (!no_open) -		{ -			items.push_back(std::string("Open")); -		} - -		if (item && item->getIsLinkType()) -		{ -			items.push_back(std::string("Find Original")); -		} - -		items.push_back(std::string("Properties")); - -		getClipboardEntries(true, items, disabled_items, flags); - -		items.push_back(std::string("Wearable Separator")); - -		items.push_back(std::string("Wearable Wear")); -		items.push_back(std::string("Wearable Add")); -		items.push_back(std::string("Wearable Edit")); - -		if ((flags & FIRST_SELECTED_ITEM) == 0) -		{ -			disabled_items.push_back(std::string("Wearable Edit")); -		} -		// Don't allow items to be worn if their baseobj is in the trash. -		if (isLinkedObjectInTrash()) -		{ -			disabled_items.push_back(std::string("Wearable Wear")); -			disabled_items.push_back(std::string("Wearable Add")); -			disabled_items.push_back(std::string("Wearable Edit")); -		} - -		// Disable wear and take off based on whether the item is worn. -		if(item) -		{ -			switch (item->getType()) -			{ -				case LLAssetType::AT_CLOTHING: -					items.push_back(std::string("Take Off")); -				case LLAssetType::AT_BODYPART: -					if (gAgentWearables.isWearingItem(item->getUUID())) -					{ -						disabled_items.push_back(std::string("Wearable Wear")); -						disabled_items.push_back(std::string("Wearable Add")); -					} -					else -					{ -						disabled_items.push_back(std::string("Take Off")); -					} -					break; -				default: -					break; -			} -		} -	} -	hide_context_entries(menu, items, disabled_items); -} - -// Called from menus -// static -BOOL LLWearableBridge::canWearOnAvatar(void* user_data) -{ -	LLWearableBridge* self = (LLWearableBridge*)user_data; -	if(!self) return FALSE; -	if(!self->isAgentInventory()) -	{ -		LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem(); -		if(!item || !item->isComplete()) return FALSE; -	} -	return (!gAgentWearables.isWearingItem(self->mUUID)); -} - -// Called from menus -// static -void LLWearableBridge::onWearOnAvatar(void* user_data) -{ -	LLWearableBridge* self = (LLWearableBridge*)user_data; -	if(!self) return; -	self->wearOnAvatar(); -} - -void LLWearableBridge::wearOnAvatar() -{ -	// Don't wear anything until initial wearables are loaded, can -	// destroy clothing items. -	if (!gAgentWearables.areWearablesLoaded()) -	{ -		LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded"); -		return; -	} - -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		if(!isAgentInventory()) -		{ -			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); -			copy_inventory_item( -				gAgent.getID(), -				item->getPermissions().getOwner(), -				item->getUUID(), -				LLUUID::null, -				std::string(), -				cb); -		} -		else -		{ -			wear_inventory_item_on_avatar(item); -		} -	} -} - -void LLWearableBridge::wearAddOnAvatar() -{ -	// Don't wear anything until initial wearables are loaded, can -	// destroy clothing items. -	if (!gAgentWearables.areWearablesLoaded()) -	{ -		LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded"); -		return; -	} - -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		if(!isAgentInventory()) -		{ -			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); -			copy_inventory_item( -				gAgent.getID(), -				item->getPermissions().getOwner(), -				item->getUUID(), -				LLUUID::null, -				std::string(), -				cb); -		} -		else -		{ -			wear_add_inventory_item_on_avatar(item); -		} -	} -} - -// static -void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata ) -{ -	LLUUID* item_id = (LLUUID*) userdata; -	if(wearable) -	{ -		LLViewerInventoryItem* item = NULL; -		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id); -		if(item) -		{ -			if(item->getAssetUUID() == wearable->getAssetID()) -			{ -				gAgentWearables.setWearableItem(item, wearable); -				gInventory.notifyObservers(); -				//self->getFolderItem()->refreshFromRoot(); -			} -			else -			{ -				llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl; -			} -		} -	} -	delete item_id; -} - -// static -// BAP remove the "add" code path once everything is fully COF-ified. -void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata ) -{ -	LLUUID* item_id = (LLUUID*) userdata; -	if(wearable) -	{ -		LLViewerInventoryItem* item = NULL; -		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id); -		if(item) -		{ -			if(item->getAssetUUID() == wearable->getAssetID()) -			{ -				bool do_append = true; -				gAgentWearables.setWearableItem(item, wearable, do_append); -				gInventory.notifyObservers(); -				//self->getFolderItem()->refreshFromRoot(); -			} -			else -			{ -				llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl; -			} -		} -	} -	delete item_id; -} - -// static -BOOL LLWearableBridge::canEditOnAvatar(void* user_data) -{ -	LLWearableBridge* self = (LLWearableBridge*)user_data; -	if(!self) return FALSE; - -	return (gAgentWearables.isWearingItem(self->mUUID)); -} - -// static -void LLWearableBridge::onEditOnAvatar(void* user_data) -{ -	LLWearableBridge* self = (LLWearableBridge*)user_data; -	if(self) -	{ -		self->editOnAvatar(); -	} -} - -void LLWearableBridge::editOnAvatar() -{ -	const LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID); -	if( wearable ) -	{ -		// Set the tab to the right wearable. -		if (gFloaterCustomize) -			gFloaterCustomize->setCurrentWearableType( wearable->getType() ); - -		if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() ) -		{ -			// Start Avatar Customization -			gAgent.changeCameraToCustomizeAvatar(); -		} -	} -} - -// static -BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data) -{ -	LLWearableBridge* self = (LLWearableBridge*)user_data; -	if( self && (LLAssetType::AT_BODYPART != self->mAssetType) ) -	{ -		return gAgentWearables.isWearingItem( self->mUUID ); -	} -	return FALSE; -} - -// static -void LLWearableBridge::onRemoveFromAvatar(void* user_data) -{ -	LLWearableBridge* self = (LLWearableBridge*)user_data; -	if(!self) return; -	if(gAgentWearables.isWearingItem(self->mUUID)) -	{ -		LLViewerInventoryItem* item = self->getItem(); -		if (item) -		{ -			LLUUID parent_id = item->getParentUUID(); -			LLWearableList::instance().getAsset(item->getAssetUUID(), -												item->getName(), -												item->getType(), -												onRemoveFromAvatarArrived, -												new OnRemoveStruct(LLUUID(self->mUUID))); -		} -	} -} - -// static -void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, -												 void* userdata) -{ -	OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata; -	const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID); -	if(wearable) -	{ -		if( gAgentWearables.isWearingItem( item_id ) ) -		{ -			EWearableType type = wearable->getType(); - -			if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES ) ) //&& -				//!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) -			{ -				// MULTI_WEARABLE: FIXME HACK - always remove all -				bool do_remove_all = false; -				gAgentWearables.removeWearable( type, do_remove_all, 0 ); -			} -		} -	} - -	// Find and remove this item from the COF. -	LLInventoryModel::item_array_t items = gInventory.collectLinkedItems(item_id, LLAppearanceManager::instance().getCOF()); -	llassert(items.size() == 1); // Should always have one and only one item linked to this in the COF. -	for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); -		 iter != items.end(); -		 ++iter) -	{ -		const LLViewerInventoryItem *linked_item = (*iter); -		const LLUUID &item_id = linked_item->getUUID(); -		gInventory.purgeObject(item_id); -	} -	gInventory.notifyObservers(); - -	delete on_remove_struct; -} - -LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type, -													   const LLUUID& uuid,LLInventoryModel* model) -{ -	LLInvFVBridgeAction* action = NULL; -	switch(asset_type) -	{ -	case LLAssetType::AT_TEXTURE: -		action = new LLTextureBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_SOUND: -		action = new LLSoundBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_LANDMARK: -		action = new LLLandmarkBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_CALLINGCARD: -		action = new LLCallingCardBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_OBJECT: -		action = new LLObjectBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_NOTECARD: -		action = new LLNotecardBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_ANIMATION: -		action = new LLAnimationBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_GESTURE: -		action = new LLGestureBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_LSL_TEXT: -		action = new LLLSLTextBridgeAction(uuid,model); -		break; - -	case LLAssetType::AT_CLOTHING: -	case LLAssetType::AT_BODYPART: -		action = new LLWearableBridgeAction(uuid,model); - -		break; - -	default: -		break; -	} -	return action; -} - -//static -void LLInvFVBridgeAction::doAction(LLAssetType::EType asset_type, -								   const LLUUID& uuid,LLInventoryModel* model) -{ -	LLInvFVBridgeAction* action = createAction(asset_type,uuid,model); -	if(action) -	{ -		action->doIt(); -		delete action; -	} -} - -//static -void LLInvFVBridgeAction::doAction(const LLUUID& uuid, LLInventoryModel* model) -{ -	LLAssetType::EType asset_type = model->getItem(uuid)->getType(); -	LLInvFVBridgeAction* action = createAction(asset_type,uuid,model); -	if(action) -	{ -		action->doIt(); -		delete action; -	} -} - -LLViewerInventoryItem* LLInvFVBridgeAction::getItem() const -{ -	if(mModel) -		return (LLViewerInventoryItem*)mModel->getItem(mUUID); -	return NULL; -} - -//virtual -void	LLTextureBridgeAction::doIt() -{ -	if (getItem()) -	{ -		LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES); -	} - -	LLInvFVBridgeAction::doIt(); -} - -//virtual -void	LLSoundBridgeAction::doIt() -{ -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		LLFloaterReg::showInstance("preview_sound", LLSD(mUUID), TAKE_FOCUS_YES); -	} - -	LLInvFVBridgeAction::doIt(); -} - - -//virtual -void	LLLandmarkBridgeAction::doIt() -{ -	LLViewerInventoryItem* item = getItem(); -	if( item ) -	{ -		// Opening (double-clicking) a landmark immediately teleports, -		// but warns you the first time. -		LLSD payload; -		payload["asset_id"] = item->getAssetUUID(); -		LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload); -	} - -	LLInvFVBridgeAction::doIt(); -} - - -//virtual -void	LLCallingCardBridgeAction::doIt() -{ -	LLViewerInventoryItem* item = getItem(); -	if(item && item->getCreatorUUID().notNull()) -	{ -		LLAvatarActions::showProfile(item->getCreatorUUID()); -	} - -	LLInvFVBridgeAction::doIt(); -} - -//virtual -void -LLNotecardBridgeAction::doIt() -{ -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); -	} - -	LLInvFVBridgeAction::doIt(); -} - -//virtual -void	LLGestureBridgeAction::doIt() -{ -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null); -		preview->setFocus(TRUE); -	} - -	LLInvFVBridgeAction::doIt(); -} - -//virtual -void	LLAnimationBridgeAction::doIt() -{ -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); -	} - -	LLInvFVBridgeAction::doIt(); -} - - -//virtual -void	LLObjectBridgeAction::doIt() -{ -	LLFloaterReg::showInstance("properties", mUUID); - -	LLInvFVBridgeAction::doIt(); -} - - -//virtual -void	LLLSLTextBridgeAction::doIt() -{ -	LLViewerInventoryItem* item = getItem(); -	if (item) -	{ -		LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES); -	} - -	LLInvFVBridgeAction::doIt(); -} - - -BOOL LLWearableBridgeAction::isInTrash() const -{ -	if(!mModel) return FALSE; -	const LLUUID trash_id = mModel->findCategoryUUIDForType(LLFolderType::FT_TRASH); -	return mModel->isObjectDescendentOf(mUUID, trash_id); -} - -BOOL LLWearableBridgeAction::isAgentInventory() const -{ -	if(!mModel) return FALSE; -	if(gInventory.getRootFolderID() == mUUID) return TRUE; -	return mModel->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); -} - -void LLWearableBridgeAction::wearOnAvatar() -{ -	// Don't wear anything until initial wearables are loaded, can -	// destroy clothing items. -	if (!gAgentWearables.areWearablesLoaded()) -	{ -		LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded"); -		return; -	} - -	LLViewerInventoryItem* item = getItem(); -	if(item) -	{ -		if(!isAgentInventory()) -		{ -			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); -			copy_inventory_item( -				gAgent.getID(), -				item->getPermissions().getOwner(), -				item->getUUID(), -				LLUUID::null, -				std::string(), -				cb); -		} -		else -		{ -			wear_inventory_item_on_avatar(item); -		} -	} -} - -//virtual -void LLWearableBridgeAction::doIt() -{ -	if(isInTrash()) -	{ -		LLNotifications::instance().add("CannotWearTrash"); -	} -	else if(isAgentInventory()) -	{ -		if(!gAgentWearables.isWearingItem(mUUID)) -		{ -			wearOnAvatar(); -		} -	} -	else -	{ -		// must be in the inventory library. copy it to our inventory -		// and put it on right away. -		LLViewerInventoryItem* item = getItem(); -		if(item && item->isComplete()) -		{ -			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); -			copy_inventory_item( -				gAgent.getID(), -				item->getPermissions().getOwner(), -				item->getUUID(), -				LLUUID::null, -				std::string(), -				cb); -		} -		else if(item) -		{ -			// *TODO: We should fetch the item details, and then do -			// the operation above. -			LLNotifications::instance().add("CannotWearInfoNotComplete"); -		} -	} - -	LLInvFVBridgeAction::doIt(); -} - -// +=================================================+ -// |        LLLinkItemBridge                         | -// +=================================================+ -// For broken links - -std::string LLLinkItemBridge::sPrefix("Link: "); - - -LLUIImagePtr LLLinkItemBridge::getIcon() const -{ -	if (LLViewerInventoryItem *item = getItem()) -	{ -		return get_item_icon(item->getActualType(), LLInventoryType::IT_NONE, 0, FALSE); -	} -	return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE); -} - -void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	// *TODO: Translate -	lldebugs << "LLLink::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; - -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		items.push_back(std::string("Delete")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Delete")); -		} -	} -	hide_context_entries(menu, items, disabled_items); -} - - -// +=================================================+ -// |        LLLinkBridge                             | -// +=================================================+ -// For broken links. - -std::string LLLinkFolderBridge::sPrefix("Link: "); - - -LLUIImagePtr LLLinkFolderBridge::getIcon() const -{ -	LLFolderType::EType preferred_type = LLFolderType::FT_NONE; -	if (LLViewerInventoryItem *item = getItem()) -	{ -		if (const LLViewerInventoryCategory* cat = item->getLinkedCategory()) -		{ -			preferred_type = cat->getPreferredType(); -		} -	} -	return LLFolderBridge::getIcon(preferred_type); -} - -void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ -	// *TODO: Translate -	lldebugs << "LLLink::buildContextMenu()" << llendl; -	std::vector<std::string> items; -	std::vector<std::string> disabled_items; - -	if(isInTrash()) -	{ -		items.push_back(std::string("Purge Item")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Purge Item")); -		} - -		items.push_back(std::string("Restore Item")); -	} -	else -	{ -		items.push_back(std::string("Find Original")); -		items.push_back(std::string("Delete")); -		if (!isItemRemovable()) -		{ -			disabled_items.push_back(std::string("Delete")); -		} -	} -	hide_context_entries(menu, items, disabled_items); -} - -void LLLinkFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) -{ -	if ("goto" == action) -	{ -		gotoItem(folder); -		return; -	} -	LLItemBridge::performAction(folder,model,action); -} - -void LLLinkFolderBridge::gotoItem(LLFolderView *folder) -{ -	const LLUUID &cat_uuid = getFolderID(); -	if (!cat_uuid.isNull()) -	{ -		if (LLFolderViewItem *base_folder = folder->getItemByID(cat_uuid)) -		{ -			if (LLInventoryModel* model = getInventoryModel()) -			{ -				model->fetchDescendentsOf(cat_uuid); -			} -			base_folder->setOpen(TRUE); -			folder->setSelectionFromRoot(base_folder,TRUE); -			folder->scrollToShowSelection(); -		} -	} -} - -const LLUUID &LLLinkFolderBridge::getFolderID() const -{ -	if (LLViewerInventoryItem *link_item = getItem()) -	{ -		if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory()) -		{ -			const LLUUID& cat_uuid = cat->getUUID(); -			return cat_uuid; -		} -	} -	return LLUUID::null; -} +/**
 + * @file llinventorybridge.cpp
 + * @brief Implementation of the Inventory-Folder-View-Bridge classes.
 + *
 + * $LicenseInfo:firstyear=2001&license=viewergpl$
 + *
 + * Copyright (c) 2001-2009, Linden Research, Inc.
 + *
 + * Second Life Viewer Source Code
 + * The source code in this file ("Source Code") is provided by Linden Lab
 + * to you under the terms of the GNU General Public License, version 2.0
 + * ("GPL"), unless you have obtained a separate licensing agreement
 + * ("Other License"), formally executed by you and Linden Lab.  Terms of
 + * the GPL can be found in doc/GPL-license.txt in this distribution, or
 + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 + *
 + * There are special exceptions to the terms and conditions of the GPL as
 + * it is applied to this Source Code. View the full text of the exception
 + * in the file doc/FLOSS-exception.txt in this software distribution, or
 + * online at
 + * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 + *
 + * By copying, modifying or distributing this software, you acknowledge
 + * that you have read and understood your obligations described above,
 + * and agree to abide by those obligations.
 + *
 + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 + * COMPLETENESS OR PERFORMANCE.
 + * $/LicenseInfo$
 + */
 +
 +#include "llviewerprecompiledheaders.h"
 +#include "llinventorybridge.h"
 +
 +#include "llagent.h"
 +#include "llagentwearables.h"
 +#include "llappearancemgr.h"
 +#include "llavataractions.h"
 +#include "llfloatercustomize.h"
 +#include "llfloaterinventory.h"
 +#include "llfloateropenobject.h"
 +#include "llfloaterreg.h"
 +#include "llfloaterworldmap.h"
 +#include "llfriendcard.h"
 +#include "llgesturemgr.h"
 +#include "llimfloater.h"
 +#include "llimview.h"
 +#include "llinventoryclipboard.h"
 +#include "llinventoryfunctions.h"
 +#include "llinventorymodel.h"
 +#include "llinventorypanel.h"
 +#include "llpreviewanim.h"
 +#include "llpreviewgesture.h"
 +#include "llpreviewtexture.h"
 +#include "llselectmgr.h"
 +#include "llsidetray.h"
 +#include "lltrans.h"
 +#include "llviewerassettype.h"
 +#include "llviewermessage.h"
 +#include "llviewerobjectlist.h"
 +#include "llviewerwindow.h"
 +#include "llvoavatarself.h"
 +#include "llwearablelist.h"
 +#include "llpaneloutfitsinventory.h"
 +
 +using namespace LLOldEvents;
 +
 +// Helpers
 +// bug in busy count inc/dec right now, logic is complex... do we really need it?
 +void inc_busy_count()
 +{
 +// 	gViewerWindow->getWindow()->incBusyCount();
 +//  check balance of these calls if this code is changed to ever actually
 +//  *do* something!
 +}
 +void dec_busy_count()
 +{
 +// 	gViewerWindow->getWindow()->decBusyCount();
 +//  check balance of these calls if this code is changed to ever actually
 +//  *do* something!
 +}
 +
 +// Function declarations
 +void wear_add_inventory_item_on_avatar(LLInventoryItem* item);
 +void remove_inventory_category_from_avatar(LLInventoryCategory* category);
 +void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
 +bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
 +bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response);
 +
 +std::string ICON_NAME[ICON_NAME_COUNT] =
 +{
 +	"Inv_Texture",
 +	"Inv_Sound",
 +	"Inv_CallingCard",
 +	"Inv_CallingCard",
 +	"Inv_Landmark",
 +	"Inv_Landmark",
 +	"Inv_Script",
 +	"Inv_Clothing",
 +	"Inv_Object",
 +	"Inv_Object",
 +	"Inv_Notecard",
 +	"Inv_Skin",
 +	"Inv_Snapshot",
 +
 +	"Inv_BodyShape",
 +	"Inv_Skin",
 +	"Inv_Hair",
 +	"Inv_Eye",
 +	"Inv_Shirt",
 +	"Inv_Pants",
 +	"Inv_Shoe",
 +	"Inv_Socks",
 +	"Inv_Jacket",
 +	"Inv_Gloves",
 +	"Inv_Undershirt",
 +	"Inv_Underpants",
 +	"Inv_Skirt",
 +	"Inv_Alpha",
 +	"Inv_Tattoo",
 +
 +	"Inv_Animation",
 +	"Inv_Gesture",
 +
 +	"inv_item_linkitem.tga",
 +	"inv_item_linkfolder.tga"
 +};
 +
 +// +=================================================+
 +// |        LLInvFVBridge                            |
 +// +=================================================+
 +
 +LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
 +mUUID(uuid), mInvType(LLInventoryType::IT_NONE)
 +{
 +	mInventoryPanel = inventory->getHandle();
 +}
 +
 +const std::string& LLInvFVBridge::getName() const
 +{
 +	LLInventoryObject* obj = getInventoryObject();
 +	if(obj)
 +	{
 +		return obj->getName();
 +	}
 +	return LLStringUtil::null;
 +}
 +
 +const std::string& LLInvFVBridge::getDisplayName() const
 +{
 +	return getName();
 +}
 +
 +// Folders have full perms
 +PermissionMask LLInvFVBridge::getPermissionMask() const
 +{
 +
 +	return PERM_ALL;
 +}
 +
 +// virtual
 +LLFolderType::EType LLInvFVBridge::getPreferredType() const
 +{
 +	return LLFolderType::FT_NONE;
 +}
 +
 +
 +// Folders don't have creation dates.
 +time_t LLInvFVBridge::getCreationDate() const
 +{
 +	return 0;
 +}
 +
 +// Can be destroyed (or moved to trash)
 +BOOL LLInvFVBridge::isItemRemovable()
 +{
 +	const LLInventoryModel* model = getInventoryModel();
 +	if(!model) 
 +	{
 +		return FALSE;
 +	}
 +	if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
 +	{
 +		return FALSE;
 +	}
 +	const LLInventoryObject *obj = model->getItem(mUUID);
 +	if (obj && obj->getIsLinkType())
 +	{
 +		return TRUE;
 +	}
 +	if (gAgentWearables.isWearingItem(mUUID))
 +	{
 +		return FALSE;
 +	}
 +	const LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
 +	if (avatar && avatar->isWearingAttachment(mUUID))
 +	{
 +		return FALSE;
 +	}
 +	return TRUE;
 +}
 +
 +// Can be moved to another folder
 +BOOL LLInvFVBridge::isItemMovable() const
 +{
 +	return TRUE;
 +}
 +
 +/*virtual*/
 +/**
 + * @brief Adds this item into clipboard storage
 + */
 +void LLInvFVBridge::cutToClipboard()
 +{
 +	if(isItemMovable())
 +	{
 +		LLInventoryClipboard::instance().cut(mUUID);
 +	}
 +}
 +// *TODO: make sure this does the right thing
 +void LLInvFVBridge::showProperties()
 +{
 +	LLSD key;
 +	key["id"] = mUUID;
 +	LLSideTray::getInstance()->showPanel("sidepanel_inventory", key);
 +
 +	// Disable old properties floater; this is replaced by the sidepanel.
 +	/*
 +	LLFloaterReg::showInstance("properties", mUUID);
 +	*/
 +}
 +
 +void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
 +{
 +	// Deactivate gestures when moving them into Trash
 +	LLInvFVBridge* bridge;
 +	LLInventoryModel* model = getInventoryModel();
 +	LLViewerInventoryItem* item = NULL;
 +	LLViewerInventoryCategory* cat = NULL;
 +	LLInventoryModel::cat_array_t	descendent_categories;
 +	LLInventoryModel::item_array_t	descendent_items;
 +	S32 count = batch.count();
 +	S32 i,j;
 +	for(i = 0; i < count; ++i)
 +	{
 +		bridge = (LLInvFVBridge*)(batch.get(i));
 +		if(!bridge || !bridge->isItemRemovable()) continue;
 +		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 +		if (item)
 +		{
 +			if(LLAssetType::AT_GESTURE == item->getType())
 +			{
 +				LLGestureManager::instance().deactivateGesture(item->getUUID());
 +			}
 +		}
 +	}
 +	for(i = 0; i < count; ++i)
 +	{
 +		bridge = (LLInvFVBridge*)(batch.get(i));
 +		if(!bridge || !bridge->isItemRemovable()) continue;
 +		cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
 +		if (cat)
 +		{
 +			gInventory.collectDescendents( cat->getUUID(), descendent_categories, descendent_items, FALSE );
 +			for (j=0; j<descendent_items.count(); j++)
 +			{
 +				if(LLAssetType::AT_GESTURE == descendent_items[j]->getType())
 +				{
 +					LLGestureManager::instance().deactivateGesture(descendent_items[j]->getUUID());
 +				}
 +			}
 +		}
 +	}
 +	removeBatchNoCheck(batch);
 +}
 +
 +void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch)
 +{
 +	// this method moves a bunch of items and folders to the trash. As
 +	// per design guidelines for the inventory model, the message is
 +	// built and the accounting is performed first. After all of that,
 +	// we call LLInventoryModel::moveObject() to move everything
 +	// around.
 +	LLInvFVBridge* bridge;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return;
 +	LLMessageSystem* msg = gMessageSystem;
 +	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +	LLViewerInventoryItem* item = NULL;
 +	LLViewerInventoryCategory* cat = NULL;
 +	std::vector<LLUUID> move_ids;
 +	LLInventoryModel::update_map_t update;
 +	bool start_new_message = true;
 +	S32 count = batch.count();
 +	S32 i;
 +	for(i = 0; i < count; ++i)
 +	{
 +		bridge = (LLInvFVBridge*)(batch.get(i));
 +		if(!bridge || !bridge->isItemRemovable()) continue;
 +		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 +		if(item)
 +		{
 +			if(item->getParentUUID() == trash_id) continue;
 +			move_ids.push_back(item->getUUID());
 +			LLPreview::hide(item->getUUID());
 +			--update[item->getParentUUID()];
 +			++update[trash_id];
 +			if(start_new_message)
 +			{
 +				start_new_message = false;
 +				msg->newMessageFast(_PREHASH_MoveInventoryItem);
 +				msg->nextBlockFast(_PREHASH_AgentData);
 +				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 +				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 +				msg->addBOOLFast(_PREHASH_Stamp, TRUE);
 +			}
 +			msg->nextBlockFast(_PREHASH_InventoryData);
 +			msg->addUUIDFast(_PREHASH_ItemID, item->getUUID());
 +			msg->addUUIDFast(_PREHASH_FolderID, trash_id);
 +			msg->addString("NewName", NULL);
 +			if(msg->isSendFullFast(_PREHASH_InventoryData))
 +			{
 +				start_new_message = true;
 +				gAgent.sendReliableMessage();
 +				gInventory.accountForUpdate(update);
 +				update.clear();
 +			}
 +		}
 +	}
 +	if(!start_new_message)
 +	{
 +		start_new_message = true;
 +		gAgent.sendReliableMessage();
 +		gInventory.accountForUpdate(update);
 +		update.clear();
 +	}
 +	for(i = 0; i < count; ++i)
 +	{
 +		bridge = (LLInvFVBridge*)(batch.get(i));
 +		if(!bridge || !bridge->isItemRemovable()) continue;
 +		cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
 +		if(cat)
 +		{
 +			if(cat->getParentUUID() == trash_id) continue;
 +			move_ids.push_back(cat->getUUID());
 +			--update[cat->getParentUUID()];
 +			++update[trash_id];
 +			if(start_new_message)
 +			{
 +				start_new_message = false;
 +				msg->newMessageFast(_PREHASH_MoveInventoryFolder);
 +				msg->nextBlockFast(_PREHASH_AgentData);
 +				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 +				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 +				msg->addBOOL("Stamp", TRUE);
 +			}
 +			msg->nextBlockFast(_PREHASH_InventoryData);
 +			msg->addUUIDFast(_PREHASH_FolderID, cat->getUUID());
 +			msg->addUUIDFast(_PREHASH_ParentID, trash_id);
 +			if(msg->isSendFullFast(_PREHASH_InventoryData))
 +			{
 +				start_new_message = true;
 +				gAgent.sendReliableMessage();
 +				gInventory.accountForUpdate(update);
 +				update.clear();
 +			}
 +		}
 +	}
 +	if(!start_new_message)
 +	{
 +		gAgent.sendReliableMessage();
 +		gInventory.accountForUpdate(update);
 +	}
 +
 +	// move everything.
 +	std::vector<LLUUID>::iterator it = move_ids.begin();
 +	std::vector<LLUUID>::iterator end = move_ids.end();
 +	for(; it != end; ++it)
 +	{
 +		gInventory.moveObject((*it), trash_id);
 +	}
 +
 +	// notify inventory observers.
 +	model->notifyObservers();
 +}
 +
 +BOOL LLInvFVBridge::isClipboardPasteable() const
 +{
 +	if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory())
 +	{
 +		return FALSE;
 +	}
 +	LLInventoryModel* model = getInventoryModel();
 +	if (!model)
 +	{
 +		return FALSE;
 +	}
 +
 +	const LLUUID &agent_id = gAgent.getID();
 +
 +	LLDynamicArray<LLUUID> objects;
 +	LLInventoryClipboard::instance().retrieve(objects);
 +	S32 count = objects.count();
 +	for(S32 i = 0; i < count; i++)
 +	{
 +		const LLUUID &item_id = objects.get(i);
 +
 +		// Can't paste folders
 +		const LLInventoryCategory *cat = model->getCategory(item_id);
 +		if (cat)
 +		{
 +			return FALSE;
 +		}
 +
 +		const LLInventoryItem *item = model->getItem(item_id);
 +		if (item)
 +		{
 +			if (!item->getPermissions().allowCopyBy(agent_id))
 +			{
 +				return FALSE;
 +			}
 +		}
 +	}
 +	return TRUE;
 +}
 +
 +BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
 +{
 +	if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory())
 +	{
 +		return FALSE;
 +	}
 +	const LLInventoryModel* model = getInventoryModel();
 +	if (!model)
 +	{
 +		return FALSE;
 +	}
 +
 +	LLDynamicArray<LLUUID> objects;
 +	LLInventoryClipboard::instance().retrieve(objects);
 +	S32 count = objects.count();
 +	for(S32 i = 0; i < count; i++)
 +	{
 +		const LLInventoryItem *item = model->getItem(objects.get(i));
 +		if (item)
 +		{
 +			if (!LLAssetType::lookupCanLink(item->getActualType()))
 +			{
 +				return FALSE;
 +			}
 +		}
 +		const LLViewerInventoryCategory *cat = model->getCategory(objects.get(i));
 +		if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
 +		{
 +			return FALSE;
 +		}
 +	}
 +	return TRUE;
 +}
 +
 +void hide_context_entries(LLMenuGL& menu, 
 +						const std::vector<std::string> &entries_to_show,
 +						const std::vector<std::string> &disabled_entries)
 +{
 +	const LLView::child_list_t *list = menu.getChildList();
 +
 +	LLView::child_list_t::const_iterator itor;
 +	for (itor = list->begin(); itor != list->end(); ++itor)
 +	{
 +		std::string name = (*itor)->getName();
 +
 +		// descend into split menus:
 +		LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(*itor);
 +		if ((name == "More") && branchp)
 +		{
 +			hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries);
 +		}
 +
 +
 +		bool found = false;
 +		std::vector<std::string>::const_iterator itor2;
 +		for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2)
 +		{
 +			if (*itor2 == name)
 +			{
 +				found = true;
 +			}
 +		}
 +		if (!found)
 +		{
 +			(*itor)->setVisible(FALSE);
 +		}
 +		else
 +		{
 +			(*itor)->setVisible(TRUE);
 +			for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
 +			{
 +				if (*itor2 == name)
 +				{
 +					(*itor)->setEnabled(FALSE);
 +				}
 +			}
 +		}
 +	}
 +}
 +
 +// Helper for commonly-used entries
 +void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
 +										std::vector<std::string> &items,
 +										std::vector<std::string> &disabled_items, U32 flags)
 +{
 +	const LLInventoryObject *obj = getInventoryObject();
 +	if (obj && obj->getIsLinkType())
 +	{
 +		items.push_back(std::string("Find Original"));
 +		if (LLAssetType::lookupIsLinkType(obj->getType()))
 +		{
 +			disabled_items.push_back(std::string("Find Original"));
 +		}
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Rename"));
 +		if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
 +		{
 +			disabled_items.push_back(std::string("Rename"));
 +		}
 +		
 +		if (show_asset_id)
 +		{
 +			items.push_back(std::string("Copy Asset UUID"));
 +			if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
 +				 || (flags & FIRST_SELECTED_ITEM) == 0)
 +			{
 +				disabled_items.push_back(std::string("Copy Asset UUID"));
 +			}
 +		}
 +		items.push_back(std::string("Copy Separator"));
 +		
 +		items.push_back(std::string("Copy"));
 +		if (!isItemCopyable())
 +		{
 +			disabled_items.push_back(std::string("Copy"));
 +		}
 +	}
 +
 +	items.push_back(std::string("Paste"));
 +	if (!isClipboardPasteable() || (flags & FIRST_SELECTED_ITEM) == 0)
 +	{
 +		disabled_items.push_back(std::string("Paste"));
 +	}
 +
 +	items.push_back(std::string("Paste As Link"));
 +	if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
 +	{
 +		disabled_items.push_back(std::string("Paste As Link"));
 +	}
 +	items.push_back(std::string("Paste Separator"));
 +
 +	items.push_back(std::string("Delete"));
 +	if (!isItemRemovable())
 +	{
 +		disabled_items.push_back(std::string("Delete"));
 +	}
 +
 +	// If multiple items are selected, disable properties (if it exists).
 +	if ((flags & FIRST_SELECTED_ITEM) == 0)
 +	{
 +		disabled_items.push_back(std::string("Properties"));
 +	}
 +}
 +
 +void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	lldebugs << "LLInvFVBridge::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("PurgeItem"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("PurgeItem"));
 +		}
 +		items.push_back(std::string("RestoreItem"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Open"));
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +	}
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +// *TODO: remove this
 +BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 +{
 +	BOOL rv = FALSE;
 +
 +	const LLInventoryObject* obj = getInventoryObject();
 +
 +	if(obj)
 +	{
 +		*type = LLViewerAssetType::lookupDragAndDropType(obj->getActualType());
 +		if(*type == DAD_NONE)
 +		{
 +			return FALSE;
 +		}
 +
 +		*id = obj->getUUID();
 +		//object_ids.put(obj->getUUID());
 +
 +		if (*type == DAD_CATEGORY)
 +		{
 +			gInventory.startBackgroundFetch(obj->getUUID());
 +		}
 +
 +		rv = TRUE;
 +	}
 +
 +	return rv;
 +}
 +
 +LLInventoryObject* LLInvFVBridge::getInventoryObject() const
 +{
 +	LLInventoryObject* obj = NULL;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(model)
 +	{
 +		obj = (LLInventoryObject*)model->getObject(mUUID);
 +	}
 +	return obj;
 +}
 +
 +LLInventoryModel* LLInvFVBridge::getInventoryModel() const
 +{
 +	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
 +	return panel ? panel->getModel() : NULL;
 +}
 +
 +BOOL LLInvFVBridge::isInTrash() const
 +{
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return FALSE;
 +	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +	return model->isObjectDescendentOf(mUUID, trash_id);
 +}
 +
 +BOOL LLInvFVBridge::isLinkedObjectInTrash() const
 +{
 +	if (isInTrash()) return TRUE;
 +
 +	const LLInventoryObject *obj = getInventoryObject();
 +	if (obj && obj->getIsLinkType())
 +	{
 +		LLInventoryModel* model = getInventoryModel();
 +		if(!model) return FALSE;
 +		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +		return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id);
 +	}
 +	return FALSE;
 +}
 +
 +BOOL LLInvFVBridge::isAgentInventory() const
 +{
 +	const LLInventoryModel* model = getInventoryModel();
 +	if(!model) return FALSE;
 +	if(gInventory.getRootFolderID() == mUUID) return TRUE;
 +	return model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID());
 +}
 +
 +BOOL LLInvFVBridge::isCOFFolder() const
 +{
 +	const LLInventoryModel* model = getInventoryModel();
 +	if(!model) return TRUE;
 +	const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 +	if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id))
 +	{
 +		return TRUE;
 +	}
 +	return FALSE;
 +}
 +
 +BOOL LLInvFVBridge::isItemPermissive() const
 +{
 +	return FALSE;
 +}
 +
 +// static
 +void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
 +									 LLViewerInventoryItem* item,
 +									 const LLUUID& new_parent,
 +									 BOOL restamp)
 +{
 +	if(item->getParentUUID() != new_parent)
 +	{
 +		LLInventoryModel::update_list_t update;
 +		LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
 +		update.push_back(old_folder);
 +		LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
 +		update.push_back(new_folder);
 +		gInventory.accountForUpdate(update);
 +
 +		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 +		new_item->setParent(new_parent);
 +		new_item->updateParentOnServer(restamp);
 +		model->updateItem(new_item);
 +		model->notifyObservers();
 +	}
 +}
 +
 +// static
 +void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model,
 +										 LLViewerInventoryCategory* cat,
 +										 const LLUUID& new_parent,
 +										 BOOL restamp)
 +{
 +	if(cat->getParentUUID() != new_parent)
 +	{
 +		LLInventoryModel::update_list_t update;
 +		LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
 +		update.push_back(old_folder);
 +		LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
 +		update.push_back(new_folder);
 +		gInventory.accountForUpdate(update);
 +
 +		LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
 +		new_cat->setParent(new_parent);
 +		new_cat->updateParentOnServer(restamp);
 +		model->updateCategory(new_cat);
 +		model->notifyObservers();
 +	}
 +}
 +
 +
 +const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type)
 +{
 +	const std::string rv= LLInventoryType::lookup(inv_type);
 +	if(rv.empty())
 +	{
 +		return std::string("<invalid>");
 +	}
 +	return rv;
 +}
 +
 +LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 +										   LLAssetType::EType actual_asset_type,
 +										   LLInventoryType::EType inv_type,
 +										   LLInventoryPanel* inventory,
 +										   const LLUUID& uuid,
 +										   U32 flags)
 +{
 +	LLInvFVBridge* new_listener = NULL;
 +	switch(asset_type)
 +	{
 +		case LLAssetType::AT_TEXTURE:
 +			if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLTextureBridge(inventory, uuid, inv_type);
 +			break;
 +
 +		case LLAssetType::AT_SOUND:
 +			if(!(inv_type == LLInventoryType::IT_SOUND))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLSoundBridge(inventory, uuid);
 +			break;
 +
 +		case LLAssetType::AT_LANDMARK:
 +			if(!(inv_type == LLInventoryType::IT_LANDMARK))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLLandmarkBridge(inventory, uuid, flags);
 +			break;
 +
 +		case LLAssetType::AT_CALLINGCARD:
 +			if(!(inv_type == LLInventoryType::IT_CALLINGCARD))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLCallingCardBridge(inventory, uuid);
 +			break;
 +
 +		case LLAssetType::AT_SCRIPT:
 +			if(!(inv_type == LLInventoryType::IT_LSL))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLScriptBridge(inventory, uuid);
 +			break;
 +
 +		case LLAssetType::AT_OBJECT:
 +			if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags);
 +			break;
 +
 +		case LLAssetType::AT_NOTECARD:
 +			if(!(inv_type == LLInventoryType::IT_NOTECARD))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLNotecardBridge(inventory, uuid);
 +			break;
 +
 +		case LLAssetType::AT_ANIMATION:
 +			if(!(inv_type == LLInventoryType::IT_ANIMATION))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLAnimationBridge(inventory, uuid);
 +			break;
 +
 +		case LLAssetType::AT_GESTURE:
 +			if(!(inv_type == LLInventoryType::IT_GESTURE))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLGestureBridge(inventory, uuid);
 +			break;
 +
 +		case LLAssetType::AT_LSL_TEXT:
 +			if(!(inv_type == LLInventoryType::IT_LSL))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLLSLTextBridge(inventory, uuid);
 +			break;
 +
 +		case LLAssetType::AT_CLOTHING:
 +		case LLAssetType::AT_BODYPART:
 +			if(!(inv_type == LLInventoryType::IT_WEARABLE))
 +			{
 +				llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
 +			}
 +			new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags);
 +			break;
 +		case LLAssetType::AT_CATEGORY:
 +			if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
 +			{
 +				// Create a link folder handler instead.
 +				new_listener = new LLLinkFolderBridge(inventory, uuid);
 +				break;
 +			}
 +			new_listener = new LLFolderBridge(inventory, uuid);
 +			break;
 +		case LLAssetType::AT_LINK:
 +			// Only should happen for broken links.
 +			new_listener = new LLLinkItemBridge(inventory, uuid);
 +			break;
 +		case LLAssetType::AT_LINK_FOLDER:
 +			// Only should happen for broken links.
 +			new_listener = new LLLinkItemBridge(inventory, uuid);
 +			break;
 +		default:
 +			llinfos << "Unhandled asset type (llassetstorage.h): "
 +					<< (S32)asset_type << llendl;
 +			break;
 +	}
 +
 +	if (new_listener)
 +	{
 +		new_listener->mInvType = inv_type;
 +	}
 +
 +	return new_listener;
 +}
 +
 +void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
 +{
 +	LLInventoryCategory* cat = model->getCategory(uuid);
 +	if (cat)
 +	{
 +		model->purgeDescendentsOf(uuid);
 +		model->notifyObservers();
 +	}
 +	LLInventoryObject* obj = model->getObject(uuid);
 +	if (obj)
 +	{
 +		model->purgeObject(uuid);
 +		model->notifyObservers();
 +	}
 +}
 +
 +// +=================================================+
 +// |        InventoryFVBridgeBuilder                 |
 +// +=================================================+
 +LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type,
 +														LLAssetType::EType actual_asset_type,
 +														LLInventoryType::EType inv_type,
 +														LLInventoryPanel* inventory,
 +														const LLUUID& uuid,
 +														U32 flags /* = 0x00 */) const
 +{
 +	return LLInvFVBridge::createBridge(asset_type,
 +		actual_asset_type,
 +		inv_type,
 +		inventory,
 +		uuid,
 +		flags);
 +}
 +
 +// +=================================================+
 +// |        LLItemBridge                             |
 +// +=================================================+
 +
 +void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("goto" == action)
 +	{
 +		gotoItem(folder);
 +	}
 +	if ("open" == action)
 +	{
 +		openItem();
 +		return;
 +	}
 +	else if ("properties" == action)
 +	{
 +		showProperties();
 +		return;
 +	}
 +	else if ("purge" == action)
 +	{
 +		purgeItem(model, mUUID);
 +		return;
 +	}
 +	else if ("restoreToWorld" == action)
 +	{
 +		restoreToWorld();
 +		return;
 +	}
 +	else if ("restore" == action)
 +	{
 +		restoreItem();
 +		return;
 +	}
 +	else if ("copy_uuid" == action)
 +	{
 +		// Single item only
 +		LLInventoryItem* item = model->getItem(mUUID);
 +		if(!item) return;
 +		LLUUID asset_id = item->getAssetUUID();
 +		std::string buffer;
 +		asset_id.toString(buffer);
 +
 +		gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer));
 +		return;
 +	}
 +	else if ("copy" == action)
 +	{
 +		copyToClipboard();
 +		return;
 +	}
 +	else if ("paste" == action)
 +	{
 +		// Single item only
 +		LLInventoryItem* itemp = model->getItem(mUUID);
 +		if (!itemp) return;
 +
 +		LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID());
 +		if (!folder_view_itemp) return;
 +
 +		folder_view_itemp->getListener()->pasteFromClipboard();
 +		return;
 +	}
 +	else if ("paste_link" == action)
 +	{
 +		// Single item only
 +		LLInventoryItem* itemp = model->getItem(mUUID);
 +		if (!itemp) return;
 +
 +		LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID());
 +		if (!folder_view_itemp) return;
 +
 +		folder_view_itemp->getListener()->pasteLinkFromClipboard();
 +		return;
 +	}
 +}
 +
 +void LLItemBridge::selectItem()
 +{
 +	LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
 +	if(item && !item->isComplete())
 +	{
 +		item->fetchFromServer();
 +	}
 +}
 +
 +void LLItemBridge::restoreItem()
 +{
 +	LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
 +	if(item)
 +	{
 +		LLInventoryModel* model = getInventoryModel();
 +		const LLUUID new_parent = model->findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(item->getType()));
 +		// do not restamp on restore.
 +		LLInvFVBridge::changeItemParent(model, item, new_parent, FALSE);
 +	}
 +}
 +
 +void LLItemBridge::restoreToWorld()
 +{
 +	LLViewerInventoryItem* itemp = (LLViewerInventoryItem*)getItem();
 +	if (itemp)
 +	{
 +		LLMessageSystem* msg = gMessageSystem;
 +		msg->newMessage("RezRestoreToWorld");
 +		msg->nextBlockFast(_PREHASH_AgentData);
 +		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 +		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 +
 +		msg->nextBlockFast(_PREHASH_InventoryData);
 +		itemp->packMessage(msg);
 +		msg->sendReliable(gAgent.getRegion()->getHost());
 +	}
 +
 +	//Similar functionality to the drag and drop rez logic
 +	BOOL remove_from_inventory = FALSE;
 +
 +	//remove local inventory copy, sim will deal with permissions and removing the item
 +	//from the actual inventory if its a no-copy etc
 +	if(!itemp->getPermissions().allowCopyBy(gAgent.getID()))
 +	{
 +		remove_from_inventory = TRUE;
 +	}
 +
 +	// Check if it's in the trash. (again similar to the normal rez logic)
 +	const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +	if(gInventory.isObjectDescendentOf(itemp->getUUID(), trash_id))
 +	{
 +		remove_from_inventory = TRUE;
 +	}
 +
 +	if(remove_from_inventory)
 +	{
 +		gInventory.deleteObject(itemp->getUUID());
 +		gInventory.notifyObservers();
 +	}
 +}
 +
 +void LLItemBridge::gotoItem(LLFolderView *folder)
 +{
 +	LLInventoryObject *obj = getInventoryObject();
 +	if (obj && obj->getIsLinkType())
 +	{
 +		LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
 +		if (active_panel)
 +		{
 +			active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
 +		}
 +	}
 +}
 +
 +LLUIImagePtr LLItemBridge::getIcon() const
 +{
 +	return LLUI::getUIImage(ICON_NAME[OBJECT_ICON_NAME]);
 +}
 +
 +PermissionMask LLItemBridge::getPermissionMask() const
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	PermissionMask perm_mask = 0;
 +	if(item)
 +	{
 +		BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
 +		BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
 +		BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
 +															gAgent.getID());
 +
 +		if (copy) perm_mask |= PERM_COPY;
 +		if (mod)  perm_mask |= PERM_MODIFY;
 +		if (xfer) perm_mask |= PERM_TRANSFER;
 +
 +	}
 +	return perm_mask;
 +}
 +
 +const std::string& LLItemBridge::getDisplayName() const
 +{
 +	if(mDisplayName.empty())
 +	{
 +		buildDisplayName(getItem(), mDisplayName);
 +	}
 +	return mDisplayName;
 +}
 +
 +void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name)
 +{
 +	if(item)
 +	{
 +		name.assign(item->getName());
 +	}
 +	else
 +	{
 +		name.assign(LLStringUtil::null);
 +	}
 +}
 +
 +LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
 +{
 +	U8 font = LLFontGL::NORMAL;
 +
 +	if( gAgentWearables.isWearingItem( mUUID ) )
 +	{
 +		// llinfos << "BOLD" << llendl;
 +		font |= LLFontGL::BOLD;
 +	}
 +
 +	const LLViewerInventoryItem* item = getItem();
 +	if (item && item->getIsLinkType())
 +	{
 +		font |= LLFontGL::ITALIC;
 +	}
 +	return (LLFontGL::StyleFlags)font;
 +}
 +
 +std::string LLItemBridge::getLabelSuffix() const
 +{
 +	// String table is loaded before login screen and inventory items are
 +	// loaded after login, so LLTrans should be ready.
 +	static std::string NO_COPY =LLTrans::getString("no_copy");
 +	static std::string NO_MOD = LLTrans::getString("no_modify");
 +	static std::string NO_XFER = LLTrans::getString("no_transfer");
 +	static std::string LINK = LLTrans::getString("link");
 +	static std::string BROKEN_LINK = LLTrans::getString("broken_link");
 +	std::string suffix;
 +	LLInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		// it's a bit confusing to put nocopy/nomod/etc on calling cards.
 +		if(LLAssetType::AT_CALLINGCARD != item->getType()
 +		   && item->getPermissions().getOwner() == gAgent.getID())
 +		{
 +			BOOL broken_link = LLAssetType::lookupIsLinkType(item->getType());
 +			if (broken_link) return BROKEN_LINK;
 +
 +			BOOL link = item->getIsLinkType();
 +			if (link) return LINK;
 +
 +			BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
 +			if (!copy)
 +			{
 +				suffix += NO_COPY;
 +			}
 +			BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
 +			if (!mod)
 +			{
 +				suffix += NO_MOD;
 +			}
 +			BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
 +																gAgent.getID());
 +			if (!xfer)
 +			{
 +				suffix += NO_XFER;
 +			}
 +		}
 +	}
 +	return suffix;
 +}
 +
 +time_t LLItemBridge::getCreationDate() const
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		return item->getCreationDate();
 +	}
 +	return 0;
 +}
 +
 +
 +BOOL LLItemBridge::isItemRenameable() const
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		// (For now) Don't allow calling card rename since that may confuse users as to
 +		// what the calling card points to.
 +		if (item->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
 +		{
 +			return FALSE;
 +		}
 +		return (item->getPermissions().allowModifyBy(gAgent.getID()));
 +	}
 +	return FALSE;
 +}
 +
 +BOOL LLItemBridge::renameItem(const std::string& new_name)
 +{
 +	if(!isItemRenameable())
 +		return FALSE;
 +	LLPreview::dirty(mUUID);
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model)
 +		return FALSE;
 +	LLViewerInventoryItem* item = getItem();
 +	if(item && (item->getName() != new_name))
 +	{
 +		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 +		new_item->rename(new_name);
 +		buildDisplayName(new_item, mDisplayName);
 +		new_item->updateServer(FALSE);
 +		model->updateItem(new_item);
 +
 +		model->notifyObservers();
 +	}
 +	// return FALSE because we either notified observers (& therefore
 +	// rebuilt) or we didn't update.
 +	return FALSE;
 +}
 +
 +
 +BOOL LLItemBridge::removeItem()
 +{
 +	if(!isItemRemovable())
 +	{
 +		return FALSE;
 +	}
 +	// move it to the trash
 +	LLPreview::hide(mUUID, TRUE);
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return FALSE;
 +	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +	LLViewerInventoryItem* item = getItem();
 +
 +	// if item is not already in trash
 +	if(item && !model->isObjectDescendentOf(mUUID, trash_id))
 +	{
 +		// move to trash, and restamp
 +		LLInvFVBridge::changeItemParent(model, item, trash_id, TRUE);
 +		// delete was successful
 +		return TRUE;
 +	}
 +	else
 +	{
 +		// tried to delete already item in trash (should purge?)
 +		return FALSE;
 +	}
 +}
 +
 +BOOL LLItemBridge::isItemCopyable() const
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		// can't copy worn objects. DEV-15183
 +		LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
 +		if( !avatarp )
 +		{
 +			return FALSE;
 +		}
 +
 +		if(avatarp->isWearingAttachment(mUUID))
 +		{
 +			return FALSE;
 +		}
 +
 +		// All items can be copied, not all can be pasted.
 +		// The only time an item can't be copied is if it's a link
 +		// return (item->getPermissions().allowCopyBy(gAgent.getID()));
 +		if (item->getIsLinkType())
 +		{
 +			return FALSE;
 +		}
 +		return TRUE;
 +	}
 +	return FALSE;
 +}
 +BOOL LLItemBridge::copyToClipboard() const
 +{
 +	if(isItemCopyable())
 +	{
 +		LLInventoryClipboard::instance().add(mUUID);
 +		return TRUE;
 +	}
 +	return FALSE;
 +}
 +
 +LLViewerInventoryItem* LLItemBridge::getItem() const
 +{
 +	LLViewerInventoryItem* item = NULL;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(model)
 +	{
 +		item = (LLViewerInventoryItem*)model->getItem(mUUID);
 +	}
 +	return item;
 +}
 +
 +BOOL LLItemBridge::isItemPermissive() const
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		U32 mask = item->getPermissions().getMaskBase();
 +		if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
 +		{
 +			return TRUE;
 +		}
 +	}
 +	return FALSE;
 +}
 +
 +// +=================================================+
 +// |        LLFolderBridge                           |
 +// +=================================================+
 +
 +LLFolderBridge* LLFolderBridge::sSelf=NULL;
 +
 +// Can be moved to another folder
 +BOOL LLFolderBridge::isItemMovable() const
 +{
 +	LLInventoryObject* obj = getInventoryObject();
 +	if(obj)
 +	{
 +		return (!LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType()));
 +	}
 +	return FALSE;
 +}
 +
 +void LLFolderBridge::selectItem()
 +{
 +}
 +
 +
 +// Iterate through a folder's children to determine if
 +// all the children are removable.
 +class LLIsItemRemovable : public LLFolderViewFunctor
 +{
 +public:
 +	LLIsItemRemovable() : mPassed(TRUE) {}
 +	virtual void doFolder(LLFolderViewFolder* folder)
 +	{
 +		mPassed &= folder->getListener()->isItemRemovable();
 +	}
 +	virtual void doItem(LLFolderViewItem* item)
 +	{
 +		mPassed &= item->getListener()->isItemRemovable();
 +	}
 +	BOOL mPassed;
 +};
 +
 +// Can be destroyed (or moved to trash)
 +BOOL LLFolderBridge::isItemRemovable()
 +{
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model)
 +	{
 +		return FALSE;
 +	}
 +
 +	if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
 +	{
 +		return FALSE;
 +	}
 +
 +	LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
 +	if( !avatar )
 +	{
 +		return FALSE;
 +	}
 +
 +	LLInventoryCategory* category = model->getCategory(mUUID);
 +	if( !category )
 +	{
 +		return FALSE;
 +	}
 +	// Allow protected types to be removed, but issue a warning.
 +	/*
 +	if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
 +	{
 +		return FALSE;
 +	}
 +	*/
 +
 +	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
 +	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
 +	if (folderp)
 +	{
 +		LLIsItemRemovable folder_test;
 +		folderp->applyFunctorToChildren(folder_test);
 +		if (!folder_test.mPassed)
 +		{
 +			return FALSE;
 +		}
 +	}
 +	return TRUE;
 +}
 +
 +BOOL LLFolderBridge::isUpToDate() const
 +{
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return FALSE;
 +	LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
 +	if( !category )
 +	{
 +		return FALSE;
 +	}
 +
 +	return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN;
 +}
 +
 +BOOL LLFolderBridge::isItemCopyable() const
 +{
 +	return TRUE;
 +}
 +
 +BOOL LLFolderBridge::copyToClipboard() const
 +{
 +	if(isItemCopyable())
 +	{
 +		LLInventoryClipboard::instance().add(mUUID);
 +		return TRUE;
 +	}
 +	return FALSE;
 +}
 +
 +BOOL LLFolderBridge::isClipboardPasteable() const
 +{
 +	if ( ! LLInvFVBridge::isClipboardPasteable() )
 +		return FALSE;
 +
 +	// Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599
 +	if ( LLFriendCardsManager::instance().isCategoryInFriendFolder( getCategory() ) )
 +	{
 +		LLInventoryModel* model = getInventoryModel();
 +		if ( !model )
 +		{
 +			return FALSE;
 +		}
 +
 +		LLDynamicArray<LLUUID> objects;
 +		LLInventoryClipboard::instance().retrieve(objects);
 +		const LLViewerInventoryCategory *current_cat = getCategory();
 +
 +		// Search for the direct descendent of current Friends subfolder among all pasted items,
 +		// and return false if is found.
 +		for(S32 i = objects.count() - 1; i >= 0; --i)
 +		{
 +			const LLUUID &obj_id = objects.get(i);
 +			if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) )
 +			{
 +				return FALSE;
 +			}
 +		}
 +
 +	}
 +	return TRUE;
 +}
 +
 +BOOL LLFolderBridge::isClipboardPasteableAsLink() const
 +{
 +	// Check normal paste-as-link permissions
 +	if (!LLInvFVBridge::isClipboardPasteableAsLink())
 +	{
 +		return FALSE;
 +	}
 +
 +	const LLInventoryModel* model = getInventoryModel();
 +	if (!model)
 +	{
 +		return FALSE;
 +	}
 +
 +	const LLViewerInventoryCategory *current_cat = getCategory();
 +	if (current_cat)
 +	{
 +		const BOOL is_in_friend_folder = LLFriendCardsManager::instance().isCategoryInFriendFolder( current_cat );
 +		const LLUUID ¤t_cat_id = current_cat->getUUID();
 +		LLDynamicArray<LLUUID> objects;
 +		LLInventoryClipboard::instance().retrieve(objects);
 +		S32 count = objects.count();
 +		for(S32 i = 0; i < count; i++)
 +		{
 +			const LLUUID &obj_id = objects.get(i);
 +			const LLInventoryCategory *cat = model->getCategory(obj_id);
 +			if (cat)
 +			{
 +				const LLUUID &cat_id = cat->getUUID();
 +				// Don't allow recursive pasting
 +				if ((cat_id == current_cat_id) ||
 +					model->isObjectDescendentOf(current_cat_id, cat_id))
 +				{
 +					return FALSE;
 +				}
 +			}
 +			// Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599
 +			if ( is_in_friend_folder )
 +			{
 +				// If object is direct descendent of current Friends subfolder than return false.
 +				// Note: We can't use 'const LLInventoryCategory *cat', because it may be null
 +				// in case type of obj_id is LLInventoryItem.
 +				if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) )
 +				{
 +					return FALSE;
 +				}
 +			}
 +		}
 +	}
 +	return TRUE;
 +
 +}
 +
 +BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 +											BOOL drop)
 +{
 +	// This should never happen, but if an inventory item is incorrectly parented,
 +	// the UI will get confused and pass in a NULL.
 +	if(!inv_cat) return FALSE;
 +
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return FALSE;
 +
 +	LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
 +	if(!avatar) return FALSE;
 +
 +	// cannot drag categories into library
 +	if(!isAgentInventory())
 +	{
 +		return FALSE;
 +	}
 +
 +	// check to make sure source is agent inventory, and is represented there.
 +	LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
 +	BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL)
 +		&& (LLToolDragAndDrop::SOURCE_AGENT == source);
 +
 +	BOOL accept = FALSE;
 +	S32 i;
 +	LLInventoryModel::cat_array_t	descendent_categories;
 +	LLInventoryModel::item_array_t	descendent_items;
 +	if(is_agent_inventory)
 +	{
 +		const LLUUID& cat_id = inv_cat->getUUID();
 +
 +		// Is the destination the trash?
 +		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +		BOOL move_is_into_trash = (mUUID == trash_id)
 +				|| model->isObjectDescendentOf(mUUID, trash_id);
 +		BOOL is_movable = (!LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()));
 +		const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 +		BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
 +		BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
 +		if (move_is_into_current_outfit || move_is_into_outfit)
 +		{
 +			// BAP - restrictions?
 +			is_movable = true;
 +		}
 +
 +		if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE))
 +		{
 +			is_movable = FALSE; // It's generally movable but not into Favorites folder. EXT-1604
 +		}
 +
 +		if( is_movable )
 +		{
 +			gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE );
 +
 +			for( i = 0; i < descendent_categories.count(); i++ )
 +			{
 +				LLInventoryCategory* category = descendent_categories[i];
 +				if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
 +				{
 +					// ...can't move "special folders" like Textures
 +					is_movable = FALSE;
 +					break;
 +				}
 +			}
 +
 +			if( is_movable )
 +			{
 +				if( move_is_into_trash )
 +				{
 +					for( i = 0; i < descendent_items.count(); i++ )
 +					{
 +						LLInventoryItem* item = descendent_items[i];
 +						if( (item->getType() == LLAssetType::AT_CLOTHING) ||
 +							(item->getType() == LLAssetType::AT_BODYPART) )
 +						{
 +							if( gAgentWearables.isWearingItem( item->getUUID() ) )
 +							{
 +								is_movable = FALSE;  // It's generally movable, but not into the trash!
 +								break;
 +							}
 +						}
 +						else
 +						if( item->getType() == LLAssetType::AT_OBJECT )
 +						{
 +							if( avatar->isWearingAttachment( item->getUUID() ) )
 +							{
 +								is_movable = FALSE;  // It's generally movable, but not into the trash!
 +								break;
 +							}
 +						}
 +					}
 +				}
 +			}
 +		}
 +
 +
 +		accept =	is_movable
 +					&& (mUUID != cat_id)								// Can't move a folder into itself
 +					&& (mUUID != inv_cat->getParentUUID())				// Avoid moves that would change nothing
 +					&& !(model->isObjectDescendentOf(mUUID, cat_id));	// Avoid circularity
 +		if(accept && drop)
 +		{
 +			// Look for any gestures and deactivate them
 +			if (move_is_into_trash)
 +			{
 +				for (i = 0; i < descendent_items.count(); i++)
 +				{
 +					LLInventoryItem* item = descendent_items[i];
 +					if (item->getType() == LLAssetType::AT_GESTURE
 +						&& LLGestureManager::instance().isGestureActive(item->getUUID()))
 +					{
 +						LLGestureManager::instance().deactivateGesture(item->getUUID());
 +					}
 +				}
 +			}
 +			// if target is an outfit or current outfit folder we use link
 +			if (move_is_into_current_outfit || move_is_into_outfit)
 +			{
 +				if (inv_cat->getPreferredType() == LLFolderType::FT_NONE)
 +				{
 +					if (move_is_into_current_outfit)
 +					{
 +						// traverse category and add all contents to currently worn.
 +						BOOL append = true;
 +						LLAppearanceManager::instance().wearInventoryCategory(inv_cat, false, append);
 +					}
 +					else
 +					{
 +						// Recursively create links in target outfit.
 +						LLInventoryModel::cat_array_t cats;
 +						LLInventoryModel::item_array_t items;
 +						gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
 +						LLAppearanceManager::instance().linkAll(mUUID,items,NULL);
 +					}
 +				}
 +				else
 +				{
 +#if SUPPORT_ENSEMBLES
 +				// BAP - should skip if dup.
 +				if (move_is_into_current_outfit)
 +				{
 +					LLAppearanceManager::instance().addEnsembleLink(inv_cat);
 +				}
 +				else
 +				{
 +					LLPointer<LLInventoryCallback> cb = NULL;
 +					link_inventory_item(
 +						gAgent.getID(),
 +						inv_cat->getUUID(),
 +						mUUID,
 +						inv_cat->getName(),
 +						LLAssetType::AT_LINK_FOLDER,
 +						cb);
 +				}
 +#endif
 +				}
 +			}
 +			else
 +			{
 +
 +				// Reparent the folder and restamp children if it's moving
 +				// into trash.
 +				LLInvFVBridge::changeCategoryParent(
 +					model,
 +					(LLViewerInventoryCategory*)inv_cat,
 +					mUUID,
 +					move_is_into_trash);
 +			}
 +		}
 +	}
 +	else if(LLToolDragAndDrop::SOURCE_WORLD == source)
 +	{
 +		// content category has same ID as object itself
 +		LLUUID object_id = inv_cat->getUUID();
 +		LLUUID category_id = mUUID;
 +		accept = move_inv_category_world_to_agent(object_id, category_id, drop);
 +	}
 +	return accept;
 +}
 +
 +void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv)
 +{
 +	const char* dialog = NULL;
 +	if (object->flagScripted())
 +	{
 +		dialog = "MoveInventoryFromScriptedObject";
 +	}
 +	else
 +	{
 +		dialog = "MoveInventoryFromObject";
 +	}
 +	LLNotifications::instance().add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv));
 +}
 +
 +// Move/copy all inventory items from the Contents folder of an in-world
 +// object to the agent's inventory, inside a given category.
 +BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
 +									  const LLUUID& category_id,
 +									  BOOL drop,
 +									  void (*callback)(S32, void*),
 +									  void* user_data)
 +{
 +	// Make sure the object exists. If we allowed dragging from
 +	// anonymous objects, it would be possible to bypass
 +	// permissions.
 +	// content category has same ID as object itself
 +	LLViewerObject* object = gObjectList.findObject(object_id);
 +	if(!object)
 +	{
 +		llinfos << "Object not found for drop." << llendl;
 +		return FALSE;
 +	}
 +
 +	// this folder is coming from an object, as there is only one folder in an object, the root,
 +	// we need to collect the entire contents and handle them as a group
 +	InventoryObjectList inventory_objects;
 +	object->getInventoryContents(inventory_objects);
 +
 +	if (inventory_objects.empty())
 +	{
 +		llinfos << "Object contents not found for drop." << llendl;
 +		return FALSE;
 +	}
 +
 +	BOOL accept = TRUE;
 +	BOOL is_move = FALSE;
 +
 +	// coming from a task. Need to figure out if the person can
 +	// move/copy this item.
 +	InventoryObjectList::iterator it = inventory_objects.begin();
 +	InventoryObjectList::iterator end = inventory_objects.end();
 +	for ( ; it != end; ++it)
 +	{
 +		// coming from a task. Need to figure out if the person can
 +		// move/copy this item.
 +		LLPermissions perm(((LLInventoryItem*)((LLInventoryObject*)(*it)))->getPermissions());
 +		if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
 +			&& perm.allowTransferTo(gAgent.getID())))
 +//			|| gAgent.isGodlike())
 +		{
 +			accept = TRUE;
 +		}
 +		else if(object->permYouOwner())
 +		{
 +			// If the object cannot be copied, but the object the
 +			// inventory is owned by the agent, then the item can be
 +			// moved from the task to agent inventory.
 +			is_move = TRUE;
 +			accept = TRUE;
 +		}
 +		else
 +		{
 +			accept = FALSE;
 +			break;
 +		}
 +	}
 +
 +	if(drop && accept)
 +	{
 +		it = inventory_objects.begin();
 +		InventoryObjectList::iterator first_it = inventory_objects.begin();
 +		LLMoveInv* move_inv = new LLMoveInv;
 +		move_inv->mObjectID = object_id;
 +		move_inv->mCategoryID = category_id;
 +		move_inv->mCallback = callback;
 +		move_inv->mUserData = user_data;
 +
 +		for ( ; it != end; ++it)
 +		{
 +			two_uuids_t two(category_id, (*it)->getUUID());
 +			move_inv->mMoveList.push_back(two);
 +		}
 +
 +		if(is_move)
 +		{
 +			// Callback called from within here.
 +			warn_move_inventory(object, move_inv);
 +		}
 +		else
 +		{
 +			LLNotification::Params params("MoveInventoryFromObject");
 +			params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
 +			LLNotifications::instance().forceResponse(params, 0);
 +		}
 +	}
 +	return accept;
 +}
 +
 +bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat,
 +									 LLInventoryItem* item)
 +{
 +	// Valid COF items are:
 +	// - links to wearables (body parts or clothing)
 +	// - links to attachments
 +	// - links to gestures
 +	// - links to ensemble folders
 +	LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); // BAP - safe?
 +	if (linked_item)
 +	{
 +		LLAssetType::EType type = linked_item->getType();
 +		return (type == LLAssetType::AT_CLOTHING ||
 +				type == LLAssetType::AT_BODYPART ||
 +				type == LLAssetType::AT_GESTURE ||
 +				type == LLAssetType::AT_OBJECT);
 +	}
 +	else
 +	{
 +		LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); // BAP - safe?
 +		// BAP remove AT_NONE support after ensembles are fully working?
 +		return (linked_category &&
 +				((linked_category->getPreferredType() == LLFolderType::FT_NONE) ||
 +				 (LLFolderType::lookupIsEnsembleType(linked_category->getPreferredType()))));
 +	}
 +}
 +
 +
 +bool LLFindWearables::operator()(LLInventoryCategory* cat,
 +								 LLInventoryItem* item)
 +{
 +	if(item)
 +	{
 +		if((item->getType() == LLAssetType::AT_CLOTHING)
 +		   || (item->getType() == LLAssetType::AT_BODYPART))
 +		{
 +			return TRUE;
 +		}
 +	}
 +	return FALSE;
 +}
 +
 +
 +
 +//Used by LLFolderBridge as callback for directory recursion.
 +class LLRightClickInventoryFetchObserver : public LLInventoryFetchObserver
 +{
 +public:
 +	LLRightClickInventoryFetchObserver() :
 +		mCopyItems(false)
 +	{ };
 +	LLRightClickInventoryFetchObserver(const LLUUID& cat_id, bool copy_items) :
 +		mCatID(cat_id),
 +		mCopyItems(copy_items)
 +		{ };
 +	virtual void done()
 +	{
 +		// we've downloaded all the items, so repaint the dialog
 +		LLFolderBridge::staticFolderOptionsMenu();
 +
 +		gInventory.removeObserver(this);
 +		delete this;
 +	}
 +
 +
 +protected:
 +	LLUUID mCatID;
 +	bool mCopyItems;
 +
 +};
 +
 +//Used by LLFolderBridge as callback for directory recursion.
 +class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
 +{
 +public:
 +	LLRightClickInventoryFetchDescendentsObserver(bool copy_items) : mCopyItems(copy_items) {}
 +	~LLRightClickInventoryFetchDescendentsObserver() {}
 +	virtual void done();
 +protected:
 +	bool mCopyItems;
 +};
 +
 +void LLRightClickInventoryFetchDescendentsObserver::done()
 +{
 +	// Avoid passing a NULL-ref as mCompleteFolders.front() down to
 +	// gInventory.collectDescendents()
 +	if( mCompleteFolders.empty() )
 +	{
 +		llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl;
 +		dec_busy_count();
 +		gInventory.removeObserver(this);
 +		delete this;
 +		return;
 +	}
 +
 +	// What we do here is get the complete information on the items in
 +	// the library, and set up an observer that will wait for that to
 +	// happen.
 +	LLInventoryModel::cat_array_t cat_array;
 +	LLInventoryModel::item_array_t item_array;
 +	gInventory.collectDescendents(mCompleteFolders.front(),
 +								  cat_array,
 +								  item_array,
 +								  LLInventoryModel::EXCLUDE_TRASH);
 +	S32 count = item_array.count();
 +#if 0 // HACK/TODO: Why?
 +	// This early causes a giant menu to get produced, and doesn't seem to be needed.
 +	if(!count)
 +	{
 +		llwarns << "Nothing fetched in category " << mCompleteFolders.front()
 +				<< llendl;
 +		dec_busy_count();
 +		gInventory.removeObserver(this);
 +		delete this;
 +		return;
 +	}
 +#endif
 +
 +	LLRightClickInventoryFetchObserver* outfit;
 +	outfit = new LLRightClickInventoryFetchObserver(mCompleteFolders.front(), mCopyItems);
 +	LLInventoryFetchObserver::item_ref_t ids;
 +	for(S32 i = 0; i < count; ++i)
 +	{
 +		ids.push_back(item_array.get(i)->getUUID());
 +	}
 +
 +	// clean up, and remove this as an observer since the call to the
 +	// outfit could notify observers and throw us into an infinite
 +	// loop.
 +	dec_busy_count();
 +	gInventory.removeObserver(this);
 +	delete this;
 +
 +	// increment busy count and either tell the inventory to check &
 +	// call done, or add this object to the inventory for observation.
 +	inc_busy_count();
 +
 +	// do the fetch
 +	outfit->fetchItems(ids);
 +	outfit->done();				//Not interested in waiting and this will be right 99% of the time.
 +//Uncomment the following code for laggy Inventory UI.
 +/*	if(outfit->isEverythingComplete())
 +	{
 +		// everything is already here - call done.
 +		outfit->done();
 +	}
 +	else
 +	{
 +		// it's all on it's way - add an observer, and the inventory
 +		// will call done for us when everything is here.
 +		gInventory.addObserver(outfit);
 +	}*/
 +}
 +
 +
 +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 +// Class LLInventoryWearObserver
 +//
 +// Observer for "copy and wear" operation to support knowing
 +// when the all of the contents have been added to inventory.
 +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 +class LLInventoryCopyAndWearObserver : public LLInventoryObserver
 +{
 +public:
 +	LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) :mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {}
 +	virtual ~LLInventoryCopyAndWearObserver() {}
 +	virtual void changed(U32 mask);
 +
 +protected:
 +	LLUUID mCatID;
 +	int    mContentsCount;
 +	BOOL   mFolderAdded;
 +};
 +
 +
 +
 +void LLInventoryCopyAndWearObserver::changed(U32 mask)
 +{
 +	if((mask & (LLInventoryObserver::ADD)) != 0)
 +	{
 +		if (!mFolderAdded)
 +		{
 +			const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
 +
 +			std::set<LLUUID>::const_iterator id_it = changed_items.begin();
 +			std::set<LLUUID>::const_iterator id_end = changed_items.end();
 +			for (;id_it != id_end; ++id_it)
 +			{
 +				if ((*id_it) == mCatID)
 +				{
 +					mFolderAdded = TRUE;
 +					break;
 +				}
 +			}
 +		}
 +
 +		if (mFolderAdded)
 +		{
 +			LLViewerInventoryCategory* category = gInventory.getCategory(mCatID);
 +
 +			if (NULL == category)
 +			{
 +				llwarns << "gInventory.getCategory(" << mCatID
 +					<< ") was NULL" << llendl;
 +			}
 +			else
 +			{
 +				if (category->getDescendentCount() ==
 +				    mContentsCount)
 +				{
 +					gInventory.removeObserver(this);
 +					LLAppearanceManager::instance().wearInventoryCategory(category, FALSE, TRUE);
 +					delete this;
 +				}
 +			}
 +		}
 +
 +	}
 +}
 +
 +
 +
 +void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("open" == action)
 +	{
 +		openItem();
 +		return;
 +	}
 +	else if ("paste" == action)
 +	{
 +		pasteFromClipboard();
 +		return;
 +	}
 +	else if ("paste_link" == action)
 +	{
 +		pasteLinkFromClipboard();
 +		return;
 +	}
 +	else if ("properties" == action)
 +	{
 +		showProperties();
 +		return;
 +	}
 +	else if ("replaceoutfit" == action)
 +	{
 +		modifyOutfit(FALSE);
 +		return;
 +	}
 +#if SUPPORT_ENSEMBLES
 +	else if ("wearasensemble" == action)
 +	{
 +		LLInventoryModel* model = getInventoryModel();
 +		if(!model) return;
 +		LLViewerInventoryCategory* cat = getCategory();
 +		if(!cat) return;
 +		LLAppearanceManager::instance().addEnsembleLink(cat,true);
 +		return;
 +	}
 +#endif
 +	else if ("addtooutfit" == action)
 +	{
 +		modifyOutfit(TRUE);
 +		return;
 +	}
 +	else if ("copy" == action)
 +	{
 +		copyToClipboard();
 +		return;
 +	}
 +	else if ("removefromoutfit" == action)
 +	{
 +		LLInventoryModel* model = getInventoryModel();
 +		if(!model) return;
 +		LLViewerInventoryCategory* cat = getCategory();
 +		if(!cat) return;
 +
 +		remove_inventory_category_from_avatar ( cat );
 +		return;
 +	}
 +	else if ("purge" == action)
 +	{
 +		purgeItem(model, mUUID);
 +		return;
 +	}
 +	else if ("restore" == action)
 +	{
 +		restoreItem();
 +		return;
 +	}
 +}
 +
 +void LLFolderBridge::openItem()
 +{
 +	lldebugs << "LLFolderBridge::openItem()" << llendl;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return;
 +	if(mUUID.isNull()) return;
 +	bool fetching_inventory = model->fetchDescendentsOf(mUUID);
 +	// Only change folder type if we have the folder contents.
 +	if (!fetching_inventory)
 +	{
 +		// Disabling this for now, it's causing crash when new items are added to folders
 +		// since folder type may change before new item item has finished processing.
 +		// determineFolderType();
 +	}
 +}
 +
 +void LLFolderBridge::closeItem()
 +{
 +	determineFolderType();
 +}
 +
 +void LLFolderBridge::determineFolderType()
 +{
 +	if (isUpToDate())
 +	{
 +		LLInventoryModel* model = getInventoryModel();
 +		LLViewerInventoryCategory* category = model->getCategory(mUUID);
 +		category->determineFolderType();
 +	}
 +}
 +
 +BOOL LLFolderBridge::isItemRenameable() const
 +{
 +	LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory();
 +	if(cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType())
 +	   && (cat->getOwnerID() == gAgent.getID()))
 +	{
 +		return TRUE;
 +	}
 +	return FALSE;
 +}
 +
 +void LLFolderBridge::restoreItem()
 +{
 +	LLViewerInventoryCategory* cat;
 +	cat = (LLViewerInventoryCategory*)getCategory();
 +	if(cat)
 +	{
 +		LLInventoryModel* model = getInventoryModel();
 +		const LLUUID new_parent = model->findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(cat->getType()));
 +		// do not restamp children on restore
 +		LLInvFVBridge::changeCategoryParent(model, cat, new_parent, FALSE);
 +	}
 +}
 +
 +LLFolderType::EType LLFolderBridge::getPreferredType() const
 +{
 +	LLFolderType::EType preferred_type = LLFolderType::FT_NONE;
 +	LLViewerInventoryCategory* cat = getCategory();
 +	if(cat)
 +	{
 +		preferred_type = cat->getPreferredType();
 +	}
 +
 +	return preferred_type;
 +}
 +
 +// Icons for folders are based on the preferred type
 +LLUIImagePtr LLFolderBridge::getIcon() const
 +{
 +	LLFolderType::EType preferred_type = LLFolderType::FT_NONE;
 +	LLViewerInventoryCategory* cat = getCategory();
 +	if(cat)
 +	{
 +		preferred_type = cat->getPreferredType();
 +	}
 +	return getIcon(preferred_type);
 +}
 +
 +LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
 +{
 +	// we only have one folder image now
 +	return LLUI::getUIImage("Inv_FolderClosed");
 +}
 +
 +BOOL LLFolderBridge::renameItem(const std::string& new_name)
 +{
 +	if(!isItemRenameable())
 +		return FALSE;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model)
 +		return FALSE;
 +	LLViewerInventoryCategory* cat = getCategory();
 +	if(cat && (cat->getName() != new_name))
 +	{
 +		LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
 +		new_cat->rename(new_name);
 +		new_cat->updateServer(FALSE);
 +		model->updateCategory(new_cat);
 +
 +		model->notifyObservers();
 +	}
 +	// return FALSE because we either notified observers (& therefore
 +	// rebuilt) or we didn't update.
 +	return FALSE;
 +}
 +
 +BOOL LLFolderBridge::removeItem()
 +{
 +	if(!isItemRemovable())
 +	{
 +		return FALSE;
 +	}
 +	const LLViewerInventoryCategory *cat = getCategory();
 +	
 +	LLSD payload;
 +	LLSD args;
 +	args["FOLDERNAME"] = cat->getName();
 +
 +	LLNotification::Params params("ConfirmDeleteProtectedCategory");
 +	params.payload(payload).substitutions(args).functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
 +	//params.functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
 +	/*
 +	LLNotification::Params params("ChangeLindenEstate");
 +	params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
 +	*/
 +	if (LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
 +	{
 +		LLNotifications::instance().add(params);
 +	}
 +	else
 +	{
 +		LLNotifications::instance().forceResponse(params, 0);
 +	}
 +	return TRUE;
 +}
 +
 +bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& response)
 +{
 +	S32 option = LLNotification::getSelectedOption(notification, response);
 +
 +	// if they choose delete, do it.  Otherwise, don't do anything
 +	if(option == 0) 
 +	{
 +		// move it to the trash
 +		LLPreview::hide(mUUID);
 +		LLInventoryModel* model = getInventoryModel();
 +		if(!model) return FALSE;
 +		
 +		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +		
 +		// Look for any gestures and deactivate them
 +		LLInventoryModel::cat_array_t	descendent_categories;
 +		LLInventoryModel::item_array_t	descendent_items;
 +		gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
 +		
 +		S32 i;
 +		for (i = 0; i < descendent_items.count(); i++)
 +		{
 +			LLInventoryItem* item = descendent_items[i];
 +			if (item->getType() == LLAssetType::AT_GESTURE
 +				&& LLGestureManager::instance().isGestureActive(item->getUUID()))
 +			{
 +				LLGestureManager::instance().deactivateGesture(item->getUUID());
 +			}
 +		}
 +		
 +		// go ahead and do the normal remove if no 'last calling
 +		// cards' are being removed.
 +		LLViewerInventoryCategory* cat = getCategory();
 +		if(cat)
 +		{
 +			LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
 +		}
 +		return TRUE;
 +	}
 +	return FALSE;
 +}
 +
 +void LLFolderBridge::pasteFromClipboard()
 +{
 +	LLInventoryModel* model = getInventoryModel();
 +	if(model && isClipboardPasteable())
 +	{
 +		LLInventoryItem* item = NULL;
 +		LLDynamicArray<LLUUID> objects;
 +		LLInventoryClipboard::instance().retrieve(objects);
 +		S32 count = objects.count();
 +		const LLUUID parent_id(mUUID);
 +		for(S32 i = 0; i < count; i++)
 +		{
 +			item = model->getItem(objects.get(i));
 +			if (item)
 +			{
 +				if(LLInventoryClipboard::instance().isCutMode())
 +				{
 +					// move_inventory_item() is not enough,
 +					//we have to update inventory locally too
 +					changeItemParent(model, dynamic_cast<LLViewerInventoryItem*>(item), parent_id, FALSE);
 +				}
 +				else
 +				{
 +					copy_inventory_item(
 +						gAgent.getID(),
 +						item->getPermissions().getOwner(),
 +						item->getUUID(),
 +						parent_id,
 +						std::string(),
 +						LLPointer<LLInventoryCallback>(NULL));
 +				}
 +			}
 +		}
 +	}
 +}
 +
 +void LLFolderBridge::pasteLinkFromClipboard()
 +{
 +	const LLInventoryModel* model = getInventoryModel();
 +	if(model)
 +	{
 +		LLDynamicArray<LLUUID> objects;
 +		LLInventoryClipboard::instance().retrieve(objects);
 +		S32 count = objects.count();
 +		LLUUID parent_id(mUUID);
 +		for(S32 i = 0; i < count; i++)
 +		{
 +			const LLUUID &object_id = objects.get(i);
 +#if SUPPORT_ENSEMBLES
 +			if (LLInventoryCategory *cat = model->getCategory(object_id))
 +			{
 +				link_inventory_item(
 +					gAgent.getID(),
 +					cat->getUUID(),
 +					parent_id,
 +					cat->getName(),
 +					LLAssetType::AT_LINK_FOLDER,
 +					LLPointer<LLInventoryCallback>(NULL));
 +			}
 +			else
 +#endif
 +			if (LLInventoryItem *item = model->getItem(object_id))
 +			{
 +				link_inventory_item(
 +					gAgent.getID(),
 +					item->getLinkedUUID(),
 +					parent_id,
 +					item->getName(),
 +					LLAssetType::AT_LINK,
 +					LLPointer<LLInventoryCallback>(NULL));
 +			}
 +		}
 +	}
 +}
 +
 +void LLFolderBridge::staticFolderOptionsMenu()
 +{
 +	if (!sSelf) return;
 +	sSelf->folderOptionsMenu();
 +}
 +
 +bool isInOutfitsSidePanel(LLPanel *panel)
 +{
 +	LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(panel);
 +	LLPanelOutfitsInventory *outfit_panel =
 +		dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
 +	if (!outfit_panel)
 +		return false;
 +	return outfit_panel->isAccordionPanel(my_panel);
 +
 +	//LLInventoryPanel *outfit_inv_panel = outfit_panel ? outfit_panel->getActivePanel(): NULL;
 +	//return (my_panel && (my_panel == outfit_inv_panel));
 +}
 +
 +void LLFolderBridge::folderOptionsMenu()
 +{
 +	std::vector<std::string> disabled_items;
 +
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return;
 +
 +	const LLInventoryCategory* category = model->getCategory(mUUID);
 +	LLFolderType::EType type = category->getPreferredType();
 +	const bool is_default_folder = category && LLFolderType::lookupIsProtectedType(type);
 +	// BAP change once we're no longer treating regular categories as ensembles.
 +	const bool is_ensemble = category && (type == LLFolderType::FT_NONE ||
 +										  LLFolderType::lookupIsEnsembleType(type));
 +	const bool is_sidepanel = isInOutfitsSidePanel(mInventoryPanel.get());
 +
 +	// calling card related functionality for folders.
 +
 +	if (is_sidepanel)
 +	{
 +		mItems.clear();
 +	}
 +
 +	// Only enable calling-card related options for non-default folders.
 +	if (!is_sidepanel && !is_default_folder)
 +	{
 +		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"));
 +		}
 +	}
 +
 +	// wearables related functionality for folders.
 +	//is_wearable
 +	LLFindWearables is_wearable;
 +	LLIsType is_object( LLAssetType::AT_OBJECT );
 +	LLIsType is_gesture( LLAssetType::AT_GESTURE );
 +
 +	if (mWearables ||
 +		checkFolderForContentsOfType(model, is_wearable)  ||
 +		checkFolderForContentsOfType(model, is_object) ||
 +		checkFolderForContentsOfType(model, is_gesture) )
 +	{
 +		mItems.push_back(std::string("Folder Wearables Separator"));
 +
 +		// Only enable add/replace outfit for non-default folders.
 +		if (!is_default_folder)
 +		{
 +			mItems.push_back(std::string("Add To Outfit"));
 +			mItems.push_back(std::string("Replace Outfit"));
 +		}
 +		if (is_ensemble)
 +		{
 +			mItems.push_back(std::string("Wear As Ensemble"));
 +		}
 +		mItems.push_back(std::string("Remove From Outfit"));
 +	}
 +	hide_context_entries(*mMenu, mItems, disabled_items);
 +
 +	// Reposition the menu, in case we're adding items to an existing menu.
 +	mMenu->needsArrange();
 +	mMenu->arrangeAndClear();
 +}
 +
 +BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
 +{
 +	LLInventoryModel::cat_array_t cat_array;
 +	LLInventoryModel::item_array_t item_array;
 +	model->collectDescendentsIf(mUUID,
 +								cat_array,
 +								item_array,
 +								LLInventoryModel::EXCLUDE_TRASH,
 +								is_type);
 +	return ((item_array.count() > 0) ? TRUE : FALSE );
 +}
 +
 +// Flags unused
 +void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	mItems.clear();
 +	mDisabledItems.clear();
 +
 +	lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
 +//	std::vector<std::string> disabled_items;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return;
 +	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +	const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
 +
 +	mItems.clear(); //adding code to clear out member Items (which means Items should not have other data here at this point)
 +	mDisabledItems.clear(); //adding code to clear out disabled members from previous
 +	if (lost_and_found_id == mUUID)
 +	  {
 +		// This is the lost+found folder.
 +		  mItems.push_back(std::string("Empty Lost And Found"));
 +	  }
 +
 +	if(trash_id == mUUID)
 +	{
 +		// This is the trash.
 +		mItems.push_back(std::string("Empty Trash"));
 +	}
 +	else if(model->isObjectDescendentOf(mUUID, trash_id))
 +	{
 +		// This is a folder in the trash.
 +		mItems.clear(); // clear any items that used to exist
 +		mItems.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			mDisabledItems.push_back(std::string("Purge Item"));
 +		}
 +
 +		mItems.push_back(std::string("Restore Item"));
 +	}
 +	else if(isAgentInventory()) // do not allow creating in library
 +	{
 +		LLViewerInventoryCategory *cat =  getCategory();
 +		// BAP removed protected check to re-enable standard ops in untyped folders.
 +		// Not sure what the right thing is to do here.
 +		if (!isCOFFolder() && cat /*&&
 +			LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())*/)
 +		{
 +			// 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"));
 +			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"));
 +			mItems.push_back(std::string("Change Type"));
 +
 +			LLViewerInventoryCategory *cat = getCategory();
 +			if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
 +			{
 +				mDisabledItems.push_back(std::string("Change Type"));
 +			}
 +
 +			getClipboardEntries(false, mItems, mDisabledItems, 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"));
 +				mItems.push_back(std::string("Delete"));
 +			}
 +		}
 +
 +		//Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06
 +		mCallingCards = mWearables = FALSE;
 +
 +		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
 +		if (checkFolderForContentsOfType(model, is_callingcard))
 +		{
 +			mCallingCards=TRUE;
 +		}
 +
 +		LLFindWearables is_wearable;
 +		LLIsType is_object( LLAssetType::AT_OBJECT );
 +		LLIsType is_gesture( LLAssetType::AT_GESTURE );
 +
 +		if (checkFolderForContentsOfType(model, is_wearable)  ||
 +			checkFolderForContentsOfType(model, is_object) ||
 +			checkFolderForContentsOfType(model, is_gesture) )
 +		{
 +			mWearables=TRUE;
 +		}
 +
 +		mMenu = &menu;
 +		sSelf = this;
 +		LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(FALSE);
 +
 +		LLInventoryFetchDescendentsObserver::folder_ref_t folders;
 +		LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
 +		if (category)
 +		{
 +			folders.push_back(category->getUUID());
 +		}
 +		fetch->fetchDescendents(folders);
 +		inc_busy_count();
 +		if(fetch->isEverythingComplete())
 +		{
 +			// everything is already here - call done.
 +			fetch->done();
 +		}
 +		else
 +		{
 +			// it's all on it's way - add an observer, and the inventory
 +			// will call done for us when everything is here.
 +			gInventory.addObserver(fetch);
 +		}
 +	}
 +	else
 +	{
 +		mItems.push_back(std::string("--no options--"));
 +		mDisabledItems.push_back(std::string("--no options--"));
 +	}
 +	hide_context_entries(menu, mItems, mDisabledItems);
 +}
 +
 +BOOL LLFolderBridge::hasChildren() const
 +{
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return FALSE;
 +	LLInventoryModel::EHasChildren has_children;
 +	has_children = gInventory.categoryHasChildren(mUUID);
 +	return has_children != LLInventoryModel::CHILDREN_NO;
 +}
 +
 +BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 +								EDragAndDropType cargo_type,
 +								void* cargo_data)
 +{
 +	//llinfos << "LLFolderBridge::dragOrDrop()" << llendl;
 +	BOOL accept = FALSE;
 +	switch(cargo_type)
 +	{
 +		case DAD_TEXTURE:
 +		case DAD_SOUND:
 +		case DAD_CALLINGCARD:
 +		case DAD_LANDMARK:
 +		case DAD_SCRIPT:
 +		case DAD_OBJECT:
 +		case DAD_NOTECARD:
 +		case DAD_CLOTHING:
 +		case DAD_BODYPART:
 +		case DAD_ANIMATION:
 +		case DAD_GESTURE:
 +		case DAD_LINK:
 +			accept = dragItemIntoFolder((LLInventoryItem*)cargo_data,
 +										drop);
 +			break;
 +		case DAD_CATEGORY:
 +			if (LLFriendCardsManager::instance().isAnyFriendCategory(mUUID))
 +			{
 +				accept = FALSE;
 +			}
 +			else
 +			{
 +				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop);
 +			}
 +			break;
 +		default:
 +			break;
 +	}
 +	return accept;
 +}
 +
 +LLViewerInventoryCategory* LLFolderBridge::getCategory() const
 +{
 +	LLViewerInventoryCategory* cat = NULL;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(model)
 +	{
 +		cat = (LLViewerInventoryCategory*)model->getCategory(mUUID);
 +	}
 +	return cat;
 +}
 +
 +
 +// static
 +void LLFolderBridge::pasteClipboard(void* user_data)
 +{
 +	LLFolderBridge* self = (LLFolderBridge*)user_data;
 +	if(self) self->pasteFromClipboard();
 +}
 +
 +void LLFolderBridge::createNewCategory(void* user_data)
 +{
 +	LLFolderBridge* bridge = (LLFolderBridge*)user_data;
 +	if(!bridge) return;
 +	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(bridge->mInventoryPanel.get());
 +	if (!panel) return;
 +	LLInventoryModel* model = panel->getModel();
 +	if(!model) return;
 +	LLUUID id;
 +	id = model->createNewCategory(bridge->getUUID(),
 +								  LLFolderType::FT_NONE,
 +								  LLStringUtil::null);
 +	model->notifyObservers();
 +
 +	// At this point, the bridge has probably been deleted, but the
 +	// view is still there.
 +	panel->setSelection(id, TAKE_FOCUS_YES);
 +}
 +
 +void LLFolderBridge::createNewShirt(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHIRT);
 +}
 +
 +void LLFolderBridge::createNewPants(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_PANTS);
 +}
 +
 +void LLFolderBridge::createNewShoes(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHOES);
 +}
 +
 +void LLFolderBridge::createNewSocks(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SOCKS);
 +}
 +
 +void LLFolderBridge::createNewJacket(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_JACKET);
 +}
 +
 +void LLFolderBridge::createNewSkirt(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SKIRT);
 +}
 +
 +void LLFolderBridge::createNewGloves(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_GLOVES);
 +}
 +
 +void LLFolderBridge::createNewUndershirt(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERSHIRT);
 +}
 +
 +void LLFolderBridge::createNewUnderpants(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERPANTS);
 +}
 +
 +void LLFolderBridge::createNewShape(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHAPE);
 +}
 +
 +void LLFolderBridge::createNewSkin(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SKIN);
 +}
 +
 +void LLFolderBridge::createNewHair(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_HAIR);
 +}
 +
 +void LLFolderBridge::createNewEyes(void* user_data)
 +{
 +	LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_EYES);
 +}
 +
 +// static
 +void LLFolderBridge::createWearable(LLFolderBridge* bridge, EWearableType type)
 +{
 +	if(!bridge) return;
 +	LLUUID parent_id = bridge->getUUID();
 +	createWearable(parent_id, type);
 +}
 +
 +// Separate function so can be called by global menu as well as right-click
 +// menu.
 +// static
 +void LLFolderBridge::createWearable(const LLUUID &parent_id, EWearableType type)
 +{
 +	LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
 +	LLAssetType::EType asset_type = wearable->getAssetType();
 +	LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
 +	create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
 +		parent_id, wearable->getTransactionID(), wearable->getName(),
 +		wearable->getDescription(), asset_type, inv_type, wearable->getType(),
 +		wearable->getPermissions().getMaskNextOwner(),
 +		LLPointer<LLInventoryCallback>(NULL));
 +}
 +
 +void LLFolderBridge::modifyOutfit(BOOL append)
 +{
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model) return;
 +	LLViewerInventoryCategory* cat = getCategory();
 +	if(!cat) return;
 +
 +	// BAP - was:
 +	// wear_inventory_category_on_avatar( cat, append );
 +	LLAppearanceManager::instance().wearInventoryCategory( cat, FALSE, append );
 +}
 +
 +// helper stuff
 +bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv* move_inv)
 +{
 +	LLFloaterOpenObject::LLCatAndWear* cat_and_wear = (LLFloaterOpenObject::LLCatAndWear* )move_inv->mUserData;
 +	LLViewerObject* object = gObjectList.findObject(move_inv->mObjectID);
 +	S32 option = LLNotification::getSelectedOption(notification, response);
 +
 +	if(option == 0 && object)
 +	{
 +		if (cat_and_wear && cat_and_wear->mWear)
 +		{
 +			InventoryObjectList inventory_objects;
 +			object->getInventoryContents(inventory_objects);
 +			int contents_count = inventory_objects.size()-1; //subtract one for containing folder
 +
 +			LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count);
 +			gInventory.addObserver(inventoryObserver);
 +		}
 +
 +		two_uuids_list_t::iterator move_it;
 +		for (move_it = move_inv->mMoveList.begin();
 +			move_it != move_inv->mMoveList.end();
 +			++move_it)
 +		{
 +			object->moveInventory(move_it->first, move_it->second);
 +		}
 +
 +		// update the UI.
 +		dialog_refresh_all();
 +	}
 +
 +	if (move_inv->mCallback)
 +	{
 +		move_inv->mCallback(option, move_inv->mUserData);
 +	}
 +
 +	delete move_inv;
 +	return false;
 +}
 +
 +/*
 +Next functions intended to reorder items in the inventory folder and save order on server
 +Is now used for Favorites folder.
 +
 +*TODO: refactoring is needed with Favorites Bar functionality. Probably should be moved in LLInventoryModel
 +*/
 +void saveItemsOrder(LLInventoryModel::item_array_t& items)
 +{
 +	int sortField = 0;
 +
 +	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
 +	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
 +	{
 +		LLViewerInventoryItem* item = *i;
 +
 +		item->setSortField(++sortField);
 +		item->setComplete(TRUE);
 +		item->updateServer(FALSE);
 +
 +		gInventory.updateItem(item);
 +	}
 +
 +	gInventory.notifyObservers();
 +}
 +
 +LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
 +{
 +	LLInventoryModel::item_array_t::iterator result = items.end();
 +
 +	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
 +	{
 +		if ((*i)->getUUID() == id)
 +		{
 +			result = i;
 +			break;
 +		}
 +	}
 +
 +	return result;
 +}
 +
 +void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId)
 +{
 +	LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId);
 +	LLViewerInventoryItem* destItem = gInventory.getItem(destItemId);
 +
 +	items.erase(findItemByUUID(items, srcItem->getUUID()));
 +	items.insert(findItemByUUID(items, destItem->getUUID()), srcItem);
 +}
 +
 +BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 +										BOOL drop)
 +{
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model || !inv_item) return FALSE;
 +
 +	// cannot drag into library
 +	if(!isAgentInventory())
 +	{
 +		return FALSE;
 +	}
 +
 +	LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
 +	if(!avatar) return FALSE;
 +
 +	LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
 +	BOOL accept = FALSE;
 +	LLViewerObject* object = NULL;
 +	if(LLToolDragAndDrop::SOURCE_AGENT == source)
 +	{
 +
 +		BOOL is_movable = TRUE;
 +		switch( inv_item->getActualType() )
 +		{
 +		case LLAssetType::AT_CATEGORY:
 +			is_movable = !LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)inv_item)->getPreferredType());
 +			break;
 +		default:
 +			break;
 +		}
 +
 +		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +		BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
 +		const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 +		BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
 +		BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
 +
 +		if(is_movable && move_is_into_trash)
 +		{
 +			switch(inv_item->getType())
 +			{
 +			case LLAssetType::AT_CLOTHING:
 +			case LLAssetType::AT_BODYPART:
 +				is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID());
 +				break;
 +
 +			case LLAssetType::AT_OBJECT:
 +				is_movable = !avatar->isWearingAttachment(inv_item->getUUID());
 +				break;
 +			default:
 +				break;
 +			}
 +		}
 +
 +		if ( is_movable )
 +		{
 +			// Don't allow creating duplicates in the Calling Card/Friends
 +			// subfolders, see bug EXT-1599. Check is item direct descendent
 +			// of target folder and forbid item's movement if it so.
 +			// Note: isItemDirectDescendentOfCategory checks if
 +			// passed category is in the Calling Card/Friends folder
 +			is_movable = ! LLFriendCardsManager::instance()
 +				.isObjDirectDescendentOfCategory (inv_item, getCategory());
 +		}
 +
 +		const LLUUID& favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
 +		const LLUUID& landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
 +		const BOOL folder_allows_reorder = ((mUUID == landmarks_id) || (mUUID == favorites_id));
 +	   
 +		// we can move item inside a folder only if this folder is Favorites. See EXT-719
 +		accept = is_movable && ((mUUID != inv_item->getParentUUID()) || folder_allows_reorder);
 +		if(accept && drop)
 +		{
 +			if (inv_item->getType() == LLAssetType::AT_GESTURE
 +				&& LLGestureManager::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash)
 +			{
 +				LLGestureManager::instance().deactivateGesture(inv_item->getUUID());
 +			}
 +			// 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).
 +			if (LLFloaterInventory::getActiveInventory())
 +			{
 +				LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
 +				LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
 +				if (active_panel && (panel != active_panel))
 +				{
 +					active_panel->unSelectAll();
 +				}
 +			}
 +
 +			// if dragging from/into favorites folder only reorder items
 +			if ((mUUID == inv_item->getParentUUID()) && folder_allows_reorder)
 +			{
 +				LLInventoryModel::cat_array_t cats;
 +				LLInventoryModel::item_array_t items;
 +				LLIsType is_type(LLAssetType::AT_LANDMARK);
 +				model->collectDescendentsIf(mUUID, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
 +
 +				LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
 +				LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
 +				if (itemp)
 +				{
 +					LLUUID srcItemId = inv_item->getUUID();
 +					LLUUID destItemId = itemp->getListener()->getUUID();
 +
 +					// update order
 +					updateItemsOrder(items, srcItemId, destItemId);
 +
 +					saveItemsOrder(items);
 +				}
 +			}
 +			else if (favorites_id == mUUID) // if target is the favorites folder we use copy
 +			{
 +				copy_inventory_item(
 +					gAgent.getID(),
 +					inv_item->getPermissions().getOwner(),
 +					inv_item->getUUID(),
 +					mUUID,
 +					std::string(),
 +					LLPointer<LLInventoryCallback>(NULL));
 +			}
 +			else if (move_is_into_current_outfit || move_is_into_outfit)
 +			{
 +				// BAP - should skip if dup.
 +				if (move_is_into_current_outfit)
 +				{
 +					LLAppearanceManager::instance().addCOFItemLink(inv_item);
 +				}
 +				else
 +				{
 +					LLPointer<LLInventoryCallback> cb = NULL;
 +					link_inventory_item(
 +						gAgent.getID(),
 +						inv_item->getLinkedUUID(),
 +						mUUID,
 +						inv_item->getName(),
 +						LLAssetType::AT_LINK,
 +						cb);
 +				}
 +			}
 +			else
 +			{
 +				// restamp if the move is into the trash.
 +				LLInvFVBridge::changeItemParent(
 +					model,
 +					(LLViewerInventoryItem*)inv_item,
 +					mUUID,
 +					move_is_into_trash);
 +			}
 +		}
 +	}
 +	else if(LLToolDragAndDrop::SOURCE_WORLD == source)
 +	{
 +		// Make sure the object exists. If we allowed dragging from
 +		// anonymous objects, it would be possible to bypass
 +		// permissions.
 +		object = gObjectList.findObject(inv_item->getParentUUID());
 +		if(!object)
 +		{
 +			llinfos << "Object not found for drop." << llendl;
 +			return FALSE;
 +		}
 +
 +		// coming from a task. Need to figure out if the person can
 +		// move/copy this item.
 +		LLPermissions perm(inv_item->getPermissions());
 +		BOOL is_move = FALSE;
 +		if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
 +			&& perm.allowTransferTo(gAgent.getID())))
 +//		   || gAgent.isGodlike())
 +
 +		{
 +			accept = TRUE;
 +		}
 +		else if(object->permYouOwner())
 +		{
 +			// If the object cannot be copied, but the object the
 +			// inventory is owned by the agent, then the item can be
 +			// moved from the task to agent inventory.
 +			is_move = TRUE;
 +			accept = TRUE;
 +		}
 +		if(drop && accept)
 +		{
 +			LLMoveInv* move_inv = new LLMoveInv;
 +			move_inv->mObjectID = inv_item->getParentUUID();
 +			two_uuids_t item_pair(mUUID, inv_item->getUUID());
 +			move_inv->mMoveList.push_back(item_pair);
 +			move_inv->mCallback = NULL;
 +			move_inv->mUserData = NULL;
 +			if(is_move)
 +			{
 +				warn_move_inventory(object, move_inv);
 +			}
 +			else
 +			{
 +				LLNotification::Params params("MoveInventoryFromObject");
 +				params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
 +				LLNotifications::instance().forceResponse(params, 0);
 +			}
 +		}
 +
 +	}
 +	else if(LLToolDragAndDrop::SOURCE_NOTECARD == source)
 +	{
 +		accept = TRUE;
 +		if(drop)
 +		{
 +			copy_inventory_from_notecard(LLToolDragAndDrop::getInstance()->getObjectID(),
 +				LLToolDragAndDrop::getInstance()->getSourceID(), inv_item);
 +		}
 +	}
 +	else if(LLToolDragAndDrop::SOURCE_LIBRARY == source)
 +	{
 +		LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_item;
 +		if(item && item->isComplete())
 +		{
 +			accept = TRUE;
 +			if(drop)
 +			{
 +				copy_inventory_item(
 +					gAgent.getID(),
 +					inv_item->getPermissions().getOwner(),
 +					inv_item->getUUID(),
 +					mUUID,
 +					std::string(),
 +					LLPointer<LLInventoryCallback>(NULL));
 +			}
 +		}
 +	}
 +	else
 +	{
 +		llwarns << "unhandled drag source" << llendl;
 +	}
 +	return accept;
 +}
 +
 +// +=================================================+
 +// |        LLScriptBridge (DEPRECTED)               |
 +// +=================================================+
 +
 +LLUIImagePtr LLScriptBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
 +}
 +
 +// +=================================================+
 +// |        LLTextureBridge                          |
 +// +=================================================+
 +
 +LLUIImagePtr LLTextureBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_TEXTURE, mInvType, 0, FALSE);
 +}
 +
 +void LLTextureBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +}
 +
 +void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	lldebugs << "LLTextureBridge::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Open"));
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +
 +		items.push_back(std::string("Texture Separator"));
 +		items.push_back(std::string("Save As"));
 +	}
 +	hide_context_entries(menu, items, disabled_items);	
 +}
 +
 +// virtual
 +void LLTextureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("save_as" == action)
 +	{
 +		LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
 +		LLPreviewTexture* preview_texture = LLFloaterReg::findTypedInstance<LLPreviewTexture>("preview_texture", mUUID);
 +		if (preview_texture)
 +		{
 +			preview_texture->openToSave();
 +		}
 +	}
 +	else LLItemBridge::performAction(folder, model, action);
 +}
 +
 +// +=================================================+
 +// |        LLSoundBridge                            |
 +// +=================================================+
 +
 +LLUIImagePtr LLSoundBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE);
 +}
 +
 +void LLSoundBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +/*
 +// Changed this back to the way it USED to work:
 +// only open the preview dialog through the contextual right-click menu
 +// double-click just plays the sound
 +
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		openSoundPreview((void*)this);
 +		//send_uuid_sound_trigger(item->getAssetUUID(), 1.0);
 +	}
 +*/
 +}
 +
 +void LLSoundBridge::previewItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		send_sound_trigger(item->getAssetUUID(), 1.0);
 +	}
 +}
 +
 +void LLSoundBridge::openSoundPreview(void* which)
 +{
 +	LLSoundBridge *me = (LLSoundBridge *)which;
 +	LLFloaterReg::showInstance("preview_sound", LLSD(me->mUUID), TAKE_FOCUS_YES);
 +}
 +
 +void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	lldebugs << "LLSoundBridge::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Sound Open"));
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +	}
 +
 +	items.push_back(std::string("Sound Separator"));
 +	items.push_back(std::string("Sound Play"));
 +
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +// +=================================================+
 +// |        LLLandmarkBridge                         |
 +// +=================================================+
 +
 +LLLandmarkBridge::LLLandmarkBridge(LLInventoryPanel* inventory, const LLUUID& uuid, U32 flags/* = 0x00*/) :
 +LLItemBridge(inventory, uuid)
 +{
 +	mVisited = FALSE;
 +	if (flags & LLInventoryItem::II_FLAGS_LANDMARK_VISITED)
 +	{
 +		mVisited = TRUE;
 +	}
 +}
 +
 +LLUIImagePtr LLLandmarkBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mVisited, FALSE);
 +}
 +
 +void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +
 +	lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl;
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Landmark Open"));
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +	}
 +
 +	items.push_back(std::string("Landmark Separator"));
 +	items.push_back(std::string("About Landmark"));
 +
 +	// Disable "About Landmark" menu item for
 +	// multiple landmarks selected. Only one landmark
 +	// info panel can be shown at a time.
 +	if ((flags & FIRST_SELECTED_ITEM) == 0)
 +	{
 +		disabled_items.push_back(std::string("About Landmark"));
 +	}
 +
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +// Convenience function for the two functions below.
 +void teleport_via_landmark(const LLUUID& asset_id)
 +{
 +	gAgent.teleportViaLandmark( asset_id );
 +
 +	// we now automatically track the landmark you're teleporting to
 +	// because you'll probably arrive at a telehub instead
 +	LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
 +	if( floater_world_map )
 +	{
 +		floater_world_map->trackLandmark( asset_id );
 +	}
 +}
 +
 +// virtual
 +void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("teleport" == action)
 +	{
 +		LLViewerInventoryItem* item = getItem();
 +		if(item)
 +		{
 +			teleport_via_landmark(item->getAssetUUID());
 +		}
 +	}
 +	else if ("about" == action)
 +	{
 +		LLViewerInventoryItem* item = getItem();
 +		if(item)
 +		{
 +			LLSD key;
 +			key["type"] = "landmark";
 +			key["id"] = item->getUUID();
 +
 +			LLSideTray::getInstance()->showPanel("panel_places", key);
 +		}
 +	}
 +	else
 +	{
 +		LLItemBridge::performAction(folder, model, action);
 +	}
 +}
 +
 +static bool open_landmark_callback(const LLSD& notification, const LLSD& response)
 +{
 +	S32 option = LLNotification::getSelectedOption(notification, response);
 +
 +	LLUUID asset_id = notification["payload"]["asset_id"].asUUID();
 +	if (option == 0)
 +	{
 +		teleport_via_landmark(asset_id);
 +	}
 +
 +	return false;
 +}
 +static LLNotificationFunctorRegistration open_landmark_callback_reg("TeleportFromLandmark", open_landmark_callback);
 +
 +
 +void LLLandmarkBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +/*
 +	LLViewerInventoryItem* item = getItem();
 +	if( item )
 +	{
 +		// Opening (double-clicking) a landmark immediately teleports,
 +		// but warns you the first time.
 +		// open_landmark(item);
 +		LLSD payload;
 +		payload["asset_id"] = item->getAssetUUID();
 +		LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
 +	}
 +*/
 +}
 +
 +
 +// +=================================================+
 +// |        LLCallingCardObserver                    |
 +// +=================================================+
 +void LLCallingCardObserver::changed(U32 mask)
 +{
 +	mBridgep->refreshFolderViewItem();
 +}
 +
 +// +=================================================+
 +// |        LLCallingCardBridge                      |
 +// +=================================================+
 +
 +LLCallingCardBridge::LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid ) :
 +	LLItemBridge(inventory, uuid)
 +{
 +	mObserver = new LLCallingCardObserver(this);
 +	LLAvatarTracker::instance().addObserver(mObserver);
 +}
 +
 +LLCallingCardBridge::~LLCallingCardBridge()
 +{
 +	LLAvatarTracker::instance().removeObserver(mObserver);
 +	delete mObserver;
 +}
 +
 +void LLCallingCardBridge::refreshFolderViewItem()
 +{
 +	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
 +	LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL;
 +	if (itemp)
 +	{
 +		itemp->refresh();
 +	}
 +}
 +
 +// virtual
 +void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("begin_im" == action)
 +	{
 +		LLViewerInventoryItem *item = getItem();
 +		if (item && (item->getCreatorUUID() != gAgent.getID()) &&
 +			(!item->getCreatorUUID().isNull()))
 +		{
 +			std::string callingcard_name;
 +			gCacheName->getFullName(item->getCreatorUUID(), callingcard_name);
 +			LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());
 +			if (session_id != LLUUID::null)
 +			{
 +				LLIMFloater::show(session_id);
 +			}
 +		}
 +	}
 +	else if ("lure" == action)
 +	{
 +		LLViewerInventoryItem *item = getItem();
 +		if (item && (item->getCreatorUUID() != gAgent.getID()) &&
 +			(!item->getCreatorUUID().isNull()))
 +		{
 +			LLAvatarActions::offerTeleport(item->getCreatorUUID());
 +		}
 +	}
 +	else LLItemBridge::performAction(folder, model, action);
 +}
 +
 +LLUIImagePtr LLCallingCardBridge::getIcon() const
 +{
 +	BOOL online = FALSE;
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());
 +	}
 +	return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, online, FALSE);
 +}
 +
 +std::string LLCallingCardBridge::getLabelSuffix() const
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if( item && LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()) )
 +	{
 +		return LLItemBridge::getLabelSuffix() + " (online)";
 +	}
 +	else
 +	{
 +		return LLItemBridge::getLabelSuffix();
 +	}
 +}
 +
 +void LLCallingCardBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +/*
 +	LLViewerInventoryItem* item = getItem();
 +	if(item && !item->getCreatorUUID().isNull())
 +	{
 +		LLAvatarActions::showProfile(item->getCreatorUUID());
 +	}
 +*/
 +}
 +
 +void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	lldebugs << "LLCallingCardBridge::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Open"));
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +
 +		LLInventoryItem* item = getItem();
 +		BOOL good_card = (item
 +						  && (LLUUID::null != item->getCreatorUUID())
 +						  && (item->getCreatorUUID() != gAgent.getID()));
 +		BOOL user_online = (LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()));
 +		items.push_back(std::string("Send Instant Message Separator"));
 +		items.push_back(std::string("Send Instant Message"));
 +		items.push_back(std::string("Offer Teleport..."));
 +		items.push_back(std::string("Conference Chat"));
 +
 +		if (!good_card)
 +		{
 +			disabled_items.push_back(std::string("Send Instant Message"));
 +		}
 +		if (!good_card || !user_online)
 +		{
 +			disabled_items.push_back(std::string("Offer Teleport..."));
 +			disabled_items.push_back(std::string("Conference Chat"));
 +		}
 +	}
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
 +									 EDragAndDropType cargo_type,
 +									 void* cargo_data)
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	BOOL rv = FALSE;
 +	if(item)
 +	{
 +		// check the type
 +		switch(cargo_type)
 +		{
 +		case DAD_TEXTURE:
 +		case DAD_SOUND:
 +		case DAD_LANDMARK:
 +		case DAD_SCRIPT:
 +		case DAD_CLOTHING:
 +		case DAD_OBJECT:
 +		case DAD_NOTECARD:
 +		case DAD_BODYPART:
 +		case DAD_ANIMATION:
 +		case DAD_GESTURE:
 +			{
 +				LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
 +				const LLPermissions& perm = inv_item->getPermissions();
 +				if(gInventory.getItem(inv_item->getUUID())
 +				   && perm.allowOperationBy(PERM_TRANSFER, gAgent.getID()))
 +				{
 +					rv = TRUE;
 +					if(drop)
 +					{
 +						LLToolDragAndDrop::giveInventory(item->getCreatorUUID(),
 +														 (LLInventoryItem*)cargo_data);
 +					}
 +				}
 +				else
 +				{
 +					// It's not in the user's inventory (it's probably in
 +					// an object's contents), so disallow dragging it here.
 +					// You can't give something you don't yet have.
 +					rv = FALSE;
 +				}
 +				break;
 +			}
 +		case DAD_CATEGORY:
 +			{
 +				LLInventoryCategory* inv_cat = (LLInventoryCategory*)cargo_data;
 +				if( gInventory.getCategory( inv_cat->getUUID() ) )
 +				{
 +					rv = TRUE;
 +					if(drop)
 +					{
 +						LLToolDragAndDrop::giveInventoryCategory(
 +							item->getCreatorUUID(),
 +							inv_cat);
 +					}
 +				}
 +				else
 +				{
 +					// It's not in the user's inventory (it's probably in
 +					// an object's contents), so disallow dragging it here.
 +					// You can't give something you don't yet have.
 +					rv = FALSE;
 +				}
 +				break;
 +			}
 +		default:
 +			break;
 +		}
 +	}
 +	return rv;
 +}
 +
 +BOOL LLCallingCardBridge::removeItem()
 +{
 +	if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem()))
 +	{
 +		LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID());
 +		return FALSE;
 +	}
 +	else
 +	{
 +		return LLItemBridge::removeItem();
 +	}
 +}
 +// +=================================================+
 +// |        LLNotecardBridge                         |
 +// +=================================================+
 +
 +LLUIImagePtr LLNotecardBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);
 +}
 +
 +void LLNotecardBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +
 +/*
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES);
 +	}
 +*/
 +}
 +
 +
 +// +=================================================+
 +// |        LLGestureBridge                          |
 +// +=================================================+
 +
 +LLUIImagePtr LLGestureBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE);
 +}
 +
 +LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const
 +{
 +	if( LLGestureManager::instance().isGestureActive(mUUID) )
 +	{
 +		return LLFontGL::BOLD;
 +	}
 +	else
 +	{
 +		return LLFontGL::NORMAL;
 +	}
 +}
 +
 +std::string LLGestureBridge::getLabelSuffix() const
 +{
 +	if( LLGestureManager::instance().isGestureActive(mUUID) )
 +	{
 +		return LLItemBridge::getLabelSuffix() + " (active)";
 +	}
 +	else
 +	{
 +		return LLItemBridge::getLabelSuffix();
 +	}
 +}
 +
 +// virtual
 +void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("activate" == action)
 +	{
 +		LLGestureManager::instance().activateGesture(mUUID);
 +
 +		LLViewerInventoryItem* item = gInventory.getItem(mUUID);
 +		if (!item) return;
 +
 +		// Since we just changed the suffix to indicate (active)
 +		// the server doesn't need to know, just the viewer.
 +		gInventory.updateItem(item);
 +		gInventory.notifyObservers();
 +	}
 +	else if ("deactivate" == action)
 +	{
 +		LLGestureManager::instance().deactivateGesture(mUUID);
 +
 +		LLViewerInventoryItem* item = gInventory.getItem(mUUID);
 +		if (!item) return;
 +
 +		// Since we just changed the suffix to indicate (active)
 +		// the server doesn't need to know, just the viewer.
 +		gInventory.updateItem(item);
 +		gInventory.notifyObservers();
 +	}
 +	else LLItemBridge::performAction(folder, model, action);
 +}
 +
 +void LLGestureBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +/*
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null);
 +		preview->setFocus(TRUE);
 +	}
 +*/
 +}
 +
 +BOOL LLGestureBridge::removeItem()
 +{
 +	// Force close the preview window, if it exists
 +	LLGestureManager::instance().deactivateGesture(mUUID);
 +	return LLItemBridge::removeItem();
 +}
 +
 +void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	lldebugs << "LLGestureBridge::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Open"));
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +
 +		items.push_back(std::string("Gesture Separator"));
 +		items.push_back(std::string("Activate"));
 +		items.push_back(std::string("Deactivate"));
 +	}
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +// +=================================================+
 +// |        LLAnimationBridge                        |
 +// +=================================================+
 +
 +LLUIImagePtr LLAnimationBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE);
 +}
 +
 +void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +
 +	lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl;
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Animation Open"));
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +	}
 +
 +	items.push_back(std::string("Animation Separator"));
 +	items.push_back(std::string("Animation Play"));
 +	items.push_back(std::string("Animation Audition"));
 +
 +	hide_context_entries(menu, items, disabled_items);
 +
 +}
 +
 +// virtual
 +void LLAnimationBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ((action == "playworld") || (action == "playlocal"))
 +	{
 +		if (getItem())
 +		{
 +			LLPreviewAnim::e_activation_type activate = LLPreviewAnim::NONE;
 +			if ("playworld" == action) activate = LLPreviewAnim::PLAY;
 +			if ("playlocal" == action) activate = LLPreviewAnim::AUDITION;
 +
 +			LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID));
 +			if (preview)
 +			{
 +				preview->activate(activate);
 +			}
 +		}
 +	}
 +	else
 +	{
 +		LLItemBridge::performAction(folder, model, action);
 +	}
 +}
 +
 +void LLAnimationBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +/*
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
 +	}
 +*/
 +}
 +
 +// +=================================================+
 +// |        LLObjectBridge                           |
 +// +=================================================+
 +
 +// static
 +LLUUID LLObjectBridge::sContextMenuItemID;
 +
 +LLObjectBridge::LLObjectBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type, U32 flags) :
 +LLItemBridge(inventory, uuid), mInvType(type)
 +{
 +	mAttachPt = (flags & 0xff); // low bye of inventory flags
 +
 +	mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ?  TRUE: FALSE;
 +}
 +
 +LLUIImagePtr LLObjectBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject );
 +}
 +
 +LLInventoryObject* LLObjectBridge::getObject() const
 +{
 +	LLInventoryObject* object = NULL;
 +	LLInventoryModel* model = getInventoryModel();
 +	if(model)
 +	{
 +		object = (LLInventoryObject*)model->getObject(mUUID);
 +	}
 +	return object;
 +}
 +
 +// virtual
 +void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("attach" == action)
 +	{
 +		LLUUID object_id = mUUID;
 +		LLViewerInventoryItem* item;
 +		item = (LLViewerInventoryItem*)gInventory.getItem(object_id);
 +		if(item && gInventory.isObjectDescendentOf(object_id, gInventory.getRootFolderID()))
 +		{
 +			rez_attachment(item, NULL);
 +		}
 +		else if(item && item->isComplete())
 +		{
 +			// must be in library. copy it to our inventory and put it on.
 +			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
 +			copy_inventory_item(
 +				gAgent.getID(),
 +				item->getPermissions().getOwner(),
 +				item->getUUID(),
 +				LLUUID::null,
 +				std::string(),
 +				cb);
 +		}
 +		gFocusMgr.setKeyboardFocus(NULL);
 +	}
 +	else if ("detach" == action)
 +	{
 +		LLInventoryItem* item = gInventory.getItem(mUUID);
 +		if(item)
 +		{
 +			gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
 +			gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
 +			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 +			gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
 +			gMessageSystem->sendReliable( gAgent.getRegion()->getHost());
 +		}
 +		// this object might have been selected, so let the selection manager know it's gone now
 +		LLViewerObject *found_obj = gObjectList.findObject(item->getLinkedUUID());
 +		if (found_obj)
 +		{
 +			LLSelectMgr::getInstance()->remove(found_obj);
 +		}
 +	}
 +	else LLItemBridge::performAction(folder, model, action);
 +}
 +
 +void LLObjectBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +
 +	LLSD key;
 +	key["id"] = mUUID;
 +	LLSideTray::getInstance()->showPanel("sidepanel_inventory", key);
 +
 +	// Disable old properties floater; this is replaced by the sidepanel.
 +	/*
 +	LLFloaterReg::showInstance("properties", mUUID);
 +	*/
 +}
 +
 +LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const
 +{
 +	U8 font = LLFontGL::NORMAL;
 +
 +	LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
 +	if( avatar && avatar->isWearingAttachment( mUUID ) )
 +	{
 +		font |= LLFontGL::BOLD;
 +	}
 +
 +	LLInventoryItem* item = getItem();
 +	if (item && item->getIsLinkType())
 +	{
 +		font |= LLFontGL::ITALIC;
 +	}
 +
 +	return (LLFontGL::StyleFlags)font;
 +}
 +
 +std::string LLObjectBridge::getLabelSuffix() const
 +{
 +	LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
 +	if( avatar && avatar->isWearingAttachment( mUUID ) )
 +	{
 +		std::string attachment_point_name = avatar->getAttachedPointName(mUUID);
 +
 +		// e.g. "(worn on ...)" / "(attached to ...)"
 +		LLStringUtil::format_map_t args;
 +		args["[ATTACHMENT_POINT]"] =  attachment_point_name.c_str();
 +		return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args);
 +	}
 +	else
 +	{
 +		return LLItemBridge::getLabelSuffix();
 +	}
 +}
 +
 +void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment)
 +{
 +	LLSD payload;
 +	payload["item_id"] = item->getLinkedUUID(); // Wear the base object in case this is a link.
 +
 +	S32 attach_pt = 0;
 +	if (gAgent.getAvatarObject() && attachment)
 +	{
 +		for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin();
 +			 iter != gAgent.getAvatarObject()->mAttachmentPoints.end(); ++iter)
 +		{
 +			if (iter->second == attachment)
 +			{
 +				attach_pt = iter->first;
 +				break;
 +			}
 +		}
 +	}
 +
 +	payload["attachment_point"] = attach_pt;
 +
 +#if !ENABLE_MULTIATTACHMENTS
 +	if (attachment && attachment->getNumObjects() > 0)
 +	{
 +		LLNotifications::instance().add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
 +	}
 +	else
 +#endif
 +	{
 +		LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
 +	}
 +}
 +
 +bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response)
 +{
 +	LLVOAvatar *avatarp = gAgent.getAvatarObject();
 +
 +	if (!avatarp->canAttachMoreObjects())
 +	{
 +		LLSD args;
 +		args["MAX_ATTACHMENTS"] = llformat("%d", MAX_AGENT_ATTACHMENTS);
 +		LLNotifications::instance().add("MaxAttachmentsOnOutfit", args);
 +		return false;
 +	}
 +
 +	S32 option = LLNotification::getSelectedOption(notification, response);
 +	if (option == 0/*YES*/)
 +	{
 +		LLViewerInventoryItem* itemp = gInventory.getItem(notification["payload"]["item_id"].asUUID());
 +
 +		if (itemp)
 +		{
 +			LLMessageSystem* msg = gMessageSystem;
 +			msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
 +			msg->nextBlockFast(_PREHASH_AgentData);
 +			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 +			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 +			msg->nextBlockFast(_PREHASH_ObjectData);
 +			msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
 +			msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
 +			U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
 +#if ENABLE_MULTIATTACHMENTS
 +			attachment_pt |= ATTACHMENT_ADD;
 +#endif
 +			msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
 +			pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
 +			msg->addStringFast(_PREHASH_Name, itemp->getName());
 +			msg->addStringFast(_PREHASH_Description, itemp->getDescription());
 +			msg->sendReliable(gAgent.getRegion()->getHost());
 +		}
 +	}
 +	return false;
 +}
 +static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_replace_attachment_rez);
 +
 +void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Properties"));
 +
 +		LLInventoryItem *item = getItem();
 +		getClipboardEntries(true, items, disabled_items, flags);
 +
 +		LLObjectBridge::sContextMenuItemID = mUUID;
 +
 +		if(item)
 +		{
 +			LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
 +			if( !avatarp )
 +			{
 +				return;
 +			}
 +
 +			if( avatarp->isWearingAttachment( mUUID ) )
 +			{
 +				items.push_back(std::string("Detach From Yourself"));
 +			}
 +			else
 +			if( !isInTrash() && !isLinkedObjectInTrash() )
 +			{
 +				items.push_back(std::string("Attach Separator"));
 +				items.push_back(std::string("Object Wear"));
 +				items.push_back(std::string("Attach To"));
 +				items.push_back(std::string("Attach To HUD"));
 +				// commented out for DEV-32347
 +				//items.push_back(std::string("Restore to Last Position"));
 +
 +				if (!avatarp->canAttachMoreObjects())
 +				{
 +					disabled_items.push_back(std::string("Object Wear"));
 +					disabled_items.push_back(std::string("Attach To"));
 +					disabled_items.push_back(std::string("Attach To HUD"));
 +				}
 +				LLMenuGL* attach_menu = menu.findChildMenuByName("Attach To", TRUE);
 +				LLMenuGL* attach_hud_menu = menu.findChildMenuByName("Attach To HUD", TRUE);
 +				LLVOAvatar *avatarp = gAgent.getAvatarObject();
 +				if (attach_menu
 +					&& (attach_menu->getChildCount() == 0)
 +					&& attach_hud_menu
 +					&& (attach_hud_menu->getChildCount() == 0)
 +					&& avatarp)
 +				{
 +					for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
 +						 iter != avatarp->mAttachmentPoints.end(); )
 +					{
 +						LLVOAvatar::attachment_map_t::iterator curiter = iter++;
 +						LLViewerJointAttachment* attachment = curiter->second;
 +						LLMenuItemCallGL::Params p;
 +						std::string submenu_name = attachment->getName();
 +						if (LLTrans::getString(submenu_name) != "")
 +						{
 +						    p.name = (" ")+LLTrans::getString(submenu_name)+" ";
 +						}
 +						else
 +						{
 +							p.name = submenu_name;
 +						}
 +						LLSD cbparams;
 +						cbparams["index"] = curiter->first;
 +						cbparams["label"] = attachment->getName();
 +						p.on_click.function_name = "Inventory.AttachObject";
 +						p.on_click.parameter = LLSD(attachment->getName());
 +						p.on_enable.function_name = "Attachment.Label";
 +						p.on_enable.parameter = cbparams;
 +						LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu;
 +						LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
 +					}
 +				}
 +			}
 +		}
 +	}
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +BOOL LLObjectBridge::renameItem(const std::string& new_name)
 +{
 +	if(!isItemRenameable())
 +		return FALSE;
 +	LLPreview::dirty(mUUID);
 +	LLInventoryModel* model = getInventoryModel();
 +	if(!model)
 +		return FALSE;
 +	LLViewerInventoryItem* item = getItem();
 +	if(item && (item->getName() != new_name))
 +	{
 +		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 +		new_item->rename(new_name);
 +		buildDisplayName(new_item, mDisplayName);
 +		new_item->updateServer(FALSE);
 +		model->updateItem(new_item);
 +
 +		model->notifyObservers();
 +
 +		LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
 +		if( avatar )
 +		{
 +			LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() );
 +			if( obj )
 +			{
 +				LLSelectMgr::getInstance()->deselectAll();
 +				LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, FALSE );
 +				LLSelectMgr::getInstance()->selectionSetObjectName( new_name );
 +				LLSelectMgr::getInstance()->deselectAll();
 +			}
 +		}
 +	}
 +	// return FALSE because we either notified observers (& therefore
 +	// rebuilt) or we didn't update.
 +	return FALSE;
 +}
 +
 +// +=================================================+
 +// |        LLLSLTextBridge                          |
 +// +=================================================+
 +
 +LLUIImagePtr LLLSLTextBridge::getIcon() const
 +{
 +	return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
 +}
 +
 +void LLLSLTextBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +	/*
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES);
 +	}
 +	*/
 +}
 +
 +// +=================================================+
 +// |        LLWearableBridge                         |
 +// +=================================================+
 +
 +// *NOTE: hack to get from avatar inventory to avatar
 +void wear_inventory_item_on_avatar( LLInventoryItem* item )
 +{
 +	if(item)
 +	{
 +		lldebugs << "wear_inventory_item_on_avatar( " << item->getName()
 +				 << " )" << llendl;
 +
 +		LLAppearanceManager::instance().addCOFItemLink(item);
 +	}
 +}
 +
 +void wear_add_inventory_item_on_avatar( LLInventoryItem* item )
 +{
 +	if(item)
 +	{
 +		lldebugs << "wear_add_inventory_item_on_avatar( " << item->getName()
 +				 << " )" << llendl;
 +
 +		LLWearableList::instance().getAsset(item->getAssetUUID(),
 +							   item->getName(),
 +							   item->getType(),
 +							   LLWearableBridge::onWearAddOnAvatarArrived,
 +							   new LLUUID(item->getUUID()));
 +	}
 +}
 +
 +void remove_inventory_category_from_avatar( LLInventoryCategory* category )
 +{
 +	if(!category) return;
 +	lldebugs << "remove_inventory_category_from_avatar( " << category->getName()
 +			 << " )" << llendl;
 +
 +
 +	if( gFloaterCustomize )
 +	{
 +		gFloaterCustomize->askToSaveIfDirty(
 +			boost::bind(remove_inventory_category_from_avatar_step2, _1, category->getUUID()));
 +	}
 +	else
 +	{
 +		remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() );
 +	}
 +}
 +
 +struct OnRemoveStruct
 +{
 +	LLUUID mUUID;
 +	OnRemoveStruct(const LLUUID& uuid):
 +		mUUID(uuid)
 +	{
 +	}
 +};
 +
 +void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id)
 +{
 +
 +	// Find all the wearables that are in the category's subtree.
 +	lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl;
 +	if(proceed)
 +	{
 +		LLInventoryModel::cat_array_t cat_array;
 +		LLInventoryModel::item_array_t item_array;
 +		LLFindWearables is_wearable;
 +		gInventory.collectDescendentsIf(category_id,
 +										cat_array,
 +										item_array,
 +										LLInventoryModel::EXCLUDE_TRASH,
 +										is_wearable);
 +		S32 i;
 +		S32 wearable_count = item_array.count();
 +
 +		LLInventoryModel::cat_array_t	obj_cat_array;
 +		LLInventoryModel::item_array_t	obj_item_array;
 +		LLIsType is_object( LLAssetType::AT_OBJECT );
 +		gInventory.collectDescendentsIf(category_id,
 +										obj_cat_array,
 +										obj_item_array,
 +										LLInventoryModel::EXCLUDE_TRASH,
 +										is_object);
 +		S32 obj_count = obj_item_array.count();
 +
 +		// Find all gestures in this folder
 +		LLInventoryModel::cat_array_t	gest_cat_array;
 +		LLInventoryModel::item_array_t	gest_item_array;
 +		LLIsType is_gesture( LLAssetType::AT_GESTURE );
 +		gInventory.collectDescendentsIf(category_id,
 +										gest_cat_array,
 +										gest_item_array,
 +										LLInventoryModel::EXCLUDE_TRASH,
 +										is_gesture);
 +		S32 gest_count = gest_item_array.count();
 +
 +		if (wearable_count > 0)	//Loop through wearables.  If worn, remove.
 +		{
 +			for(i = 0; i  < wearable_count; ++i)
 +			{
 +				LLViewerInventoryItem *item = item_array.get(i);
 +				if (item->getType() == LLAssetType::AT_BODYPART)
 +					continue;
 +				if (gAgent.isTeen() && item->isWearableType() &&
 +					(item->getWearableType() == WT_UNDERPANTS || item->getWearableType() == WT_UNDERSHIRT))
 +					continue;
 +				if( gAgentWearables.isWearingItem (item->getLinkedUUID()) )
 +				{
 +					LLWearableList::instance().getAsset(item->getAssetUUID(),
 +														item->getName(),
 +														item->getType(),
 +														LLWearableBridge::onRemoveFromAvatarArrived,
 +														new OnRemoveStruct(item->getLinkedUUID()));
 +				}
 +			}
 +		}
 +
 +		if (obj_count > 0)
 +		{
 +			for(i = 0; i  < obj_count; ++i)
 +			{
 +				LLViewerInventoryItem *obj_item = obj_item_array.get(i);
 +				gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
 +				gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
 +				gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
 +				gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() );
 +
 +				gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
 +
 +				// this object might have been selected, so let the selection manager know it's gone now
 +				LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID());
 +				if (found_obj)
 +				{
 +					LLSelectMgr::getInstance()->remove(found_obj);
 +				}
 +			}
 +		}
 +
 +		if (gest_count > 0)
 +		{
 +			for(i = 0; i  < gest_count; ++i)
 +			{
 +				LLViewerInventoryItem *gest_item = gest_item_array.get(i);
 +				if ( LLGestureManager::instance().isGestureActive( gest_item->getLinkedUUID()) )
 +				{
 +					LLGestureManager::instance().deactivateGesture( gest_item->getLinkedUUID() );
 +					gInventory.updateItem( gest_item );
 +					gInventory.notifyObservers();
 +				}
 +
 +			}
 +		}
 +	}
 +}
 +
 +BOOL LLWearableBridge::renameItem(const std::string& new_name)
 +{
 +	if( gAgentWearables.isWearingItem( mUUID ) )
 +	{
 +		gAgentWearables.setWearableName( mUUID, new_name );
 +	}
 +	return LLItemBridge::renameItem(new_name);
 +}
 +
 +std::string LLWearableBridge::getLabelSuffix() const
 +{
 +	if( gAgentWearables.isWearingItem( mUUID ) )
 +	{
 +		// e.g. "(worn)" 
 +		return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
 +	}
 +	else
 +	{
 +		return LLItemBridge::getLabelSuffix();
 +	}
 +}
 +
 +LLUIImagePtr LLWearableBridge::getIcon() const
 +{
 +	return get_item_icon(mAssetType, mInvType, mWearableType, FALSE);
 +}
 +
 +// virtual
 +void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("wear" == action)
 +	{
 +		wearOnAvatar();
 +	}
 +	else if ("wear_add" == action)
 +	{
 +		wearAddOnAvatar();
 +	}
 +	else if ("edit" == action)
 +	{
 +		editOnAvatar();
 +		return;
 +	}
 +	else if ("take_off" == action)
 +	{
 +		if(gAgentWearables.isWearingItem(mUUID))
 +		{
 +			LLViewerInventoryItem* item = getItem();
 +			if (item)
 +			{
 +				LLWearableList::instance().getAsset(item->getAssetUUID(),
 +													item->getName(),
 +													item->getType(),
 +													LLWearableBridge::onRemoveFromAvatarArrived,
 +													new OnRemoveStruct(mUUID));
 +			}
 +		}
 +	}
 +	else LLItemBridge::performAction(folder, model, action);
 +}
 +
 +void LLWearableBridge::openItem()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +
 +	if (item)
 +	{
 +		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
 +	}
 +	/*
 +	if( isInTrash() )
 +	{
 +		LLNotifications::instance().add("CannotWearTrash");
 +	}
 +	else if(isAgentInventory())
 +	{
 +		if( !gAgentWearables.isWearingItem( mUUID ) )
 +		{
 +			wearOnAvatar();
 +		}
 +	}
 +	else
 +	{
 +		// must be in the inventory library. copy it to our inventory
 +		// and put it on right away.
 +		LLViewerInventoryItem* item = getItem();
 +		if(item && item->isComplete())
 +		{
 +			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
 +			copy_inventory_item(
 +				gAgent.getID(),
 +				item->getPermissions().getOwner(),
 +				item->getUUID(),
 +				LLUUID::null,
 +				std::string(),
 +				cb);
 +		}
 +		else if(item)
 +		{
 +			// *TODO: We should fetch the item details, and then do
 +			// the operation above.
 +			LLNotifications::instance().add("CannotWearInfoNotComplete");
 +		}
 +	}
 +	*/
 +}
 +
 +void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	lldebugs << "LLWearableBridge::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{	// FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere
 +		BOOL no_open = ((flags & SUPPRESS_OPEN_ITEM) == SUPPRESS_OPEN_ITEM);
 +
 +		// If we have clothing, don't add "Open" as it's the same action as "Wear"   SL-18976
 +		LLViewerInventoryItem* item = getItem();
 +		if( !no_open && item )
 +		{
 +			no_open = (item->getType() == LLAssetType::AT_CLOTHING) ||
 +					  (item->getType() == LLAssetType::AT_BODYPART);
 +		}
 +		if (!no_open)
 +		{
 +			items.push_back(std::string("Open"));
 +		}
 +
 +		items.push_back(std::string("Properties"));
 +
 +		getClipboardEntries(true, items, disabled_items, flags);
 +
 +		items.push_back(std::string("Wearable Separator"));
 +
 +		items.push_back(std::string("Wearable Wear"));
 +		items.push_back(std::string("Wearable Add"));
 +		items.push_back(std::string("Wearable Edit"));
 +
 +		if ((flags & FIRST_SELECTED_ITEM) == 0)
 +		{
 +			disabled_items.push_back(std::string("Wearable Edit"));
 +		}
 +		// Don't allow items to be worn if their baseobj is in the trash.
 +		if (isLinkedObjectInTrash())
 +		{
 +			disabled_items.push_back(std::string("Wearable Wear"));
 +			disabled_items.push_back(std::string("Wearable Add"));
 +			disabled_items.push_back(std::string("Wearable Edit"));
 +		}
 +
 +		// Disable wear and take off based on whether the item is worn.
 +		if(item)
 +		{
 +			switch (item->getType())
 +			{
 +				case LLAssetType::AT_CLOTHING:
 +					items.push_back(std::string("Take Off"));
 +				case LLAssetType::AT_BODYPART:
 +					if (gAgentWearables.isWearingItem(item->getUUID()))
 +					{
 +						disabled_items.push_back(std::string("Wearable Wear"));
 +						disabled_items.push_back(std::string("Wearable Add"));
 +					}
 +					else
 +					{
 +						disabled_items.push_back(std::string("Take Off"));
 +					}
 +					break;
 +				default:
 +					break;
 +			}
 +		}
 +	}
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +// Called from menus
 +// static
 +BOOL LLWearableBridge::canWearOnAvatar(void* user_data)
 +{
 +	LLWearableBridge* self = (LLWearableBridge*)user_data;
 +	if(!self) return FALSE;
 +	if(!self->isAgentInventory())
 +	{
 +		LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem();
 +		if(!item || !item->isComplete()) return FALSE;
 +	}
 +	return (!gAgentWearables.isWearingItem(self->mUUID));
 +}
 +
 +// Called from menus
 +// static
 +void LLWearableBridge::onWearOnAvatar(void* user_data)
 +{
 +	LLWearableBridge* self = (LLWearableBridge*)user_data;
 +	if(!self) return;
 +	self->wearOnAvatar();
 +}
 +
 +void LLWearableBridge::wearOnAvatar()
 +{
 +	// Don't wear anything until initial wearables are loaded, can
 +	// destroy clothing items.
 +	if (!gAgentWearables.areWearablesLoaded())
 +	{
 +		LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
 +		return;
 +	}
 +
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		if(!isAgentInventory())
 +		{
 +			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
 +			copy_inventory_item(
 +				gAgent.getID(),
 +				item->getPermissions().getOwner(),
 +				item->getUUID(),
 +				LLUUID::null,
 +				std::string(),
 +				cb);
 +		}
 +		else
 +		{
 +			wear_inventory_item_on_avatar(item);
 +		}
 +	}
 +}
 +
 +void LLWearableBridge::wearAddOnAvatar()
 +{
 +	// Don't wear anything until initial wearables are loaded, can
 +	// destroy clothing items.
 +	if (!gAgentWearables.areWearablesLoaded())
 +	{
 +		LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
 +		return;
 +	}
 +
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		if(!isAgentInventory())
 +		{
 +			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
 +			copy_inventory_item(
 +				gAgent.getID(),
 +				item->getPermissions().getOwner(),
 +				item->getUUID(),
 +				LLUUID::null,
 +				std::string(),
 +				cb);
 +		}
 +		else
 +		{
 +			wear_add_inventory_item_on_avatar(item);
 +		}
 +	}
 +}
 +
 +// static
 +void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
 +{
 +	LLUUID* item_id = (LLUUID*) userdata;
 +	if(wearable)
 +	{
 +		LLViewerInventoryItem* item = NULL;
 +		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
 +		if(item)
 +		{
 +			if(item->getAssetUUID() == wearable->getAssetID())
 +			{
 +				gAgentWearables.setWearableItem(item, wearable);
 +				gInventory.notifyObservers();
 +				//self->getFolderItem()->refreshFromRoot();
 +			}
 +			else
 +			{
 +				llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
 +			}
 +		}
 +	}
 +	delete item_id;
 +}
 +
 +// static
 +// BAP remove the "add" code path once everything is fully COF-ified.
 +void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata )
 +{
 +	LLUUID* item_id = (LLUUID*) userdata;
 +	if(wearable)
 +	{
 +		LLViewerInventoryItem* item = NULL;
 +		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
 +		if(item)
 +		{
 +			if(item->getAssetUUID() == wearable->getAssetID())
 +			{
 +				bool do_append = true;
 +				gAgentWearables.setWearableItem(item, wearable, do_append);
 +				gInventory.notifyObservers();
 +				//self->getFolderItem()->refreshFromRoot();
 +			}
 +			else
 +			{
 +				llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
 +			}
 +		}
 +	}
 +	delete item_id;
 +}
 +
 +// static
 +BOOL LLWearableBridge::canEditOnAvatar(void* user_data)
 +{
 +	LLWearableBridge* self = (LLWearableBridge*)user_data;
 +	if(!self) return FALSE;
 +
 +	return (gAgentWearables.isWearingItem(self->mUUID));
 +}
 +
 +// static
 +void LLWearableBridge::onEditOnAvatar(void* user_data)
 +{
 +	LLWearableBridge* self = (LLWearableBridge*)user_data;
 +	if(self)
 +	{
 +		self->editOnAvatar();
 +	}
 +}
 +
 +void LLWearableBridge::editOnAvatar()
 +{
 +	const LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID);
 +	if( wearable )
 +	{
 +		// Set the tab to the right wearable.
 +		if (gFloaterCustomize)
 +			gFloaterCustomize->setCurrentWearableType( wearable->getType() );
 +
 +		if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() )
 +		{
 +			// Start Avatar Customization
 +			gAgent.changeCameraToCustomizeAvatar();
 +		}
 +	}
 +}
 +
 +// static
 +BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
 +{
 +	LLWearableBridge* self = (LLWearableBridge*)user_data;
 +	if( self && (LLAssetType::AT_BODYPART != self->mAssetType) )
 +	{
 +		return gAgentWearables.isWearingItem( self->mUUID );
 +	}
 +	return FALSE;
 +}
 +
 +// static
 +void LLWearableBridge::onRemoveFromAvatar(void* user_data)
 +{
 +	LLWearableBridge* self = (LLWearableBridge*)user_data;
 +	if(!self) return;
 +	if(gAgentWearables.isWearingItem(self->mUUID))
 +	{
 +		LLViewerInventoryItem* item = self->getItem();
 +		if (item)
 +		{
 +			LLUUID parent_id = item->getParentUUID();
 +			LLWearableList::instance().getAsset(item->getAssetUUID(),
 +												item->getName(),
 +												item->getType(),
 +												onRemoveFromAvatarArrived,
 +												new OnRemoveStruct(LLUUID(self->mUUID)));
 +		}
 +	}
 +}
 +
 +// static
 +void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
 +												 void* userdata)
 +{
 +	OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata;
 +	const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID);
 +	if(wearable)
 +	{
 +		if( gAgentWearables.isWearingItem( item_id ) )
 +		{
 +			EWearableType type = wearable->getType();
 +
 +			if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES ) ) //&&
 +				//!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) )
 +			{
 +				// MULTI_WEARABLE: FIXME HACK - always remove all
 +				bool do_remove_all = false;
 +				gAgentWearables.removeWearable( type, do_remove_all, 0 );
 +			}
 +		}
 +	}
 +
 +	// Find and remove this item from the COF.
 +	LLInventoryModel::item_array_t items = gInventory.collectLinkedItems(item_id, LLAppearanceManager::instance().getCOF());
 +	llassert(items.size() == 1); // Should always have one and only one item linked to this in the COF.
 +	for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();
 +		 iter != items.end();
 +		 ++iter)
 +	{
 +		const LLViewerInventoryItem *linked_item = (*iter);
 +		const LLUUID &item_id = linked_item->getUUID();
 +		gInventory.purgeObject(item_id);
 +	}
 +	gInventory.notifyObservers();
 +
 +	delete on_remove_struct;
 +}
 +
 +LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type,
 +													   const LLUUID& uuid,LLInventoryModel* model)
 +{
 +	LLInvFVBridgeAction* action = NULL;
 +	switch(asset_type)
 +	{
 +	case LLAssetType::AT_TEXTURE:
 +		action = new LLTextureBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_SOUND:
 +		action = new LLSoundBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_LANDMARK:
 +		action = new LLLandmarkBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_CALLINGCARD:
 +		action = new LLCallingCardBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_OBJECT:
 +		action = new LLObjectBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_NOTECARD:
 +		action = new LLNotecardBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_ANIMATION:
 +		action = new LLAnimationBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_GESTURE:
 +		action = new LLGestureBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_LSL_TEXT:
 +		action = new LLLSLTextBridgeAction(uuid,model);
 +		break;
 +
 +	case LLAssetType::AT_CLOTHING:
 +	case LLAssetType::AT_BODYPART:
 +		action = new LLWearableBridgeAction(uuid,model);
 +
 +		break;
 +
 +	default:
 +		break;
 +	}
 +	return action;
 +}
 +
 +//static
 +void LLInvFVBridgeAction::doAction(LLAssetType::EType asset_type,
 +								   const LLUUID& uuid,LLInventoryModel* model)
 +{
 +	LLInvFVBridgeAction* action = createAction(asset_type,uuid,model);
 +	if(action)
 +	{
 +		action->doIt();
 +		delete action;
 +	}
 +}
 +
 +//static
 +void LLInvFVBridgeAction::doAction(const LLUUID& uuid, LLInventoryModel* model)
 +{
 +	LLAssetType::EType asset_type = model->getItem(uuid)->getType();
 +	LLInvFVBridgeAction* action = createAction(asset_type,uuid,model);
 +	if(action)
 +	{
 +		action->doIt();
 +		delete action;
 +	}
 +}
 +
 +LLViewerInventoryItem* LLInvFVBridgeAction::getItem() const
 +{
 +	if(mModel)
 +		return (LLViewerInventoryItem*)mModel->getItem(mUUID);
 +	return NULL;
 +}
 +
 +//virtual
 +void	LLTextureBridgeAction::doIt()
 +{
 +	if (getItem())
 +	{
 +		LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +//virtual
 +void	LLSoundBridgeAction::doIt()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		LLFloaterReg::showInstance("preview_sound", LLSD(mUUID), TAKE_FOCUS_YES);
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +
 +//virtual
 +void	LLLandmarkBridgeAction::doIt()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if( item )
 +	{
 +		// Opening (double-clicking) a landmark immediately teleports,
 +		// but warns you the first time.
 +		LLSD payload;
 +		payload["asset_id"] = item->getAssetUUID();
 +		LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +
 +//virtual
 +void	LLCallingCardBridgeAction::doIt()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if(item && item->getCreatorUUID().notNull())
 +	{
 +		LLAvatarActions::showProfile(item->getCreatorUUID());
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +//virtual
 +void
 +LLNotecardBridgeAction::doIt()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES);
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +//virtual
 +void	LLGestureBridgeAction::doIt()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null);
 +		preview->setFocus(TRUE);
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +//virtual
 +void	LLAnimationBridgeAction::doIt()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +
 +//virtual
 +void	LLObjectBridgeAction::doIt()
 +{
 +	LLFloaterReg::showInstance("properties", mUUID);
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +
 +//virtual
 +void	LLLSLTextBridgeAction::doIt()
 +{
 +	LLViewerInventoryItem* item = getItem();
 +	if (item)
 +	{
 +		LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES);
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +
 +BOOL LLWearableBridgeAction::isInTrash() const
 +{
 +	if(!mModel) return FALSE;
 +	const LLUUID trash_id = mModel->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 +	return mModel->isObjectDescendentOf(mUUID, trash_id);
 +}
 +
 +BOOL LLWearableBridgeAction::isAgentInventory() const
 +{
 +	if(!mModel) return FALSE;
 +	if(gInventory.getRootFolderID() == mUUID) return TRUE;
 +	return mModel->isObjectDescendentOf(mUUID, gInventory.getRootFolderID());
 +}
 +
 +void LLWearableBridgeAction::wearOnAvatar()
 +{
 +	// Don't wear anything until initial wearables are loaded, can
 +	// destroy clothing items.
 +	if (!gAgentWearables.areWearablesLoaded())
 +	{
 +		LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
 +		return;
 +	}
 +
 +	LLViewerInventoryItem* item = getItem();
 +	if(item)
 +	{
 +		if(!isAgentInventory())
 +		{
 +			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
 +			copy_inventory_item(
 +				gAgent.getID(),
 +				item->getPermissions().getOwner(),
 +				item->getUUID(),
 +				LLUUID::null,
 +				std::string(),
 +				cb);
 +		}
 +		else
 +		{
 +			wear_inventory_item_on_avatar(item);
 +		}
 +	}
 +}
 +
 +//virtual
 +void LLWearableBridgeAction::doIt()
 +{
 +	if(isInTrash())
 +	{
 +		LLNotifications::instance().add("CannotWearTrash");
 +	}
 +	else if(isAgentInventory())
 +	{
 +		if(!gAgentWearables.isWearingItem(mUUID))
 +		{
 +			wearOnAvatar();
 +		}
 +	}
 +	else
 +	{
 +		// must be in the inventory library. copy it to our inventory
 +		// and put it on right away.
 +		LLViewerInventoryItem* item = getItem();
 +		if(item && item->isComplete())
 +		{
 +			LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
 +			copy_inventory_item(
 +				gAgent.getID(),
 +				item->getPermissions().getOwner(),
 +				item->getUUID(),
 +				LLUUID::null,
 +				std::string(),
 +				cb);
 +		}
 +		else if(item)
 +		{
 +			// *TODO: We should fetch the item details, and then do
 +			// the operation above.
 +			LLNotifications::instance().add("CannotWearInfoNotComplete");
 +		}
 +	}
 +
 +	LLInvFVBridgeAction::doIt();
 +}
 +
 +// +=================================================+
 +// |        LLLinkItemBridge                         |
 +// +=================================================+
 +// For broken links
 +
 +std::string LLLinkItemBridge::sPrefix("Link: ");
 +
 +
 +LLUIImagePtr LLLinkItemBridge::getIcon() const
 +{
 +	if (LLViewerInventoryItem *item = getItem())
 +	{
 +		return get_item_icon(item->getActualType(), LLInventoryType::IT_NONE, 0, FALSE);
 +	}
 +	return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE);
 +}
 +
 +void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	// *TODO: Translate
 +	lldebugs << "LLLink::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Delete"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Delete"));
 +		}
 +	}
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +
 +// +=================================================+
 +// |        LLLinkBridge                             |
 +// +=================================================+
 +// For broken links.
 +
 +std::string LLLinkFolderBridge::sPrefix("Link: ");
 +
 +
 +LLUIImagePtr LLLinkFolderBridge::getIcon() const
 +{
 +	LLFolderType::EType preferred_type = LLFolderType::FT_NONE;
 +	if (LLViewerInventoryItem *item = getItem())
 +	{
 +		if (const LLViewerInventoryCategory* cat = item->getLinkedCategory())
 +		{
 +			preferred_type = cat->getPreferredType();
 +		}
 +	}
 +	return LLFolderBridge::getIcon(preferred_type);
 +}
 +
 +void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 +{
 +	// *TODO: Translate
 +	lldebugs << "LLLink::buildContextMenu()" << llendl;
 +	std::vector<std::string> items;
 +	std::vector<std::string> disabled_items;
 +
 +	if(isInTrash())
 +	{
 +		items.push_back(std::string("Purge Item"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Purge Item"));
 +		}
 +
 +		items.push_back(std::string("Restore Item"));
 +	}
 +	else
 +	{
 +		items.push_back(std::string("Find Original"));
 +		items.push_back(std::string("Delete"));
 +		if (!isItemRemovable())
 +		{
 +			disabled_items.push_back(std::string("Delete"));
 +		}
 +	}
 +	hide_context_entries(menu, items, disabled_items);
 +}
 +
 +void LLLinkFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 +{
 +	if ("goto" == action)
 +	{
 +		gotoItem(folder);
 +		return;
 +	}
 +	LLItemBridge::performAction(folder,model,action);
 +}
 +
 +void LLLinkFolderBridge::gotoItem(LLFolderView *folder)
 +{
 +	const LLUUID &cat_uuid = getFolderID();
 +	if (!cat_uuid.isNull())
 +	{
 +		if (LLFolderViewItem *base_folder = folder->getItemByID(cat_uuid))
 +		{
 +			if (LLInventoryModel* model = getInventoryModel())
 +			{
 +				model->fetchDescendentsOf(cat_uuid);
 +			}
 +			base_folder->setOpen(TRUE);
 +			folder->setSelectionFromRoot(base_folder,TRUE);
 +			folder->scrollToShowSelection();
 +		}
 +	}
 +}
 +
 +const LLUUID &LLLinkFolderBridge::getFolderID() const
 +{
 +	if (LLViewerInventoryItem *link_item = getItem())
 +	{
 +		if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory())
 +		{
 +			const LLUUID& cat_uuid = cat->getUUID();
 +			return cat_uuid;
 +		}
 +	}
 +	return LLUUID::null;
 +}
 diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 49e64ebdde..6a284e0550 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -288,6 +288,8 @@ public:  	virtual BOOL renameItem(const std::string& new_name);  	virtual BOOL removeItem(); +	bool removeItemResponse(const LLSD& notification, const LLSD& response); +  	virtual void pasteFromClipboard();  	virtual void pasteLinkFromClipboard();  	virtual void buildContextMenu(LLMenuGL& menu, U32 flags); @@ -508,7 +510,6 @@ public:  	virtual LLFontGL::StyleFlags getLabelStyle() const;  	virtual std::string getLabelSuffix() const;  	virtual void			buildContextMenu(LLMenuGL& menu, U32 flags); -	virtual BOOL			isItemRemovable();  	virtual BOOL renameItem(const std::string& new_name);  	LLInventoryObject* getObject() const; @@ -546,7 +547,6 @@ public:  	virtual void	openItem();  	virtual void	buildContextMenu(LLMenuGL& menu, U32 flags);  	virtual std::string getLabelSuffix() const; -	virtual BOOL	isItemRemovable();  	virtual BOOL renameItem(const std::string& new_name);  	static void		onWearOnAvatar( void* userdata );	// Access to wearOnAvatar() from menu diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index fbaab385fe..9e37c5be38 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1118,9 +1118,16 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const  	return mObservers.find(observer) != mObservers.end();  } -// Call this method when it's time to update everyone on a new state, -// by default, the inventory model will not update observers -// automatically. +void LLInventoryModel::idleNotifyObservers() +{ +	if (mModifyMask == LLInventoryObserver::NONE && (mChangedItemIDs.size() == 0)) +	{ +		return; +	} +	notifyObservers(""); +} + +// Call this method when it's time to update everyone on a new state.  // The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]  void LLInventoryModel::notifyObservers(const std::string service_name)  { @@ -1133,13 +1140,6 @@ void LLInventoryModel::notifyObservers(const std::string service_name)  		return;  	} -	if ((mModifyMask == LLInventoryObserver::NONE) && (service_name == "")) -	{ -		mModifyMask = LLInventoryObserver::NONE; -		mChangedItemIDs.clear(); -		return; -	} -  	mIsNotifyObservers = TRUE;  	for (observer_list_t::iterator iter = mObservers.begin();  		 iter != mObservers.end(); ) @@ -3308,8 +3308,7 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);  	if(agent_id != gAgent.getID())  	{ -		llwarns << "Got a UpdateInventoryItem for the wrong agent." -				<< llendl; +		llwarns << "Got a UpdateInventoryItem for the wrong agent." << llendl;  		return;  	}  	LLUUID parent_id; @@ -3320,6 +3319,7 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)  	msg->getS32("AgentData", "Version", version);  	S32 descendents;  	msg->getS32("AgentData", "Descendents", descendents); +  	S32 i;  	S32 count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);  	LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id); @@ -3349,6 +3349,9 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)  	{  		cat->setVersion(version);  		cat->setDescendentCount(descendents); +		// Get this UUID on the changed list so that whatever's listening for it +		// will get triggered. +		gInventory.addChangedMask(LLInventoryObserver::INTERNAL, cat->getUUID());  	}  	gInventory.notifyObservers();  } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index da12dbdf7f..50f54cb842 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -252,9 +252,12 @@ public:  	// multiple trash can bug.  	const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder = true, bool find_in_library = false); -	// Call this method when it's time to update everyone on a new -	// state, by default, the inventory model will not update -	// observers automatically. +	// This gets called by the idle loop.  It only updates if new +	// state is detected.  Call notifyObservers() manually to update +	// regardless of whether state change has been indicated. +	void idleNotifyObservers(); + +	// Call this method to explicitly update everyone on a new state.  	// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]  	void notifyObservers(const std::string service_name=""); diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 3ccf593d27..06f4b36df3 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -112,10 +112,20 @@ void LLInventoryFetchObserver::changed(U32 mask)  			LLViewerInventoryItem* item = gInventory.getItem(*it);  			if(!item)  			{ -				// BUG: This can cause done() to get called prematurely below. -				// This happens with the LLGestureInventoryFetchObserver that -				// loads gestures at startup. JC -				it = mIncomplete.erase(it); +				if (mRetryIfMissing) +				{ +					// BAP changed to skip these items, so we should keep retrying until they arrive. +					// Did not make this the default behavior because of uncertainty about impact - +					// could cause some observers that currently complete to wait forever. +					++it; +				} +				else +				{ +					// BUG: This can cause done() to get called prematurely below. +					// This happens with the LLGestureInventoryFetchObserver that +					// loads gestures at startup. JC +					it = mIncomplete.erase(it); +				}  				continue;  			}  			if(item->isComplete()) diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index e908506b33..73b25a8ed0 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -106,7 +106,7 @@ protected:  class LLInventoryFetchObserver : public LLInventoryObserver  {  public: -	LLInventoryFetchObserver() {} +	LLInventoryFetchObserver(bool retry_if_missing = false): mRetryIfMissing(retry_if_missing) {}  	virtual void changed(U32 mask);  	typedef std::vector<LLUUID> item_ref_t; @@ -116,6 +116,7 @@ public:  	virtual void done() {};  protected: +	bool mRetryIfMissing;  	item_ref_t mComplete;  	item_ref_t mIncomplete;  }; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 327a735f78..0c893dddd6 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -78,7 +78,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mSortOrderSetting(p.sort_order_setting),  	mInventory(p.inventory),  	mAllowMultiSelect(p.allow_multi_select), -	mHasInventoryConnection(false), +	mViewsInitialized(false),  	mStartFolderString(p.start_folder),	  	mBuildDefaultHierarchy(true),  	mInvFVBridgeBuilder(NULL) @@ -96,6 +96,11 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor"));  	setBackgroundVisible(TRUE);  	setBackgroundOpaque(TRUE); +	 +	if (mStartFolderString != "") +	{ +		mBuildDefaultHierarchy = false; +	}  }  BOOL LLInventoryPanel::postBuild() @@ -146,13 +151,13 @@ BOOL LLInventoryPanel::postBuild()  	mInventory->addObserver(mInventoryObserver);  	// build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback -	if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection) +	if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized)  	{ -		rebuildViews(); -		mHasInventoryConnection = true; -		defaultOpenInventory(); +		initializeViews();  	} +	gIdleCallbacks.addFunction(onIdle, (void*)this); +  	if (mSortOrderSetting != INHERIT_SORT_ORDER)  	{  		setSortOrder(gSavedSettings.getU32(mSortOrderSetting)); @@ -252,15 +257,11 @@ void LLInventoryPanel::modelChanged(U32 mask)  	bool handled = false; -	// inventory just initialized, do complete build -	if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection) +	if (!mViewsInitialized)  	{ -		rebuildViews(); -		mHasInventoryConnection = true; -		defaultOpenInventory();  		return;  	} - +	  	if (mask & LLInventoryObserver::LABEL)  	{  		handled = true; @@ -327,22 +328,26 @@ void LLInventoryPanel::modelChanged(U32 mask)  				// around in the panel's directory structure (i.e. reparented).  				if (model_item && view_item)  				{ -					LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID()); - -					// Item has been moved. -					if (view_item->getParentFolder() != new_parent) +					// Don't process the item if it's hanging from the root, since its +					// model_item's parent will be NULL. +					if (view_item->getRoot() != view_item->getParent())  					{ -						if (new_parent != NULL) +						LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID()); +						// Item has been moved. +						if (view_item->getParentFolder() != new_parent)  						{ -							// 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, mFolders); -						} -						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(); +							if (new_parent != NULL) +							{ +								// 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, mFolders); +							} +							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(); +							}  						}  					}  				} @@ -366,11 +371,28 @@ void LLInventoryPanel::modelChanged(U32 mask)  	}  } +// static +void LLInventoryPanel::onIdle(void *userdata) +{ +	LLInventoryPanel *self = (LLInventoryPanel*)userdata; +	// inventory just initialized, do complete build +	if (!self->mViewsInitialized && gInventory.isInventoryUsable()) +	{ +		self->initializeViews(); +	} +	if (self->mViewsInitialized) +	{ +		gIdleCallbacks.deleteFunction(onIdle, (void*)self); +	} +} -void LLInventoryPanel::rebuildViews() +void LLInventoryPanel::initializeViews()  { -	// Determine the root folder and rebuild the views starting -	// at that folder. +	if (!gInventory.isInventoryUsable()) +		return; + +	// Determine the root folder in case specified, and +	// build the views starting with that folder.  	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);  	if ("LIBRARY" == mStartFolderString) @@ -381,16 +403,17 @@ void LLInventoryPanel::rebuildViews()  	{  		mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);  	} -	 +	llinfos << this << " Generating views for start folder " << mStartFolderString << llendl;  	rebuildViewsFor(mStartFolderID); + +	mViewsInitialized = true; +	defaultOpenInventory();  }  void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)  { -	LLFolderViewItem* old_view = NULL; - -	// get old LLFolderViewItem -	old_view = mFolders->getItemByID(id); +	// Destroy the old view for this ID so we can rebuild it +	LLFolderViewItem* old_view = mFolders->getItemByID(id);  	if (old_view && id.notNull())  	{  		old_view->destroyView(); @@ -409,11 +432,13 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  		const LLUUID &parent_id = objectp->getParentUUID();  		LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(parent_id);  		if (id == mStartFolderID) +		{  			parent_folder = mFolders; -		 -		if (!parent_folder) +		} +		else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))  		{ -			// This item exists outside the inventory's hierarchy, so don't add it. +			// This item exists outside the inventory's hierarchy, +			// so don't add it.  			return;  		} @@ -520,19 +545,20 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  // bit of a hack to make sure the inventory is open.  void LLInventoryPanel::defaultOpenInventory()  { -	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString); -	if (preferred_type != LLFolderType::FT_NONE) +	if (mStartFolderString != "")  	{ -		const std::string& top_level_folder_name = LLViewerFolderType::lookupNewCategoryName(preferred_type); -		mFolders->openFolder(top_level_folder_name); +		mFolders->openFolder(mStartFolderString);  	}  	else  	{  		// Get the first child (it should be "My Inventory") and  		// open it up by name (just to make sure the first child is actually a folder).  		LLView* first_child = mFolders->getFirstChild(); -		const std::string& first_child_name = first_child->getName(); -		mFolders->openFolder(first_child_name); +		if (first_child) +		{ +			const std::string& first_child_name = first_child->getName(); +			mFolders->openFolder(first_child_name); +		}  	}  } @@ -640,13 +666,6 @@ void LLInventoryPanel::openAllFolders()  	mFolders->arrangeAll();  } -void LLInventoryPanel::openDefaultFolderForType(LLFolderType::EType type) -{ -	LLUUID category_id = mInventory->findCategoryUUIDForType(type); -	LLOpenFolderByID opener(category_id); -	mFolders->applyFunctorRecursively(opener); -} -  void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)  {  	// Don't select objects in COF (e.g. to prevent refocus when items are worn). diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 0ccee337c9..fd23b375fa 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -122,7 +122,6 @@ public:  	// Call this method to set the selection.  	void openAllFolders(); -	void openDefaultFolderForType(LLFolderType::EType);  	void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);  	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }  	void clearSelection(); @@ -161,40 +160,23 @@ public:  	void openSelected();  	void unSelectAll()	{ mFolders->setSelection(NULL, FALSE, FALSE); } -protected: -	// Destroys the old views, and regenerates them based on the -	// start folder ID. -	void rebuildViews(); +	static void onIdle(void* user_data); + +private:  	// Given the id and the parent, build all of the folder views.  	void rebuildViewsFor(const LLUUID& id);  	virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719 -	void defaultOpenInventory(); // open the first level of inventory  protected: +	void defaultOpenInventory(); // open the first level of inventory +  	LLInventoryModel*			mInventory;  	LLInventoryObserver*		mInventoryObserver;  	BOOL 						mAllowMultiSelect;  	std::string					mSortOrderSetting; -//private: // Can not make these private - needed by llinventorysubtreepanel  	LLFolderView*				mFolders; -	std::string                 mStartFolderString; - -	/** -	 * Contains UUID of Inventory item from which hierarchy should be built. -	 * Can be set with the "start_folder" xml property. -	 * Default is LLUUID::null that means total Inventory hierarchy. -	 */ -	LLUUID						mStartFolderID;  	LLScrollContainer*			mScroller; -	bool						mHasInventoryConnection; - -	/** -	 * Flag specified if default inventory hierarchy should be created in postBuild() -	 */ -	bool						mBuildDefaultHierarchy; - -	LLUUID						mRootInventoryItemUUID;  	/**  	 * Pointer to LLInventoryFVBridgeBuilder. @@ -205,6 +187,21 @@ protected:  	 */  	const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder; +	//-------------------------------------------------------------------- +	// Initialization routines for building up the UI ("views") +	//-------------------------------------------------------------------- +public: +	BOOL 				getIsViewsInitialized() const { return mViewsInitialized; } +private: +	// Builds the UI.  Call this once the inventory is usable. +	void 				initializeViews(); +	BOOL				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild() +	BOOL				mViewsInitialized; // Views have been generated +	 +	// UUID of category from which hierarchy should be built.  Set with the  +	// "start_folder" xml property.  Default is LLUUID::null that means total Inventory hierarchy.  +	std::string         mStartFolderString; +	LLUUID				mStartFolderID;  };  #endif // LL_LLINVENTORYPANEL_H diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index badef4c7ae..3c337961e1 100755 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -260,7 +260,8 @@ void LLMediaDataClient::Responder::result(const LLSD& content)  //  ////////////////////////////////////////////////////////////////////////////////////// -bool LLMediaDataClient::Comparator::operator() (const request_ptr_t &o1, const request_ptr_t &o2) const +// static +bool LLMediaDataClient::compareRequests(const request_ptr_t &o1, const request_ptr_t &o2)  {  	if (o2.isNull()) return true;  	if (o1.isNull()) return false; @@ -277,20 +278,13 @@ bool LLMediaDataClient::Comparator::operator() (const request_ptr_t &o1, const r  	// 3: One item with an impl, another without: item with impl wins   	//	  (XXX is that what we want?)		   	// Calculate the scores for each.   -	F64 o1_score = Comparator::getObjectScore(o1->getObject()); -	F64 o2_score = Comparator::getObjectScore(o2->getObject()); - -    // XXX Weird: a higher score should go earlier, but by observation I notice -    // that this causes further-away objects load first.  This is counterintuitive -    // to the priority_queue Comparator, which states that this function should -    // return 'true' if o1 should be *before* o2. -    // In other words, I'd have expected that the following should return -    // ( o1_score > o2_score). -	return ( o1_score < o2_score ); +	F64 o1_score = getObjectScore(o1->getObject()); +	F64 o2_score = getObjectScore(o2->getObject()); +	return ( o1_score > o2_score );  } -	 +  // static -F64 LLMediaDataClient::Comparator::getObjectScore(const LLMediaDataClientObject::ptr_t &obj) +F64 LLMediaDataClient::getObjectScore(const LLMediaDataClientObject::ptr_t &obj)  {  	// *TODO: make this less expensive?  	F64 dist = obj->getDistanceFromAvatar() + 0.1;	 // avoids div by 0 @@ -310,12 +304,12 @@ F64 LLMediaDataClient::Comparator::getObjectScore(const LLMediaDataClientObject:  //////////////////////////////////////////////////////////////////////////////////////  // dump the queue -std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue &q) +std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q)  {  	int i = 0; -	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = q.c.begin(); -	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = q.c.end(); -	while (iter < end) +	LLMediaDataClient::request_queue_t::const_iterator iter = q.begin(); +	LLMediaDataClient::request_queue_t::const_iterator end = q.end(); +	while (iter != end)  	{  		s << "\t" << i << "]: " << (*iter)->getObject()->getID().asString();  		iter++; @@ -325,11 +319,11 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue  }  // find the given object in the queue. -bool LLMediaDataClient::PriorityQueue::find(const LLMediaDataClientObject::ptr_t &obj) const +bool LLMediaDataClient::find(const LLMediaDataClientObject::ptr_t &obj) const  { -	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = c.begin(); -	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = c.end(); -	while (iter < end) +	request_queue_t::const_iterator iter = pRequestQueue->begin(); +	request_queue_t::const_iterator end = pRequestQueue->end(); +	while (iter != end)  	{  		if (obj->getID() == (*iter)->getObject()->getID())  		{ @@ -370,13 +364,17 @@ BOOL LLMediaDataClient::QueueTimer::tick()  		return TRUE;  	} -	LLMediaDataClient::PriorityQueue &queue = *(mMDC->pRequestQueue); +	request_queue_t &queue = *(mMDC->pRequestQueue);  	if(!queue.empty())  	{  		LL_INFOS("LLMediaDataClient") << "QueueTimer::tick() started, queue is:	  " << queue << LL_ENDL; -	} +		// Re-sort the list every time... +		// XXX Is this really what we want? +		queue.sort(LLMediaDataClient::compareRequests); +	} +	  	// quick retry loop for cases where we shouldn't wait for the next timer tick  	while(true)  	{ @@ -387,7 +385,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()  		}  		// Peel one off of the items from the queue, and execute request -		request_ptr_t request = queue.top(); +		request_ptr_t request = queue.front();  		llassert(!request.isNull());  		const LLMediaDataClientObject *object = (request.isNull()) ? NULL : request->getObject();  		bool performed_request = false; @@ -398,7 +396,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()  		{  			// This object has been marked dead.  Pop it and move on to the next item in the queue immediately.  			LL_INFOS("LLMediaDataClient") << "Skipping " << *request << ": object is dead!" << LL_ENDL; -			queue.pop(); +			queue.pop_front();  			continue;	// jump back to the start of the quick retry loop  		} @@ -442,7 +440,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()  											  << mMDC->mMaxNumRetries << " tries...popping object id " << object->getID() << LL_ENDL;   				// XXX Should we bring up a warning dialog??  			} -			queue.pop(); +			queue.pop_front();  		}  		else {  			request->incRetryCount(); @@ -451,7 +449,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()   		// end of quick retry loop -- any cases where we want to loop will use 'continue' to jump back to the start.   		break;  	}   -	 +  	LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue is now: " << (*(mMDC->pRequestQueue)) << LL_ENDL;  	return queue.empty(); @@ -488,7 +486,7 @@ void LLMediaDataClient::enqueue(const Request *request)  	LL_INFOS("LLMediaDataClient") << "Queuing request for " << *request << LL_ENDL;  	// Push the request on the priority queue  	// Sadly, we have to const-cast because items put into the queue are not const -	pRequestQueue->push(const_cast<LLMediaDataClient::Request*>(request)); +	pRequestQueue->push_back(const_cast<LLMediaDataClient::Request*>(request));  	LL_DEBUGS("LLMediaDataClient") << "Queue:" << (*pRequestQueue) << LL_ENDL;  	// Start the timer if not already running  	startQueueTimer(); @@ -508,7 +506,7 @@ LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,  	  mMaxNumRetries(max_retries),  	  mQueueTimerIsRunning(false)  { -	pRequestQueue = new PriorityQueue(); +	pRequestQueue = new request_queue_t();  }  LLMediaDataClient::~LLMediaDataClient() @@ -529,7 +527,7 @@ bool LLMediaDataClient::isEmpty() const  bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) const  { -	return (NULL == pRequestQueue) ? false : pRequestQueue->find(object); +	return (NULL == pRequestQueue) ? false : find(object);  }  ////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h index d5dd050111..812e9cbdec 100755 --- a/indra/newview/llmediadataclient.h +++ b/indra/newview/llmediadataclient.h @@ -195,30 +195,14 @@ protected:  private: -	// Comparator for PriorityQueue -	class Comparator -	{ -	public: -		bool operator() (const request_ptr_t &o1, const request_ptr_t &o2) const; -	private: -		static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj); -	}; +	typedef std::list<request_ptr_t> request_queue_t; -    // PriorityQueue -	class PriorityQueue : public std::priority_queue< -		request_ptr_t,  -		std::vector<request_ptr_t>,  -		Comparator > -	{ -	public: -		// Return whether the given object is in the queue -		bool find(const LLMediaDataClientObject::ptr_t &obj) const; -		 -		friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q); -	}; +	// Comparator for sorting +	static bool compareRequests(const request_ptr_t &o1, const request_ptr_t &o2); +	static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);  	friend std::ostream& operator<<(std::ostream &s, const Request &q); -    friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q); +	friend std::ostream& operator<<(std::ostream &s, const request_queue_t &q);  	class QueueTimer : public LLEventTimer  	{ @@ -232,6 +216,9 @@ private:  		LLPointer<LLMediaDataClient> mMDC;  	}; +	// Return whether the given object is in the queue +	bool find(const LLMediaDataClientObject::ptr_t &obj) const; +	  	void startQueueTimer();  	void stopQueueTimer();  	void setIsRunning(bool val) { mQueueTimerIsRunning = val; } @@ -242,7 +229,7 @@ private:  	bool mQueueTimerIsRunning; -	PriorityQueue *pRequestQueue; +	request_queue_t *pRequestQueue;  }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 2c27808f03..f29a7b25a7 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -340,6 +340,7 @@ BOOL LLPanelAvatarProfile::postBuild()  	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;  	registrar.add("Profile.Pay",  boost::bind(&LLPanelAvatarProfile::pay, this)); +	registrar.add("Profile.Share", boost::bind(&LLPanelAvatarProfile::share, this));  	mProfileMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); @@ -535,6 +536,11 @@ void LLPanelAvatarProfile::pay()  	LLAvatarActions::pay(getAvatarId());  } +void LLPanelAvatarProfile::share() +{ +	LLAvatarActions::share(getAvatarId()); +} +  void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url)  {  	LLWeb::loadURL(url); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 716bb29d45..527e1c0d34 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -172,6 +172,11 @@ protected:  	 */  	void pay(); +	/** +	 * opens inventory and IM for sharing items +	 */ +	void share(); +  	void onUrlTextboxClicked(const std::string& url);  	void onHomepageTextboxClicked();  	void onAddFriendButtonClick(); diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 40319d949d..fa6d16cfb1 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -160,13 +160,7 @@ void LLPanelIMControlPanel::onAddFriendButtonClicked()  void LLPanelIMControlPanel::onShareButtonClicked()  { -	LLSD key; -	LLSideTray::getInstance()->showPanel("sidepanel_inventory", key); - -	if (gIMMgr->hasSession(getSessionId())) -	{ -		LLIMModel::getInstance()->addMessage(getSessionId(), SYSTEM_FROM, LLUUID::null, LLTrans::getString("share_alert"), false); -	} +	LLAvatarActions::share(mAvatarID);  }  void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id) diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index ad8a379cc1..9b1f71a9a9 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -387,17 +387,19 @@ void LLPanelMediaSettingsGeneral::preApply()  //  void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in )  { -    fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue(); -    fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue(); -    fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue(); -    fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue(); -    fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex(); -    //Don't fill in current URL: this is only supposed to get changed via navigate +	fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue(); +	fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue(); +	fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue(); +	fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue(); +	fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex(); +	//Don't fill in current URL: this is only supposed to get changed via navigate  	// fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue(); -    fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue(); -    fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue(); -    fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue(); -    fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue(); +	fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue(); +	// Don't fill in the home URL if it is the special "Multiple Media" string! +	if (LLTrans::getString("Multiple Media") != mHomeURL->getValue()) +		fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue(); +	fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue(); +	fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue();  }  //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 5ad9bf056e..5af26c1ad9 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -59,7 +59,7 @@  static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");  LLPanelOutfitsInventory::LLPanelOutfitsInventory() : -	mInventoryPanel(NULL), +	mActivePanel(NULL),  	mParent(NULL)  {  	mSavedFolderState = new LLSaveFolderState(); @@ -74,12 +74,8 @@ LLPanelOutfitsInventory::~LLPanelOutfitsInventory()  // virtual  BOOL LLPanelOutfitsInventory::postBuild()  { -	mInventoryPanel = getChild<LLInventoryPanel>("outfits_list"); -	mInventoryPanel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE); -	mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); -	mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_MY_OUTFITS); -	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onSelectionChange, this, _1, _2)); +	initAccordionPanels();  	initListCommandsHandlers();  	return TRUE;  } @@ -102,7 +98,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)  {  	if (string == "")  	{ -		mInventoryPanel->setFilterSubString(LLStringUtil::null); +		mActivePanel->setFilterSubString(LLStringUtil::null);  		// re-open folders that were initially open  		mSavedFolderState->setApply(TRUE); @@ -114,7 +110,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)  	gInventory.startBackgroundFetch(); -	if (mInventoryPanel->getFilterSubString().empty() && string.empty()) +	if (mActivePanel->getFilterSubString().empty() && string.empty())  	{  		// current filter and new filter empty, do nothing  		return; @@ -128,7 +124,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)  	}  	// set new filter string -	mInventoryPanel->setFilterSubString(string); +	mActivePanel->setFilterSubString(string);  }  void LLPanelOutfitsInventory::onWear() @@ -148,13 +144,20 @@ void LLPanelOutfitsInventory::onNew()  {  	const std::string& outfit_name = LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_OUTFIT);  	LLUUID outfit_folder = gAgentWearables.makeNewOutfitLinks(outfit_name); +  	getRootFolder()->setSelectionByID(outfit_folder, TRUE);  	getRootFolder()->setNeedsAutoRename(TRUE);  }  void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)  { +	updateListCommands();  	updateParent(); +	if (getRootFolder()->needsAutoRename()) +	{ +		getRootFolder()->startRenamingSelectedItem(); +		getRootFolder()->setNeedsAutoRename(FALSE); +	}  }  void LLPanelOutfitsInventory::onSelectorButtonClicked() @@ -203,7 +206,7 @@ bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *  LLFolderView *LLPanelOutfitsInventory::getRootFolder()  { -	return mInventoryPanel->getRootFolder(); +	return mActivePanel->getRootFolder();  }  ////////////////////////////////////////////////////////////////////////////////// @@ -345,3 +348,67 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy  // List Commands                                                              //  //////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// +// Accordion                                                                    // + +void LLPanelOutfitsInventory::initAccordionPanels() +{ +	mAccordionPanels.resize(2); +	 +	LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_accordionpanel"); +	myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE); +	myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); +	mAccordionPanels[0] = myoutfits_panel; +	mActivePanel = myoutfits_panel; + +	LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>("cof_accordionpanel"); +	cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); +	mAccordionPanels[1] = cof_panel; + +	for (accordionpanels_vec_t::iterator iter = mAccordionPanels.begin(); +		 iter != mAccordionPanels.end(); +		 ++iter) +	{ +		LLInventoryPanel *panel = (*iter); +		panel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onAccordionSelectionChange, this, panel, _1, _2)); +	} +} + +void LLPanelOutfitsInventory::onAccordionSelectionChange(LLInventoryPanel* accordion_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action) +{ +	if (user_action && items.size() > 0) +	{ +		for (accordionpanels_vec_t::iterator iter = mAccordionPanels.begin(); +			 iter != mAccordionPanels.end(); +			 ++iter) +		{ +			LLInventoryPanel *panel = (*iter); +			if (panel == accordion_panel) +			{ +				mActivePanel = panel; +			} +			else +			{ +				panel->getRootFolder()->clearSelection(); +			} +		} +	} +	onSelectionChange(items, user_action); +} + +LLInventoryPanel* LLPanelOutfitsInventory::getActivePanel() +{ +	return mActivePanel; +} + +bool LLPanelOutfitsInventory::isAccordionPanel(LLInventoryPanel *panel) +{ +	for(accordionpanels_vec_t::iterator it = mAccordionPanels.begin(); +		it != mAccordionPanels.end(); +		++it) +	{ +		if (*it == panel) +			return true; +	} +	return false; +} diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 4d903a389b..7769a7d172 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -61,8 +61,6 @@ public:  	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);  	void onSelectorButtonClicked(); -	LLInventoryPanel* getActivePanel() { return mInventoryPanel; } -  	// If a compatible listener type is selected, then return a pointer to that.  	// Otherwise, return NULL.  	LLFolderViewEventListener* getCorrectListenerForAction(); @@ -74,9 +72,26 @@ protected:  private:  	LLSidepanelAppearance*      mParent; -	LLInventoryPanel*			mInventoryPanel;  	LLSaveFolderState*			mSavedFolderState; +public: +	////////////////////////////////////////////////////////////////////////////////// +	// Accordion                                                                    // +	LLInventoryPanel* 	getActivePanel(); +	bool isAccordionPanel(LLInventoryPanel *panel); +	 +protected: +	void 				initAccordionPanels(); +	void 				onAccordionSelectionChange(LLInventoryPanel* accordion_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action); +	 +private: +	LLInventoryPanel* 	mActivePanel; +	typedef std::vector<LLInventoryPanel *> accordionpanels_vec_t; +	accordionpanels_vec_t 		mAccordionPanels; + +	// Accordion                                                                  // +	//////////////////////////////////////////////////////////////////////////////// +	  	//////////////////////////////////////////////////////////////////////////////////  	// List Commands                                                                // @@ -95,7 +110,7 @@ private:  	LLPanel*					mListCommands;  	LLMenuGL*					mMenuGearDefault;  	LLMenuGL*					mMenuAdd; -	//                                                                            // +	// List Commands                                                              //  	////////////////////////////////////////////////////////////////////////////////  }; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index f9e6e5507c..e6b6ec64bd 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -767,7 +767,7 @@ void LLPanelPeople::updateButtons()  	buttonSetEnabled("view_profile_btn",	item_selected);  	buttonSetEnabled("im_btn",				multiple_selected); // allow starting the friends conference for multiple selection  	buttonSetEnabled("call_btn",			multiple_selected); -	buttonSetEnabled("share_btn",			item_selected && false); // not implemented yet +	buttonSetEnabled("share_btn",			item_selected); // not implemented yet  	bool none_group_selected = item_selected && selected_id.isNull();  	buttonSetEnabled("group_info_btn", !none_group_selected); @@ -1220,7 +1220,7 @@ void LLPanelPeople::onTeleportButtonClicked()  void LLPanelPeople::onShareButtonClicked()  { -	// *TODO: not implemented yet +	LLAvatarActions::share(getCurrentItemID());  }  void LLPanelPeople::onMoreButtonClicked() diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 529912929d..71c1b0cbb9 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -510,7 +510,7 @@ void LLPanelPrimMediaControls::updateShape()  				mMediaProgressBar->setPercent(media_plugin->getProgressPercent());  				gFocusMgr.setTopCtrl(mMediaProgressPanel);  			} -			else +			else if (mMediaProgressPanel->getVisible())  			{  				mMediaProgressPanel->setVisible(false);  				gFocusMgr.setTopCtrl(NULL); diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp index b5e55df1f5..32a915608e 100644 --- a/indra/newview/llscrollingpanelparam.cpp +++ b/indra/newview/llscrollingpanelparam.cpp @@ -86,9 +86,8 @@ LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_param  	childSetEnabled("param slider", mAllowModify);  	childSetCommitCallback("param slider", LLScrollingPanelParam::onSliderMoved, this); -	// *TODO: Translate -	std::string min_name = param->getMinDisplayName(); -	std::string max_name = param->getMaxDisplayName(); +	std::string min_name = LLTrans::getString(param->getMinDisplayName()); +	std::string max_name = LLTrans::getString(param->getMaxDisplayName());  	childSetValue("min param text", min_name);  	childSetValue("max param text", max_name); diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 0f8e86cb3c..d5f01418c6 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -32,6 +32,7 @@  #include "llviewerprecompiledheaders.h"  #include "llsidepanelappearance.h" +#include "llaccordionctrltab.h"  #include "llagent.h"  #include "llagentwearables.h"  #include "llappearancemgr.h" @@ -142,6 +143,7 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)  {  	fetchInventory();  	refreshCurrentOutfitName(); +	updateVerbs();  	if(key.size() == 0)  		return; @@ -188,16 +190,22 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()  		return;  	if (!outfit_link->getIsLinkType())  		return; -	LLInventoryPanel *inventory_panel = mPanelOutfitsInventory->getActivePanel(); -	if (inventory_panel) + +	LLAccordionCtrlTab* tab_outfits = mPanelOutfitsInventory->findChild<LLAccordionCtrlTab>("tab_outfits"); +	if (tab_outfits)  	{ -		LLFolderView *folder = inventory_panel->getRootFolder(); -		LLFolderViewItem *outfit_folder = folder->getItemByID(outfit_link->getLinkedUUID()); -		if (outfit_folder) +		tab_outfits->changeOpenClose(FALSE); +		LLInventoryPanel *inventory_panel = tab_outfits->findChild<LLInventoryPanel>("outfitslist_accordionpanel"); +		if (inventory_panel)  		{ -			outfit_folder->setOpen(!outfit_folder->isOpen()); -			folder->setSelectionFromRoot(outfit_folder,TRUE); -			folder->scrollToShowSelection(); +			LLFolderView *folder = inventory_panel->getRootFolder(); +			LLFolderViewItem *outfit_folder = folder->getItemByID(outfit_link->getLinkedUUID()); +			if (outfit_folder) +			{ +				outfit_folder->setOpen(!outfit_folder->isOpen()); +				folder->setSelectionFromRoot(outfit_folder,TRUE); +				folder->scrollToShowSelection(); +			}  		}  	}  } diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 25e0ca46e4..a90f3ee181 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -223,7 +223,16 @@ BOOL LLTexLayerSetBuffer::render()  		}  		else  		{ -			readBackAndUpload(); +			if (mTexLayerSet->isVisible()) +			{ +				readBackAndUpload(); +			} +			else +			{ +				mUploadPending = FALSE; +				mNeedsUpload = FALSE; +				mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE); +			}  		}  	} @@ -551,6 +560,7 @@ LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) :  	mComposite( NULL ),  	mAvatar( avatar ),  	mUpdatesEnabled( FALSE ), +	mIsVisible( TRUE ),  	mInfo( NULL )  {  } @@ -665,38 +675,54 @@ BOOL LLTexLayerSet::isLocalTextureDataFinal() const  BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )  {  	BOOL success = TRUE; +	mIsVisible = TRUE; -	LLGLSUIDefault gls_ui; -	LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); -	gGL.setColorMask(true, true); - -	// clear buffer area to ensure we don't pick up UI elements +	if (mMaskLayerList.size() > 0)  	{ -		gGL.flush(); -		LLGLDisable no_alpha(GL_ALPHA_TEST); -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -		gGL.color4f( 0.f, 0.f, 0.f, 1.f ); -		 -		gl_rect_2d_simple( width, height ); -		 -		gGL.flush(); +		for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) +		{ +			LLTexLayerInterface* layer = *iter; +			if (layer->isInvisibleAlphaMask()) +			{ +				mIsVisible = FALSE; +			} +		}  	} -	// composite color layers -	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) +	if (mIsVisible)  	{ -		LLTexLayerInterface* layer = *iter; -		if (layer->getRenderPass() == LLTexLayer::RP_COLOR) +		LLGLSUIDefault gls_ui; +		LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); +		gGL.setColorMask(true, true); +	 +		// clear buffer area to ensure we don't pick up UI elements  		{  			gGL.flush(); -			success &= layer->render(x, y, width, height); +			LLGLDisable no_alpha(GL_ALPHA_TEST); +			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			gGL.color4f( 0.f, 0.f, 0.f, 1.f ); +			 +			gl_rect_2d_simple( width, height ); +			  			gGL.flush();  		} -	} -	renderAlphaMaskTextures(x, y, width, height, false); - -	stop_glerror(); +		// composite color layers +		for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) +		{ +			LLTexLayerInterface* layer = *iter; +			if (layer->getRenderPass() == LLTexLayer::RP_COLOR) +			{ +				gGL.flush(); +				success &= layer->render(x, y, width, height); +				gGL.flush(); +			} +		} +		 +		renderAlphaMaskTextures(x, y, width, height, false); +	 +		stop_glerror(); +	}  	return success;  } @@ -1709,6 +1735,19 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32  	}  } +/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask() +{ +	if (mLocalTextureObject) +	{ +		if (mLocalTextureObject->getID() == IMG_INVISIBLE) +		{ +			return TRUE; +		} +	} + +	return FALSE; +} +  // private helper function  LLUUID LLTexLayer::getUUID()  { @@ -1898,6 +1937,23 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)  	}  } +/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask() +{ +	U32 num_wearables = updateWearableCache(); +	for (U32 i = 0; i < num_wearables; i++) +	{ +		LLTexLayer *layer = getLayer(i); +		if (layer) +		{ +			 if (layer->isInvisibleAlphaMask()) +			 { +				 return TRUE; +			 } +		} +	} + +	return FALSE; +}  //----------------------------------------------------------------------------- diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index cd8f27a96b..5be58f64a9 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -99,6 +99,7 @@ public:  	virtual void			gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;  	BOOL					hasAlphaParams() const { return !mParamAlphaList.empty(); }  	BOOL					isVisibilityMask() const; +	virtual BOOL			isInvisibleAlphaMask() = 0;  	LLTexLayerSet*			getLayerSet() {return mTexLayerSet;} @@ -141,6 +142,8 @@ public:  	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);  	/*virtual*/ void		setHasMorph(BOOL newval);  	/*virtual*/ void		deleteCaches(); +	/*virtual*/ BOOL		isInvisibleAlphaMask(); +  private:  	U32 	updateWearableCache();  	LLTexLayer* getLayer(U32 i); @@ -173,6 +176,7 @@ public:  	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);  	BOOL					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);  	void					addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height); +	/*virtual*/ BOOL		isInvisibleAlphaMask();  	void					setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }  	LLLocalTextureObject* 	getLTO() { return mLocalTextureObject; } @@ -272,6 +276,7 @@ public:  	BOOL					hasComposite() const { return (mComposite.notNull()); }  	LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }  	void					setBakedTexIndex( LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } +	BOOL					isVisible() const { return mIsVisible; }  public:  	static BOOL		sHasCaches; @@ -284,6 +289,7 @@ private:  	LLPointer<LLTexLayerSetBuffer>	mComposite;  	LLVOAvatarSelf*	const	mAvatar; // Backlink only; don't make this an LLPointer.  	BOOL					mUpdatesEnabled; +	BOOL					mIsVisible;  	LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 8c41133a3a..9dfdf3d5b1 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -169,6 +169,12 @@ public:  			completeAny(status, "text/html");  		}  		else +		if(status == 404) +		{ +			// Treat 404s like an html page. +			completeAny(status, "text/html"); +		} +		else  		{  			llwarns << "responder failed with status " << status << ", reason " << reason << llendl; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 75e35e5221..9882dcd6af 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3868,7 +3868,7 @@ U32 LLVOAvatar::renderRigid()  		return 0;  	} -	if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy) +	if (isTextureVisible(TEX_EYES_BAKED)  || mIsDummy)  	{  		num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy);  		num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy); @@ -7636,15 +7636,19 @@ void LLVOAvatar::idleUpdateRenderCost()  		return;  	} -	U32 shame = 0; +	U32 cost = 0; +	std::set<LLUUID> textures;  	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)  	{  		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);  		ETextureIndex tex_index = baked_dict->mTextureIndex; -		if (isTextureVisible(tex_index)) +		if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(WT_SKIRT)))  		{ -			shame +=20; +			if (isTextureVisible(tex_index)) +			{ +				cost +=20; +			}  		}  	} @@ -7663,20 +7667,22 @@ void LLVOAvatar::idleUpdateRenderCost()  				const LLDrawable* drawable = attached_object->mDrawable;  				if (drawable)  				{ -					shame += 10; +					cost += 10;  					const LLVOVolume* volume = drawable->getVOVolume();  					if (volume)  					{ -						shame += volume->getRenderCost(); +						cost += volume->getRenderCost(textures);  					}  				}  			}  		}  	} -	setDebugText(llformat("%d", shame)); -	F32 green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f); -	F32 red = llmin((F32) shame/1024.f, 1.f); +	cost += textures.size() * 5; + +	setDebugText(llformat("%d", cost)); +	F32 green = 1.f-llclamp(((F32) cost-1024.f)/1024.f, 0.f, 1.f); +	F32 red = llmin((F32) cost/1024.f, 1.f);  	mText->setColor(LLColor4(red,green,0,1));  } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index d9c5e932a2..f3e787ae7e 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -318,11 +318,6 @@ BOOL LLVOAvatarSelf::buildMenus()  				}  			} - -			if (!attachment_found) -			{ -				gAttachPieMenu->addSeparator(); -			}  		}  		if (gDetachBodyPartPieMenus[i]) @@ -362,11 +357,6 @@ BOOL LLVOAvatarSelf::buildMenus()  					break;  				}  			} - -			if (!attachment_found) -			{ -				gDetachPieMenu->addSeparator(); -			}  		}  	} @@ -1849,6 +1839,13 @@ ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const  } +void LLVOAvatarSelf::setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid) +{ +	ETextureIndex index = LLVOAvatarDictionary::bakedToLocalTextureIndex(i); +	setNewBakedTexture(index, uuid); +} + +  //-----------------------------------------------------------------------------  // setNewBakedTexture()  // A new baked texture has been successfully uploaded and we can start using it now. diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index a1cad82eff..e376e5e9ef 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -209,6 +209,7 @@ private:  	//--------------------------------------------------------------------  public:  	LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const; +	void				setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid);  	void				setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);  	void				setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);  	void				forceBakeAllTextures(bool slam_for_debug = false); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 428af5380c..48bd387022 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2566,7 +2566,11 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const  	return mDrawable->getWorldMatrix();  } -U32 LLVOVolume::getRenderCost() const +// Returns a base cost and adds textures to passed in set. +// total cost is returned value + 5 * size of the resulting set. +// Cannot include cost of textures, as they may be re-used in linked +// children, and cost should only be increased for unique textures  -Nyx +U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const  {  	U32 shame = 0; @@ -2599,7 +2603,7 @@ U32 LLVOVolume::getRenderCost() const  	{  		const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);  		LLUUID sculpt_id = sculpt_params->getSculptTexture(); -		shame += 5; +		textures.insert(sculpt_id);  	}  	for (S32 i = 0; i < drawablep->getNumFaces(); ++i) @@ -2608,7 +2612,7 @@ U32 LLVOVolume::getRenderCost() const  		const LLTextureEntry* te = face->getTextureEntry();  		const LLViewerTexture* img = face->getTexture(); -		shame += 5; +		textures.insert(img->getID());  		if (face->getPoolType() == LLDrawPool::POOL_ALPHA)  		{ @@ -2658,7 +2662,7 @@ U32 LLVOVolume::getRenderCost() const  			const LLVOVolume* child_volumep = child_drawablep->getVOVolume();  			if (child_volumep)  			{ -				shame += child_volumep->getRenderCost(); +				shame += child_volumep->getRenderCost(textures);  			}  		}  	} diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 70d203daf2..06e214b41e 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -121,7 +121,7 @@ public:  	const LLMatrix4&	getRelativeXform() const				{ return mRelativeXform; }  	const LLMatrix3&	getRelativeXformInvTrans() const		{ return mRelativeXformInvTrans; }  	/*virtual*/	const LLMatrix4	getRenderMatrix() const; -				U32 	getRenderCost() const; +				U32 	getRenderCost(std::set<LLUUID> &textures) const;  	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index ced0b64896..d92da4ef44 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -421,18 +421,6 @@ BOOL LLWearable::importFile( LLFILE* file )  	// copy all saved param values to working params  	revertValues(); -	// Hack pt 2. If the wearable we just loaded has definition version 24, -	// then force a re-save of this wearable after slamming the version number to 22. -	// This number was incorrectly incremented for internal builds before release, and -	// this fix will ensure that the affected wearables are re-saved with the right version number. -	// the versions themselves are compatible. This code can be removed before release. -	if( mDefinitionVersion == 24 ) -	{ -		mDefinitionVersion = 22; -		U32 index = gAgentWearables.getWearableIndex(this); -		gAgentWearables.saveWearable(mType,index,TRUE); -	} -  	return TRUE;  } diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index 0863adb7f5..43ffa12420 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -82,6 +82,8 @@ public:  	const std::string&			getTypeName() const;  	LLAssetType::EType			getAssetType() const;  	LLLocalTextureObject*		getLocalTextureObject(S32 index) const; +	S32							getDefinitionVersion() const { return mDefinitionVersion; } +	void						setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }  public:  	typedef std::vector<LLVisualParam*> visual_param_vec_t; diff --git a/indra/newview/skins/default/textures/icons/Stop_Off.png b/indra/newview/skins/default/textures/icons/Stop_Off.pngBinary files differ new file mode 100644 index 0000000000..3ee215d36f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Stop_Off.png diff --git a/indra/newview/skins/default/textures/icons/UnZoom_Off.png b/indra/newview/skins/default/textures/icons/UnZoom_Off.pngBinary files differ new file mode 100644 index 0000000000..c794113755 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/UnZoom_Off.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 99f6fc5cb3..3576b6ed77 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -490,6 +490,9 @@ with the same filename but different name    <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true" />    <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true" /> +  <texture name="Stop_Off" file_name="icons/Stop_Off.png" preload="false" /> +  <texture name="Stop_Over" file_name="icons/Stop_Over.png" preload="false" /> +  <texture name="Stop_Press" file_name="icons/Stop_Press.png" preload="false" />    <texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" />    <texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" />    <texture name="StopReload_Press" file_name="icons/StopReload_Press.png" preload="false" /> @@ -607,6 +610,15 @@ with the same filename but different name    <texture name="Zoom_Off" file_name="icons/Zoom_Off.png" preload="false" />    <texture name="Zoom_Over" file_name="icons/Zoom_Over.png" preload="false" />    <texture name="Zoom_Press" file_name="icons/Zoom_Press.png" preload="false" /> +  <texture name="UnZoom_Off" file_name="icons/UnZoom_Off.png" preload="false" /> +  <texture name="UnZoom_Over" file_name="icons/UnZoom_Over.png" preload="false" /> +  <texture name="UnZoom_Press" file_name="icons/UnZoom_Press.png" preload="false" /> +  <texture name="PowerOn_Off" file_name="icons/PowerOn_Off.png" preload="false" /> +  <texture name="PowerOn_Over" file_name="icons/PowerOn_Over.png" preload="false" /> +  <texture name="PowerOn_Press" file_name="icons/PowerOn_Press.png" preload="false" /> +  <texture name="PowerOff_Off" file_name="icons/PowerOff_Off.png" preload="false" /> +  <texture name="PowerOff_Over" file_name="icons/PowerOff_Over.png" preload="false" /> +  <texture name="PowerOff_Press" file_name="icons/PowerOff_Press.png" preload="false" />    <!--WARNING OLD ART *do not use*--> diff --git a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml index 7b52fecef7..d0128d1c9a 100644 --- a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml +++ b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml @@ -12,4 +12,11 @@          <menu_item_call.on_click           function="Profile.Pay" />      </menu_item_call> +    <menu_item_call +     label="Share" +     layout="topleft" +     name="share"> +        <menu_item_call.on_click +         function="Profile.Share" /> +    </menu_item_call>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index e19e11a1b8..9722849690 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1718,6 +1718,8 @@               layout="topleft"               name="Fly"               shortcut="Home"> +                <menu_item_check.on_check +                 function="Agent.getFlying" />                  <menu_item_check.on_click                   function="Agent.toggleFlying" />                  <menu_item_check.on_enable diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a87f05cbcc..1d385b5a9f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3939,6 +3939,18 @@ Would you like to leave Busy Mode before completing this transaction?    <notification     icon="alertmodal.tga" +   name="ConfirmDeleteProtectedCategory" +   type="alertmodal"> +The folder '[FOLDERNAME]' is a system folder. Deleting system folders can cause instability.  Are you sure you want to delete it? +    <usetemplate +     ignoretext="Confirm before I delete a system folder" +     name="okcancelignore" +     notext="Cancel" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="ConfirmEmptyTrash"     type="alertmodal">  Are you sure you want to permanently delete the contents of your Trash? diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml index 73d843e6dd..0a5812882d 100644 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml @@ -38,12 +38,12 @@       label="Teleport"       name="teleport_btn"       width="100" /> -  <!--  <button +   <button       follows="left|top"       height="20"       label="Share"       name="share_btn" -     width="100" />--> +     width="100" />       <!--Removing pay button to save space - will update spec - verified by Erica/Steve -->   <!--   <button       follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml index 686f4ac1d5..e00f654750 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml @@ -93,27 +93,19 @@    </text>    <combo_box      allow_text_entry="false"  -   bottom_delta="-20"  -   enabled="true"  +   bottom_delta="-20"     follows="left|top"     height="18"      left="10"  -   max_chars="20"  -   mouse_opaque="true" +   max_chars="20"     name="controls"      width="120">      <combo_item  -	 type="string"  -	 length="1"  -	 enabled="true"   	 name="Standard"   	 value="Standard">        Standard      </combo_item>      <combo_item  -	 type="string"  -	 length="1"  -	 enabled="true"   	 name="Mini"   	 value="Mini">        Mini diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index f511ec0d6f..d805209bf5 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -6,6 +6,18 @@  	  width="310"  	  border="true"  	  follows="left|top|right|bottom"> +    <accordion +     follows="left|top|right|bottom" +     height="315" +     layout="topleft" +     left="0" +     name="outfits_accordion" +     top="2" +     width="310"> +        <accordion_tab +         layout="topleft" +         name="tab_outfits" +         title="Outfits bar">  	 <inventory_panel   	 	 allow_multi_select="true"   		 border="true"  @@ -14,9 +26,28 @@  		 height="326"   		 left="0"   		 mouse_opaque="true" -	     name="outfits_list" +	     name="outfitslist_accordionpanel"  		 width="310"  		 start_folder="My Outfits"/> +        </accordion_tab> +        <accordion_tab +         layout="topleft" +         name="tab_cof" +         title="Current Outfit bar"> +	 <inventory_panel  +	 	 allow_multi_select="true"  +		 border="true"  +		 bottom="0" +	     follows="left|top|right|bottom"  +		 height="326"  +		 left="0"  +		 mouse_opaque="true" +	     name="cof_accordionpanel" +		 width="310" +		 start_folder="Current Outfit"/> +        </accordion_tab> +	</accordion> +  	<button bottom="0"  		 halign="center"  		 height="16" diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml index 88049fe7d1..af4c01185a 100644 --- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -3,7 +3,7 @@  	follows="left|right|top|bottom"  	name="MediaControls"  	background_visible="false" -	height="160" +	height="192"  	layout="topleft"  	mouse_opaque="false"  	width="800"> @@ -17,44 +17,6 @@  	  mouse_opaque="false"  	  top="20" />    <layout_stack -	  follows="left|right|bottom" -	  height="32" -	  layout="topleft" -	  animate="false" -	  left="0" -	  orientation="horizontal" -	  top="96"> -	<!-- outer layout_panels center the inner one --> -	<layout_panel -		width="0" -		layout="topleft" -		user_resize="false" /> -	<panel -		name="media_progress_indicator" -		height="22" -		layout="topleft" -		visible="false" -		left="0" -		top="0" -		auto_resize="false" -		user_resize="false" -		min_width="100" -		width="200"> -	  <progress_bar -		  name="media_progress_bar" -		  color_bar="1 1 1 0.96" -		  follows="left|right|top" -		  height="16" -		  layout="topleft" -		  left="0" -		  tool_tip="Media is Loading"/> -	</panel> -	<layout_panel -		width="0" -		layout="topleft" -		user_resize="false" /> -  </layout_stack> -  <layout_stack  	  name="media_controls"  	  follows="left|right"  	  animate="false" @@ -152,9 +114,8 @@  		top="2"  		min_width="22"  		width="22"> -	  <!-- The stop button here is temporary artwork -->  	  <button -		  image_overlay="media_btn_stoploading.png" +		  image_overlay="Stop_Off"  		  image_disabled="PushButton_Disabled"  		  image_disabled_selected="PushButton_Disabled"  		  image_selected="PushButton_Selected" @@ -417,8 +378,8 @@ function="MediaCtrl.CommitURL" />  		height="22"  		min_width="22"  		width="22"> -	  <!-- Note: this isn't quite right either...the mute button is not the --> -	  <!-- same as the others because it can't have the "image_overlay" be  --> +	  <!-- Note: this is not quite right either...the mute button is not the --> +	  <!-- same as the others because it cannot have the "image_overlay" be  -->  	  <!-- two different images.  -->  	  <button  		  image_disabled="PushButton_Disabled" @@ -439,7 +400,7 @@ function="MediaCtrl.CommitURL" />  			function="MediaCtrl.ToggleMute" />  	  </button>  	</layout_panel> -	<!-- We don't have a design yet for "volume", so this is a temporary --> +	<!-- We do not have a design yet for "volume", so this is a temporary -->  	<!-- solution.  See DEV-42827. -->  	<layout_panel  		name="volume_up" @@ -609,9 +570,8 @@ function="MediaCtrl.CommitURL" />  		layout="topleft"  		min_width="21"  		width="21" > -	  <!-- There is no "Zoom out" icon, so we use this temporarily -->  	  <button -		  image_overlay="ForwardArrow_Off" +		  image_overlay="UnZoom_Off"  		  image_disabled="PushButton_Disabled"  		  image_disabled_selected="PushButton_Disabled"  		  image_selected="PushButton_Selected" @@ -657,4 +617,41 @@ function="MediaCtrl.CommitURL" />  		layout="topleft"  		user_resize="false" />    </layout_stack> +  <layout_stack +	  follows="left|right|bottom" +	  height="32" +	  layout="topleft" +	  animate="false" +	  left="0" +	  orientation="horizontal" +	  top="150"> +	<!-- outer layout_panels center the inner one --> +	<layout_panel +		width="0" +		layout="topleft" +		user_resize="false" /> +	<panel +		name="media_progress_indicator" +		height="22" +		layout="topleft" +		left="0" +		top="0" +		auto_resize="false" +		user_resize="false" +		min_width="100" +		width="200"> +	  <progress_bar +		  name="media_progress_bar" +		  color_bar="1 1 1 0.96" +		  follows="left|right|top" +		  height="8" +		  layout="topleft" +		  left="0" +		  tool_tip="Media is Loading"/> +	</panel> +	<layout_panel +		width="0" +		layout="topleft" +		user_resize="false" /> +  </layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 51b74307c8..33a6a52f5c 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -49,16 +49,6 @@  				 top="0"  				 width="60" />  			<button -				 enabled="true" -				 follows="bottom|left" -				 height="25" -				 label="Share" -				 layout="topleft" -				 left_pad="5" -				 name="share_btn" -				 top="0" -				 width="60" /> -			<button  				 enabled="false"  				 follows="bottom|left"  				 height="25" diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp index 217889c390..6ff2c9446e 100644 --- a/indra/newview/tests/llmediadataclient_test.cpp +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -191,6 +191,12 @@ public:  	virtual bool isDead() const  		{ return mDead; } +	void setDistanceFromAvatar(F64 val) +		{ mRep["distance"] = val; } +	 +	void setTotalMediaInterest(F64 val) +		{ mRep["interest"] = val; } +  	int getNumBounceBacks() const  		{ return mNumBounceBacks; } @@ -593,6 +599,91 @@ namespace tut  			ensure("queue empty", mdc->isEmpty());  		} -		 +		ensure("refcount of o1", o1->getNumRefs(), 1); +		ensure("refcount of o2", o2->getNumRefs(), 1); +		ensure("refcount of o3", o3->getNumRefs(), 1); +		ensure("refcount of o4", o4->getNumRefs(), 1); +  	} +	 +	////////////////////////////////////////////////////////////////////////////////////////// + +    template<> template<> +    void mediadataclient_object_t::test<9>() +    { +		// +		// Test queue re-ordering +		// +		LOG_TEST(9); +		 +		LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"10.0","1.0")); +		LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"20.0","1.0")); +		LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"30.0","1.0")); +		LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"40.0","1.0")); +		{ +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); +			 +			// queue up all 4 objects.  They should now be in the queue in +			// order 1 through 4, with 4 being at the front of the queue +			mdc->fetchMedia(o1); +			mdc->fetchMedia(o2); +			mdc->fetchMedia(o3); +			mdc->fetchMedia(o4); +			 +			int test_num = 0; +			 +			ensure(STR(test_num) + ". is in queue 1", mdc->isInQueue(o1)); +			ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2)); +			ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3)); +			ensure(STR(test_num) + ". is in queue 4", mdc->isInQueue(o4)); +			ensure(STR(test_num) + ". post records", gPostRecords->size(), 0); +			 +			::pump_timers(); +			++test_num; +			 +			// The first tick should remove the first one  +			ensure(STR(test_num) + ". is not in queue 1", !mdc->isInQueue(o1)); +			ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2)); +			ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3)); +			ensure(STR(test_num) + ". is in queue 4", mdc->isInQueue(o4)); +			ensure(STR(test_num) + ". post records", gPostRecords->size(), 1); +			 +			// Now, pretend that object 4 moved relative to the avatar such +			// that it is now closest +			static_cast<LLMediaDataClientObjectTest*>( +				static_cast<LLMediaDataClientObject*>(o4))->setDistanceFromAvatar(5.0); +			 +			::pump_timers(); +			++test_num; +			 +			// The second tick should still pick off item 2, but then re-sort +			// have picked off object 4 +			ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2)); +			ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3)); +			ensure(STR(test_num) + ". is not in queue 4", !mdc->isInQueue(o4)); +			ensure(STR(test_num) + ". post records", gPostRecords->size(), 2); + +			::pump_timers(); +			++test_num; +			 +			// The third tick should pick off object 2 +			ensure(STR(test_num) + ". is not in queue 2", !mdc->isInQueue(o2)); +			ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3)); +			ensure(STR(test_num) + ". post records", gPostRecords->size(), 3); + +			// The fourth tick should pick off object 3 +			::pump_timers(); +			++test_num; + +			ensure(STR(test_num) + ". is not in queue 3", !mdc->isInQueue(o3)); +			ensure(STR(test_num) + ". post records", gPostRecords->size(), 4); + +			ensure("queue empty", mdc->isEmpty()); +		} +		ensure("refcount of o1", o1->getNumRefs(), 1); +		ensure("refcount of o2", o2->getNumRefs(), 1); +		ensure("refcount of o3", o3->getNumRefs(), 1); +		ensure("refcount of o4", o4->getNumRefs(), 1); +    } +	  } | 
