From dd7f0e2954a80e39eba50b7a06e167a50a248632 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Fri, 13 Mar 2015 16:55:19 -0400
Subject: [PATCH] MAINT-4980 WIP - moved canAddWearables() to LLAppearanceMgr

---
 indra/llui/llfolderview.cpp           | 21 +++---------
 indra/newview/llappearancemgr.cpp     | 43 ++++++++++++++++++++++++
 indra/newview/llappearancemgr.h       |  3 ++
 indra/newview/llinventorybridge.cpp   |  2 +-
 indra/newview/llwearableitemslist.cpp | 48 ++-------------------------
 indra/newview/llwearableitemslist.h   |  2 --
 6 files changed, 53 insertions(+), 66 deletions(-)

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 7f0d486981..0fb163c73a 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1809,14 +1809,6 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
 		(*menu_itor)->setEnabled(TRUE);
 	}
 
-
-	// FIXME this item-by-item approach does not allow options to be
-	// enabled/disabled based on the selection as a whole - for
-	// example, if avatar has room for one more wearable, and the
-	// selection includes two wearables, add should be disabled.
-	// canAddWearables() in llwearableitemslist.cpp has a more
-	// holistic approach to this.
-
 	// Successively filter out invalid options
 	U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0);
 	U32 flags = multi_select_flag | FIRST_SELECTED_ITEM;
@@ -1829,19 +1821,14 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
 		flags = multi_select_flag;
 	}
 
+	// This adds a check for restrictions based on the entire
+	// selection set - for example, any one wearable may not push you
+	// over the limit, but all wearables together still might.
     if (getFolderViewGroupedItemModel())
     {
         getFolderViewGroupedItemModel()->groupFilterContextMenu(mSelectedItems,*menu);
     }
-#if 0
-    selected_items_t::iterator item_itor = mSelectedItems.begin();
-    if (item_itor != mSelectedItems.end())
-    {
-		LLFolderViewItem* selected_item = (*item_itor);
-		selected_item->getViewModelItem()->groupFilterContextMenu(mSelectedItems,*menu);
-    }
-#endif
-    
+
 	addNoOptions(menu);
 }
 
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index b5af1af5bc..2c166b6001 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1782,6 +1782,49 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
 	return items.size() > 0;
 }
 
+// Moved from LLWearableList::ContextMenu for wider utility.
+bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
+{
+	// TODO: investigate wearables may not be loaded at this point EXT-8231
+
+	U32 n_objects = 0;
+	U32 n_clothes = 0;
+
+	// Count given clothes (by wearable type) and objects.
+	for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
+	{
+		LLViewerInventoryItem* item = gInventory.getItem(*it);
+		if (!item)
+		{
+			return false;
+		}
+
+		if (item->getType() == LLAssetType::AT_OBJECT)
+		{
+			++n_objects;
+		}
+		else if (item->getType() == LLAssetType::AT_CLOTHING)
+		{
+			++n_clothes;
+		}
+		else
+		{
+			LL_WARNS() << "Unexpected wearable type" << LL_ENDL;
+			return false;
+		}
+	}
+
+	// Check whether we can add all the objects.
+	if (!isAgentAvatarValid() || !gAgentAvatarp->canAttachMoreObjects(n_objects))
+	{
+		return false;
+	}
+
+	// Check whether we can add all the clothes.
+    U32 sum_clothes = n_clothes + gAgentWearables.getClothingLayerCount();
+    return sum_clothes <= LLAgentWearables::MAX_CLOTHING_LAYERS;
+}
+
 void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> cb)
 {
 	LLInventoryModel::cat_array_t cats;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 399cd6388f..10d97bb8cb 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -100,6 +100,9 @@ public:
 	// Determine whether we can replace current outfit with the given one.
 	bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
 
+    // Can we add all referenced items to the avatar?
+    bool canAddWearables(const uuid_vec_t& item_ids);
+    
 	// Copy all items in a category.
 	void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
 									 LLPointer<LLInventoryCallback> cb);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 3ec8bb0ab9..cd45d0a4f3 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -6515,7 +6515,7 @@ void LLFolderViewGroupedItemBridge::groupFilterContextMenu(folder_view_item_dequ
 	menuentry_vec_t disabled_items;
     if (get_selection_item_uuids(selected_items, ids))
     {
-        if (!LLWearableItemsList::ContextMenu::canAddWearables(ids))
+        if (!LLAppearanceMgr::instance().canAddWearables(ids))
         {
 			disabled_items.push_back(std::string("Wearable Add"));
         }
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 98559e7782..888ead0613 100755
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -894,13 +894,13 @@ 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",			canAddWearables(ids));
+	setMenuItemEnabled(menu, "wear_add",			LLAppearanceMgr::instance().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);
 	setMenuItemEnabled(menu, "edit",				n_editable == 1 && n_worn == 1 && n_items == 1);
 	setMenuItemVisible(menu, "create_new",			mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1);
-	setMenuItemEnabled(menu, "create_new",			canAddWearables(ids));
+	setMenuItemEnabled(menu, "create_new",			LLAppearanceMgr::instance().canAddWearables(ids));
 	setMenuItemVisible(menu, "show_original",		!standalone);
 	setMenuItemEnabled(menu, "show_original",		n_items == 1 && n_links == n_items);
 	setMenuItemVisible(menu, "take_off",			mask == MASK_CLOTHING && n_worn == n_items);
@@ -1004,48 +1004,4 @@ void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id)
 	LLAgentWearables::createWearable(item->getWearableType(), true);
 }
 
-// Returns true if all the given objects and clothes can be added.
-// static
-bool LLWearableItemsList::ContextMenu::canAddWearables(const uuid_vec_t& item_ids)
-{
-	// TODO: investigate wearables may not be loaded at this point EXT-8231
-
-	U32 n_objects = 0;
-	U32 n_clothes = 0;
-
-	// Count given clothes (by wearable type) and objects.
-	for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
-	{
-		LLViewerInventoryItem* item = gInventory.getItem(*it);
-		if (!item)
-		{
-			return false;
-		}
-
-		if (item->getType() == LLAssetType::AT_OBJECT)
-		{
-			++n_objects;
-		}
-		else if (item->getType() == LLAssetType::AT_CLOTHING)
-		{
-			++n_clothes;
-		}
-		else
-		{
-			LL_WARNS() << "Unexpected wearable type" << LL_ENDL;
-			return false;
-		}
-	}
-
-	// Check whether we can add all the objects.
-	if (!isAgentAvatarValid() || !gAgentAvatarp->canAttachMoreObjects(n_objects))
-	{
-		return false;
-	}
-
-	// Check whether we can add all the clothes.
-    U32 sum_clothes = n_clothes + gAgentWearables.getClothingLayerCount();
-    return sum_clothes <= LLAgentWearables::MAX_CLOTHING_LAYERS;
-}
-
 // EOF
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index eb975b6301..715c249616 100755
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -410,8 +410,6 @@ public:
 		ContextMenu();
 		/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
 
-        // FIXME logic should live somewhere more generally useful.
-		static bool canAddWearables(const uuid_vec_t& item_ids);
 	protected:
 		enum {
 			MASK_CLOTHING		= 0x01,
-- 
GitLab