From 73db0816e0a12d74c36ffdb64df6c745f7f39e9e Mon Sep 17 00:00:00 2001
From: Sergei Litovchuk <slitovchuk@productengine.com>
Date: Thu, 23 Sep 2010 01:34:51 +0300
Subject: STORM-199 FIXED Added wearing an object from Library if it was
 dragged to COF - Disabled moving items from in-world objects to COF or outfit
 folders not to create copies of items instead of links. - Enabled dropping a
 landmark from Library to certain position in Favorites folder which supports
 items reordering.

---
 indra/newview/llinventorybridge.cpp | 166 +++++++++++++++++++++++-------------
 indra/newview/llinventorybridge.h   |   2 +
 2 files changed, 109 insertions(+), 59 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 311d791319..569dfc08e2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2856,6 +2856,66 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
 	return false;
 }
 
+// Returns true if the item can be moved to Current Outfit or any outfit folder.
+static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
+{
+	if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) &&
+		(inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) &&
+		(inv_item->getInventoryType() != LLInventoryType::IT_OBJECT))
+	{
+		return FALSE;
+	}
+
+	if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID()))
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
+{
+	// use callback to rearrange favorite landmarks after adding
+	// to have new one placed before target (on which it was dropped). See EXT-4312.
+	LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
+	LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+	LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
+	if (drag_over_item && drag_over_item->getListener())
+	{
+		cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID());
+	}
+
+	copy_inventory_item(
+		gAgent.getID(),
+		inv_item->getPermissions().getOwner(),
+		inv_item->getUUID(),
+		mUUID,
+		std::string(),
+		cb);
+}
+
+void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
+{
+	// BAP - should skip if dup.
+	if (move_is_into_current_outfit)
+	{
+		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item->getUUID(), true, true);
+	}
+	else
+	{
+		LLPointer<LLInventoryCallback> cb = NULL;
+		link_inventory_item(
+			gAgent.getID(),
+			inv_item->getLinkedUUID(),
+			mUUID,
+			inv_item->getName(),
+			inv_item->getDescription(),
+			LLAssetType::AT_LINK,
+			cb);
+	}
+}
+
 // This is used both for testing whether an item can be dropped
 // into the folder, as well as performing the actual drop, depending
 // if drop == TRUE.
@@ -2868,18 +2928,20 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 	if(!isAgentInventory()) return FALSE; // cannot drag into library
 	if (!isAgentAvatarValid()) return FALSE;
 
+	const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
+	const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false);
+
+	const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+	const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
+
 	LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
 	BOOL accept = FALSE;
 	LLViewerObject* object = NULL;
 	if(LLToolDragAndDrop::SOURCE_AGENT == source)
 	{
 		const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
-		const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
-		const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false);
 
 		const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
-		const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
-		const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
 		const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID());
 		const BOOL folder_allows_reorder = (mUUID == favorites_id);
 
@@ -2931,14 +2993,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			accept = FALSE;
 		if (move_is_into_current_outfit || move_is_into_outfit)
 		{
-			if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) &&
-				(inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) &&
-				(inv_item->getInventoryType() != LLInventoryType::IT_OBJECT))
-				accept = FALSE;
-		}
-		if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID()))
-		{
-			accept = FALSE;
+			accept = can_move_to_outfit(inv_item, move_is_into_current_outfit);
 		}
 
 		if(accept && drop)
@@ -2982,50 +3037,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			// (copy the item)
 			else if (favorites_id == mUUID)
 			{
-				// use callback to rearrange favorite landmarks after adding
-				// to have new one placed before target (on which it was dropped). See EXT-4312.
-				LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
-				LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
-				LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
-				if (drag_over_item && drag_over_item->getListener())
-				{
-					cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID());
-				}
-
-				copy_inventory_item(
-					gAgent.getID(),
-					inv_item->getPermissions().getOwner(),
-					inv_item->getUUID(),
-					mUUID,
-					std::string(),
-					cb);
+				dropToFavorites(inv_item);
 			}
 			// CURRENT OUTFIT or OUTFIT folder
 			// (link the item)
 			else if (move_is_into_current_outfit || move_is_into_outfit)
 			{
-				if ((inv_item->getInventoryType() == LLInventoryType::IT_WEARABLE) || 
-					(inv_item->getInventoryType() == LLInventoryType::IT_GESTURE) || 
-					(inv_item->getInventoryType() == LLInventoryType::IT_OBJECT))
-				{
-					// BAP - should skip if dup.
-					if (move_is_into_current_outfit)
-					{
-						LLAppearanceMgr::instance().wearItemOnAvatar(inv_item->getUUID(), true, true);
-					}
-					else
-					{
-						LLPointer<LLInventoryCallback> cb = NULL;
-						link_inventory_item(
-							gAgent.getID(),
-							inv_item->getLinkedUUID(),
-							mUUID,
-							inv_item->getName(),
-							inv_item->getDescription(),
-							LLAssetType::AT_LINK,
-							cb);
-					}
-				}
+				dropToOutfit(inv_item, move_is_into_current_outfit);
 			}
 			// NORMAL or TRASH folder
 			// (move the item, restamp if into trash)
@@ -3074,6 +3092,15 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			is_move = TRUE;
 			accept = TRUE;
 		}
+
+		// Don't allow placing an original item into Current Outfit or an outfit folder
+		// because they must contain only links to wearable items.
+		// *TODO: Probably we should create a link to an item if it was dragged to outfit or COF.
+		if(move_is_into_current_outfit || move_is_into_outfit)
+		{
+			accept = FALSE;
+		}
+
 		if(drop && accept)
 		{
 			LLMoveInv* move_inv = new LLMoveInv;
@@ -3113,15 +3140,36 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 		if(item && item->isFinished())
 		{
 			accept = TRUE;
-			if(drop)
+
+			if (move_is_into_current_outfit || move_is_into_outfit)
 			{
-				copy_inventory_item(
-					gAgent.getID(),
-					inv_item->getPermissions().getOwner(),
-					inv_item->getUUID(),
-					mUUID,
-					std::string(),
-					LLPointer<LLInventoryCallback>(NULL));
+				accept = can_move_to_outfit(inv_item, move_is_into_current_outfit);
+			}
+
+			if (accept && drop)
+			{
+				// FAVORITES folder
+				// (copy the item)
+				if (favorites_id == mUUID)
+				{
+					dropToFavorites(inv_item);
+				}
+				// CURRENT OUTFIT or OUTFIT folder
+				// (link the item)
+				else if (move_is_into_current_outfit || move_is_into_outfit)
+				{
+					dropToOutfit(inv_item, move_is_into_current_outfit);
+				}
+				else
+				{
+					copy_inventory_item(
+						gAgent.getID(),
+						inv_item->getPermissions().getOwner(),
+						inv_item->getUUID(),
+						mUUID,
+						std::string(),
+						LLPointer<LLInventoryCallback>(NULL));
+				}
 			}
 		}
 	}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 14abdd76b9..5ac328dcef 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -295,6 +295,8 @@ protected:
 
 	menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
 
+	void dropToFavorites(LLInventoryItem* inv_item);
+	void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
 
 	//--------------------------------------------------------------------
 	// Messy hacks for handling folder options
-- 
cgit v1.2.3