summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llinventorybridge.cpp22
-rw-r--r--indra/newview/llinventorybridge.h2
-rw-r--r--indra/newview/llinventoryfunctions.cpp96
-rw-r--r--indra/newview/llinventoryfunctions.h1
4 files changed, 108 insertions, 13 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 4d7fc41ae3..02ca331bff 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2430,7 +2430,7 @@ BOOL LLFolderBridge::isItemRemovable(bool check_worn) const
LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getItemByID(mUUID) : NULL);
if (folderp)
{
- LLIsItemRemovable folder_test;
+ LLIsItemRemovable folder_test(check_worn);
folderp->applyFunctorToChildren(folder_test);
if (!folder_test.mPassed)
{
@@ -6626,6 +6626,26 @@ LLInventoryObject* LLObjectBridge::getObject() const
return object;
}
+LLViewerInventoryItem* LLObjectBridge::getItem() const
+{
+ LLInventoryModel* model = getInventoryModel();
+ if (model)
+ {
+ return model->getItem(mUUID);
+ }
+ return NULL;
+}
+
+LLViewerInventoryCategory* LLObjectBridge::getCategory() const
+{
+ LLInventoryModel* model = getInventoryModel();
+ if (model)
+ {
+ return model->getCategory(mUUID);
+ }
+ return NULL;
+}
+
// virtual
void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
{
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 62e26b2f28..0d87e2b97c 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -524,6 +524,8 @@ public:
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual BOOL renameItem(const std::string& new_name);
LLInventoryObject* getObject() const;
+ LLViewerInventoryItem* getItem() const;
+ LLViewerInventoryCategory* getCategory() const;
protected:
static LLUUID sContextMenuItemID; // Only valid while the context menu is open.
U32 mAttachPt;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 5e702ef755..849f641758 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -579,9 +579,8 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id)
return FALSE;
}
-BOOL get_is_item_worn(const LLUUID& id)
+BOOL get_is_item_worn(const LLUUID& id, const LLViewerInventoryItem* item)
{
- const LLViewerInventoryItem* item = gInventory.getItem(id);
if (!item)
return FALSE;
@@ -619,6 +618,21 @@ BOOL get_is_item_worn(const LLUUID& id)
return FALSE;
}
+BOOL get_is_item_worn(const LLUUID& id)
+{
+ const LLViewerInventoryItem* item = gInventory.getItem(id);
+ return get_is_item_worn(item);
+}
+
+BOOL get_is_item_worn(const LLViewerInventoryItem* item)
+{
+ if (!item)
+ {
+ return FALSE;
+ }
+ return get_is_item_worn(item->getUUID(), item);
+}
+
BOOL get_can_item_be_worn(const LLUUID& id)
{
const LLViewerInventoryItem* item = gInventory.getItem(id);
@@ -3034,15 +3048,47 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
folder->applyFunctorRecursively(f);
}
LLFolderViewModelItemInventory * viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
- if (viewModel && gInventory.isObjectDescendentOf(viewModel->getUUID(), marketplacelistings_id))
+ LLUUID obj_id = viewModel->getUUID();
+ if (viewModel && gInventory.isObjectDescendentOf(obj_id, marketplacelistings_id))
{
marketplacelistings_item = true;
break;
}
- if (get_is_item_worn(viewModel->getUUID()))
+
+ LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id);
+ if (cat)
+ {
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendents(obj_id, categories, items, FALSE);
+
+ for (LLInventoryModel::item_array_t::value_type& item : items)
+ {
+ if (get_is_item_worn(item))
+ {
+ has_worn = true;
+ LLWearableType::EType type = item->getWearableType();
+ if (type == LLWearableType::WT_SHAPE
+ || type == LLWearableType::WT_SKIN
+ || type == LLWearableType::WT_HAIR
+ || type == LLWearableType::WT_EYES)
+ {
+ needs_replacement = true;
+ break;
+ }
+ }
+ }
+ if (needs_replacement)
+ {
+ break;
+ }
+ }
+ LLViewerInventoryItem* item = gInventory.getItem(obj_id);
+ if (item && get_is_item_worn(item))
{
has_worn = true;
- LLWearableType::EType type = viewModel->getWearableType();
+ LLWearableType::EType type = item->getWearableType();
if (type == LLWearableType::WT_SHAPE
|| type == LLWearableType::WT_SKIN
|| type == LLWearableType::WT_HAIR
@@ -3381,6 +3427,7 @@ void LLInventoryAction::removeItemFromDND(LLFolderView* root)
}
}
}
+
void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -3394,6 +3441,7 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con
// removeSelectedItems will change selection, collect worn items beforehand
uuid_vec_t worn;
+ uuid_vec_t deletion_list;
if (has_worn)
{
//Get selected items
@@ -3403,18 +3451,42 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con
//from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
for (LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
{
- LLObjectBridge* view_model = dynamic_cast<LLObjectBridge*>((*it)->getViewModelItem());
+ LLFolderViewModelItemInventory* viewModel = dynamic_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem());
+
+ LLUUID obj_id = viewModel->getUUID();
+ LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id);
+ bool cat_has_worn = false;
+ if (cat)
+ {
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendents(obj_id, categories, items, FALSE);
- if (view_model && get_is_item_worn(view_model->getUUID()))
+ for (LLInventoryModel::item_array_t::value_type& item : items)
+ {
+ if (get_is_item_worn(item))
+ {
+ worn.push_back(item->getUUID());
+ cat_has_worn = true;
+ }
+ }
+ if (cat_has_worn)
+ {
+ deletion_list.push_back(obj_id);
+ }
+ }
+ LLViewerInventoryItem* item = gInventory.getItem(obj_id);
+ if (item && get_is_item_worn(item))
{
- worn.push_back(view_model->getUUID());
+ worn.push_back(obj_id);
+ deletion_list.push_back(obj_id);
}
}
}
- // TODO: collect worn items from content and folders that neede to be deleted after that
// removeSelectedItems will check if items are worn before deletion,
- // don't 'unwear' yet to prevent a race condition from unwearing
+ // don't 'unwear' yet to prevent race conditions from unwearing
// and removing simultaneously
folder_root->removeSelectedItems();
@@ -3423,9 +3495,9 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con
{
// should fire once after every item gets detached
LLAppearanceMgr::instance().removeItemsFromAvatar(worn,
- [worn]()
+ [deletion_list]()
{
- for (const LLUUID& id : worn)
+ for (const LLUUID& id : deletion_list)
{
remove_inventory_item(id, NULL);
}
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index cac1d77f5e..a8a9bb9735 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -47,6 +47,7 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id);
// Is this item or its baseitem is worn, attached, etc...
BOOL get_is_item_worn(const LLUUID& id);
+BOOL get_is_item_worn(const LLViewerInventoryItem* item);
// Could this item be worn (correct type + not already being worn)
BOOL get_can_item_be_worn(const LLUUID& id);