From 06838dfd5714603f4d52a8c5a430b1709907dd58 Mon Sep 17 00:00:00 2001
From: Mike Antipov <mantipov@productengine.com>
Date: Fri, 15 Jan 2010 19:56:37 +0200
Subject: Work on normal bug EXT-4312 (Landmark occupy random location in the
 'Favorites Bar' accordion if drag-and-drop it) -- refactoring: move
 functionality to rearange Favorite landmarks from Inventory Folder bridge to
 Inventory model -- improved logic to place dragged landmark before target
 one.

--HG--
branch : product-engine
---
 indra/newview/llinventorybridge.cpp | 35 +------------------------------
 indra/newview/llinventorymodel.cpp  | 41 +++++++++++++++++++++++++++++++++++++
 indra/newview/llinventorymodel.h    |  9 ++++++++
 3 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index e9176da715..a68a7b7aa2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2931,27 +2931,6 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
 	return false;
 }
 
-// See also LLInventorySort where landmarks in the Favorites folder are sorted.
-class LLViewerInventoryItemSort
-{
-public:
-	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
-	{
-		return a->getSortField() < b->getSortField();
-	}
-};
-
-/**
- * Sorts passed items by LLViewerInventoryItem sort field.
- *
- * @param[in, out] items - array of items, not sorted.
- */
-void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
-{
-	static LLViewerInventoryItemSort sort_functor;
-	std::sort(items.begin(), items.end(), sort_functor);
-}
-
 BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 										BOOL drop)
 {
@@ -3034,25 +3013,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			// if dragging from/into favorites folder only reorder items
 			if ((mUUID == inv_item->getParentUUID()) && folder_allows_reorder)
 			{
-				LLInventoryModel::cat_array_t cats;
-				LLInventoryModel::item_array_t items;
-				LLIsType is_type(LLAssetType::AT_LANDMARK);
-				model->collectDescendentsIf(mUUID, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
-
 				LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
 				LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
 				if (itemp)
 				{
 					LLUUID srcItemId = inv_item->getUUID();
 					LLUUID destItemId = itemp->getListener()->getUUID();
-
-					// ensure items are sorted properly before changing order. EXT-3498
-					rearrange_item_order_by_sort_field(items);
-
-					// update order
-					LLInventoryModel::updateItemsOrder(items, srcItemId, destItemId);
-
-					gInventory.saveItemsOrder(items);
+					gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
 				}
 			}
 			else if (favorites_id == mUUID) // if target is the favorites folder we use copy
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index ef18386e57..4f38fdbde4 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -3648,6 +3648,9 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c
 
 	LLViewerInventoryItem* src_item = *it_src;
 	items.erase(it_src);
+	
+	// target iterator can nt be valid due to container was changed, so update it.
+	it_dest = find_item_iter_by_uuid(items, dest_item_id);
 	items.insert(it_dest, src_item);
 }
 
@@ -3673,6 +3676,44 @@ void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& item
 	notifyObservers();
 }
 
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
+	{
+		return a->getSortField() < b->getSortField();
+	}
+};
+
+/**
+ * Sorts passed items by LLViewerInventoryItem sort field.
+ *
+ * @param[in, out] items - array of items, not sorted.
+ */
+static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
+{
+	static LLViewerInventoryItemSort sort_functor;
+	std::sort(items.begin(), items.end(), sort_functor);
+}
+
+void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLIsType is_type(LLAssetType::AT_LANDMARK);
+	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+	// ensure items are sorted properly before changing order. EXT-3498
+	rearrange_item_order_by_sort_field(items);
+
+	// update order
+	updateItemsOrder(items, source_item_id, target_item_id);
+
+	saveItemsOrder(items);
+}
+
 //----------------------------------------------------------------------------
 
 // *NOTE: DEBUG functionality
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index e8698c0759..2a2b48ce3c 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -408,6 +408,15 @@ public:
 	 */
 	void saveItemsOrder(const LLInventoryModel::item_array_t& items);
 
+	/**
+	 * Rearranges Landmarks inside Favorites folder.
+	 * Moves source landmark before target one.
+	 *
+	 * @param source_item_id - LLUUID of the source item to be moved into new position
+	 * @param target_item_id - LLUUID of the target item before which source item should be placed.
+	 */
+	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+
 protected:
 
 	// Internal methods which add inventory and make sure that all of
-- 
cgit v1.2.3