Fix link replace creating dirty outfits
parent
be330ca7e0
commit
5df728d42b
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "fsdroptarget.h"
|
||||
#include "llagent.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "lltextbox.h"
|
||||
|
|
@ -147,16 +148,34 @@ void FSFloaterLinkReplace::onStartClicked()
|
|||
mStatusText->setText(getString("ItemsRemaining", args));
|
||||
|
||||
const LLUUID cof_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
|
||||
const LLUUID outfit_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
|
||||
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
if ((*it)->getParentUUID() != cof_folder_id)
|
||||
LLPointer<LLInventoryItem> source_item = *it;
|
||||
|
||||
if (source_item->getParentUUID() != cof_folder_id)
|
||||
{
|
||||
bool is_outfit_folder = gInventory.isObjectDescendentOf(source_item->getParentUUID(), outfit_folder_id);
|
||||
// If either the new or old item in the COF is a wearable, we need to update wearable ordering after the link has been replaced
|
||||
bool needs_wearable_ordering_update = is_outfit_folder && source_item->getType() == LLAssetType::AT_CLOTHING || target_item->getType() == LLAssetType::AT_CLOTHING;
|
||||
// Other items in the COF need a description update (description of the actual link item must be empty)
|
||||
bool needs_description_update = is_outfit_folder && target_item->getType() != LLAssetType::AT_CLOTHING;
|
||||
|
||||
LL_DEBUGS() << "is_outfit_folder = " << (is_outfit_folder ? "true" : "false") << LL_NEWLINE
|
||||
<< "needs_wearable_ordering_update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_NEWLINE
|
||||
<< "needs_description_update = " << (needs_description_update ? "true" : "false") << LL_ENDL;
|
||||
|
||||
LLInventoryObject::const_object_list_t obj_array;
|
||||
obj_array.push_back(LLConstPointer<LLInventoryObject>(target_item));
|
||||
link_inventory_array((*it)->getParentUUID(),
|
||||
link_inventory_array(source_item->getParentUUID(),
|
||||
obj_array,
|
||||
new LLBoostFuncInventoryCallback(boost::bind(&FSFloaterLinkReplace::linkCreatedCallback, this, (*it)->getUUID())));
|
||||
|
||||
new LLBoostFuncInventoryCallback(boost::bind(&FSFloaterLinkReplace::linkCreatedCallback,
|
||||
this,
|
||||
source_item->getUUID(),
|
||||
target_item->getUUID(),
|
||||
needs_wearable_ordering_update,
|
||||
needs_description_update,
|
||||
(is_outfit_folder ? source_item->getParentUUID() : LLUUID::null) )));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -172,10 +191,71 @@ void FSFloaterLinkReplace::onStartClicked()
|
|||
}
|
||||
}
|
||||
|
||||
void FSFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id)
|
||||
void FSFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id,
|
||||
const LLUUID& target_item_id,
|
||||
bool needs_wearable_ordering_update,
|
||||
bool needs_description_update,
|
||||
const LLUUID& outfit_folder_id)
|
||||
{
|
||||
LL_DEBUGS() << "Inventory link replace: old_item_id = " << old_item_id.asString() << LL_ENDL;
|
||||
remove_inventory_object(old_item_id, NULL);
|
||||
LL_DEBUGS() << "Inventory link replace:" << LL_NEWLINE
|
||||
<< " - old_item_id = " << old_item_id.asString() << LL_NEWLINE
|
||||
<< " - target_item_id = " << target_item_id.asString() << LL_NEWLINE
|
||||
<< " - order update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_NEWLINE
|
||||
<< " - description update = " << (needs_description_update ? "true" : "false") << LL_NEWLINE
|
||||
<< " - outfit_folder_id = " << outfit_folder_id.asString() << LL_ENDL;
|
||||
|
||||
// If we are replacing an object, bodypart or gesture link within an outfit folder,
|
||||
// we need to change the actual description of the link itself. LLAppearanceMgr *should*
|
||||
// have created COF links that will be used to save the outfit with an empty description.
|
||||
// Since link_inventory_array() will set the description of the linked item for the link
|
||||
// itself, this will lead to a dirty outfit state when the outfit with the replaced
|
||||
// link is worn. So we have to correct this.
|
||||
if (needs_description_update && outfit_folder_id.notNull())
|
||||
{
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLLinkedItemIDMatches is_target_link(target_item_id);
|
||||
gInventory.collectDescendentsIf(outfit_folder_id,
|
||||
cats,
|
||||
items,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_target_link);
|
||||
|
||||
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
LLPointer<LLViewerInventoryItem> item = *it;
|
||||
|
||||
if ((item->getType() == LLAssetType::AT_BODYPART ||
|
||||
item->getType() == LLAssetType::AT_OBJECT ||
|
||||
item->getType() == LLAssetType::AT_GESTURE)
|
||||
&& !item->getActualDescription().empty())
|
||||
{
|
||||
LL_DEBUGS() << "Updating description for " << item->getName() << LL_ENDL;
|
||||
|
||||
LLSD updates;
|
||||
updates["desc"] = "";
|
||||
update_inventory_item(item->getUUID(), updates, LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_wearable_ordering_update && outfit_folder_id.notNull())
|
||||
{
|
||||
// If a wearable item was involved in the link replace operation and replaced
|
||||
// a link in an outfit folder, we need to update the clothing ordering information
|
||||
// *after* the original link has been removed. LLAppearanceMgr abuses the actual link
|
||||
// description to store the clothing ordering information it. We will have to update
|
||||
// the clothing ordering information or the outfit will be in dirty state when worn.
|
||||
remove_inventory_object(old_item_id, new LLBoostFuncInventoryCallback(boost::bind(&LLAppearanceMgr::updateClothingOrderingInfo,
|
||||
LLAppearanceMgr::getInstance(),
|
||||
outfit_folder_id,
|
||||
LLPointer<LLInventoryCallback>(NULL))));
|
||||
}
|
||||
else
|
||||
{
|
||||
remove_inventory_object(old_item_id, NULL);
|
||||
}
|
||||
|
||||
decreaseOpenItemCount();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ class LLTextBox;
|
|||
|
||||
class FSFloaterLinkReplace : public LLFloater
|
||||
{
|
||||
LOG_CLASS(FSFloaterLinkReplace);
|
||||
|
||||
public:
|
||||
FSFloaterLinkReplace(const LLSD& key);
|
||||
virtual ~FSFloaterLinkReplace();
|
||||
|
|
@ -48,7 +50,12 @@ private:
|
|||
void decreaseOpenItemCount();
|
||||
void updateFoundLinks();
|
||||
|
||||
void linkCreatedCallback(const LLUUID& old_item_id);
|
||||
void linkCreatedCallback(const LLUUID& old_item_id,
|
||||
const LLUUID& target_item_id,
|
||||
bool needs_wearable_ordering_update,
|
||||
bool needs_description_update,
|
||||
const LLUUID& outfit_folder_id);
|
||||
|
||||
void onSourceItemDrop(const LLUUID& source_item_id);
|
||||
void onTargetItemDrop(const LLUUID& target_item_id);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue