summaryrefslogtreecommitdiff
path: root/indra/newview/llappearancemgr.cpp
diff options
context:
space:
mode:
authorBradley Payne <vir@lindenlab.com>2009-09-24 18:05:38 +0000
committerBradley Payne <vir@lindenlab.com>2009-09-24 18:05:38 +0000
commit7eca974a11cba4c4ed0bc89bccb937b044770c29 (patch)
treee655f479d446715e921731180b37d01be426483b /indra/newview/llappearancemgr.cpp
parent7b2737e0e14f815e69da7114dda693cdaea2c341 (diff)
Merging down avatar-pipeline/currently-worn-folder-8. Includes fixes for EXT-1121: Attaching / detaching objects doesn't affect the Current Outfit folder, and EXT-1090: Attachments detach on login, as well as work in progress for ensemble support and look details.
Diffstat (limited to 'indra/newview/llappearancemgr.cpp')
-rw-r--r--indra/newview/llappearancemgr.cpp205
1 files changed, 161 insertions, 44 deletions
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 &current_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();
+ }
+}