summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/app_settings/settings.xml11
-rwxr-xr-xindra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl4
-rwxr-xr-xindra/newview/llavataractions.cpp4
-rwxr-xr-xindra/newview/llfloateroutbox.cpp252
-rwxr-xr-xindra/newview/llfloateroutbox.h6
-rwxr-xr-xindra/newview/llfolderviewmodelinventory.cpp20
-rwxr-xr-xindra/newview/llinventorymodel.cpp79
-rwxr-xr-xindra/newview/llinventorymodel.h5
-rwxr-xr-xindra/newview/llinventoryobserver.cpp19
-rwxr-xr-xindra/newview/llinventorypanel.cpp194
-rwxr-xr-xindra/newview/llinventorypanel.h11
-rwxr-xr-xindra/newview/llmarketplacefunctions.cpp88
-rwxr-xr-xindra/newview/llmarketplacefunctions.h20
-rwxr-xr-xindra/newview/llpanelmarketplaceinboxinventory.cpp4
-rwxr-xr-xindra/newview/llplacesinventorypanel.cpp12
-rwxr-xr-xindra/newview/llsidepanelinventory.cpp32
-rwxr-xr-xindra/newview/llsidepanelinventory.h4
-rw-r--r--indra/newview/llviewerfoldertype.cpp8
-rwxr-xr-xindra/newview/skins/default/xui/en/notifications.xml4
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml10
20 files changed, 532 insertions, 255 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d39bf6c3c2..de11309394 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4655,6 +4655,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>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index c98e7d1cd3..bc63d07d72 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -33,8 +33,8 @@ mat4 getSkinnedTransform()
mat4 ret;
int i = int(floor(weight.x));
float x = fract(weight.x);
-
- ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], 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);
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/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 29a3e6ac3a..de96f75602 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -95,7 +95,7 @@ public:
if (added_category_type == LLFolderType::FT_OUTBOX)
{
- mOutboxFloater->setupOutbox(added_category->getUUID());
+ mOutboxFloater->initializeMarketPlace();
}
}
}
@@ -120,7 +120,6 @@ LLFloaterOutbox::LLFloaterOutbox(const LLSD& key)
, mInventoryText(NULL)
, mInventoryTitle(NULL)
, mOutboxId(LLUUID::null)
- , mOutboxInventoryPanel(NULL)
, mOutboxItemCount(0)
, mOutboxTopLevelDropZone(NULL)
, mWindowShade(NULL)
@@ -157,9 +156,24 @@ 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;
}
+void LLFloaterOutbox::cleanOutbox()
+{
+ // Note: we cannot delete the mOutboxInventoryPanel as that point
+ // as this is called through callback observers of the panel itself.
+ // Doing so would crash rapidly.
+
+ // Invalidate the outbox data
+ mOutboxId.setNull();
+ mOutboxItemCount = 0;
+}
+
void LLFloaterOutbox::onClose(bool app_quitting)
{
if (mWindowShade)
@@ -173,33 +187,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 LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder);
-
- 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();
}
@@ -216,14 +222,34 @@ 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.
+ 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;
+ }
+
+ // 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;
+ return;
+ }
+ mOutboxId = outbox_id;
+
// No longer need to observe new category creation
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
{
@@ -231,45 +257,55 @@ 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));
+ // Create observer for outbox modifications : clear the old one and create a new one
+ if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
+ {
+ 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
- //
-
- mOutboxInventoryPanel =
- LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
- mInventoryPlaceholder->getParent(),
- LLInventoryPanel::child_registry_t::instance());
-
- llassert(mOutboxInventoryPanel);
+ LLInventoryPanel* inventory_panel = mOutboxInventoryPanel.get();
+ if (inventory_panel)
+ {
+ delete inventory_panel;
+ }
+ 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
LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect();
- mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
+ inventory_panel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest
-
- mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
- mOutboxInventoryPanel->getFilter().markDefault();
-
+ inventory_panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ inventory_panel->getFilter().markDefault();
+
+ // Get the content of the outbox
fetchOutboxContents();
-
+}
+
+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)
@@ -281,18 +317,26 @@ void LLFloaterOutbox::setStatusString(const std::string& statusString)
void LLFloaterOutbox::updateFolderCount()
{
- S32 item_count = 0;
-
- if (mOutboxId.notNull())
+ if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
{
- 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)
{
@@ -302,7 +346,7 @@ void LLFloaterOutbox::updateFolderCount()
void LLFloaterOutbox::updateFolderCountStatus()
{
- if (mOutboxInventoryPanel)
+ if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
{
switch (mOutboxItemCount)
{
@@ -327,18 +371,23 @@ void LLFloaterOutbox::updateFolderCountStatus()
void LLFloaterOutbox::updateView()
{
updateFolderCount();
+ LLInventoryPanel* panel = mOutboxInventoryPanel.get();
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
+ mOutboxTopLevelDropZone->setVisible(mOutboxId.notNull());
mInventoryPlaceholder->setVisible(TRUE);
@@ -347,19 +396,41 @@ void LLFloaterOutbox::updateView()
std::string outbox_tooltip;
const LLSD& subs = getMarketplaceStringSubstitutions();
+ U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus();
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");
outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
}
- else
+ 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 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);
@@ -378,9 +449,10 @@ 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())
+ LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() ||
+ mOutboxId.isNull())
{
return FALSE;
}
@@ -391,15 +463,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);
}
@@ -439,23 +512,26 @@ void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask)
void LLFloaterOutbox::onImportButtonClicked()
{
- mOutboxInventoryPanel->clearSelection();
+ if (mOutboxInventoryPanel.get())
+ {
+ mOutboxInventoryPanel.get()->clearSelection();
+ }
mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();
}
void LLFloaterOutbox::onOutboxChanged()
{
- llassert(!mOutboxId.isNull());
-
- //if (mOutboxInventoryPanel)
- //{
- // mOutboxInventoryPanel->requestSort();
- //}
-
- fetchOutboxContents();
-
- updateView();
+ LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
+ if (mOutboxId.notNull() && category)
+ {
+ fetchOutboxContents();
+ updateView();
+ }
+ else
+ {
+ cleanOutbox();
+ }
}
void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
@@ -486,6 +562,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)
@@ -503,6 +584,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)
}
else
{
+ setStatusString("");
mImportBusy = false;
mImportButton->setEnabled(mOutboxItemCount > 0);
mInventoryImportInProgress->setVisible(false);
@@ -513,7 +595,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/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index a91d8c1139..40519c8fd2 100755
--- 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,8 @@ public:
void onMouseLeave(S32 x, S32 y, MASK mask);
protected:
+ void setupOutbox();
+ void cleanOutbox();
void fetchOutboxContents();
void importReportResults(U32 status, const LLSD& content);
@@ -104,7 +106,7 @@ private:
LLTextBox * mInventoryTitle;
LLUUID mOutboxId;
- LLInventoryPanel * mOutboxInventoryPanel;
+ LLHandle<LLInventoryPanel> mOutboxInventoryPanel;
U32 mOutboxItemCount;
LLPanel * mOutboxTopLevelDropZone;
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/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 935fe2b4d0..ed7fd3cd34 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -369,15 +369,74 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
mItemLock[cat_id] = false;
}
+void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::EType type)
+{
+ // 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)
+ {
+ LLViewerInventoryCategory* cat = cit->second;
+ if ((cat->getPreferredType() == type) && (cat->getUUID() != main_id))
+ {
+ 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
// 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 +451,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;
}
}
@@ -587,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
@@ -1003,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)
@@ -1209,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())
{
@@ -1225,7 +1278,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/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
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 9db175ec2e..16427f2016 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -690,15 +690,24 @@ 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)
{
const LLUUID& cat_id = (*iter).first;
-
+ LLCategoryData& cat_data = (*iter).second;
+
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
if (!category)
+ {
+ 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;
+ }
const S32 version = category->getVersion();
const S32 expected_num_descendents = category->getDescendentCount();
@@ -726,8 +735,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
@@ -757,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)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index e5b9e11d48..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);
@@ -259,8 +284,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"))
@@ -277,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()
@@ -360,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();
}
}
@@ -505,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);
}
@@ -556,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
{
@@ -587,6 +599,9 @@ LLUUID LLInventoryPanel::getRootFolderID()
}
else if (preferred_type != LLFolderType::FT_NONE)
{
+ LLStringExplicit label(mParams.start_folder.name());
+ setLabel(label);
+
root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
if (root_id.isNull())
{
@@ -646,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();
+ }
}
@@ -714,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;
@@ -730,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;
@@ -771,7 +795,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
LLInventoryType::IT_CATEGORY,
this,
&mInventoryViewModel,
- mFolderRoot,
+ mFolderRoot.get(),
objectp->getUUID());
if (new_listener)
{
@@ -787,7 +811,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
item->getInventoryType(),
this,
&mInventoryViewModel,
- mFolderRoot,
+ mFolderRoot.get(),
item->getUUID(),
item->getFlags());
@@ -844,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
@@ -859,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;
@@ -873,7 +897,7 @@ void LLInventoryPanel::openSelected()
void LLInventoryPanel::unSelectAll()
{
- mFolderRoot->setSelection(NULL, FALSE, FALSE);
+ mFolderRoot.get()->setSelection(NULL, FALSE, FALSE);
}
@@ -911,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();
}
}
@@ -928,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;
}
@@ -939,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();
}
@@ -950,7 +974,7 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)
if (acceptsBadge())
{
- badge_added = badge->addToView(mFolderRoot);
+ badge_added = badge->addToView(mFolderRoot.get());
}
return badge_added;
@@ -958,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)
@@ -975,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);
}
}
@@ -1001,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);
@@ -1020,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;
@@ -1114,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();
@@ -1141,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()
@@ -1343,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;
}
@@ -1357,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;
@@ -1367,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;
@@ -1378,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/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 0b009b68f7..05c9d76810 100755
--- 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"
@@ -135,19 +136,25 @@ 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_JOB_TIMEOUT))
+ // 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 clearing marketplace cookie due to authentication failure or timeout" << llendl;
+ 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"))
+ {
+ llinfos << " SLM POST clearing marketplace cookie due to client or server error" << llendl;
}
-
sMarketplaceCookie.clear();
}
@@ -182,20 +189,25 @@ 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_JOB_TIMEOUT))
+ // 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_NOT_FOUND))
{
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();
}
+ else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST))
+ {
+ llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl;
+ }
sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
sImportGetPending = false;
@@ -256,7 +268,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();
@@ -287,7 +304,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();
@@ -321,11 +342,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;
}
@@ -356,6 +381,7 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
: mAutoTriggerImport(false)
, mImportInProgress(false)
, mInitialized(false)
+ , mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
, mErrorInitSignal(NULL)
, mStatusChangedSignal(NULL)
, mStatusReportSignal(NULL)
@@ -394,20 +420,27 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb
void LLMarketplaceInventoryImporter::initialize()
{
- llassert(!mInitialized);
+ if (mInitialized)
+ {
+ return;
+ }
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();
-
mAutoTriggerImport = true;
}
@@ -459,17 +492,30 @@ 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());
+ U32 status = LLMarketplaceImport::getResultStatus();
+ if ((status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
+ (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR))
+ {
+ 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 4b8f7a1ac7..abe60890a3 100755
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -47,10 +47,27 @@ 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,
+ };
+}
+
+namespace MarketplaceStatusCodes
+{
+ enum sCode
+ {
+ MARKET_PLACE_NOT_INITIALIZED = 0,
+ MARKET_PLACE_INITIALIZING = 1,
+ MARKET_PLACE_CONNECTION_FAILURE = 2,
+ MARKET_PLACE_MERCHANT = 3,
+ MARKET_PLACE_NOT_MERCHANT = 4,
};
}
@@ -73,6 +90,8 @@ public:
void initialize();
bool triggerImport();
bool isImportInProgress() const { return mImportInProgress; }
+ bool isInitialized() const { return mInitialized; }
+ U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
protected:
void reinitializeAndTriggerImport();
@@ -82,6 +101,7 @@ private:
bool mAutoTriggerImport;
bool mImportInProgress;
bool mInitialized;
+ U32 mMarketPlaceStatus;
status_report_signal_t * mErrorInitSignal;
status_changed_signal_t * mStatusChangedSignal;
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;
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 2e91ceee2e..040cbc22a6 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;
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));
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index c97af4e9ef..370a2af5e0 100755
--- 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.
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 67f75fe1d2..3252ed2b62 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2245,6 +2245,16 @@ 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="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>