Automated merge with ssh://hg.lindenlab.com/viewer/viewer-2-0/

meow-7.2.2
Eric M. Tulla (BigPapi) 2009-11-13 19:27:48 -05:00
commit 99dcd4f493
4 changed files with 162 additions and 15 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -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();