From 813b0e7675f0f9fb682831bdf60319f8b584b882 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 14 Oct 2023 12:14:51 +0300 Subject: SL-20232 Allow deletion of worn items #2 --- indra/newview/llinventoryfunctions.cpp | 7 ++-- indra/newview/llinventorygallery.cpp | 64 +++++++++++++++++++++++++++++--- indra/newview/llinventorygallerymenu.cpp | 7 +++- 3 files changed, 68 insertions(+), 10 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 109dffae6b..5e702ef755 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -3024,7 +3024,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); bool marketplacelistings_item = false; - bool worn_item = false; + bool has_worn = false; bool needs_replacement = false; LLAllDescendentsPassedFilter f; for (std::set::iterator it = selected_items.begin(); (it != selected_items.end()) && (f.allDescendentsPassedFilter()); ++it) @@ -3041,7 +3041,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } if (get_is_item_worn(viewModel->getUUID())) { - worn_item = true; + has_worn = true; LLWearableType::EType type = viewModel->getWearableType(); if (type == LLWearableType::WT_SHAPE || type == LLWearableType::WT_SKIN @@ -3058,7 +3058,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { LLNotificationsUtil::add("CantDeleteRequiredClothing"); } - else if (worn_item) + else if (has_worn) { LLSD payload; payload["has_worn"] = true; @@ -3411,6 +3411,7 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con } } } + // 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 diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index 9074c8466a..23a00e2e51 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -1864,6 +1864,8 @@ void LLInventoryGallery::onDelete(const LLSD& notification, const LLSD& response S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { + bool has_worn = notification["payload"]["has_worn"].asBoolean(); + uuid_vec_t worn; for (const LLUUID& id : selected_ids) { LLInventoryObject* obj = gInventory.getObject(id); @@ -1884,22 +1886,72 @@ void LLInventoryGallery::onDelete(const LLSD& notification, const LLSD& response { gInventory.removeItem(id); } + else if (has_worn && get_is_item_worn(id)) + { + worn.push_back(id); + } } } + + if (!worn.empty()) + { + // should fire once after every item gets detached + LLAppearanceMgr::instance().removeItemsFromAvatar(worn, + [worn]() + { + for (const LLUUID& id : worn) + { + remove_inventory_item(id, NULL); + } + }); + } } } void LLInventoryGallery::deleteSelection() { - if (!LLInventoryAction::sDeleteConfirmationDisplayed) // ask for the confirmation at least once per session + bool has_worn = false; + bool needs_replacement = false; + for (const LLUUID& id : mSelectedItemIDs) { - LLNotifications::instance().setIgnored("DeleteItems", false); - LLInventoryAction::sDeleteConfirmationDisplayed = true; + if (get_is_item_worn(id)) + { + has_worn = true; + const LLViewerInventoryItem* item = gInventory.getItem(id); + 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; + } + } } - LLSD args; - args["QUESTION"] = LLTrans::getString("DeleteItem"); - LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs)); + if (needs_replacement) + { + LLNotificationsUtil::add("CantDeleteRequiredClothing"); + } + else if (has_worn) + { + LLSD payload; + payload["has_worn"] = true; + LLNotificationsUtil::add("DeleteWornItems", LLSD(), payload, boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs)); + } + else + { + if (!LLInventoryAction::sDeleteConfirmationDisplayed) // ask for the confirmation at least once per session + { + LLNotifications::instance().setIgnored("DeleteItems", false); + LLInventoryAction::sDeleteConfirmationDisplayed = true; + } + + LLSD args; + args["QUESTION"] = LLTrans::getString("DeleteItem"); + LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs)); + } } bool LLInventoryGallery::canDeleteSelection() diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 50eefc7d25..d4cf9c2f9f 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -542,6 +542,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } items.push_back(std::string("Cut")); items.push_back(std::string("Delete")); + // TODO: check descendants!!! if(!get_is_category_removable(&gInventory, selected_id)) { disabled_items.push_back(std::string("Delete")); @@ -577,11 +578,15 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men { items.push_back(std::string("Delete")); } - if(!get_is_item_removable(&gInventory, selected_id, true)) + if (!get_is_item_removable(&gInventory, selected_id, false)) { disabled_items.push_back(std::string("Delete")); disabled_items.push_back(std::string("Cut")); } + else if(!get_is_item_removable(&gInventory, selected_id, true)) + { + disabled_items.push_back(std::string("Cut")); + } if (selected_item && (selected_item->getInventoryType() != LLInventoryType::IT_CALLINGCARD) && !is_inbox && selected_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) { -- cgit v1.2.3