From 605511d6738817c7df3a85da873ef72c2471c642 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 25 Jan 2013 15:17:36 -0800
Subject: MAINT-2287 : WIP : Add a InventoryOutboxMakeVisible setting for
 maintenance and debugging

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 1 file changed, 11 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 7deb1284b9..a9073d619d 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4337,6 +4337,17 @@
 		<key>Value</key>
 		<integer>0</integer>
 	</map>
+	<key>InventoryOutboxMakeVisible</key>
+	<map>
+		<key>Comment</key>
+		<string>Enable making the Merchant Outbox and Inbox visible in the inventory for debug purposes.</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+		<string>Boolean</string>
+		<key>Value</key>
+		<integer>0</integer>
+	</map>
     <key>InventoryOutboxMaxFolderCount</key>
     <map>
       <key>Comment</key>
-- 
cgit v1.2.3


From 9b52a0d15a265c5bc3a9eaeea1eac00b0e25ad0b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 25 Jan 2013 17:35:56 -0800
Subject: MAINT-2287 : WIP : Make inbox and outbox visible and accessible if
 InventoryOutboxMakeVisible is set (default is false)

---
 indra/llcommon/llfoldertype.cpp      | 5 +++--
 indra/newview/llinventorypanel.cpp   | 7 +++++--
 indra/newview/llviewerfoldertype.cpp | 8 ++++++--
 3 files changed, 14 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp
index f6d0f5bce8..9c38349cf7 100644
--- a/indra/llcommon/llfoldertype.cpp
+++ b/indra/llcommon/llfoldertype.cpp
@@ -92,8 +92,9 @@ LLFolderDictionary::LLFolderDictionary()
 
 	addEntry(LLFolderType::FT_MESH, 				new FolderEntry("mesh",	TRUE));
 
-	addEntry(LLFolderType::FT_INBOX, 				new FolderEntry("inbox",	TRUE));
-	addEntry(LLFolderType::FT_OUTBOX, 				new FolderEntry("outbox",	TRUE));
+	addEntry(LLFolderType::FT_INBOX, 				new FolderEntry("inbox",	FALSE));
+	addEntry(LLFolderType::FT_OUTBOX, 				new FolderEntry("outbox",	FALSE));
+	
 	addEntry(LLFolderType::FT_BASIC_ROOT,			new FolderEntry("basic_rt", TRUE));
 		 
 	addEntry(LLFolderType::FT_NONE, 				new FolderEntry("-1",		FALSE));
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 05c81957c6..139f754e93 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -240,8 +240,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	}
 
 	// hide inbox
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+	if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible"))
+	{
+		getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
+		getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+	}
 
 	// set the filter for the empty folder if the debug setting is on
 	if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders"))
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index a179b61cff..991f6b40e6 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -30,6 +30,9 @@
 #include "lldictionary.h"
 #include "llmemory.h"
 #include "llvisualparam.h"
+#include "llcontrol.h"
+
+extern LLControlGroup gSavedSettings;
 
 static const std::string empty_string;
 
@@ -132,8 +135,9 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
 	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"Inv_SysOpen",			"Inv_SysClosed",		TRUE,      true));
 	addEntry(LLFolderType::FT_MESH, 				new ViewerFolderEntry("Meshes",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true));
 	
-	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true));
-	addEntry(LLFolderType::FT_OUTBOX, 				new ViewerFolderEntry("Outbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true));
+	bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible");
+	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     boxes_invisible));
+	addEntry(LLFolderType::FT_OUTBOX, 				new ViewerFolderEntry("Merchant Outbox",		"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     boxes_invisible));
 
 	addEntry(LLFolderType::FT_BASIC_ROOT, 			new ViewerFolderEntry("Basic Root",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true));
 		 
-- 
cgit v1.2.3


From cdf551d9aeee90b3133a74a9e7858a9a5052b5cc Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 28 Jan 2013 10:48:26 -0800
Subject: MAINT-2287 : WIP : Implement a market place state

---
 indra/newview/llmarketplacefunctions.cpp |  9 +++++++++
 indra/newview/llmarketplacefunctions.h   | 14 ++++++++++++++
 2 files changed, 23 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 0b009b68f7..d3daf605e0 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -141,6 +141,7 @@ namespace LLMarketplaceImport
 
 			if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
 				(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
+				(status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
 				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
 			{
 				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
@@ -187,6 +188,7 @@ namespace LLMarketplaceImport
 			}
 			
 			if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
+				(status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
 				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
 			{
 				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
@@ -356,6 +358,7 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
 	: mAutoTriggerImport(false)
 	, mImportInProgress(false)
 	, mInitialized(false)
+	, mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
 	, mErrorInitSignal(NULL)
 	, mStatusChangedSignal(NULL)
 	, mStatusReportSignal(NULL)
@@ -398,13 +401,19 @@ void LLMarketplaceInventoryImporter::initialize()
 
 	if (!LLMarketplaceImport::hasSessionCookie())
 	{
+		mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING;
 		LLMarketplaceImport::establishMarketplaceSessionCookie();
 	}
+	else
+	{
+		mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT;
+	}
 }
 
 void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
 {
 	mInitialized = false;
+	mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED();
 
 	initialize();
 
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 4b8f7a1ac7..092e730a88 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -48,12 +48,24 @@ namespace MarketplaceErrorCodes
 		IMPORT_PROCESSING = 202,
 		IMPORT_REDIRECT = 302,
 		IMPORT_AUTHENTICATION_ERROR = 401,
+		IMPORT_FORBIDDEN = 403,
 		IMPORT_DONE_WITH_ERRORS = 409,
 		IMPORT_JOB_FAILED = 410,
 		IMPORT_JOB_TIMEOUT = 499,
 	};
 }
 
+namespace MarketplaceStatusCodes
+{
+	enum sCode
+	{
+		MARKET_PLACE_NOT_INITIALIZED = 0,
+		MARKET_PLACE_INITIALIZING = 1,
+		MARKET_PLACE_MERCHANT = 2,
+		MARKET_PLACE_NOT_MERCHANT = 3,
+	};
+}
+
 
 class LLMarketplaceInventoryImporter
 	: public LLSingleton<LLMarketplaceInventoryImporter>
@@ -73,6 +85,7 @@ public:
 	void initialize();
 	bool triggerImport();
 	bool isImportInProgress() const { return mImportInProgress; }
+	U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
 	
 protected:
 	void reinitializeAndTriggerImport();
@@ -82,6 +95,7 @@ private:
 	bool mAutoTriggerImport;
 	bool mImportInProgress;
 	bool mInitialized;
+	U32  mMarketPlaceStatus;
 	
 	status_report_signal_t *	mErrorInitSignal;
 	status_changed_signal_t *	mStatusChangedSignal;
-- 
cgit v1.2.3


From 158393c404422bcc7b21d736d15a22ba6857dd04 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 28 Jan 2013 11:01:14 -0800
Subject: MAINT-2287 : WIP : Fix compile issue

---
 indra/newview/llmarketplacefunctions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index d3daf605e0..5da615d37b 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -413,7 +413,7 @@ void LLMarketplaceInventoryImporter::initialize()
 void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
 {
 	mInitialized = false;
-	mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED();
+	mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED;
 
 	initialize();
 
-- 
cgit v1.2.3


From c8e76908d71a67355beecf22c4daa8d0a50ef08e Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 28 Jan 2013 18:32:47 -0800
Subject: MAINT-2287 : Fixed : Test the merchant/no merchant status without
 relying on outbox, Recreate missing outbox for a merchant, UI clean up on
 init.

---
 indra/newview/llfloateroutbox.cpp              | 104 +++++++++++++++----------
 indra/newview/llfloateroutbox.h                |   3 +-
 indra/newview/llmarketplacefunctions.cpp       |  12 +--
 indra/newview/llmarketplacefunctions.h         |   5 +-
 indra/newview/skins/default/xui/en/strings.xml |   5 ++
 5 files changed, 82 insertions(+), 47 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 540f977305..d999307f28 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -84,7 +84,7 @@ public:
 			
 			if (added_category_type == LLFolderType::FT_OUTBOX)
 			{
-				mOutboxFloater->setupOutbox(added_category->getUUID());
+				mOutboxFloater->initializeMarketPlace();
 			}
 		}
 	}
@@ -146,6 +146,10 @@ BOOL LLFloaterOutbox::postBuild()
 
 	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this));
 
+	// Observe category creation to catch outbox creation (moot if already existing)
+	mCategoryAddedObserver = new LLOutboxAddedObserver(this);
+	gInventory.addObserver(mCategoryAddedObserver);
+	
 	return TRUE;
 }
 
@@ -162,34 +166,25 @@ void LLFloaterOutbox::onClose(bool app_quitting)
 void LLFloaterOutbox::onOpen(const LLSD& key)
 {
 	//
-	// Look for an outbox and set up the inventory API
+	// Initialize the Market Place or go update the outbox
 	//
-	
-	if (mOutboxId.isNull())
+	if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
 	{
-		const bool do_not_create_folder = false;
-		const bool do_not_find_in_library = false;
-		
-		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library);
-		
-		if (outbox_id.isNull())
-		{
-			// Observe category creation to catch outbox creation
-			mCategoryAddedObserver = new LLOutboxAddedObserver(this);
-			gInventory.addObserver(mCategoryAddedObserver);
-		}
-		else
-		{
-			setupOutbox(outbox_id);
-		}
+		initializeMarketPlace();
+	}
+	else 
+	{
+		setupOutbox();
 	}
 	
+	//
+	// Update the floater view
+	//
 	updateView();
 	
 	//
 	// Trigger fetch of outbox contents
 	//
-	
 	fetchOutboxContents();
 }
 
@@ -206,14 +201,23 @@ void LLFloaterOutbox::fetchOutboxContents()
 	}
 }
 
-void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
+void LLFloaterOutbox::setupOutbox()
 {
-	llassert(outboxId.notNull());
-	llassert(mOutboxId.isNull());
-	llassert(mCategoriesObserver == NULL);
-	
-	mOutboxId = outboxId;
-	
+	if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() != MarketplaceStatusCodes::MARKET_PLACE_MERCHANT)
+	{
+		// If we are *not* a merchant or we have no market place connection established yet, do nothing
+		return;
+	}
+		
+	// We are a merchant. Get the outbox, create it if needs be.
+	mOutboxId = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true, false);
+	if (mOutboxId.isNull())
+	{
+		// We should never get there unless the inventory fails badly
+		llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl;
+		return;
+	}
+
 	// No longer need to observe new category creation
 	if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
 	{
@@ -221,22 +225,24 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
 		delete mCategoryAddedObserver;
 		mCategoryAddedObserver = NULL;
 	}
+	llassert(!mCategoryAddedObserver);
 	
 	// Create observer for outbox modifications
-	mCategoriesObserver = new LLInventoryCategoriesObserver();
-	gInventory.addObserver(mCategoriesObserver);
-	
-	mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+	if (mCategoriesObserver == NULL)
+	{
+		mCategoriesObserver = new LLInventoryCategoriesObserver();
+		gInventory.addObserver(mCategoriesObserver);
+		mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+	}
+	llassert(mCategoriesObserver);
 	
 	//
 	// Set up the outbox inventory view
 	//
-	
-	mOutboxInventoryPanel = 
-		LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
-														  mInventoryPlaceholder->getParent(),
-														  LLInventoryPanel::child_registry_t::instance());
-	
+	if (mOutboxInventoryPanel == NULL)
+	{
+		mOutboxInventoryPanel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
+	}	
 	llassert(mOutboxInventoryPanel);
 	
 	// Reshape the inventory to the proper size
@@ -247,8 +253,12 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
 	mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
 	mOutboxInventoryPanel->getFilter()->markDefault();
 	
+	// Get the content of the outbox
 	fetchOutboxContents();
-	
+}
+
+void LLFloaterOutbox::initializeMarketPlace()
+{
 	//
 	// Initialize the marketplace import API
 	//
@@ -321,6 +331,7 @@ void LLFloaterOutbox::updateView()
 	{
 		mOutboxInventoryPanel->setVisible(TRUE);
 		mInventoryPlaceholder->setVisible(FALSE);
+		mOutboxTopLevelDropZone->setVisible(TRUE);
 	}
 	else
 	{
@@ -328,6 +339,9 @@ void LLFloaterOutbox::updateView()
 		{
 			mOutboxInventoryPanel->setVisible(FALSE);
 		}
+		
+		// Show the drop zone if there is an outbox folder
+		mOutboxTopLevelDropZone->setVisible(mOutboxId.notNull());
 
 		mInventoryPlaceholder->setVisible(TRUE);
 
@@ -343,6 +357,12 @@ void LLFloaterOutbox::updateView()
 			outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
 			outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
 		}
+		else if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING)
+		{
+			outbox_text = LLTrans::getString("InventoryOutboxInitializing", subs);
+			outbox_title = LLTrans::getString("InventoryOutboxInitializingTitle");
+			outbox_tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip");
+		}
 		else
 		{
 			outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", subs);
@@ -436,7 +456,7 @@ void LLFloaterOutbox::onImportButtonClicked()
 void LLFloaterOutbox::onOutboxChanged()
 {
 	llassert(!mOutboxId.isNull());
-	
+
 	if (mOutboxInventoryPanel)
 	{
 		mOutboxInventoryPanel->requestSort();
@@ -475,6 +495,11 @@ void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
 
 void LLFloaterOutbox::importStatusChanged(bool inProgress)
 {
+	if (mOutboxId.isNull() && (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT))
+	{
+		setupOutbox();
+	}
+	
 	if (inProgress)
 	{
 		if (mImportBusy)
@@ -492,6 +517,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)
 	}
 	else
 	{
+		setStatusString("");
 		mImportBusy = false;
 		mImportButton->setEnabled(mOutboxItemCount > 0);
 		mInventoryImportInProgress->setVisible(false);
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index 18baccf1c9..483f4d0780 100644
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -54,7 +54,7 @@ public:
 	LLFloaterOutbox(const LLSD& key);
 	~LLFloaterOutbox();
 	
-	void setupOutbox(const LLUUID& outboxId);
+	void initializeMarketPlace();
 
 	// virtuals
 	BOOL postBuild();
@@ -70,6 +70,7 @@ public:
 	void onMouseLeave(S32 x, S32 y, MASK mask);
 
 protected:
+	void setupOutbox();
 	void fetchOutboxContents();
 
 	void importReportResults(U32 status, const LLSD& content);
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 5da615d37b..becdfa1ddc 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -414,9 +414,7 @@ void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
 {
 	mInitialized = false;
 	mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED;
-
 	initialize();
-
 	mAutoTriggerImport = true;
 }
 
@@ -468,17 +466,21 @@ void LLMarketplaceInventoryImporter::updateImport()
 				
 				if (mInitialized)
 				{
+					mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT;
 					// Follow up with auto trigger of import
 					if (mAutoTriggerImport)
 					{
 						mAutoTriggerImport = false;
-
 						mImportInProgress = triggerImport();
 					}
 				}
-				else if (mErrorInitSignal)
+				else
 				{
-					(*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+					mMarketPlaceStatus = (LLMarketplaceImport::getResultStatus() == MarketplaceErrorCodes::IMPORT_FORBIDDEN ? MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT : MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+					if (mErrorInitSignal && (mMarketPlaceStatus == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE))
+					{
+						(*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+					}
 				}
 			}
 		}
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 092e730a88..1ea6768a02 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -61,8 +61,9 @@ namespace MarketplaceStatusCodes
 	{
 		MARKET_PLACE_NOT_INITIALIZED = 0,
 		MARKET_PLACE_INITIALIZING = 1,
-		MARKET_PLACE_MERCHANT = 2,
-		MARKET_PLACE_NOT_MERCHANT = 3,
+		MARKET_PLACE_CONNECTION_FAILURE = 2,
+		MARKET_PLACE_MERCHANT = 3,
+		MARKET_PLACE_NOT_MERCHANT = 4,
 	};
 }
 
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 2157a05bbf..c375e4906c 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2190,6 +2190,11 @@ If you'd like to become a merchant, you'll need to [[MARKETPLACE_CREATE_STORE_UR
 	<string name="InventoryOutboxNoItems">
 Drag folders to this area and click "Send to Marketplace" to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace].
 	</string>
+	<string name="InventoryOutboxInitializingTitle">Initializing Marketplace.</string>
+	<string name="InventoryOutboxInitializingTooltip"></string>
+	<string name="InventoryOutboxInitializing">
+We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace store].
+	</string>
 
 	<string name="Marketplace Error None">No errors</string>
 	<string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string>
-- 
cgit v1.2.3


From 677f65b3a2f863895250f1c25f91c79e43810caf Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 31 Jan 2013 20:26:59 -0800
Subject: MAINT-2301 : WIP : Catch a bit more 4xx and 5xx error codes, display
 the error code in the alert.

---
 indra/newview/llfloateroutbox.cpp                  |  2 +-
 indra/newview/llmarketplacefunctions.cpp           | 29 +++++++++++-----------
 indra/newview/llmarketplacefunctions.h             |  4 +++
 .../newview/skins/default/xui/en/notifications.xml |  4 +--
 4 files changed, 22 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index d999307f28..2545fcbc36 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -528,7 +528,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)
 
 void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
 {
-	if (status != MarketplaceErrorCodes::IMPORT_DONE)
+	if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
 	{
 		char status_string[16];
 		sprintf(status_string, "%d", status);
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index becdfa1ddc..79d663ead8 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -135,20 +135,15 @@ namespace LLMarketplaceImport
 				llinfos << " SLM POST status: " << status << llendl;
 				llinfos << " SLM POST reason: " << reason << llendl;
 				llinfos << " SLM POST content: " << content.asString() << llendl;
-
 				llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;
 			}
 
-			if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
-				(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
-				(status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
-				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+			if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
 			{
 				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 				{
-					llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl;
+					llinfos << " SLM POST clearing marketplace cookie due to client or server error" << llendl;
 				}
-
 				sMarketplaceCookie.clear();
 			}
 
@@ -183,19 +178,15 @@ namespace LLMarketplaceImport
 				llinfos << " SLM GET status: " << status << llendl;
 				llinfos << " SLM GET reason: " << reason << llendl;
 				llinfos << " SLM GET content: " << content.asString() << llendl;
-
 				llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
 			}
 			
-			if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
-				(status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
-				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+			if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
 			{
 				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 				{
-					llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl;
+					llinfos << " SLM GET clearing marketplace cookie due to client or server error" << llendl;
 				}
-
 				sMarketplaceCookie.clear();
 			}
 
@@ -476,7 +467,17 @@ void LLMarketplaceInventoryImporter::updateImport()
 				}
 				else
 				{
-					mMarketPlaceStatus = (LLMarketplaceImport::getResultStatus() == MarketplaceErrorCodes::IMPORT_FORBIDDEN ? MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT : MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+					U32 status = LLMarketplaceImport::getResultStatus();
+					if ((status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
+						(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
+						(status == MarketplaceErrorCodes::IMPORT_NOT_FOUND))
+					{
+						mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT;
+					}
+					else 
+					{
+						mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
+					}
 					if (mErrorInitSignal && (mMarketPlaceStatus == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE))
 					{
 						(*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 1ea6768a02..7f645e2fe2 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -47,11 +47,15 @@ namespace MarketplaceErrorCodes
 		IMPORT_DONE = 200,
 		IMPORT_PROCESSING = 202,
 		IMPORT_REDIRECT = 302,
+		IMPORT_BAD_REQUEST = 400,
 		IMPORT_AUTHENTICATION_ERROR = 401,
 		IMPORT_FORBIDDEN = 403,
+		IMPORT_NOT_FOUND = 404,
 		IMPORT_DONE_WITH_ERRORS = 409,
 		IMPORT_JOB_FAILED = 410,
 		IMPORT_JOB_TIMEOUT = 499,
+		IMPORT_SERVER_SITE_DOWN = 500,
+		IMPORT_SERVER_API_DISABLED = 503,
 	};
 }
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 9dae77a304..cb6372f782 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -271,7 +271,7 @@ See the [[MARKETPLACE_IMPORTS_URL] error log] for more information.
    icon="OutboxStatus_Error"
    name="OutboxImportFailed"
    type="outbox">
-Transfer failed
+Transfer failed with error &apos;[ERROR_CODE]&apos;
 
 No folders were sent to the Marketplace because of a system or network error.  Try again later.
 
@@ -284,7 +284,7 @@ No folders were sent to the Marketplace because of a system or network error.  T
    icon="OutboxStatus_Error"
    name="OutboxInitFailed"
    type="outbox">
-Marketplace initialization failed
+Marketplace initialization failed with error &apos;[ERROR_CODE]&apos;
 
 Initialization with the Marketplace failed because of a system or network error.  Try again later.
 
-- 
cgit v1.2.3


From bb841e7d21a4baf25e5dd240bc4776c853710ac9 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 31 Jan 2013 22:04:27 -0800
Subject: MAINT-2301 : Fixed : Ignoring 499 timeout errors on POST (safe).

---
 indra/newview/llmarketplacefunctions.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 79d663ead8..2eeaebf823 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -138,6 +138,16 @@ namespace LLMarketplaceImport
 				llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;
 			}
 
+			// MAINT-2301 : we determined we can safely ignore that error in that context
+			if (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)
+			{
+				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+				{
+					llinfos << " SLM POST : Ignoring time out status and treating it as success" << llendl;
+				}
+				status = MarketplaceErrorCodes::IMPORT_DONE;
+			}
+			
 			if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
 			{
 				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
-- 
cgit v1.2.3


From df54caf6f93b164eef1a0a64cc173be67d762041 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 15 Feb 2013 12:09:23 -0800
Subject: MAINT-2301 : Do not treat 404 errors (server returns not found) as
 403 errors (forbidden, i.e. resident is not a merchant)

---
 indra/newview/llmarketplacefunctions.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 2eeaebf823..d6954dc75b 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -479,8 +479,7 @@ void LLMarketplaceInventoryImporter::updateImport()
 				{
 					U32 status = LLMarketplaceImport::getResultStatus();
 					if ((status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
-						(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
-						(status == MarketplaceErrorCodes::IMPORT_NOT_FOUND))
+						(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR))
 					{
 						mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT;
 					}
-- 
cgit v1.2.3


From 6a8e22cf022bfc44335d6d8e6f83315d84b24c8c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 15 Feb 2013 14:02:33 -0800
Subject: MAINT-2301 : Change messaging in the Merchant Outbox panel when an
 error happened, so not to be confused with the not-a-merchant case.

---
 indra/newview/llfloateroutbox.cpp              | 15 +++++++++++++--
 indra/newview/skins/default/xui/en/strings.xml |  5 +++++
 2 files changed, 18 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 2545fcbc36..d66b433834 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -350,25 +350,36 @@ void LLFloaterOutbox::updateView()
 		std::string outbox_tooltip;
 		
 		const LLSD& subs = getMarketplaceStringSubstitutions();
+		U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus();
 		
 		if (mOutboxId.notNull())
 		{
+			// "Outbox is empty!" message strings
 			outbox_text = LLTrans::getString("InventoryOutboxNoItems", subs);
 			outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
 			outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
 		}
-		else if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING)
+		else if (mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING)
 		{
+			// "Initializing!" message strings
 			outbox_text = LLTrans::getString("InventoryOutboxInitializing", subs);
 			outbox_title = LLTrans::getString("InventoryOutboxInitializingTitle");
 			outbox_tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip");
 		}
-		else
+		else if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT)
 		{
+			// "Not a merchant!" message strings
 			outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", subs);
 			outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
 			outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
 		}
+		else
+		{
+			// "Errors!" message strings
+			outbox_text = LLTrans::getString("InventoryOutboxError", subs);
+			outbox_title = LLTrans::getString("InventoryOutboxErrorTitle");
+			outbox_tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+		}
 		
 		mInventoryText->setValue(outbox_text);
 		mInventoryTitle->setValue(outbox_title);
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c375e4906c..5be1285242 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2195,6 +2195,11 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="InventoryOutboxInitializing">
 We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace store].
 	</string>
+	<string name="InventoryOutboxErrorTitle">Marketplace Errors.</string>
+	<string name="InventoryOutboxErrorTooltip"></string>
+	<string name="InventoryOutboxError">
+The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
+	</string>
 
 	<string name="Marketplace Error None">No errors</string>
 	<string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string>
-- 
cgit v1.2.3


From 792eda047b5dcf35f3c2fad95a543a62eaeb1140 Mon Sep 17 00:00:00 2001
From: merov_linden <none@none>
Date: Thu, 7 Mar 2013 20:43:20 -0800
Subject: MAINT-2452 : Fixed : Do not clear the cookie in
 IMPORT_DONE_WITH_ERRORS case so future retry have a chance to work.

---
 indra/newview/llmarketplacefunctions.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index d6954dc75b..214558c459 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -191,7 +191,9 @@ namespace LLMarketplaceImport
 				llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
 			}
 			
-			if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
+            // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS
+			if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
+                (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS))
 			{
 				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 				{
-- 
cgit v1.2.3


From 0cf0efb6e31d505bc079f757fe7d832110797199 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 25 Mar 2013 19:03:49 -0700
Subject: WENG-618 : Added debug printout for POST and GET when
 InventoryOutboxLogging is turned on

---
 indra/newview/llmarketplacefunctions.cpp | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 214558c459..835615723a 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -30,6 +30,7 @@
 
 #include "llagent.h"
 #include "llhttpclient.h"
+#include "llsdserialize.h"
 #include "lltimer.h"
 #include "lltrans.h"
 #include "llviewercontrol.h"
@@ -201,6 +202,10 @@ namespace LLMarketplaceImport
 				}
 				sMarketplaceCookie.clear();
 			}
+            else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS))
+            {
+                llinfos << " SLM GET : Got IMPORT_DONE_WITH_ERRORS, marketplace cookie not cleared." << llendl;
+            }
 
 			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
 			sImportGetPending = false;
@@ -261,7 +266,12 @@ namespace LLMarketplaceImport
 		
 		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 		{
-			llinfos << " SLM GET: " << url << llendl;
+            llinfos << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << llendl;
+            LLSD headers = LLViewerMedia::getHeaders();
+            std::stringstream str;
+            LLSDSerialize::toPrettyXML(headers, str);
+            llinfos << " SLM GET: headers " << llendl;
+            llinfos << str.str() << llendl;
 		}
 
 		slmGetTimer.start();
@@ -292,7 +302,11 @@ namespace LLMarketplaceImport
 		
 		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 		{
-			llinfos << " SLM GET: " << url << llendl;
+            llinfos << " SLM GET: pollStatus, LLHTTPClient::get, url = " << url << llendl;
+            std::stringstream str;
+            LLSDSerialize::toPrettyXML(headers, str);
+            llinfos << " SLM GET: headers " << llendl;
+            llinfos << str.str() << llendl;
 		}
 
 		slmGetTimer.start();
@@ -326,11 +340,15 @@ namespace LLMarketplaceImport
 		
 		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 		{
-			llinfos << " SLM POST: " << url << llendl;
+            llinfos << " SLM POST: triggerImport, LLHTTPClient::post, url = " << url << llendl;
+            std::stringstream str;
+            LLSDSerialize::toPrettyXML(headers, str);
+            llinfos << " SLM POST: headers " << llendl;
+            llinfos << str.str() << llendl;
 		}
 
 		slmPostTimer.start();
-		LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
+        LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
 		
 		return true;
 	}
-- 
cgit v1.2.3


From be01ac2a365662360c6f64ac6cb8b4ea083291cb Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 17 Oct 2013 15:20:34 -0700
Subject: BUG-4185 : Fix glsl compilation error on Mac

---
 indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index 3df4d333ce..9a8dbeab58 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -34,8 +34,8 @@ mat4 getSkinnedTransform()
 	
 	float x = fract(weight.x);
 	int i = int(floor(weight.x));
-		i = min(i, 15);
-		i = max(i, 0);
+    i = int(min(i, 15));
+    i = int(max(i, 0));
 	ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1],  x);
 	ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x);
 	ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x);
-- 
cgit v1.2.3


From e6b4b89bf12ae410fa87baf01117daa2a47754c0 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 11 Nov 2013 18:39:02 -0800
Subject: MAINT-3320 : WIP : Use handle for elements that'll get deleted under
 us, quite a bit of debug spam to clean later

---
 indra/llui/llfolderview.cpp           |  11 +++
 indra/llui/llfolderviewmodel.cpp      |   8 ++
 indra/newview/llfloateroutbox.cpp     | 138 ++++++++++++++++++++++------------
 indra/newview/llfloateroutbox.h       |   2 +-
 indra/newview/llinventoryobserver.cpp |  13 +++-
 5 files changed, 120 insertions(+), 52 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index cf449217f5..4d1c2a38d0 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -176,6 +176,7 @@ LLFolderView::LLFolderView(const Params& p)
 {
 	mViewModel->setFolderView(this);
 	mRoot = this;
+    llinfos << "Merov : create folder view, this = " << this << ", name = " << (std::string(p.name)) << ", model = " << getFolderViewModel() << llendl;
 
 	LLRect rect = p.rect;
 	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
@@ -243,6 +244,7 @@ LLFolderView::LLFolderView(const Params& p)
 // Destroys the object
 LLFolderView::~LLFolderView( void )
 {
+    llinfos << "Merov : delete folder view (start), this = " << this << ", model = " << getFolderViewModel() << llendl;
 	closeRenamer();
 
 	// The release focus call can potentially call the
@@ -264,7 +266,9 @@ LLFolderView::~LLFolderView( void )
 	mItems.clear();
 	mFolders.clear();
 
+	mViewModel->setFolderView(NULL);
 	mViewModel = NULL;
+    llinfos << "Merov : delete folder view (end), this = " << this << ", model = " << getFolderViewModel() << llendl;
 }
 
 BOOL LLFolderView::canFocusChildren() const
@@ -1598,6 +1602,13 @@ void LLFolderView::update()
 	// If this is associated with the user's inventory, don't do anything
 	// until that inventory is loaded up.
 	LLFastTimer t2(FTM_INVENTORY);
+    
+    // If there's no model, the view is in suspended state (being deleted) and shouldn't be updated
+    if (getFolderViewModel() == NULL)
+    {
+        return;
+    }
+    //llinfos << "Merov : update, this = " << this << ", model = " << getFolderViewModel() << llendl;
 
 	if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())
 	{
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index 3363dc5316..48ca8156f2 100755
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -36,6 +36,10 @@ bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
 
 std::string LLFolderViewModelCommon::getStatusText()
 {
+    if (!mFolderView)
+    {
+        llinfos << "Merov : Trying LLFolderViewModelCommon::getStatusText() on a NULL mFolderView!!!" << llendl;
+    }
 	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter().getCurrentGeneration())
 	{
 		return LLTrans::getString("Searching");
@@ -48,6 +52,10 @@ std::string LLFolderViewModelCommon::getStatusText()
 
 void LLFolderViewModelCommon::filter()
 {
+    if (!mFolderView)
+    {
+        llinfos << "Merov : Trying LLFolderViewModelCommon::filter() on a NULL mFolderView!!!" << llendl;
+    }
     getFilter().resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsMaxTimePerFrameVisible"), 1, 100));
 	mFolderView->getViewModelItem()->filter(getFilter());
 }
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 4bd0574fc1..15d078db36 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -120,7 +120,6 @@ LLFloaterOutbox::LLFloaterOutbox(const LLSD& key)
 	, mInventoryText(NULL)
 	, mInventoryTitle(NULL)
 	, mOutboxId(LLUUID::null)
-	, mOutboxInventoryPanel(NULL)
 	, mOutboxItemCount(0)
 	, mOutboxTopLevelDropZone(NULL)
 	, mWindowShade(NULL)
@@ -221,13 +220,20 @@ void LLFloaterOutbox::setupOutbox()
 	}
 		
 	// We are a merchant. Get the outbox, create it if needs be.
-	mOutboxId = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true);
-	if (mOutboxId.isNull())
+	LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true);
+	if (outbox_id.isNull())
 	{
 		// We should never get there unless the inventory fails badly
 		llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl;
 		return;
 	}
+    if (outbox_id == mOutboxId)
+    {
+        llinfos << "Merov : setupOutbox, we already have an outbox set = " << mOutboxId.asString() << llendl;
+        return;
+    }
+    mOutboxId = outbox_id;
+    llinfos << "Merov : setupOutbox!!!, mOutboxId = " << mOutboxId.asString() << llendl;
 
 	// No longer need to observe new category creation
 	if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
@@ -238,32 +244,37 @@ void LLFloaterOutbox::setupOutbox()
 	}
 	llassert(!mCategoryAddedObserver);
 	
-	// Create observer for outbox modifications
-	if (mCategoriesObserver == NULL)
+	// Create observer for outbox modifications : clear the old one and create a new one
+	if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
 	{
-		mCategoriesObserver = new LLInventoryCategoriesObserver();
-		gInventory.addObserver(mCategoriesObserver);
-		mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+		gInventory.removeObserver(mCategoriesObserver);
+		delete mCategoriesObserver;
 	}
+    mCategoriesObserver = new LLInventoryCategoriesObserver();
+    gInventory.addObserver(mCategoriesObserver);
+    mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
 	llassert(mCategoriesObserver);
 	
-	//
 	// Set up the outbox inventory view
-	//
-	if (mOutboxInventoryPanel == NULL)
-	{
-		mOutboxInventoryPanel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
-	}	
-	llassert(mOutboxInventoryPanel);
+	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
+    if (panel)
+    {
+        delete panel;
+    }
+    LLInventoryPanel* inventory_panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
+    mOutboxInventoryPanel = inventory_panel->getInventoryPanelHandle();
+	llassert(mOutboxInventoryPanel.get() != NULL);
 	
 	// Reshape the inventory to the proper size
+	panel = mOutboxInventoryPanel.get();
 	LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect();
-	mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
+	panel->setShape(inventory_placeholder_rect);
 	
 	// Set the sort order newest to oldest
-
-	mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
-	mOutboxInventoryPanel->getFilter().markDefault();
+	panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
+	panel->getFilter().markDefault();
+    
+    llinfos << "Merov : setupOutbox!!!, viewModel = " << panel->getFolderViewModel() << llendl;
 	
 	// Get the content of the outbox
 	fetchOutboxContents();
@@ -292,18 +303,26 @@ void LLFloaterOutbox::setStatusString(const std::string& statusString)
 
 void LLFloaterOutbox::updateFolderCount()
 {
-	S32 item_count = 0;
-
-	if (mOutboxId.notNull())
+	if (mOutboxInventoryPanel.get())
 	{
-		LLInventoryModel::cat_array_t * cats;
-		LLInventoryModel::item_array_t * items;
-		gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
+        S32 item_count = 0;
 
-		item_count = cats->count() + items->count();
-	}
+        if (mOutboxId.notNull())
+        {
+            LLInventoryModel::cat_array_t * cats;
+            LLInventoryModel::item_array_t * items;
+            gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
+
+            item_count = cats->count() + items->count();
+        }
 	
-	mOutboxItemCount = item_count;
+        mOutboxItemCount = item_count;
+    }
+    else
+    {
+        // If there's no outbox, the number of items in it should be set to 0 for consistency
+        mOutboxItemCount = 0;
+    }
 
 	if (!mImportBusy)
 	{
@@ -313,7 +332,7 @@ void LLFloaterOutbox::updateFolderCount()
 
 void LLFloaterOutbox::updateFolderCountStatus()
 {
-	if (mOutboxInventoryPanel)
+	if (mOutboxInventoryPanel.get())
 	{
 		switch (mOutboxItemCount)
 		{
@@ -338,18 +357,27 @@ void LLFloaterOutbox::updateFolderCountStatus()
 void LLFloaterOutbox::updateView()
 {
 	updateFolderCount();
+	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
+    if (panel)
+    {
+        llinfos << "Merov : LLFloaterOutbox::updateView(), panel = " << panel << ", viewModel = " << panel->getFolderViewModel() << llendl;
+    }
+    else
+    {
+        llinfos << "Merov : LLFloaterOutbox::updateView(), panel = " << panel << llendl;
+    }
 
 	if (mOutboxItemCount > 0)
 	{
-		mOutboxInventoryPanel->setVisible(TRUE);
+		panel->setVisible(TRUE);
 		mInventoryPlaceholder->setVisible(FALSE);
 		mOutboxTopLevelDropZone->setVisible(TRUE);
 	}
 	else
 	{
-		if (mOutboxInventoryPanel)
+		if (panel)
 		{
-			mOutboxInventoryPanel->setVisible(FALSE);
+			panel->setVisible(FALSE);
 		}
 		
 		// Show the drop zone if there is an outbox folder
@@ -366,6 +394,11 @@ void LLFloaterOutbox::updateView()
 		
 		if (mOutboxId.notNull())
 		{
+            // Does the outbox needs recreation?
+            if ((mOutboxInventoryPanel.get() == NULL) || !gInventory.getCategory(mOutboxId))
+            {
+                setupOutbox();
+            }
 			// "Outbox is empty!" message strings
 			outbox_text = LLTrans::getString("InventoryOutboxNoItems", subs);
 			outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
@@ -410,7 +443,7 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 										EAcceptance* accept,
 										std::string& tooltip_msg)
 {
-	if ((mOutboxInventoryPanel == NULL) ||
+	if ((mOutboxInventoryPanel.get() == NULL) ||
 		(mWindowShade && mWindowShade->isShown()) ||
 		LLMarketplaceInventoryImporter::getInstance()->isImportInProgress())
 	{
@@ -423,15 +456,16 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	// Determine if the mouse is inside the inventory panel itself or just within the floater
 	bool pointInInventoryPanel = false;
 	bool pointInInventoryPanelChild = false;
-	LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();
-	if (mOutboxInventoryPanel->getVisible())
+	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
+	LLFolderView* root_folder = panel->getRootFolder();
+	if (panel->getVisible())
 	{
 		S32 inv_x, inv_y;
-		localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel);
+		localPointToOtherView(x, y, &inv_x, &inv_y, panel);
 
-		pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y);
+		pointInInventoryPanel = panel->getRect().pointInRect(inv_x, inv_y);
 
-		LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true);
+		LLView * inventory_panel_child_at_point = panel->childFromPoint(inv_x, inv_y, true);
 		pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder);
 	}
 	
@@ -471,7 +505,11 @@ void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask)
 
 void LLFloaterOutbox::onImportButtonClicked()
 {
-	mOutboxInventoryPanel->clearSelection();
+	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
+    if (panel)
+    {
+        panel->clearSelection();
+    }
 
 	mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();
 }
@@ -479,15 +517,19 @@ void LLFloaterOutbox::onImportButtonClicked()
 void LLFloaterOutbox::onOutboxChanged()
 {
 	llassert(!mOutboxId.isNull());
-	
-	//if (mOutboxInventoryPanel)
-	//{
-	//	mOutboxInventoryPanel->requestSort();
-	//}
-
-	fetchOutboxContents();
-
-	updateView();
+	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
+    llinfos << "Merov : onOutboxChanged!!!, panel = " << panel << ", view model = " << (panel ? panel->getFolderViewModel() : NULL) << llendl;
+    LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
+	if (category)
+    {
+        fetchOutboxContents();
+        updateView();
+    }
+    else
+    {
+        llinfos << "Merov : onOutboxChanged!!!, the category disappeared!" << llendl;
+        //setupOutbox();
+    }
 }
 
 void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index 8a32632a1b..f6a879fec5 100755
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -105,7 +105,7 @@ private:
 	LLTextBox *		mInventoryTitle;
 	
 	LLUUID				mOutboxId;
-	LLInventoryPanel *	mOutboxInventoryPanel;
+	LLHandle<LLInventoryPanel> mOutboxInventoryPanel;
 	U32					mOutboxItemCount;
 	LLPanel *			mOutboxTopLevelDropZone;
 	
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 9db175ec2e..bfe9ee6198 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -690,15 +690,22 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 	if (!mCategoryMap.size())
 		return;
 
+    llinfos << "Merov : Categories Observer changed, map size = " << mCategoryMap.size() << ", mask = " << mask << llendl;
+
 	for (category_map_t::iterator iter = mCategoryMap.begin();
 		 iter != mCategoryMap.end();
 		 ++iter)
 	{
 		const LLUUID& cat_id = (*iter).first;
-
+		LLCategoryData& cat_data = (*iter).second;
+        
 		LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
 		if (!category)
+        {
+            llinfos << "Merov : Categories Observer disappeared, cat_id = " << cat_id << llendl;
+			cat_data.mCallback();
 			continue;
+        }
 
 		const S32 version = category->getVersion();
 		const S32 expected_num_descendents = category->getDescendentCount();
@@ -726,8 +733,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 		
 		const S32 current_num_known_descendents = cats->count() + items->count();
 
-		LLCategoryData& cat_data = (*iter).second;
-
 		bool cat_changed = false;
 
 		// If category version or descendents count has changed
@@ -752,6 +757,8 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 				cat_changed = true;
 			}
 		}
+        
+        llinfos << "Merov : Categories Observer changed, cat_id = " << cat_id << ", changed = " << cat_changed << llendl;
 
 		// If anything has changed above, fire the callback.
 		if (cat_changed)
-- 
cgit v1.2.3


From 148c3780e164d5bc94fa14b418e85fee72f9fd39 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 13 Nov 2013 13:29:51 -0800
Subject: MAINT-3320 : WIP : Introduced a cleanOutbox() method to be called on
 outbox deletion

---
 indra/newview/llfloateroutbox.cpp  | 43 +++++++++++++++++++++++++++++++++-----
 indra/newview/llfloateroutbox.h    |  1 +
 indra/newview/llinventorypanel.cpp |  1 +
 3 files changed, 40 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 15d078db36..f8de91715c 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -163,6 +163,38 @@ BOOL LLFloaterOutbox::postBuild()
 	return TRUE;
 }
 
+void LLFloaterOutbox::cleanOutbox()
+{
+    /*
+	// Create a new category creation observer
+	if (mCategoryAddedObserver == NULL)
+	{
+        mCategoryAddedObserver = new LLOutboxAddedObserver(this);
+        gInventory.addObserver(mCategoryAddedObserver);
+	}
+	llassert(mCategoryAddedObserver);
+	
+	// Delete the observer for outbox modifications
+	if (mCategoriesObserver)
+	{
+		gInventory.removeObserver(mCategoriesObserver);
+		delete mCategoriesObserver;
+        mCategoriesObserver = NULL;
+	}
+	llassert(!mCategoriesObserver);
+     */
+	
+	// Clear the outbox data
+    mOutboxId.setNull();
+    mOutboxItemCount = 0;
+    
+    // Note: we cannot delete the mOutboxInventoryPanel as that point
+    // as this is called through callback observers of the panel itself.
+    // Doing so crashes rapidly.
+	
+    llinfos << "Merov : cleanOutbox!" << llendl;
+}
+
 void LLFloaterOutbox::onClose(bool app_quitting)
 {
 	if (mWindowShade)
@@ -303,7 +335,7 @@ void LLFloaterOutbox::setStatusString(const std::string& statusString)
 
 void LLFloaterOutbox::updateFolderCount()
 {
-	if (mOutboxInventoryPanel.get())
+	if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
 	{
         S32 item_count = 0;
 
@@ -332,7 +364,7 @@ void LLFloaterOutbox::updateFolderCount()
 
 void LLFloaterOutbox::updateFolderCountStatus()
 {
-	if (mOutboxInventoryPanel.get())
+	if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
 	{
 		switch (mOutboxItemCount)
 		{
@@ -445,7 +477,8 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 {
 	if ((mOutboxInventoryPanel.get() == NULL) ||
 		(mWindowShade && mWindowShade->isShown()) ||
-		LLMarketplaceInventoryImporter::getInstance()->isImportInProgress())
+		LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() ||
+        mOutboxId.isNull())
 	{
 		return FALSE;
 	}
@@ -516,7 +549,7 @@ void LLFloaterOutbox::onImportButtonClicked()
 
 void LLFloaterOutbox::onOutboxChanged()
 {
-	llassert(!mOutboxId.isNull());
+	//llassert(!mOutboxId.isNull());
 	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
     llinfos << "Merov : onOutboxChanged!!!, panel = " << panel << ", view model = " << (panel ? panel->getFolderViewModel() : NULL) << llendl;
     LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
@@ -528,7 +561,7 @@ void LLFloaterOutbox::onOutboxChanged()
     else
     {
         llinfos << "Merov : onOutboxChanged!!!, the category disappeared!" << llendl;
-        //setupOutbox();
+        cleanOutbox();
     }
 }
 
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index f6a879fec5..40519c8fd2 100755
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -71,6 +71,7 @@ public:
 
 protected:
 	void setupOutbox();
+    void cleanOutbox();
 	void fetchOutboxContents();
 
 	void importReportResults(U32 status, const LLSD& content);
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index f2c5f0aa55..63cedb6aa8 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -590,6 +590,7 @@ LLUUID LLInventoryPanel::getRootFolderID()
 			}
 			else if (preferred_type != LLFolderType::FT_NONE)
 			{
+                llinfos << "Merov : getRootFolderID, name = " << mParams.start_folder.name() << ", type = " << mParams.start_folder.type << llendl;
 				root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
 				if (root_id.isNull())
 				{
-- 
cgit v1.2.3


From 6ec99570cd86a89ed6367f81d6b0cccd7fe0e913 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 15 Nov 2013 15:12:11 -0800
Subject: MAINT-3320 : Fixed! Inventory panels are not resistant to folder root
 deletion, using handle instead of pointer and cleaning things consistently

---
 indra/llui/llfolderview.cpp                        |  27 ++-
 indra/llui/llfolderview.h                          |   7 +-
 indra/llui/llfolderviewmodel.cpp                   |   8 -
 indra/newview/llfloateroutbox.cpp                  |  68 ++------
 indra/newview/llfolderviewmodelinventory.cpp       |  20 +--
 indra/newview/llinventoryobserver.cpp              |   6 +-
 indra/newview/llinventorypanel.cpp                 | 188 ++++++++++++---------
 indra/newview/llinventorypanel.h                   |  11 +-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |   4 +-
 indra/newview/llplacesinventorypanel.cpp           |  12 +-
 10 files changed, 162 insertions(+), 189 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 4d1c2a38d0..225bf21b0a 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -167,16 +167,16 @@ LLFolderView::LLFolderView(const Params& p)
 	mMinWidth(0),
 	mDragAndDropThisFrame(FALSE),
 	mCallbackRegistrar(NULL),
-	mParentPanel(p.parent_panel),
 	mUseEllipses(p.use_ellipses),
 	mDraggingOverItem(NULL),
 	mStatusTextBox(NULL),
 	mShowItemLinkOverlays(p.show_item_link_overlays),
 	mViewModel(p.view_model)
 {
+    LLPanel* panel = p.parent_panel;
+    mParentPanel = panel->getHandle();
 	mViewModel->setFolderView(this);
 	mRoot = this;
-    llinfos << "Merov : create folder view, this = " << this << ", name = " << (std::string(p.name)) << ", model = " << getFolderViewModel() << llendl;
 
 	LLRect rect = p.rect;
 	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
@@ -244,7 +244,6 @@ LLFolderView::LLFolderView(const Params& p)
 // Destroys the object
 LLFolderView::~LLFolderView( void )
 {
-    llinfos << "Merov : delete folder view (start), this = " << this << ", model = " << getFolderViewModel() << llendl;
 	closeRenamer();
 
 	// The release focus call can potentially call the
@@ -268,7 +267,6 @@ LLFolderView::~LLFolderView( void )
 
 	mViewModel->setFolderView(NULL);
 	mViewModel = NULL;
-    llinfos << "Merov : delete folder view (end), this = " << this << ", model = " << getFolderViewModel() << llendl;
 }
 
 BOOL LLFolderView::canFocusChildren() const
@@ -329,7 +327,7 @@ void LLFolderView::filter( LLFolderViewFilter& filter )
 {
     // Entry point of inventory filtering (CHUI-849)
 	LLFastTimer t2(FTM_FILTER);
-    filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
+    filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel.get()->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
 
     // Note: we filter the model, not the view
 	getViewModelItem()->filter(filter);
@@ -423,7 +421,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
 
 	if( selection && take_keyboard_focus)
 	{
-		mParentPanel->setFocus(TRUE);
+		mParentPanel.get()->setFocus(TRUE);
 	}
 
 	// clear selection down here because change of keyboard focus can potentially
@@ -761,7 +759,7 @@ void LLFolderView::removeSelectedItems()
 				if (item_to_delete->remove())
 				{
 					// change selection on successful delete
-					setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+					setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
 				}
 			}
 			arrangeAll();
@@ -771,7 +769,7 @@ void LLFolderView::removeSelectedItems()
 			LLDynamicArray<LLFolderViewModelItem*> listeners;
 			LLFolderViewModelItem* listener;
 
-			setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+			setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
 
 			for(S32 i = 0; i < count; ++i)
 			{
@@ -951,7 +949,7 @@ void LLFolderView::cut()
 		}
 		
 		// Update the selection
-		setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+		setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
 	}
 	mSearchString.clear();
 }
@@ -1293,7 +1291,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
 	}
 
 	BOOL handled = FALSE;
-	if (mParentPanel->hasFocus())
+	if (mParentPanel.get()->hasFocus())
 	{
 		// SL-51858: Key presses are not being passed to the Popup menu.
 		// A proper fix is non-trivial so instead just close the menu.
@@ -1327,7 +1325,7 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
 	mKeyboardSelection = FALSE;
 	mSearchString.clear();
 
-	mParentPanel->setFocus(TRUE);
+	mParentPanel.get()->setFocus(TRUE);
 
 	LLEditMenuHandler::gEditMenuHandler = this;
 
@@ -1410,7 +1408,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
 {
 	// all user operations move keyboard focus to inventory
 	// this way, we know when to stop auto-updating a search
-	mParentPanel->setFocus(TRUE);
+	mParentPanel.get()->setFocus(TRUE);
 
 	BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
 	S32 count = mSelectedItems.size();
@@ -1608,7 +1606,6 @@ void LLFolderView::update()
     {
         return;
     }
-    //llinfos << "Merov : update, this = " << this << ", model = " << getFolderViewModel() << llendl;
 
 	if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())
 	{
@@ -1655,8 +1652,8 @@ void LLFolderView::update()
 	BOOL filter_finished = getViewModelItem()->passedFilter()
 						&& mViewModel->contentsReady();
 	if (filter_finished 
-		|| gFocusMgr.childHasKeyboardFocus(mParentPanel)
-		|| gFocusMgr.childHasMouseCapture(mParentPanel))
+		|| gFocusMgr.childHasKeyboardFocus(mParentPanel.get())
+		|| gFocusMgr.childHasMouseCapture(mParentPanel.get()))
 	{
 		// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
 		mNeedsAutoSelect = FALSE;
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 11fccdace4..5b83049e5c 100755
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -229,7 +229,7 @@ public:
 
 	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
 
-	LLPanel* getParentPanel() { return mParentPanel; }
+	LLPanel* getParentPanel() { return mParentPanel.get(); }
 	// DEBUG only
 	void dumpSelectionInformation();
 
@@ -238,6 +238,9 @@ public:
 	bool useLabelSuffix() { return mUseLabelSuffix; }
 	void updateMenu();
 
+    // Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem.
+	LLHandle<LLFolderView>	getHandle() const { return getDerivedHandle<LLFolderView>(); }
+    
 private:
 	void updateMenuOptions(LLMenuGL* menu);
 	void updateRenamerPosition();
@@ -295,7 +298,7 @@ protected:
 	S32								mMinWidth;
 	BOOL							mDragAndDropThisFrame;
 	
-	LLPanel*						mParentPanel;
+	LLHandle<LLPanel>               mParentPanel;
 	
 	LLFolderViewModelInterface*		mViewModel;
 
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index 48ca8156f2..3363dc5316 100755
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -36,10 +36,6 @@ bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
 
 std::string LLFolderViewModelCommon::getStatusText()
 {
-    if (!mFolderView)
-    {
-        llinfos << "Merov : Trying LLFolderViewModelCommon::getStatusText() on a NULL mFolderView!!!" << llendl;
-    }
 	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter().getCurrentGeneration())
 	{
 		return LLTrans::getString("Searching");
@@ -52,10 +48,6 @@ std::string LLFolderViewModelCommon::getStatusText()
 
 void LLFolderViewModelCommon::filter()
 {
-    if (!mFolderView)
-    {
-        llinfos << "Merov : Trying LLFolderViewModelCommon::filter() on a NULL mFolderView!!!" << llendl;
-    }
     getFilter().resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsMaxTimePerFrameVisible"), 1, 100));
 	mFolderView->getViewModelItem()->filter(getFilter());
 }
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index f8de91715c..fa628f2a08 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -165,34 +165,13 @@ BOOL LLFloaterOutbox::postBuild()
 
 void LLFloaterOutbox::cleanOutbox()
 {
-    /*
-	// Create a new category creation observer
-	if (mCategoryAddedObserver == NULL)
-	{
-        mCategoryAddedObserver = new LLOutboxAddedObserver(this);
-        gInventory.addObserver(mCategoryAddedObserver);
-	}
-	llassert(mCategoryAddedObserver);
-	
-	// Delete the observer for outbox modifications
-	if (mCategoriesObserver)
-	{
-		gInventory.removeObserver(mCategoriesObserver);
-		delete mCategoriesObserver;
-        mCategoriesObserver = NULL;
-	}
-	llassert(!mCategoriesObserver);
-     */
-	
-	// Clear the outbox data
-    mOutboxId.setNull();
-    mOutboxItemCount = 0;
-    
     // Note: we cannot delete the mOutboxInventoryPanel as that point
     // as this is called through callback observers of the panel itself.
-    // Doing so crashes rapidly.
+    // Doing so would crash rapidly.
 	
-    llinfos << "Merov : cleanOutbox!" << llendl;
+	// Invalidate the outbox data
+    mOutboxId.setNull();
+    mOutboxItemCount = 0;
 }
 
 void LLFloaterOutbox::onClose(bool app_quitting)
@@ -261,11 +240,10 @@ void LLFloaterOutbox::setupOutbox()
 	}
     if (outbox_id == mOutboxId)
     {
-        llinfos << "Merov : setupOutbox, we already have an outbox set = " << mOutboxId.asString() << llendl;
+        llwarns << "Inventory warning: Merchant outbox already set" << llendl;
         return;
     }
     mOutboxId = outbox_id;
-    llinfos << "Merov : setupOutbox!!!, mOutboxId = " << mOutboxId.asString() << llendl;
 
 	// No longer need to observe new category creation
 	if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
@@ -288,26 +266,23 @@ void LLFloaterOutbox::setupOutbox()
 	llassert(mCategoriesObserver);
 	
 	// Set up the outbox inventory view
-	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
-    if (panel)
+	LLInventoryPanel* inventory_panel = mOutboxInventoryPanel.get();
+    if (inventory_panel)
     {
-        delete panel;
+        delete inventory_panel;
     }
-    LLInventoryPanel* inventory_panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
+    inventory_panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
     mOutboxInventoryPanel = inventory_panel->getInventoryPanelHandle();
 	llassert(mOutboxInventoryPanel.get() != NULL);
 	
 	// Reshape the inventory to the proper size
-	panel = mOutboxInventoryPanel.get();
 	LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect();
-	panel->setShape(inventory_placeholder_rect);
+	inventory_panel->setShape(inventory_placeholder_rect);
 	
 	// Set the sort order newest to oldest
-	panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
-	panel->getFilter().markDefault();
+	inventory_panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
+	inventory_panel->getFilter().markDefault();
     
-    llinfos << "Merov : setupOutbox!!!, viewModel = " << panel->getFolderViewModel() << llendl;
-	
 	// Get the content of the outbox
 	fetchOutboxContents();
 }
@@ -390,14 +365,6 @@ void LLFloaterOutbox::updateView()
 {
 	updateFolderCount();
 	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
-    if (panel)
-    {
-        llinfos << "Merov : LLFloaterOutbox::updateView(), panel = " << panel << ", viewModel = " << panel->getFolderViewModel() << llendl;
-    }
-    else
-    {
-        llinfos << "Merov : LLFloaterOutbox::updateView(), panel = " << panel << llendl;
-    }
 
 	if (mOutboxItemCount > 0)
 	{
@@ -538,10 +505,9 @@ void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask)
 
 void LLFloaterOutbox::onImportButtonClicked()
 {
-	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
-    if (panel)
+    if (mOutboxInventoryPanel.get())
     {
-        panel->clearSelection();
+        mOutboxInventoryPanel.get()->clearSelection();
     }
 
 	mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();
@@ -549,18 +515,14 @@ void LLFloaterOutbox::onImportButtonClicked()
 
 void LLFloaterOutbox::onOutboxChanged()
 {
-	//llassert(!mOutboxId.isNull());
-	LLInventoryPanel* panel = mOutboxInventoryPanel.get();
-    llinfos << "Merov : onOutboxChanged!!!, panel = " << panel << ", view model = " << (panel ? panel->getFolderViewModel() : NULL) << llendl;
     LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
-	if (category)
+	if (mOutboxId.notNull() && category)
     {
         fetchOutboxContents();
         updateView();
     }
     else
     {
-        llinfos << "Merov : onOutboxChanged!!!, the category disappeared!" << llendl;
         cleanOutbox();
     }
 }
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index c28657dbcd..aac3a41b9e 100755
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -232,16 +232,16 @@ bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
     return continue_filtering;
 }
 
-LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
-{
-	return &mInventoryViewModel;
-}
-
-
-const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
-{
-	return &mInventoryViewModel;
-}
+//LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+//{
+//	return &mInventoryViewModel;
+//}
+//
+//
+//const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+//{
+//	return &mInventoryViewModel;
+//}
 
 bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
 {
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index bfe9ee6198..2be1d7a757 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -690,8 +690,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 	if (!mCategoryMap.size())
 		return;
 
-    llinfos << "Merov : Categories Observer changed, map size = " << mCategoryMap.size() << ", mask = " << mask << llendl;
-
 	for (category_map_t::iterator iter = mCategoryMap.begin();
 		 iter != mCategoryMap.end();
 		 ++iter)
@@ -702,7 +700,7 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 		LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
 		if (!category)
         {
-            llinfos << "Merov : Categories Observer disappeared, cat_id = " << cat_id << llendl;
+            llwarns << "Category : Category id = " << cat_id << " disappeared" << llendl;
 			cat_data.mCallback();
 			continue;
         }
@@ -757,8 +755,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 				cat_changed = true;
 			}
 		}
-        
-        llinfos << "Merov : Categories Observer changed, cat_id = " << cat_id << ", changed = " << cat_changed << llendl;
 
 		// If anything has changed above, fire the callback.
 		if (cat_changed)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 63cedb6aa8..81ee7ac07e 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -137,7 +137,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	LLPanel(p),
 	mInventoryObserver(NULL),
 	mCompletionObserver(NULL),
-	mFolderRoot(NULL),
 	mScroller(NULL),
 	mSortOrderSetting(p.sort_order_setting),
 	mInventory(p.inventory),
@@ -196,6 +195,32 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
     return LLUICtrlFactory::create<LLFolderView>(p);
 }
 
+void LLInventoryPanel::clearFolderRoot()
+{
+	gIdleCallbacks.deleteFunction(idle, this);
+    gIdleCallbacks.deleteFunction(onIdle, this);
+    
+    if (mInventoryObserver)
+    {
+        mInventory->removeObserver(mInventoryObserver);
+        delete mInventoryObserver;
+        mInventoryObserver = NULL;
+    }
+    if (mCompletionObserver)
+    {
+        mInventory->removeObserver(mCompletionObserver);
+        delete mCompletionObserver;
+        mCompletionObserver = NULL;
+    }
+    
+    if (mScroller)
+    {
+        removeChild(mScroller);
+        delete mScroller;
+        mScroller = NULL;
+    }
+}
+
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 {
 	// save off copy of params
@@ -203,23 +228,23 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	// Clear up the root view
 	// Note: This needs to be done *before* we build the new folder view 
 	LLUUID root_id = getRootFolderID();
-	if (mFolderRoot)
+	if (mFolderRoot.get())
 	{
 		removeItemID(root_id);
-		mFolderRoot->destroyView();
-		mFolderRoot = NULL;
+		mFolderRoot.get()->destroyView();
 	}
 
 	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
 	{
 		// Determine the root folder in case specified, and
 		// build the views starting with that folder.
-		mFolderRoot = createFolderRoot(root_id);
+        LLFolderView* folder_view = createFolderRoot(root_id);
+		mFolderRoot = folder_view->getHandle();
 	
-		addItemID(root_id, mFolderRoot);
+		addItemID(root_id, mFolderRoot.get());
 	}
 	mCommitCallbackRegistrar.popScope();
-	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+	mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	
 	// Scroller
 		LLRect scroller_view_rect = getRect();
@@ -228,10 +253,10 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 		scroller_params.rect(scroller_view_rect);
 		mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
 		addChild(mScroller);
-		mScroller->addChild(mFolderRoot);
-		mFolderRoot->setScrollContainer(mScroller);
-		mFolderRoot->setFollowsAll();
-		mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
+		mScroller->addChild(mFolderRoot.get());
+		mFolderRoot.get()->setScrollContainer(mScroller);
+		mFolderRoot.get()->setFollowsAll();
+		mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox);
 
 	// Set up the callbacks from the inventory we're viewing, and then build everything.
 	mInventoryObserver = new LLInventoryPanelObserver(this);
@@ -280,23 +305,13 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 
 LLInventoryPanel::~LLInventoryPanel()
 {
-	gIdleCallbacks.deleteFunction(idle, this);
-
 	U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
-		if (mSortOrderSetting != INHERIT_SORT_ORDER)
-		{
-			gSavedSettings.setU32(mSortOrderSetting, sort_order);
-		}
-
-	gIdleCallbacks.deleteFunction(onIdle, this);
-
-	// LLView destructor will take care of the sub-views.
-	mInventory->removeObserver(mInventoryObserver);
-	mInventory->removeObserver(mCompletionObserver);
-	delete mInventoryObserver;
-	delete mCompletionObserver;
-
-	mScroller = NULL;
+    if (mSortOrderSetting != INHERIT_SORT_ORDER)
+    {
+        gSavedSettings.setU32(mSortOrderSetting, sort_order);
+    }
+    
+    clearFolderRoot();
 }
 
 void LLInventoryPanel::draw()
@@ -363,9 +378,9 @@ void LLInventoryPanel::setSortOrder(U32 order)
 	if (order != getFolderViewModel()->getSorter().getSortOrder())
 	{
 		getFolderViewModel()->setSorter(sorter);
-		mFolderRoot->arrangeAll();
+		mFolderRoot.get()->arrangeAll();
 		// try to keep selection onscreen, even if it wasn't to start with
-		mFolderRoot->scrollToShowSelection();
+		mFolderRoot.get()->scrollToShowSelection();
 	}
 }
 
@@ -508,7 +523,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 				// Add the UI element for this item.
 				buildNewViews(item_id);
 				// Select any newly created object that has the auto rename at top of folder root set.
-				if(mFolderRoot->getRoot()->needsAutoRename())
+				if(mFolderRoot.get()->getRoot()->needsAutoRename())
 				{
 					setSelection(item_id, FALSE);
 				}
@@ -559,17 +574,11 @@ void LLInventoryPanel::modelChanged(U32 mask)
 	}
 }
 
-LLFolderView* LLInventoryPanel::getRootFolder() 
-{ 
-	return mFolderRoot; 
-}
-
 LLUUID LLInventoryPanel::getRootFolderID()
 {
-	if (mFolderRoot && mFolderRoot->getViewModelItem())
+	if (mFolderRoot.get() && mFolderRoot.get()->getViewModelItem())
 	{
-		return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
-
+		return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot.get()->getViewModelItem())->getUUID();
 	}
 	else
 	{
@@ -590,7 +599,9 @@ LLUUID LLInventoryPanel::getRootFolderID()
 			}
 			else if (preferred_type != LLFolderType::FT_NONE)
 			{
-                llinfos << "Merov : getRootFolderID, name = " << mParams.start_folder.name() << ", type = " << mParams.start_folder.type << llendl;
+                LLStringExplicit label(mParams.start_folder.name());
+                setLabel(label);
+                
 				root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
 				if (root_id.isNull())
 				{
@@ -650,24 +661,33 @@ void LLInventoryPanel::idle(void* user_data)
 
 	}
 
-	panel->mFolderRoot->update();
-	// while dragging, update selection rendering to reflect single/multi drag status
-	if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
-	{
-		EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
-		if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
-		{
-			panel->mFolderRoot->setShowSingleSelection(TRUE);
-		}
-		else
-		{
-			panel->mFolderRoot->setShowSingleSelection(FALSE);
-		}
-}
-	else
-	{
-		panel->mFolderRoot->setShowSingleSelection(FALSE);
-	}
+    // Take into account the fact that the root folder might be invalidated
+    if (panel->mFolderRoot.get())
+    {
+        panel->mFolderRoot.get()->update();
+        // while dragging, update selection rendering to reflect single/multi drag status
+        if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+        {
+            EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
+            if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
+            {
+                panel->mFolderRoot.get()->setShowSingleSelection(TRUE);
+            }
+            else
+            {
+                panel->mFolderRoot.get()->setShowSingleSelection(FALSE);
+            }
+        }
+        else
+        {
+            panel->mFolderRoot.get()->setShowSingleSelection(FALSE);
+        }
+    }
+    else
+    {
+        llwarns << "Inventory : Deleted folder root detected on panel" << llendl;
+        panel->clearFolderRoot();
+    }
 }
 
 
@@ -718,7 +738,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
 	LLFolderViewFolder::Params params(mParams.folder);
 
 	params.name = bridge->getDisplayName();
-	params.root = mFolderRoot;
+	params.root = mFolderRoot.get();
 	params.listener = bridge;
 	params.tool_tip = params.name;
 
@@ -734,7 +754,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
 	
 	params.name = bridge->getDisplayName();
 	params.creation_date = bridge->getCreationDate();
-	params.root = mFolderRoot;
+	params.root = mFolderRoot.get();
 	params.listener = bridge;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
@@ -775,7 +795,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   																				LLInventoryType::IT_CATEGORY,
   																				this,
 																			&mInventoryViewModel,
-  																				mFolderRoot,
+  																				mFolderRoot.get(),
   																				objectp->getUUID());
   				if (new_listener)
   				{
@@ -791,7 +811,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   																				item->getInventoryType(),
   																				this,
 																			&mInventoryViewModel,
-  																				mFolderRoot,
+  																				mFolderRoot.get(),
   																				item->getUUID(),
   																				item->getFlags());
  
@@ -848,7 +868,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 void LLInventoryPanel::openStartFolderOrMyInventory()
 {
 	// Find My Inventory folder and open it up by name
-	for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
+	for (LLView *child = mFolderRoot.get()->getFirstChild(); child; child = mFolderRoot.get()->findNextSibling(child))
 	{
 		LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
 		if (fchild
@@ -863,12 +883,12 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
 
 void LLInventoryPanel::onItemsCompletion()
 {
-	if (mFolderRoot) mFolderRoot->updateMenu();
+	if (mFolderRoot.get()) mFolderRoot.get()->updateMenu();
 }
 
 void LLInventoryPanel::openSelected()
 {
-	LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem();
+	LLFolderViewItem* folder_item = mFolderRoot.get()->getCurSelectedItem();
 	if(!folder_item) return;
 	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
 	if(!bridge) return;
@@ -877,7 +897,7 @@ void LLInventoryPanel::openSelected()
 
 void LLInventoryPanel::unSelectAll()	
 { 
-	mFolderRoot->setSelection(NULL, FALSE, FALSE); 
+	mFolderRoot.get()->setSelection(NULL, FALSE, FALSE);
 }
 
 
@@ -915,14 +935,14 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 		// If folder view is empty the (x, y) point won't be in its rect
 		// so the handler must be called explicitly.
 		// but only if was not handled before. See EXT-6746.
-		if (!handled && !mFolderRoot->hasVisibleChildren())
+		if (!handled && !mFolderRoot.get()->hasVisibleChildren())
 		{
-			handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+			handled = mFolderRoot.get()->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 		}
 
 		if (handled)
 		{
-			mFolderRoot->setDragAndDropThisFrame();
+			mFolderRoot.get()->setDragAndDropThisFrame();
 		}
 	}
 
@@ -932,7 +952,7 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 void LLInventoryPanel::onFocusLost()
 {
 	// inventory no longer handles cut/copy/paste/delete
-	if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot)
+	if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot.get())
 	{
 		LLEditMenuHandler::gEditMenuHandler = NULL;
 	}
@@ -943,7 +963,7 @@ void LLInventoryPanel::onFocusLost()
 void LLInventoryPanel::onFocusReceived()
 {
 	// inventory now handles cut/copy/paste/delete
-	LLEditMenuHandler::gEditMenuHandler = mFolderRoot;
+	LLEditMenuHandler::gEditMenuHandler = mFolderRoot.get();
 
 	LLPanel::onFocusReceived();
 }
@@ -954,7 +974,7 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)
 
 	if (acceptsBadge())
 	{
-		badge_added = badge->addToView(mFolderRoot);
+		badge_added = badge->addToView(mFolderRoot.get());
 	}
 
 	return badge_added;
@@ -962,8 +982,8 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)
 
 void LLInventoryPanel::openAllFolders()
 {
-	mFolderRoot->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
-	mFolderRoot->arrangeAll();
+	mFolderRoot.get()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
+	mFolderRoot.get()->arrangeAll();
 }
 
 void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
@@ -979,9 +999,9 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
 
 void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb) 
 { 
-	if (mFolderRoot) 
+	if (mFolderRoot.get())
 	{
-		mFolderRoot->setSelectCallback(cb);
+		mFolderRoot.get()->setSelectCallback(cb);
 	}
 }
 
@@ -1005,7 +1025,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 		}
 	}
 
-	LLFolderView* fv = getRootFolder();
+	LLFolderView* fv = mFolderRoot.get();
 	if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
 	{
 		fv->setNeedsAutoRename(FALSE);
@@ -1024,7 +1044,7 @@ void LLInventoryPanel::doCreate(const LLSD& userdata)
 
 bool LLInventoryPanel::beginIMSession()
 {
-	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList();
+	std::set<LLFolderViewItem*> selected_items =   mFolderRoot.get()->getSelectionList();
 
 	std::string name;
 
@@ -1118,7 +1138,7 @@ bool LLInventoryPanel::beginIMSession()
 bool LLInventoryPanel::attachObject(const LLSD& userdata)
 {
 	// Copy selected item UUIDs to a vector.
-	std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
+	std::set<LLFolderViewItem*> selected_items = mFolderRoot.get()->getSelectionList();
 	uuid_vec_t items;
 	for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();
 		 set_iter != selected_items.end(); 
@@ -1145,7 +1165,7 @@ BOOL LLInventoryPanel::getSinceLogoff()
 void LLInventoryPanel::dumpSelectionInformation(void* user_data)
 {
 	LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
-	iv->mFolderRoot->dumpSelectionInformation();
+	iv->mFolderRoot.get()->dumpSelectionInformation();
 }
 
 BOOL is_inventorysp_active()
@@ -1347,7 +1367,7 @@ void LLInventoryPanel::updateSelection()
 
 void LLInventoryPanel::doToSelected(const LLSD& userdata)
 {
-	LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString());
+	LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), userdata.asString());
 
 	return;
 }
@@ -1361,7 +1381,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
 		// Open selected items if enter key hit on the inventory panel
 		if (mask == MASK_NONE)
 		{
-			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open");
+			LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "open");
 			handled = TRUE;
 		}
 		break;
@@ -1371,7 +1391,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
 		// Note: on Mac laptop keyboards, backspace and delete are one and the same
 		if (isSelectionRemovable() && (mask == MASK_NONE))
 		{
-			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
+			LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "delete");
 			handled = TRUE;
 		}
 		break;
@@ -1382,9 +1402,9 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
 bool LLInventoryPanel::isSelectionRemovable()
 {
 	bool can_delete = false;
-	if (mFolderRoot)
+	if (mFolderRoot.get())
 	{
-		std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList();
+		std::set<LLFolderViewItem*> selection_set = mFolderRoot.get()->getSelectionList();
 		if (!selection_set.empty()) 
 		{
 			can_delete = true;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 00a90325ad..c0ce513694 100755
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -181,7 +181,7 @@ public:
 	LLInventoryFilter::EFolderShow getShowFolderState();
 	// This method is called when something has changed about the inventory.
 	void modelChanged(U32 mask);
-	LLFolderView* getRootFolder();
+	LLFolderView* getRootFolder() { return mFolderRoot.get(); }
 	LLUUID getRootFolderID();
 	LLScrollContainer* getScrollableContainer() { return mScroller; }
 	
@@ -217,8 +217,11 @@ public:
 	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
 	void updateSelection();
 
-	LLFolderViewModelInventory* getFolderViewModel();
-	const LLFolderViewModelInventory* getFolderViewModel() const;
+	LLFolderViewModelInventory* getFolderViewModel() { return &mInventoryViewModel; }
+	const LLFolderViewModelInventory* getFolderViewModel() const { return &mInventoryViewModel; }
+    
+    // Clean up stuff when the folder root gets deleted
+    void clearFolderRoot();
 
 protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
@@ -233,7 +236,7 @@ protected:
 	bool 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons
 	bool						mShowEmptyMessage;
 
-	LLFolderView*				mFolderRoot;
+	LLHandle<LLFolderView>      mFolderRoot;
 	LLScrollContainer*			mScroller;
 
 	LLFolderViewModelInventory	mInventoryViewModel;
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index adfb2dee86..da938712d7 100755
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -69,7 +69,7 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
 	LLInboxFolderViewFolder::Params params;
 	
 	params.name = bridge->getDisplayName();
-	params.root = mFolderRoot;
+	params.root = mFolderRoot.get();
 	params.listener = bridge;
 	params.tool_tip = params.name;
 	params.font_color = item_color;
@@ -86,7 +86,7 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
 
 	params.name = bridge->getDisplayName();
 	params.creation_date = bridge->getCreationDate();
-	params.root = mFolderRoot;
+	params.root = mFolderRoot.get();
 	params.listener = bridge;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 4c2213c198..5eadd65884 100755
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -91,17 +91,17 @@ LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
 void LLPlacesInventoryPanel::saveFolderState()
 {
 	mSavedFolderState->setApply(FALSE);
-	mFolderRoot->applyFunctorRecursively(*mSavedFolderState);
+	mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);
 }
 
 // re-open folders which state was saved
 void LLPlacesInventoryPanel::restoreFolderState()
 {
 	mSavedFolderState->setApply(TRUE);
-	mFolderRoot->applyFunctorRecursively(*mSavedFolderState);
+	mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);
 	LLOpenFoldersWithSelection opener;
-	mFolderRoot->applyFunctorRecursively(opener);
-	mFolderRoot->scrollToShowSelection();
+	mFolderRoot.get()->applyFunctorRecursively(opener);
+	mFolderRoot.get()->scrollToShowSelection();
 }
 
 S32	LLPlacesInventoryPanel::notify(const LLSD& info) 
@@ -111,11 +111,11 @@ S32	LLPlacesInventoryPanel::notify(const LLSD& info)
 		std::string str_action = info["action"];
 		if(str_action == "select_first")
 		{
-			return mFolderRoot->notify(info);
+			return mFolderRoot.get()->notify(info);
 		}
 		else if(str_action == "select_last")
 		{
-			return mFolderRoot->notify(info);
+			return mFolderRoot.get()->notify(info);
 		}
 	}
 	return 0;
-- 
cgit v1.2.3


From 125f3f071a30f4c47feb664b21f3e380ee4e7e49 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 18 Nov 2013 16:03:22 -0800
Subject: MAINT-3319 : WIP : Introduce a consolidate folder method used for
 Merchant Outbox

---
 indra/newview/llfloateroutbox.cpp  |  5 +++++
 indra/newview/llinventorymodel.cpp | 23 +++++++++++++++++++----
 indra/newview/llinventorymodel.h   |  5 +++++
 3 files changed, 29 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index fa628f2a08..90da9ad2c0 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -238,6 +238,11 @@ void LLFloaterOutbox::setupOutbox()
 		llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl;
 		return;
 	}
+    
+    // Consolidate Merchant Outbox
+    // We shouldn't have to do that but with a client/server system relying on a "well known folder" convention, things get messy and conventions get broken down eventually
+    gInventory.consolidateForType(outbox_id, LLFolderType::FT_OUTBOX);
+    
     if (outbox_id == mOutboxId)
     {
         llwarns << "Inventory warning: Merchant outbox already set" << llendl;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 935fe2b4d0..18dbce3321 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -369,15 +369,30 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
 	mItemLock[cat_id] = false;
 }
 
+void LLInventoryModel::consolidateForType(const LLUUID& id, LLFolderType::EType type)
+{
+    bool trace = (type == LLFolderType::FT_OUTBOX);
+    if (trace)
+    {
+        for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit)
+        {
+            LLViewerInventoryCategory* cat = cit->second;
+            if (cat->getPreferredType() == type)
+            {
+                llinfos << "Merov : List outbox from mCategoryMap, name = " << cat->getName() << ", type = " << cat->getPreferredType() << ", id = " << cat->getUUID().asString() << llendl;
+            }
+        }
+    }
+}
+
 // findCategoryUUIDForType() returns the uuid of the category that
 // specifies 'type' as what it defaults to containing. The category is
 // not necessarily only for that type. *NOTE: This will create a new
 // inventory category on the fly if one does not exist.
-const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*, 
+const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,
 					  bool find_in_library*/)
 {
 	LLUUID rv = LLUUID::null;
-	
 	const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID();
 	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
 	{
@@ -392,9 +407,9 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
 			S32 count = cats->count();
 			for(S32 i = 0; i < count; ++i)
 			{
-				if(cats->get(i)->getPreferredType() == preferred_type)
+				if (cats->get(i)->getPreferredType() == preferred_type)
 				{
-					rv = cats->get(i)->getUUID();
+                    rv = cats->get(i)->getUUID();
 					break;
 				}
 			}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8aac879a93..544ca5e5dc 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -263,6 +263,11 @@ public:
 	// Get the inventoryID or item that this item points to, else just return object_id
 	const LLUUID& getLinkedItemID(const LLUUID& object_id) const;
 	LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const;
+    
+    // Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders
+    // Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories
+    void consolidateForType(const LLUUID& id, LLFolderType::EType type);
+    
 private:
 	mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups	
 
-- 
cgit v1.2.3


From 8af432481db885afe215ef51da749543a59f3c6a Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 19 Nov 2013 16:15:00 -0800
Subject: ACME-3319 : Consolidate Merchant Outboxes when several are present
 into one in the right place

---
 indra/newview/llinventorymodel.cpp       | 68 ++++++++++++++++++++++++++------
 indra/newview/llmarketplacefunctions.cpp |  5 ++-
 2 files changed, 60 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 18dbce3321..3c4c16a438 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -369,20 +369,64 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
 	mItemLock[cat_id] = false;
 }
 
-void LLInventoryModel::consolidateForType(const LLUUID& id, LLFolderType::EType type)
+void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::EType type)
 {
-    bool trace = (type == LLFolderType::FT_OUTBOX);
-    if (trace)
+    // Make a list of folders that are not "main_id" and are of "type"
+    std::vector<LLUUID> folder_ids;
+    for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit)
     {
-        for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit)
+        LLViewerInventoryCategory* cat = cit->second;
+        if ((cat->getPreferredType() == type) && (cat->getUUID() != main_id))
         {
-            LLViewerInventoryCategory* cat = cit->second;
-            if (cat->getPreferredType() == type)
-            {
-                llinfos << "Merov : List outbox from mCategoryMap, name = " << cat->getName() << ", type = " << cat->getPreferredType() << ", id = " << cat->getUUID().asString() << llendl;
-            }
+            folder_ids.push_back(cat->getUUID());
         }
     }
+
+    // Iterate through those folders
+	for (std::vector<LLUUID>::iterator folder_ids_it = folder_ids.begin(); folder_ids_it != folder_ids.end(); ++folder_ids_it)
+	{
+		LLUUID folder_id = (*folder_ids_it);
+        
+        // Get the content of this folder
+        cat_array_t* cats;
+        item_array_t* items;
+        getDirectDescendentsOf(folder_id, cats, items);
+        
+        // Move all items to the main folder
+        // Note : we get the list of UUIDs and iterate on them instead of iterating directly on item_array_t
+        // elements. This is because moving elements modify the maps and, consequently, invalidate iterators on them.
+        // This "gather and iterate" method is verbose but resilient.
+        std::vector<LLUUID> list_uuids;
+        for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
+        {
+            list_uuids.push_back((*it)->getUUID());
+        }
+        for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+        {
+            LLViewerInventoryItem* item = getItem(*it);
+            changeItemParent(item, main_id, TRUE);
+        }
+
+        // Move all folders to the main folder
+        list_uuids.clear();
+        for (cat_array_t::const_iterator it = cats->begin(); it != cats->end(); ++it)
+        {
+            list_uuids.push_back((*it)->getUUID());
+        }
+        for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+        {
+            LLViewerInventoryCategory* cat = getCategory(*it);
+            changeCategoryParent(cat, main_id, TRUE);
+        }
+        
+        // Purge the emptied folder
+        // Note: we'd like to use purgeObject() but it doesn't cleanly eliminate the folder
+        // which leads to issues further down the road when the folder is found again
+        //purgeObject(folder_id);
+        // We remove the folder and empty the trash instead which seems to work
+		removeCategory(folder_id);
+        gInventory.emptyFolderType("", LLFolderType::FT_TRASH);
+	}
 }
 
 // findCategoryUUIDForType() returns the uuid of the category that
@@ -602,7 +646,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 	return id;
 }
 
-// Starting with the object specified, add it's descendents to the
+// Starting with the object specified, add its descendents to the
 // array provided, but do not add the inventory object specified by
 // id. There is no guaranteed order. Neither array will be erased
 // before adding objects to it. Do not store a copy of the pointers
@@ -1018,7 +1062,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
 		new_cat->copyViewerCategory(cat);
 		addCategory(new_cat);
 
-		// make sure this category is correctly referenced by it's parent.
+		// make sure this category is correctly referenced by its parent.
 		cat_array_t* cat_array;
 		cat_array = getUnlockedCatArray(cat->getParentUUID());
 		if(cat_array)
@@ -1240,7 +1284,7 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
 			<< " iterate and purge non hidden items" << llendl;
 			cat_array_t* categories;
 			item_array_t* items;
-			// Get the list of direct descendants in tha categoy passed as argument
+			// Get the list of direct descendants in that category passed as argument
 			getDirectDescendentsOf(id, categories, items);
 			std::vector<LLUUID> list_uuids;
 			// Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently)
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 835615723a..f01a3de16c 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -418,7 +418,10 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb
 
 void LLMarketplaceInventoryImporter::initialize()
 {
-	llassert(!mInitialized);
+    if (mInitialized)
+    {
+        return;
+    }
 
 	if (!LLMarketplaceImport::hasSessionCookie())
 	{
-- 
cgit v1.2.3


From 22a3b0bd7baf132a90ddf02d5eb965b71451b757 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 19 Nov 2013 20:27:25 -0800
Subject: MAINT-2287 : Fix merge errors when merging viewer-release

---
 indra/newview/VIEWER_VERSION.txt                                  | 2 +-
 indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl | 8 +++-----
 2 files changed, 4 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index cff2619cfb..c47e8b5872 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.6.9
+3.6.10
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index 9a8dbeab58..bc63d07d72 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -31,12 +31,10 @@ uniform vec4 matrixPalette[45];
 mat4 getSkinnedTransform()
 {
 	mat4 ret;
-	
-	float x = fract(weight.x);
 	int i = int(floor(weight.x));
-    i = int(min(i, 15));
-    i = int(max(i, 0));
-	ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1],  x);
+	float x = fract(weight.x);
+		
+	ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
 	ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x);
 	ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x);
 	ret[3] = vec4(0,0,0,1);
-- 
cgit v1.2.3


From c16de4df1834ccc15a6776c4fef7abb1789c2099 Mon Sep 17 00:00:00 2001
From: merov <none@none>
Date: Fri, 22 Nov 2013 20:16:03 +0000
Subject: ACME-1219 : Fix crash on exit on Windows 7

---
 indra/llui/llfolderview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 87cc070770..704e03a605 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -265,7 +265,7 @@ LLFolderView::~LLFolderView( void )
 	mItems.clear();
 	mFolders.clear();
 
-	mViewModel->setFolderView(NULL);
+	//mViewModel->setFolderView(NULL);
 	mViewModel = NULL;
 }
 
-- 
cgit v1.2.3


From 2776f8ac486dc34ea56b43409efeb37e35af6510 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 25 Nov 2013 17:19:48 -0800
Subject: MAINT-3320 : Make inbox (Received Items) more resilients to deletion
 while we're at it

---
 indra/newview/llavataractions.cpp      |  4 ++++
 indra/newview/llsidepanelinventory.cpp | 32 ++++++++++++++++----------------
 indra/newview/llsidepanelinventory.h   |  4 ++--
 3 files changed, 22 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 70cc48f12b..307e72fe18 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -868,6 +868,10 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 
 	// check selection in the panel
 	LLFolderView* root_folder = inv_panel->getRootFolder();
+    if (!root_folder)
+    {
+        return false;
+    }
 	const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
 	if (inventory_selected.empty()) return false; // nothing selected
 
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index cbf43dbb93..b78cb61cb9 100755
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -119,7 +119,6 @@ private:
 LLSidepanelInventory::LLSidepanelInventory()
 	: LLPanel()
 	, mItemPanel(NULL)
-	, mInventoryPanelInbox(NULL)
 	, mPanelMainInventory(NULL)
 	, mInboxEnabled(false)
 	, mCategoriesObserver(NULL)
@@ -299,7 +298,7 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
 	// (this can happen multiple times on the initial session that creates the inbox)
 	//
 
-	if (mInventoryPanelInbox != NULL)
+	if (mInventoryPanelInbox.get() != NULL)
 	{
 		return;
 	}
@@ -333,7 +332,8 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
 	//
 
 	LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
-	mInventoryPanelInbox = inbox->setupInventoryPanel();
+    LLInventoryPanel* inventory_panel = inbox->setupInventoryPanel();
+	mInventoryPanelInbox = inventory_panel->getInventoryPanelHandle();
 }
 
 void LLSidepanelInventory::enableInbox(bool enabled)
@@ -461,9 +461,9 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
 	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
 	if (!current_item)
 	{
-		if (mInventoryPanelInbox)
+		if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
 		{
-			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
+			current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
 		}
 
 		if (!current_item)
@@ -614,10 +614,10 @@ void LLSidepanelInventory::updateVerbs()
 
 bool LLSidepanelInventory::canShare()
 {
-	LLInventoryPanel* inbox = mInventoryPanelInbox;
+	LLInventoryPanel* inbox = mInventoryPanelInbox.get();
 
 	// Avoid flicker in the Recent tab while inventory is being loaded.
-	if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty())
+	if ( (!inbox || !inbox->getRootFolder() || inbox->getRootFolder()->getSelectionList().empty())
 		&& (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
 	{
 		return false;
@@ -652,9 +652,9 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
 	
 	if (!current_item)
 	{
-		if (mInventoryPanelInbox)
+		if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
 		{
-			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
+			current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
 		}
 
 		if (!current_item)
@@ -671,12 +671,12 @@ U32 LLSidepanelInventory::getSelectedCount()
 {
 	int count = 0;
 
-	std::set<LLFolderViewItem*> selection_list =    mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+	std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
 	count += selection_list.size();
 
-	if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
+	if ((count == 0) && mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
 	{
-		selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+		selection_list = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
 
 		count += selection_list.size();
 	}
@@ -714,9 +714,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
 		}
 	}
 	
-	if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL))
+	if (clearInbox && mInboxEnabled && mInventoryPanelInbox.get())
 	{
-		mInventoryPanelInbox->clearSelection();
+		mInventoryPanelInbox.get()->clearSelection();
 	}
 	
 	updateVerbs();
@@ -726,9 +726,9 @@ std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
 {
 	std::set<LLFolderViewItem*> inventory_selected_uuids;
 	
-	if (mInboxEnabled && (mInventoryPanelInbox != NULL))
+	if (mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
 	{
-		inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+		inventory_selected_uuids = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
 	}
 	
 	return inventory_selected_uuids;
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index e8b2808d4f..17a3098db9 100755
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -57,7 +57,7 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any.
-	LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox; }
+	LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox.get(); }
 
 	LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; }
 	BOOL isMainInventoryPanelActive() const;
@@ -99,7 +99,7 @@ protected:
 	//
 private:
 	LLPanel*					mInventoryPanel; // Main inventory view
-	LLInventoryPanel*			mInventoryPanelInbox;
+	LLHandle<LLInventoryPanel>	mInventoryPanelInbox;
 	LLSidepanelItemInfo*		mItemPanel; // Individual item view
 	LLSidepanelTaskInfo*		mTaskPanel; // Individual in-world object view
 	LLPanelMainInventory*		mPanelMainInventory;
-- 
cgit v1.2.3


From f0cbf849acd19e7c380b1b720b7f57a9bb9261c2 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 26 Nov 2013 12:04:01 -0800
Subject: ACME-3320 : Clearing deleted categories so not to pool on them
 forever

---
 indra/newview/llinventoryobserver.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 2be1d7a757..16427f2016 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -690,6 +690,8 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 	if (!mCategoryMap.size())
 		return;
 
+	std::vector<LLUUID> deleted_categories_ids;
+
 	for (category_map_t::iterator iter = mCategoryMap.begin();
 		 iter != mCategoryMap.end();
 		 ++iter)
@@ -702,6 +704,8 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
         {
             llwarns << "Category : Category id = " << cat_id << " disappeared" << llendl;
 			cat_data.mCallback();
+            // Keep track of those deleted categories so we can remove them
+            deleted_categories_ids.push_back(cat_id);
 			continue;
         }
 
@@ -760,6 +764,12 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
 		if (cat_changed)
 			cat_data.mCallback();
 	}
+    
+    // Remove deleted categories from the list
+ 	for (std::vector<LLUUID>::iterator deleted_id = deleted_categories_ids.begin(); deleted_id != deleted_categories_ids.end(); ++deleted_id)
+	{
+		removeCategory(*deleted_id);
+    }
 }
 
 bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
-- 
cgit v1.2.3


From 1cee31191c049011d0894763044cdcd7b85c00bf Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 26 Nov 2013 16:33:45 -0800
Subject: MAINT-3319 : Fix the purge of descendents of a category. Note: the
 cached number of descendents is not always reliable

---
 indra/newview/llinventorymodel.cpp | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 3c4c16a438..ed7fd3cd34 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1268,12 +1268,6 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
 // folders, items, etc in a fairly efficient manner.
 void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
 {
-	EHasChildren children = categoryHasChildren(id);
-	if(children == CHILDREN_NO)
-	{
-		llinfos << "Not purging descendents of " << id << llendl;
-		return;
-	}
 	LLPointer<LLViewerInventoryCategory> cat = getCategory(id);
 	if (cat.notNull())
 	{
-- 
cgit v1.2.3


From 66dff9d93bca7c6bdc18d57bb16a40c9753f6711 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 26 Nov 2013 20:17:23 -0800
Subject: ACME-1220 : Fixed. Do not accumulate callbacks when reinitializing
 market place

---
 indra/newview/llfloateroutbox.cpp      | 12 +++++++-----
 indra/newview/llmarketplacefunctions.h |  1 +
 2 files changed, 8 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 90da9ad2c0..de96f75602 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -297,13 +297,15 @@ void LLFloaterOutbox::initializeMarketPlace()
 	//
 	// Initialize the marketplace import API
 	//
-	
 	LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
 	
-	importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
-	importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
-	importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
-	importer.initialize();
+    if (!importer.isInitialized())
+    {
+        importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
+        importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
+        importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
+        importer.initialize();
+    }
 }
 
 void LLFloaterOutbox::setStatusString(const std::string& statusString)
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 7f645e2fe2..abe60890a3 100755
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -90,6 +90,7 @@ public:
 	void initialize();
 	bool triggerImport();
 	bool isImportInProgress() const { return mImportInProgress; }
+	bool isInitialized() const { return mInitialized; }
 	U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
 	
 protected:
-- 
cgit v1.2.3


From 1897e6ce87d260364d2aad1b1f3fa67e5f2e0d04 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 27 Nov 2013 12:20:06 -0800
Subject: ACME-1221 : Do not clear merchant import cookie on 404, happens to
 newly minted merchants

---
 indra/newview/llmarketplacefunctions.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index f01a3de16c..05c9d76810 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -192,9 +192,11 @@ namespace LLMarketplaceImport
 				llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
 			}
 			
-            // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS
+            // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
+            // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initally empty
 			if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
-                (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS))
+                (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
+                (status != MarketplaceErrorCodes::IMPORT_NOT_FOUND))
 			{
 				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 				{
@@ -202,9 +204,9 @@ namespace LLMarketplaceImport
 				}
 				sMarketplaceCookie.clear();
 			}
-            else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS))
+            else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST))
             {
-                llinfos << " SLM GET : Got IMPORT_DONE_WITH_ERRORS, marketplace cookie not cleared." << llendl;
+                llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl;
             }
 
 			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
-- 
cgit v1.2.3


From e5dae42252432d5a6d4453a767b1c3a9508deb32 Mon Sep 17 00:00:00 2001
From: Aura Linden <aura@lindenlab.com>
Date: Mon, 14 Apr 2014 15:11:42 -0700
Subject: Fix for MAINT-5707 bad breakpad behavior with teleport links

---
 indra/llcommon/llapp.cpp           | 70 ++++++++++++++++++++++----------------
 indra/llcommon/llapp.h             |  2 +-
 indra/newview/llappviewer.cpp      |  2 +-
 indra/newview/llappviewer.h        |  1 +
 indra/newview/llappviewerwin32.cpp |  2 ++
 5 files changed, 46 insertions(+), 31 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 5c8fff051f..63a38f2884 100755
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -320,7 +320,7 @@ void EnableCrashingOnCrashes()
 }
 #endif
 
-void LLApp::setupErrorHandling()
+void LLApp::setupErrorHandling(bool second_instance)
 {
 	// Error handling is done by starting up an error handling thread, which just sleeps and
 	// occasionally checks to see if the app is in an error state, and sees if it needs to be run.
@@ -337,40 +337,52 @@ void LLApp::setupErrorHandling()
 	// Install the Google Breakpad crash handler for Windows
 	if(mExceptionHandler == 0)
 	{
-		llwarns << "adding breakpad exception handler" << llendl;
+		if ( second_instance )  //BUG-5707 Firing teleport from a web browser causes second 
+		{
+			mExceptionHandler = new google_breakpad::ExceptionHandler(
+															L"C:\\Temp\\",		
+															0,		//No filter
+															windows_post_minidump_callback,
+															0,
+															google_breakpad::ExceptionHandler::HANDLER_ALL);  //No custom client info.
+		}
+		else
+		{
+			llwarns << "adding breakpad exception handler" << llendl;
 
-		std::wstring wpipe_name;
-		wpipe_name =  mCrashReportPipeStr + wstringize(getPid());
+			std::wstring wpipe_name;
+			wpipe_name =  mCrashReportPipeStr + wstringize(getPid());
 
-		const std::wstring wdump_path(wstringize(mDumpPath));
+			const std::wstring wdump_path(wstringize(mDumpPath));
 
-		int retries = 30;
-		for (; retries > 0; --retries)
-		{
-			if (mExceptionHandler != 0) delete mExceptionHandler;
-
-			mExceptionHandler = new google_breakpad::ExceptionHandler(
-														wdump_path,		
-														NULL,		//No filter
-														windows_post_minidump_callback,
-														0,
-														google_breakpad::ExceptionHandler::HANDLER_ALL,
-														MiniDumpNormal, //Generate a 'normal' minidump.
-														wpipe_name.c_str(),
-														NULL);  //No custom client info.
-			if (mExceptionHandler->IsOutOfProcess())
+			int retries = 30;
+			for (; retries > 0; --retries)
 			{
-				LL_INFOS("CRASHREPORT") << "Successfully attached to Out of Process exception handler." << LL_ENDL;
-				break;
-			}
-			else
-			{
-				LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler.  " << retries << " retries remaining." << LL_ENDL; 
-				::Sleep(100);  //Wait a tick and try again.
+				if (mExceptionHandler != 0) delete mExceptionHandler;
+
+				mExceptionHandler = new google_breakpad::ExceptionHandler(
+															wdump_path,		
+															NULL,		//No filter
+															windows_post_minidump_callback,
+															0,
+															google_breakpad::ExceptionHandler::HANDLER_ALL,
+															MiniDumpNormal, //Generate a 'normal' minidump.
+															wpipe_name.c_str(),
+															NULL);  //No custom client info.
+				if (mExceptionHandler->IsOutOfProcess())
+				{
+					LL_INFOS("CRASHREPORT") << "Successfully attached to Out of Process exception handler." << LL_ENDL;
+					break;
+				}
+				else
+				{
+					LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler.  " << retries << " retries remaining." << LL_ENDL; 
+					::Sleep(100);  //Wait a tick and try again.
+				}
 			}
-		}
 
-		if (retries == 0) LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler." << LL_ENDL;
+			if (retries == 0) LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler." << LL_ENDL;
+		}
 
 		if (mExceptionHandler)
 		{
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 828965b1fa..3f7bf2ca47 100755
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -214,7 +214,7 @@ public:
 	 * DO NOT call this method if your application has specialized
 	 * error handling code.
 	 */
-	void setupErrorHandling();
+	void setupErrorHandling(bool mSecondInstance=false);
 
 	void setErrorHandler(LLAppErrorHandler handler);
 	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 63d31824e4..413a0abf47 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -740,7 +740,7 @@ public:
 
 bool LLAppViewer::init()
 {	
-	setupErrorHandling();
+	setupErrorHandling(mSecondInstance);
 
 	//
 	// Start of the application
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index cbaa7bc4c2..25b5c90bb0 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -80,6 +80,7 @@ public:
 
     bool quitRequested() { return mQuitRequested; }
     bool logoutRequestSent() { return mLogoutRequestSent; }
+	bool isSecondInstance() { return mSecondInstance; }
 
 	void writeDebugInfo(bool isStatic=true);
 
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index d9a0eb25e4..5585bd914c 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -674,6 +674,8 @@ bool LLAppViewerWin32::restoreErrorTrap()
 
 void LLAppViewerWin32::initCrashReporting(bool reportFreeze)
 {
+	if (isSecondInstance()) return; //BUG-5707 do not start another crash reporter for second instance.
+
 	const char* logger_name = "win_crash_logger.exe";
 	std::string exe_path = gDirUtilp->getExecutableDir();
 	exe_path += gDirUtilp->getDirDelimiter();
-- 
cgit v1.2.3


From 13727121a5f86e28be15534a76f29061b1fa2906 Mon Sep 17 00:00:00 2001
From: Aura Linden <aura@lindenlab.com>
Date: Tue, 15 Apr 2014 10:35:40 -0700
Subject: Disabled 'Sending to server Try N' messages from crash reporting.

---
 indra/llcrashlogger/llcrashlogger.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 38858a1a91..3d3aed4272 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -389,11 +389,12 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
 	gBreak = false;
 	for(int i = 0; i < retries; ++i)
 	{
-		updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
+		//updateApplication lines removed because user doesn't really need to see these messages on their screen. 
+		//updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
 		LLHTTPClient::post(host, data, new LLCrashLoggerResponder(), timeout);
 		while(!gBreak)
 		{
-			updateApplication(); // No new message, just pump the IO
+			//updateApplication(); // No new message, just pump the IO
 		}
 		if(gSent)
 		{
-- 
cgit v1.2.3


From a39c5926fccb2e7a209240fc29d2086f1ce78272 Mon Sep 17 00:00:00 2001
From: Aura Linden <aura@lindenlab.com>
Date: Tue, 15 Apr 2014 14:57:47 -0700
Subject: maint-5707 window should no longer be displayed.

---
 indra/win_crash_logger/llcrashloggerwindows.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index 9fd66d5421..6a272fd166 100644
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
@@ -484,7 +484,7 @@ bool LLCrashLoggerWindows::mainLoop()
 	if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
 	{
 		llinfos << "Showing crash report submit progress window." << llendl;
-		ShowWindow(gHwndProgress, SW_SHOW );
+		//ShowWindow(gHwndProgress, SW_SHOW );   Maint-5707
 		sendCrashLogs();
 	}
 	else if (mCrashBehavior == CRASH_BEHAVIOR_ASK)
-- 
cgit v1.2.3


From 3c1674f786adce4d62a4453f2497a3dff749ddd9 Mon Sep 17 00:00:00 2001
From: Aura Linden <aura@lindenlab.com>
Date: Wed, 16 Apr 2014 11:08:52 -0700
Subject: Undo of overzealous removal.

---
 indra/llcrashlogger/llcrashlogger.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 3d3aed4272..38858a1a91 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -389,12 +389,11 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
 	gBreak = false;
 	for(int i = 0; i < retries; ++i)
 	{
-		//updateApplication lines removed because user doesn't really need to see these messages on their screen. 
-		//updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
+		updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
 		LLHTTPClient::post(host, data, new LLCrashLoggerResponder(), timeout);
 		while(!gBreak)
 		{
-			//updateApplication(); // No new message, just pump the IO
+			updateApplication(); // No new message, just pump the IO
 		}
 		if(gSent)
 		{
-- 
cgit v1.2.3


From c71e459bed68c1602d409e5c946c5e016d09d105 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 21 Apr 2014 14:50:54 -0400
Subject: increment viewer version to 3.7.7

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 897e56be0b..d2577d9756 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.7.6
+3.7.7
-- 
cgit v1.2.3