From 554d543b020cfd8e99322c57806b19247bce2f8b Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Mon, 9 Aug 2010 18:10:36 +0300 Subject: EXT-8577 FIXED Context menu items for multi-attachments Changes: * Implemented bulk-add from My Appearance SP. * Made sure there's no memleak when you click Wear/Attach in the in-world object context menu and the callback isn't invoked (because e.g. avatar fails to get close enough to the object). I stated that in comments. Reviewed by Seraph at https://codereview.productengine.com/secondlife/r/844/ --HG-- branch : product-engine --- indra/newview/llwearableitemslist.cpp | 56 +++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 13 deletions(-) (limited to 'indra/newview/llwearableitemslist.cpp') diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 194213f880..e2a5489fcf 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -869,7 +869,7 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu setMenuItemVisible(menu, "wear_wear", n_already_worn == 0 && n_worn == 0 && can_be_worn); setMenuItemEnabled(menu, "wear_wear", n_already_worn == 0 && n_worn == 0); setMenuItemVisible(menu, "wear_add", wear_add_visible); - setMenuItemEnabled(menu, "wear_add", n_items == 1 && canAddWearable(ids.front())); + setMenuItemEnabled(menu, "wear_add", canAddWearables(ids)); setMenuItemVisible(menu, "wear_replace", n_worn == 0 && n_already_worn != 0 && can_be_worn); //visible only when one item selected and this item is worn setMenuItemVisible(menu, "edit", !standalone && mask & (MASK_CLOTHING|MASK_BODYPART) && n_worn == n_items && n_worn == 1); @@ -978,31 +978,61 @@ void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id) LLAgentWearables::createWearable(item->getWearableType(), true); } -// Can we wear another wearable of the given item's wearable type? +// Returns true if all the given objects and clothes can be added. // static -bool LLWearableItemsList::ContextMenu::canAddWearable(const LLUUID& item_id) +bool LLWearableItemsList::ContextMenu::canAddWearables(const uuid_vec_t& item_ids) { // TODO: investigate wearables may not be loaded at this point EXT-8231 - LLViewerInventoryItem* item = gInventory.getItem(item_id); - if (!item) + U32 n_objects = 0; + boost::unordered_map clothes_by_type; + + // Count given clothes (by wearable type) and objects. + for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it) { - return false; + LLViewerInventoryItem* item = gInventory.getItem(*it); + if (!item) + { + return false; + } + + if (item->getType() == LLAssetType::AT_OBJECT) + { + ++n_objects; + } + else if (item->getType() == LLAssetType::AT_CLOTHING) + { + ++clothes_by_type[item->getWearableType()]; + } + else + { + llwarns << "Unexpected wearable type" << llendl; + return false; + } } - if (item->getType() == LLAssetType::AT_OBJECT) + // Check whether we can add all the objects. + if (!isAgentAvatarValid() || !gAgentAvatarp->canAttachMoreObjects(n_objects)) { - // *TODO: is this the right check? - return isAgentAvatarValid() && gAgentAvatarp->canAttachMoreObjects(); + return false; } - if (item->getType() != LLAssetType::AT_CLOTHING) + // Check whether we can add all the clothes. + boost::unordered_map::const_iterator m_it; + for (m_it = clothes_by_type.begin(); m_it != clothes_by_type.end(); ++m_it) { - return false; + LLWearableType::EType w_type = m_it->first; + U32 n_clothes = m_it->second; + + U32 wearable_count = gAgentWearables.getWearableCount(w_type); + if ((wearable_count + n_clothes) > LLAgentWearables::MAX_CLOTHING_PER_TYPE) + { + return false; + } + } - U32 wearable_count = gAgentWearables.getWearableCount(item->getWearableType()); - return wearable_count < LLAgentWearables::MAX_CLOTHING_PER_TYPE; + return true; } // EOF -- cgit v1.2.3