diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llagentwearables.cpp | 146 | ||||
| -rw-r--r-- | indra/newview/llagentwearables.h | 6 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.h | 11 | 
4 files changed, 160 insertions, 13 deletions
| diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 17e7eea2f1..a6664778fb 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -87,6 +87,26 @@ protected:  	static void onIdle(void *userdata);  }; +class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver +{ +public: +	enum ELibraryOutfitFetchStep { +		LOFS_FOLDER = 0, +		LOFS_OUTFITS, +		LOFS_CONTENTS +	}; +	LLLibraryOutfitsFetch() : mCurrFetchStep(LOFS_FOLDER), mOutfitsPopulated(false) {} +	~LLLibraryOutfitsFetch() {} +	virtual void done();	 +protected: +	void folderDone(void); +	void outfitsDone(void); +	void contentsDone(void); +	enum ELibraryOutfitFetchStep mCurrFetchStep; +	std::vector< std::pair< LLUUID, std::string > > mOutfits; +	bool mOutfitsPopulated; +}; +  LLAgentWearables gAgentWearables;  BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; @@ -906,6 +926,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs  			// will call done for us when everything is here.  			gInventory.addObserver(outfit);  		} +		 +		gAgentWearables.populateMyOutfitsFolder();  	}  } @@ -2005,6 +2027,130 @@ void LLAgentWearables::updateServer()  	gAgent.sendAgentSetAppearance();  } +void LLAgentWearables::populateMyOutfitsFolder(void) +{	 +	LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(); +	 +	// What we do here is get the complete information on the items in +	// the inventory, and set up an observer that will wait for that to +	// happen. +	LLInventoryFetchDescendentsObserver::folder_ref_t folders; +	const LLUUID my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + +	folders.push_back(my_outfits_id); +	outfits->fetchDescendents(folders); +	if(outfits->isEverythingComplete()) +	{ +		// everything is already here - call done. +		outfits->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(outfits); +	} +} + +void LLLibraryOutfitsFetch::done() +{ +	switch (mCurrFetchStep){ +		case LOFS_FOLDER: +			mCurrFetchStep = LOFS_OUTFITS; +			folderDone(); +			break; +		case LOFS_OUTFITS: +			mCurrFetchStep = LOFS_CONTENTS; +			outfitsDone(); +			break; +		case LOFS_CONTENTS: +			// No longer need this observer hanging around. +			gInventory.removeObserver(this); +			contentsDone(); +			break; +		default: +			gInventory.removeObserver(this); +			delete this; +			return; +	} +	if (mOutfitsPopulated) +	{ +		delete this; +	} +} + +void LLLibraryOutfitsFetch::folderDone(void) +{ +	// Early out if we already have items in My Outfits. +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t wearable_array; +	gInventory.collectDescendents(mCompleteFolders.front(), cat_array, wearable_array,  +								  LLInventoryModel::EXCLUDE_TRASH); +	if (cat_array.count() > 0 || wearable_array.count() > 0) +	{ +		mOutfitsPopulated = true; +		gInventory.removeObserver(this); +		return; +	} +	 +	// Get the UUID of the library's clothing folder +	const LLUUID library_clothing_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true); +	 +	mCompleteFolders.clear(); +	 +	// What we do here is get the complete information on the items in +	// the inventory, and set up an observer that will wait for that to +	// happen. +	LLInventoryFetchDescendentsObserver::folder_ref_t folders; +	folders.push_back(library_clothing_id); +	fetchDescendents(folders); +	if(isEverythingComplete()) +	{ +		// everything is already here - call done. +		outfitsDone(); +	} +} + +void LLLibraryOutfitsFetch::outfitsDone(void) +{ +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t wearable_array; +	gInventory.collectDescendents(mCompleteFolders.front(), cat_array, wearable_array,  +								  LLInventoryModel::EXCLUDE_TRASH); +	 +	LLInventoryFetchDescendentsObserver::folder_ref_t folders; +	for(S32 i = 0; i < cat_array.count(); ++i) +	{ +		if (cat_array.get(i)->getName() != "More Outfits" && cat_array.get(i)->getName() != "Ruth"){ +			folders.push_back(cat_array.get(i)->getUUID()); +			mOutfits.push_back( std::make_pair(cat_array.get(i)->getUUID(), cat_array.get(i)->getName() )); +		} +	} +	mCompleteFolders.clear(); +	fetchDescendents(folders); +	if(isEverythingComplete()) +	{ +		// everything is already here - call done. +		contentsDone(); +	} +} + +void LLLibraryOutfitsFetch::contentsDone(void) +{ +	for(S32 i = 0; i < mOutfits.size(); ++i) +	{ +		// First, make a folder in the My Outfits directory. +		const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +		LLUUID folder_id = gInventory.createNewCategory(parent_id, +														LLFolderType::FT_OUTFIT, +														mOutfits[i].second); +		 +		LLAppearanceManager::shallowCopyCategory(mOutfits[i].first, folder_id, NULL); +		gInventory.notifyObservers(); +	} +	mOutfitsPopulated = true; +} +  //--------------------------------------------------------------------  // InitialWearablesFetch  //  diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 9017c25fc6..8f3a16501e 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -169,9 +169,11 @@ public:  								  const LLDynamicArray<S32>& attachments_to_include,  								  BOOL rename_clothing); -	// Note:	wearables_to_include should be a list of EWearableType types -	//			attachments_to_include should be a list of attachment points  	LLUUID			makeNewOutfitLinks(const std::string& new_folder_name); +	 +	// Should only be called if we *know* we've never done so before, since users may +	// not want the Library outfits to stay in their quick outfit selector and can delete them. +	void			populateMyOutfitsFolder(void);  private:  	void			makeNewOutfitDone(S32 type, U32 index);  diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index a8e5c4c216..38a417f1a2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -307,10 +307,10 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)  // specifies 'type' as what it defaults to containing. The category is  // not necessarily only for that type. *NOTE: This will create a new  // inventory category on the fly if one does not exist. -const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType t, bool create_folder) +const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType t, bool create_folder, bool find_in_library)  { -	const LLUUID &rv = findCatUUID(t); -	if(rv.isNull() && isInventoryUsable() && create_folder) +	const LLUUID &rv = findCatUUID(t, find_in_library); +	if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library))  	{  		const LLUUID &root_id = gInventory.getRootFolderID();  		if(root_id.notNull()) @@ -323,9 +323,9 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType t, bo  // Internal method which looks for a category with the specified  // preferred type. Returns LLUUID::null if not found. -const LLUUID &LLInventoryModel::findCatUUID(LLFolderType::EType preferred_type) const +const LLUUID &LLInventoryModel::findCatUUID(LLFolderType::EType preferred_type, bool find_in_library) const  { -	const LLUUID &root_id = gInventory.getRootFolderID(); +	const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID();  	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)  	{  		return root_id; diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 3c1f606d5c..aa4ffb392f 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -247,13 +247,12 @@ public:  	// findCategoryUUIDForType() returns the uuid of the category that  	// specifies 'type' as what it defaults to containing. The -	// category is not necessarily only for that type. *NOTE: This -	// will create a new inventory category on the fly if one does not -	// exist. - +	// category is not necessarily only for that type. *NOTE: If create_folder is true, this +	// will create a new inventory category on the fly if one does not exist. *NOTE: if find_in_library is +	// true it will search in the user's library folder instead of "My Inventory"  	// SDK: Added flag to specify whether the folder should be created if not found.  This fixes the horrible  	// multiple trash can bug. -	const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder = true); +	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 @@ -404,7 +403,7 @@ protected:  	//   	// Internal method which looks for a category with the specified  	// preferred type. Returns LLUUID::null if not found - 	const LLUUID &findCatUUID(LLFolderType::EType preferred_type) const; + 	const LLUUID &findCatUUID(LLFolderType::EType preferred_type, bool find_in_library = false) const;  	// Empty the entire contents  	void empty(); | 
