Automated merge with ssh://hg.lindenlab.com/viewer/viewer-2-0/
commit
99dcd4f493
|
|
@ -84,6 +84,26 @@ protected:
|
|||
void processWearablesMessage();
|
||||
};
|
||||
|
||||
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;
|
||||
|
|
@ -903,6 +923,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
|
|||
// will call done for us when everything is here.
|
||||
gInventory.addObserver(outfit);
|
||||
}
|
||||
|
||||
gAgentWearables.populateMyOutfitsFolder();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2002,18 +2024,142 @@ 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;
|
||||
}
|
||||
|
||||
void LLInitialWearablesFetch::done()
|
||||
{
|
||||
// No longer need this observer hanging around.
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
|
||||
// Fetch the wearable items from the Current Outfit Folder
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
LLFindWearables is_wearable;
|
||||
gInventory.collectDescendentsIf(mCompleteFolders.front(), cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH, is_wearable);
|
||||
|
||||
|
||||
LLAppearanceManager::setAttachmentInvLinkEnable(true);
|
||||
if (wearable_array.count() > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -322,10 +322,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())
|
||||
|
|
@ -338,9 +338,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_CATEGORY == preferred_type)
|
||||
{
|
||||
return root_id;
|
||||
|
|
|
|||
|
|
@ -252,13 +252,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
|
||||
|
|
@ -409,7 +408,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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue