diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/llagentwearables.cpp | 99 | ||||
| -rw-r--r-- | indra/newview/llagentwearables.h | 2 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 205 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.h | 16 | ||||
| -rw-r--r-- | indra/newview/llfloaterinventory.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.cpp | 123 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.h | 15 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_inventory.xml | 8 | 
13 files changed, 351 insertions, 165 deletions
| diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index c4e01808f7..6eb248ef74 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1172,99 +1172,24 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name,  		return LLUUID::null;  	} -	// First, make a folder in the Clothes directory. +	// First, make a folder in the My Outfits directory. +	LLUUID parent_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_MY_OUTFITS);  	LLUUID folder_id = gInventory.createNewCategory( -		gInventory.findCategoryUUIDForType(LLAssetType::AT_MY_OUTFITS), +		parent_id,  		LLAssetType::AT_OUTFIT,  		new_folder_name); -//	bool found_first_item = false; - -	/////////////////// -	// Wearables +	LLAppearanceManager::shallowCopyCategory(LLAppearanceManager::getCOF(),folder_id, NULL); -	if (wearables_to_include.count()) +#if 0 +	LLViewerInventoryCategory *parent_category = gInventory.getCategory(parent_id); +	if (parent_category)  	{ -		// Then, iterate though each of the wearables and save links to them in the folder. -		S32 i; -		S32 count = wearables_to_include.count(); -		LLDynamicArray<LLUUID> delete_items; -		LLPointer<LLRefCount> cbdone = NULL; -		for (i = 0; i < count; ++i) -		{ -			const S32 type = wearables_to_include[i]; -			for (U32 j=0; j<getWearableCount((EWearableType)i); j++) -			{ -				LLWearable* old_wearable = getWearable((EWearableType)type,j); -				if (old_wearable) -				{ -					LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType) type, j)); -					if (!item) continue; -					LLPointer<LLInventoryCallback> cb = NULL; -					link_inventory_item(gAgent.getID(), -										item->getLinkedUUID(), -										folder_id, -										item->getName(), -										LLAssetType::AT_LINK, -										cb); -				} -			} -		} -		gInventory.notifyObservers(); +		parent_category->setSelectionByID(folder_id,TRUE); +		parent_category->setNeedsAutoRename(TRUE);  	} +#endif - -	/////////////////// -	// Attachments - -	if (attachments_to_include.count()) -	{ -		for (S32 i = 0; i < attachments_to_include.count(); i++) -		{ -			S32 attachment_pt = attachments_to_include[i]; -			LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL); -			if (!attachment) continue; -			LLViewerObject* attached_object = attachment->getObject(); -			if (!attached_object) continue; -			const LLUUID& item_id = attachment->getItemID(); -			if (item_id.isNull()) continue; -			LLInventoryItem* item = gInventory.getItem(item_id); -			if (!item) continue; - -			LLPointer<LLInventoryCallback> cb = NULL; -			link_inventory_item(gAgent.getID(), -								item->getLinkedUUID(), -								folder_id, -								item->getName(), -								LLAssetType::AT_LINK, -								cb); -		} -	}  - -	/////////////////// -	// Gestures - -	/* Disabling this for now, otherwise this adds all your default gestures and all previous -	   active gestures.  Need to rethink the intended behavior. -	for (LLGestureManager::item_map_t::iterator iter = LLGestureManager::instance().mActive.begin(); -		 iter != LLGestureManager::instance().mActive.end(); -		 ++iter) -	{ -		const LLUUID &gesture_id = (*iter).first; -		LLViewerInventoryItem* item = gInventory.getItem(gesture_id); -		if (item) -		{ -			LLPointer<LLInventoryCallback> cb = NULL; -			link_inventory_item(gAgent.getID(), -								item->getUUID(), -								folder_id, -								item->getName(), -								LLAssetType::AT_LINK, -								cb); -		} -	} -	*/ -	  	return folder_id;  } @@ -1759,7 +1684,7 @@ void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed)  	}  } -void LLAgentWearables::userRemoveAllAttachments(void* userdata) +void LLAgentWearables::userRemoveAllAttachments()  {  	LLVOAvatar* avatarp = gAgent.getAvatarObject();  	if (!avatarp) @@ -1819,7 +1744,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra  			msg->nextBlockFast(_PREHASH_HeaderData);  			msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );  			msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); -			msg->addBOOLFast(_PREHASH_FirstDetachAll, true ); +			msg->addBOOLFast(_PREHASH_FirstDetachAll, true ); // BAP changing this doesn't seem to matter?  		}  		const LLInventoryItem* item = obj_item_array.get(i).get(); diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index cb4de555d5..f34b23e220 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -181,7 +181,7 @@ public:  	// MULTI-WEARABLE: assuming one wearable per type.  Need upstream changes.  	static void		userRemoveWearable(void* userdata);	// userdata is EWearableType  	static void		userRemoveAllClothes(void* userdata);	// userdata is NULL -	static void		userRemoveAllAttachments(void* userdata);	// userdata is NULL  +	static void		userRemoveAllAttachments();  	static void		userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);  	BOOL			itemUpdatePending(const LLUUID& item_id) const; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6c234f23fe..74a8d8fe15 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -239,33 +239,25 @@ void LLOutfitFetch::done()  	}  } -class LLUpdateAppearanceOnCount: public LLInventoryCallback +class LLUpdateAppearanceOnDestroy: public LLInventoryCallback  {  public: -	LLUpdateAppearanceOnCount(S32 count): -		mCount(count) +	LLUpdateAppearanceOnDestroy(): +		mFireCount(0)  	{  	} -	virtual ~LLUpdateAppearanceOnCount() +	virtual ~LLUpdateAppearanceOnDestroy()  	{ +		LLAppearanceManager::updateAppearanceFromCOF();  	}  	/* virtual */ void fire(const LLUUID& inv_item)  	{ -		mCount--; -		if (mCount==0) -		{ -			done(); -		} -	} - -	void done() -	{ -		LLAppearanceManager::updateAppearanceFromCOF(); +		mFireCount++;  	}  private: -	S32 mCount; +	U32 mFireCount;  };  struct LLFoundData @@ -362,25 +354,42 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory  }  // Update appearance from outfit folder. -/* static */ void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, bool append, bool follow_folder_links) +/* static */ void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, bool append)  {  	if (!proceed)  		return; -	 -	updateCOFFromOutfit(category, append, follow_folder_links); + +	if (append) +	{ +		updateCOFFromCategory(category, append); // append is true - add non-duplicates to COF. +	} +	else +	{ +		LLViewerInventoryCategory* catp = gInventory.getCategory(category); +		if (catp->getPreferredType() == LLAssetType::AT_NONE || +			LLAssetType::lookupIsEnsembleCategoryType(catp->getPreferredType())) +		{ +			updateCOFFromCategory(category, append);  // append is false - rebuild COF. +		} +		else if (catp->getPreferredType() == LLAssetType::AT_OUTFIT) +		{ +			rebuildCOFFromOutfit(category); +		} +	}  } -// Update COF contents from outfit folder. -/* static */ void LLAppearanceManager::updateCOFFromOutfit(const LLUUID& category, bool append, bool follow_folder_links) +// Append to current COF contents by recursively traversing a folder. +/* static */ void LLAppearanceManager::updateCOFFromCategory(const LLUUID& category, bool append)  { -	// BAP consolidate into one "get all 3 types of descendents" function, use both places. +		// BAP consolidate into one "get all 3 types of descendents" function, use both places.  	LLInventoryModel::item_array_t wear_items; -	LLInventoryModel::item_array_t	obj_items; -	LLInventoryModel::item_array_t	gest_items; +	LLInventoryModel::item_array_t obj_items; +	LLInventoryModel::item_array_t gest_items; +	bool follow_folder_links = false;  	getUserDescendents(category, wear_items, obj_items, gest_items, follow_folder_links);  	// Find all the wearables that are in the category's subtree.	 -	lldebugs << "updateCOFFromOutfit()" << llendl; +	lldebugs << "appendCOFFromCategory()" << llendl;  	if( !wear_items.count() && !obj_items.count() && !gest_items.count())  	{  		LLNotifications::instance().add("CouldNotPutOnOutfit"); @@ -395,31 +404,26 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory  	LLInventoryModel::item_array_t cof_items;  	gInventory.collectDescendents(current_outfit_id, cof_cats, cof_items,  								  LLInventoryModel::EXCLUDE_TRASH); +	// Remove duplicates  	if (append)  	{ -		// Remove duplicates  		removeDuplicateItems(wear_items, cof_items);  		removeDuplicateItems(obj_items, cof_items);  		removeDuplicateItems(gest_items, cof_items);  	} -			 -	if (wear_items.count() > 0 || obj_items.count() > 0) +	S32 total_links = gest_items.count() + wear_items.count() + obj_items.count(); + +	if (!append && total_links > 0)  	{ -		if (!append)  +		// Remove all current outfit folder links since we're now replacing the contents. +		for (S32 i = 0; i < cof_items.count(); ++i)  		{ -			// Remove all current outfit folder links if we're now replacing the contents. -			for (S32 i = 0; i < cof_items.count(); ++i) -			{ -				gInventory.purgeObject(cof_items.get(i)->getUUID()); -			} +			gInventory.purgeObject(cof_items.get(i)->getUUID());  		}  	} -	// BAP should we just link all contents, rather than restricting to these 3 types? - -	S32 total_links = gest_items.count() + wear_items.count() + obj_items.count(); -	LLPointer<LLUpdateAppearanceOnCount> link_waiter = new LLUpdateAppearanceOnCount(total_links); +	LLPointer<LLUpdateAppearanceOnDestroy> link_waiter = new LLUpdateAppearanceOnDestroy;  	// Link all gestures in this folder  	if (gest_items.count() > 0) @@ -469,11 +473,86 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory  			}  		}  	} +} + +/* static */ void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, +														   LLPointer<LLInventoryCallback> cb) +{ +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	gInventory.collectDescendents(src_id, cats, items, +								  LLInventoryModel::EXCLUDE_TRASH); +	for (S32 i = 0; i < items.count(); ++i) +	{ +		const LLViewerInventoryItem* item = items.get(i).get(); +		if (item->getActualType() == LLAssetType::AT_LINK) +		{ +			link_inventory_item(gAgent.getID(), +								item->getLinkedUUID(), +								dst_id, +								item->getName(), +								LLAssetType::AT_LINK, cb); +		} +		else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER) +		{ +			link_inventory_item(gAgent.getID(), +								item->getLinkedUUID(), +								dst_id, +								item->getName(), +								LLAssetType::AT_LINK_FOLDER, cb); +		} +		else +		{ +			copy_inventory_item( +				gAgent.getID(), +				item->getPermissions().getOwner(), +				item->getUUID(), +				dst_id, +				item->getName(), +				cb); +		} +	} +} + +// Replace COF contents from a given outfit folder. +/* static */ void LLAppearanceManager::rebuildCOFFromOutfit(const LLUUID& category) +{ +	lldebugs << "rebuildCOFFromOutfit()" << llendl; + +	// Find all the wearables that are in the category's subtree.	 +	LLInventoryModel::item_array_t items; +	getCOFValidDescendents(category, items); + +	if( items.count() == 0) +	{ +		LLNotifications::instance().add("CouldNotPutOnOutfit"); +		return; +	} +		 +	const LLUUID ¤t_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); +	// Processes that take time should show the busy cursor +	//inc_busy_count(); +		 +	LLInventoryModel::cat_array_t cof_cats; +	LLInventoryModel::item_array_t cof_items; +	gInventory.collectDescendents(current_outfit_id, cof_cats, cof_items, +								  LLInventoryModel::EXCLUDE_TRASH); + +	if (items.count() > 0) +	{ +		// Remove all current outfit folder links since we're now replacing the contents. +		for (S32 i = 0; i < cof_items.count(); ++i) +		{ +			gInventory.purgeObject(cof_items.get(i)->getUUID()); +		} +	} -	// In the particular case that we're switching to a different outfit, -	// create a link to the folder that we wore. +	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; +	LLAppearanceManager::shallowCopyCategory(category, current_outfit_id, link_waiter); + +	// Create a link to the outfit that we wore.  	LLViewerInventoryCategory* catp = gInventory.getCategory(category); -	if (!append && catp && catp->getPreferredType() == LLAssetType::AT_OUTFIT) +	if (catp && catp->getPreferredType() == LLAssetType::AT_OUTFIT)  	{  		link_inventory_item(gAgent.getID(), category, current_outfit_id, catp->getName(),  							LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL)); @@ -621,7 +700,7 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,  	//If the folder doesn't contain only gestures, take off all attachments.  	if (!(wear_items.count() == 0 && obj_items.count() == 0 && gest_items.count() > 0) )  	{ -		LLAgentWearables::userRemoveAllAttachments(NULL); +		LLAgentWearables::userRemoveAllAttachments();  	}  	if( obj_items.count() > 0 ) @@ -635,6 +714,21 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,  	}  } +/* static */  +void LLAppearanceManager::getCOFValidDescendents(const LLUUID& category, +															  LLInventoryModel::item_array_t& items) +{ +	LLInventoryModel::cat_array_t cats; +	LLFindCOFValidItems is_cof_valid; +	bool follow_folder_links = false; +	gInventory.collectDescendentsIf(category, +									cats,  +									items,  +									LLInventoryModel::EXCLUDE_TRASH, +									is_cof_valid,  +									follow_folder_links); +} +  /* static */ void LLAppearanceManager::getUserDescendents(const LLUUID& category,   														  LLInventoryModel::item_array_t& wear_items,  														  LLInventoryModel::item_array_t& obj_items, @@ -708,14 +802,13 @@ void LLAppearanceManager::wearInventoryCategoryOnAvatar( LLInventoryCategory* ca  	lldebugs << "wearInventoryCategoryOnAvatar( " << category->getName()  			 << " )" << llendl; -	bool follow_folder_links = (category->getPreferredType() == LLAssetType::AT_CURRENT_OUTFIT || category->getPreferredType() == LLAssetType::AT_OUTFIT );   	if( gFloaterCustomize )  	{ -		gFloaterCustomize->askToSaveIfDirty(boost::bind(LLAppearanceManager::changeOutfit, _1, category->getUUID(), append, follow_folder_links)); +		gFloaterCustomize->askToSaveIfDirty(boost::bind(LLAppearanceManager::changeOutfit, _1, category->getUUID(), append));  	}  	else  	{ -		LLAppearanceManager::changeOutfit(TRUE, category->getUUID(), append, follow_folder_links ); +		LLAppearanceManager::changeOutfit(TRUE, category->getUUID(), append);  	}  } @@ -767,6 +860,7 @@ void LLAppearanceManager::wearOutfitByName(const std::string& name)  	//dec_busy_count();  } +/* static */  void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )  {  	// BAP add check for already in COF. @@ -779,6 +873,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )  						 cb);  } +/* static */  void LLAppearanceManager::wearEnsemble( LLInventoryCategory* cat, bool do_update )  {  	// BAP add check for already in COF. @@ -791,3 +886,25 @@ void LLAppearanceManager::wearEnsemble( LLInventoryCategory* cat, bool do_update  						 cb);  } +/* static */ +void LLAppearanceManager::removeItemLinks(LLUUID& item_id, bool do_update) +{ +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t item_array; +	gInventory.collectDescendents(LLAppearanceManager::getCOF(), +								  cat_array, +								  item_array, +								  LLInventoryModel::EXCLUDE_TRASH); +	for (S32 i=0; i<item_array.count(); i++) +	{ +		const LLInventoryItem* item = item_array.get(i).get(); +		if (item->getLinkedUUID() == item_id) +		{ +			gInventory.purgeObject(item_array.get(i)->getUUID()); +		} +	} +	if (do_update) +	{ +		LLAppearanceManager::updateAppearanceFromCOF(); +	} +} diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 89b95833d7..2aa10e0bea 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -35,6 +35,7 @@  #include "llsingleton.h"  #include "llinventorymodel.h" +#include "llviewerinventory.h"  class LLWearable;  struct LLWearableHoldingPattern; @@ -44,20 +45,29 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager>  public:  	static void updateAppearanceFromCOF();  	static bool needToSaveCOF(); -	static void changeOutfit(bool proceed, const LLUUID& category, bool append, bool follow_folder_links); -	static void updateCOFFromOutfit(const LLUUID& category, bool append, bool follow_folder_links); +	static void changeOutfit(bool proceed, const LLUUID& category, bool append); +	static void updateCOFFromCategory(const LLUUID& category, bool append); +	static void rebuildCOFFromOutfit(const LLUUID& category);  	static void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);  	static void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);  	static void wearOutfitByName(const std::string& name); +	static void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, +									LLPointer<LLInventoryCallback> cb);  	// Add COF link to individual item.  	static void wearItem(LLInventoryItem* item, bool do_update = true);  	// Add COF link to ensemble folder.  	static void wearEnsemble(LLInventoryCategory* item, bool do_update = true); +	static LLUUID getCOF(); + +	// Remove COF entries +	static void removeItemLinks(LLUUID& item_id, bool do_update = true);  private: -	static LLUUID getCOF(); +	static void getCOFValidDescendents(const LLUUID& category,  +									   LLInventoryModel::item_array_t& items); +									     	static void getUserDescendents(const LLUUID& category,   								   LLInventoryModel::item_array_t& wear_items,  								   LLInventoryModel::item_array_t& obj_items, diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 6a3a6c9514..27eb12b9cc 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -1229,7 +1229,11 @@ BOOL LLInventoryPanel::postBuild()  	// build everything.  	mInventoryObserver = new LLInventoryPanelObserver(this);  	mInventory->addObserver(mInventoryObserver); -	rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD); +	// build view of inventory if inventory ready, otherwise wait for modelChanged() callback +	if (mInventory->isInventoryUsable()) +	{ +		rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD); +	}  	// bit of a hack to make sure the inventory is open.  	mFolders->openFolder(std::string("My Inventory")); @@ -1326,6 +1330,14 @@ void LLInventoryPanel::modelChanged(U32 mask)  	LLFastTimer t2(FTM_REFRESH);  	bool handled = false; + +	// inventory just initialized, do complete build +	if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty()) +	{ +		rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD); +		return; +	} +  	if(mask & LLInventoryObserver::LABEL)  	{  		handled = true; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index eb07078402..40c5a243cc 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1481,8 +1481,8 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  	LLVOAvatarSelf* avatar = gAgent.getAvatarObject();  	if(!avatar) return FALSE; -	// cannot drag categories into library or COF -	if(!isAgentInventory() || isCOFFolder()) +	// cannot drag categories into library +	if(!isAgentInventory())  	{  		return FALSE;  	} @@ -1729,6 +1729,34 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,  	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() == LLAssetType::AT_NONE) || +				 (LLAssetType::lookupIsEnsembleCategoryType(linked_category->getPreferredType())))); +	} +} + +  bool LLFindWearables::operator()(LLInventoryCategory* cat,  								 LLInventoryItem* item)  { @@ -1743,6 +1771,8 @@ bool LLFindWearables::operator()(LLInventoryCategory* cat,  	return FALSE;  } + +  //Used by LLFolderBridge as callback for directory recursion.  class LLRightClickInventoryFetchObserver : public LLInventoryFetchObserver  { @@ -1948,6 +1978,15 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model  		modifyOutfit(FALSE);  		return;  	} +	else if ("wearasensemble" == action) +	{ +		LLInventoryModel* model = getInventoryModel(); +		if(!model) return; +		LLViewerInventoryCategory* cat = getCategory(); +		if(!cat) return; +		LLAppearanceManager::wearEnsemble(cat,true); +		return; +	}  	else if ("addtooutfit" == action)  	{  		modifyOutfit(TRUE); @@ -2277,8 +2316,11 @@ void LLFolderBridge::folderOptionsMenu()  	if(!model) return;  	const LLInventoryCategory* category = model->getCategory(mUUID); -	const bool is_default_folder = category && -		(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())); +	LLAssetType::EType type = category->getPreferredType(); +	const bool is_default_folder = category && LLAssetType::lookupIsProtectedCategoryType(type); +	// BAP change once we're no longer treating regular categories as ensembles. +	const bool is_ensemble = category && (type == LLAssetType::AT_NONE || +										  LLAssetType::lookupIsEnsembleCategoryType(type));  	// calling card related functionality for folders. @@ -2313,6 +2355,10 @@ void LLFolderBridge::folderOptionsMenu()  			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("Take Off Items"));  	}  	hideContextEntries(*mMenu, mItems, disabled_items); @@ -2370,8 +2416,10 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	{  		LLViewerInventoryCategory *cat =  getCategory(); -		if (!isCOFFolder() && cat && -			LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())) +		// 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)) @@ -3983,6 +4031,16 @@ void remove_inventory_category_from_avatar( LLInventoryCategory* category )  	}  } +struct OnRemoveStruct +{ +	LLUUID mUUID; +	LLFolderView *mFolderToDeleteSelected; +	OnRemoveStruct(const LLUUID& uuid, LLFolderView *fv = NULL): +		mUUID(uuid), +		mFolderToDeleteSelected(fv) +	{ +	} +};  void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id)  { @@ -4030,10 +4088,10 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_  				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 LLUUID(item_array.get(i)->getUUID())); +														item_array.get(i)->getName(), +														item_array.get(i)->getType(), +														LLWearableBridge::onRemoveFromAvatarArrived, +														new OnRemoveStruct(item_array.get(i)->getUUID()));  				}  			} @@ -4134,12 +4192,25 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod  		{  			LLViewerInventoryItem* item = getItem();  			if (item) -			{ -				LLWearableList::instance().getAsset(item->getAssetUUID(), -										item->getName(), -									item->getType(), -									LLWearableBridge::onRemoveFromAvatarArrived, -									new LLUUID(mUUID)); +			{	 +				if (item->getIsLinkType() && +					model->isObjectDescendentOf(mUUID,LLAppearanceManager::getCOF())) +				{ +					// Delete link after item has been taken off. +					LLWearableList::instance().getAsset(item->getAssetUUID(), +														item->getName(), +														item->getType(), +														LLWearableBridge::onRemoveFromAvatarArrived, +														new OnRemoveStruct(mUUID, folder)); +				} +				else +				{ +					LLWearableList::instance().getAsset(item->getAssetUUID(), +														item->getName(), +														item->getType(), +														LLWearableBridge::onRemoveFromAvatarArrived, +														new OnRemoveStruct(mUUID)); +				}  			}  		}  	} @@ -4452,11 +4523,12 @@ void LLWearableBridge::onRemoveFromAvatar(void* user_data)  		LLViewerInventoryItem* item = self->getItem();  		if (item)  		{ +			LLUUID parent_id = item->getParentUUID();  			LLWearableList::instance().getAsset(item->getAssetUUID(), -									item->getName(), -								   item->getType(), -								   onRemoveFromAvatarArrived, -								   new LLUUID(self->mUUID)); +												item->getName(), +												item->getType(), +												onRemoveFromAvatarArrived, +												new OnRemoveStruct(LLUUID(self->mUUID)));  		}  	}  } @@ -4465,10 +4537,11 @@ void LLWearableBridge::onRemoveFromAvatar(void* user_data)  void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,  												 void* userdata)  { -	LLUUID* item_id = (LLUUID*) userdata; +	OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata; +	LLUUID item_id = on_remove_struct->mUUID;  	if(wearable)  	{ -		if( gAgentWearables.isWearingItem( *item_id ) ) +		if( gAgentWearables.isWearingItem( item_id ) )  		{  			EWearableType type = wearable->getType(); @@ -4481,7 +4554,11 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,  			}  		}  	} -	delete item_id; +	if (on_remove_struct->mFolderToDeleteSelected) +	{ +		on_remove_struct->mFolderToDeleteSelected->removeSelectedItems(); +	} +	delete on_remove_struct;  }  LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type, diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 4cbf3e169b..2f3171a868 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -474,7 +474,10 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,  			if (item->getActualType() == LLAssetType::AT_LINK_FOLDER)  			{  				LLViewerInventoryCategory *linked_cat = item->getLinkedCategory(); -				if (linked_cat) +				if (linked_cat && linked_cat->getPreferredType() != LLAssetType::AT_OUTFIT) +					// BAP - was  +					// LLAssetType::lookupIsEnsembleCategoryType(linked_cat->getPreferredType())) +					// Change back once ensemble typing is in place.  				{  					if(add(linked_cat,NULL))  					{ @@ -2492,6 +2495,10 @@ void LLInventoryModel::buildParentChildMap()  			// root of the agent's inv found.  			// The inv tree is built.  			mIsAgentInvUsable = true; + +			llinfos << "Inventory initialized, notifying observers" << llendl; +			addChangedMask(LLInventoryObserver::ALL, LLUUID::null); +			notifyObservers();  		}  	}  } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index e3e4f6aca0..91a1906fab 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -731,6 +731,21 @@ protected:  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFindCOFValidItems +// +// Collects items that can be legitimately linked to in the COF. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFindCOFValidItems : public LLInventoryCollectFunctor +{ +public: +	LLFindCOFValidItems() {} +	virtual ~LLFindCOFValidItems() {} +	virtual bool operator()(LLInventoryCategory* cat, +							LLInventoryItem* item); +	 +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLFindWearables  //  // Collects wearables based on item type. diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index dbb3062323..6a55b571ae 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2158,10 +2158,6 @@ bool idle_startup()  		// lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" and fill it with buddies  		LLFriendCardsManager::instance().syncFriendsFolder(); -		llinfos << "Setting Inventory changed mask and notifying observers" << llendl; -		gInventory.addChangedMask(LLInventoryObserver::ALL, LLUUID::null); -		gInventory.notifyObservers(); -  		// set up callbacks  		llinfos << "Registering Callbacks" << llendl;  		LLMessageSystem* msg = gMessageSystem; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2ebf803e5e..9d278e6a6c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2836,7 +2836,7 @@ class LLSelfRemoveAllAttachments : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		LLAgentWearables::userRemoveAllAttachments(NULL); +		LLAgentWearables::userRemoveAllAttachments();  		return true;  	}  }; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1d9ca12af8..92dbb29d8e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -80,6 +80,7 @@  #include "llsky.h"  #include "llanimstatelabels.h"  #include "lltrans.h" +#include "llappearancemgr.h"  #include "llgesturemgr.h" //needed to trigger the voice gesticulations  #include "llvoiceclient.h" @@ -5492,6 +5493,18 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)  			if (isSelf())  			{  				// Then make sure the inventory is in sync with the avatar. + +				// Update COF contents, don't trigger appearance update. +				if (gAgent.getAvatarObject() == NULL) +				{ +					llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl; +				} +				else +				{ +					LLAppearanceManager::removeItemLinks(item_id, false); +				} + +				// BAP - needs to change for label to track link.  				gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);  				gInventory.notifyObservers();  			} diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index dfc82ea8d5..20b8750fbf 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -82,6 +82,7 @@  #include "llgesturemgr.h" //needed to trigger the voice gesticulations  #include "llvoiceclient.h"  #include "llvoicevisualizer.h" // Ventrella +#include "llappearancemgr.h"  #include "boost/lexical_cast.hpp" @@ -983,6 +984,11 @@ LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_obj  	updateAttachmentVisibility(gAgent.getCameraMode());  	// Then make sure the inventory is in sync with the avatar. +	LLViewerInventoryItem *item = gInventory.getItem(attachment->getItemID()); +	if (item) +	{ +		LLAppearanceManager::wearItem(item,false);  // Add COF link for item. +	}  	gInventory.addChangedMask(LLInventoryObserver::LABEL, attachment->getItemID());  	gInventory.notifyObservers(); diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 7762a7f667..72cbd3bcd5 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -457,6 +457,14 @@           function="Inventory.DoToSelected"           parameter="replaceoutfit" />      </menu_item_call> +    <menu_item_call +     label="Wear As Ensemble" +     layout="topleft" +     name="Wear As Ensemble"> +        <menu_item_call.on_click +         function="Inventory.DoToSelected" +         parameter="wearasensemble" /> +    </menu_item_call>      <menu_item_separator       layout="topleft" />      <menu_item_call | 
