From 69b57d4ac075db855d88c2ff0e8c580e9e41ebf7 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 25 Jul 2012 19:54:39 -0700
Subject: [PATCH] CHUI-252 FIX Deleting an item from object contents in build
 tools crashes viewer also improved selection behavior for object contents
 when deleting/adding items

---
 indra/llui/llhandle.h                    | 13 +++--
 indra/newview/llpanelobjectinventory.cpp | 64 ++++++++++++++++++++----
 indra/newview/llpanelobjectinventory.h   |  7 +++
 3 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
index 37c657dd922..680a1a7f1d4 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llui/llhandle.h
@@ -158,13 +158,6 @@ class LLHandleProvider
 		return mHandle; 
 	}
 
-protected:
-	typedef LLHandle<T> handle_type_t;
-	LLHandleProvider() 
-	{
-		// provided here to enforce T deriving from LLHandleProvider<T>
-	} 
-
 	template <typename U>
 	LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
 	{
@@ -173,6 +166,12 @@ class LLHandleProvider
 		return downcast_handle;
 	}
 
+protected:
+	typedef LLHandle<T> handle_type_t;
+	LLHandleProvider() 
+	{
+		// provided here to enforce T deriving from LLHandleProvider<T>
+	} 
 
 private:
 	mutable LLRootHandle<T> mHandle;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 4719191231a..473b5d94798 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1535,6 +1535,8 @@ void LLPanelObjectInventory::clearContents()
 		LLToolDragAndDrop::getInstance()->endDrag();
 	}
 
+	clearItemIDs();
+
 	if( mScroller )
 	{
 		// removes mFolders
@@ -1550,8 +1552,6 @@ void LLPanelObjectInventory::reset()
 {
 	clearContents();
 
-	//setBorderVisible(FALSE);
-	
 	mCommitCallbackRegistrar.pushScope(); // push local callbacks
 	
 	LLRect dummy_rect(0, 1, 1, 0);
@@ -1631,15 +1631,20 @@ void LLPanelObjectInventory::updateInventory()
 	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
 	//		<< " task  UUID: " << object->mID << llendl;
 	// We're still interested in this task's inventory.
+	std::vector<LLUUID> selected_item_ids;
 	std::set<LLFolderViewItem*> selected_items;
 	BOOL inventory_has_focus = FALSE;
-	if (mHaveInventory)
+	if (mHaveInventory && mFolders)
 	{
 		selected_items = mFolders->getSelectionList();
 		inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
 	}
-
-	reset();
+	for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
+		it != end_it;
+		++it)
+	{
+		selected_item_ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+	}
 
 	LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
 	if (objectp)
@@ -1647,10 +1652,11 @@ void LLPanelObjectInventory::updateInventory()
 		LLInventoryObject* inventory_root = objectp->getInventoryRoot();
 		LLInventoryObject::object_list_t contents;
 		objectp->getInventoryContents(contents);
-		mHaveInventory = TRUE;
 
 		if (inventory_root && !contents.empty())
 		{
+			reset();
+
 			createFolderViews(inventory_root, contents);
 			mIsInventoryEmpty = FALSE;
 			mFolders->setEnabled(TRUE);
@@ -1660,6 +1666,8 @@ void LLPanelObjectInventory::updateInventory()
 			// TODO: create an empty inventory
 			mIsInventoryEmpty = TRUE;
 		}
+
+		mHaveInventory = TRUE;
 	}
 	else
 	{
@@ -1669,11 +1677,12 @@ void LLPanelObjectInventory::updateInventory()
 	}
 
 	// restore previous selection
-	std::set<LLFolderViewItem*>::iterator selection_it;
-	BOOL first_item = TRUE;
-	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
+	std::vector<LLUUID>::iterator selection_it;
+	bool first_item = true;
+	for (selection_it = selected_item_ids.begin(); selection_it != selected_item_ids.end(); ++selection_it)
 	{
-		LLFolderViewItem* selected_item = (*selection_it);
+		LLFolderViewItem* selected_item = getItemByID(*selection_it);
+		
 		if (selected_item)
 		{
 			//HACK: "set" first item then "change" each other one to get keyboard focus right
@@ -1689,7 +1698,10 @@ void LLPanelObjectInventory::updateInventory()
 		}
 	}
 
-	mFolders->requestArrange();
+	if (mFolders)
+	{
+		mFolders->requestArrange();
+	}
 	mInventoryNeedsUpdate = FALSE;
 	// Edit menu handler is set in onFocusReceived
 }
@@ -1761,6 +1773,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
 			view->addToFolder(folder);
+			addItemID(obj->getUUID(), view);
 		}
 	}
 
@@ -1944,3 +1957,32 @@ void LLPanelObjectInventory::onFocusReceived()
 	
 	LLPanel::onFocusReceived();
 }
+
+
+LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id )
+{
+	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+	map_it = mItemMap.find(id);
+	if (map_it != mItemMap.end())
+	{
+		return map_it->second;
+	}
+
+	return NULL;
+}
+
+void LLPanelObjectInventory::removeItemID( const LLUUID& id )
+{
+	mItemMap.erase(id);
+}
+
+void LLPanelObjectInventory::addItemID( const LLUUID& id, LLFolderViewItem* itemp )
+{
+	mItemMap[id] = itemp;
+}
+
+void LLPanelObjectInventory::clearItemIDs()
+{
+	mItemMap.clear();
+}
+
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 593fb43b6d4..f497c695b35 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -88,8 +88,15 @@ class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
 								LLInventoryObject* parent,
 								LLFolderViewFolder* folder);
 	void clearContents();
+	LLFolderViewItem* getItemByID(const LLUUID& id);
+
+	void addItemID( const LLUUID& id, LLFolderViewItem*   itemp );
+	void removeItemID(const LLUUID& id);
+	void clearItemIDs();
 
 private:
+	std::map<LLUUID, LLFolderViewItem*> mItemMap;
+
 	LLScrollContainer* mScroller;
 	LLFolderView* mFolders;
 	
-- 
GitLab