diff options
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 22 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.h | 2 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 96 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.h | 1 |
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); |