summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2014-03-06 18:15:51 -0800
committerMerov Linden <merov@lindenlab.com>2014-03-06 18:15:51 -0800
commita030b30d34ef3152791b123c4f52d4086f3eb549 (patch)
tree27e77628ed69c53b7eb3ff4c3205eaf10e79a0c0 /indra/newview
parentc7e2f81bbf299cf884d9e687fc4a7e7f7096c877 (diff)
DD-4, DD-5, DD-6, DD-7, DD-8: WIP : Add Merchant Items panel and make it somewhat work, in a clunky sort of way
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/llfloateroutbox.cpp395
-rwxr-xr-xindra/newview/llfloateroutbox.h59
-rwxr-xr-xindra/newview/llinventorypanel.cpp2
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp1
-rw-r--r--indra/newview/llviewerfoldertype.cpp2
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_merchant_items.xml121
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml7
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_merchant_items_inventory.xml32
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml5
9 files changed, 621 insertions, 3 deletions
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index de96f75602..5ed72e4250 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -1,6 +1,8 @@
/**
* @file llfloateroutbox.cpp
- * @brief Implementation of the merchant outbox window
+ * @brief Implementation of the merchant outbox window and of the merchant items window
+ *
+ * *TODO : Eventually, take out all the merchant outbox stuff and rename that file to llfloatermerchantitems
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -105,6 +107,39 @@ private:
};
///----------------------------------------------------------------------------
+/// LLMerchantItemsAddedObserver helper class
+///----------------------------------------------------------------------------
+
+class LLMerchantItemsAddedObserver : public LLInventoryCategoryAddedObserver
+{
+public:
+ LLMerchantItemsAddedObserver(LLFloaterMerchantItems * merchant_items_floater)
+ : LLInventoryCategoryAddedObserver()
+ , mMerchantItemsFloater(merchant_items_floater)
+ {
+ }
+
+ void done()
+ {
+ for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it)
+ {
+ LLViewerInventoryCategory* added_category = *it;
+
+ LLFolderType::EType added_category_type = added_category->getPreferredType();
+
+ if (added_category_type == LLFolderType::FT_MERCHANT_ITEMS)
+ {
+ mMerchantItemsFloater->initializeMarketPlace();
+ }
+ }
+ }
+
+private:
+ LLFloaterMerchantItems * mMerchantItemsFloater;
+};
+
+
+///----------------------------------------------------------------------------
/// LLFloaterOutbox
///----------------------------------------------------------------------------
@@ -617,3 +652,361 @@ void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
notification_handler->processNotification(notification);
}
+///----------------------------------------------------------------------------
+/// LLFloaterMerchantItems
+///----------------------------------------------------------------------------
+
+LLFloaterMerchantItems::LLFloaterMerchantItems(const LLSD& key)
+: LLFloater(key)
+, mCategoriesObserver(NULL)
+, mCategoryAddedObserver(NULL)
+, mRootFolderId(LLUUID::null)
+, mInventoryPlaceholder(NULL)
+, mInventoryText(NULL)
+, mInventoryTitle(NULL)
+, mTopLevelDropZone(NULL)
+{
+}
+
+LLFloaterMerchantItems::~LLFloaterMerchantItems()
+{
+ if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
+ {
+ gInventory.removeObserver(mCategoriesObserver);
+ }
+ delete mCategoriesObserver;
+
+ if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
+ {
+ gInventory.removeObserver(mCategoryAddedObserver);
+ }
+ delete mCategoryAddedObserver;
+}
+
+BOOL LLFloaterMerchantItems::postBuild()
+{
+ mInventoryPlaceholder = getChild<LLView>("merchant_items_inventory_placeholder_panel");
+ mInventoryText = mInventoryPlaceholder->getChild<LLTextBox>("merchant_items_inventory_placeholder_text");
+ mInventoryTitle = mInventoryPlaceholder->getChild<LLTextBox>("merchant_items_inventory_placeholder_title");
+
+ mTopLevelDropZone = getChild<LLPanel>("merchant_items_generic_drag_target");
+
+ LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterMerchantItems::onFocusReceived, this));
+
+ // Observe category creation to catch merchant items creation (moot if already existing)
+ mCategoryAddedObserver = new LLMerchantItemsAddedObserver(this);
+ gInventory.addObserver(mCategoryAddedObserver);
+
+ return TRUE;
+}
+
+void LLFloaterMerchantItems::clean()
+{
+ // 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
+ mRootFolderId.setNull();
+}
+
+void LLFloaterMerchantItems::onClose(bool app_quitting)
+{
+}
+
+void LLFloaterMerchantItems::onOpen(const LLSD& key)
+{
+ //
+ // Initialize the Market Place or go update the outbox
+ //
+ if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
+ {
+ initializeMarketPlace();
+ }
+ else
+ {
+ setup();
+ }
+
+ //
+ // Update the floater view
+ //
+ updateView();
+
+ //
+ // Trigger fetch of the contents
+ //
+ fetchContents();
+}
+
+void LLFloaterMerchantItems::onFocusReceived()
+{
+ fetchContents();
+}
+
+void LLFloaterMerchantItems::fetchContents()
+{
+ if (mRootFolderId.notNull())
+ {
+ LLInventoryModelBackgroundFetch::instance().start(mRootFolderId);
+ }
+}
+
+void LLFloaterMerchantItems::setup()
+{
+ 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 Merchant items folder, create it if needs be.
+ LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MERCHANT_ITEMS, true);
+ if (outbox_id.isNull())
+ {
+ // We should never get there unless the inventory fails badly
+ llinfos << "Merov : Inventory problem: failure to create the merchant items folder for a merchant!" << llendl;
+ llerrs << "Inventory problem: failure to create the merchant items folder for a merchant!" << llendl;
+ return;
+ }
+
+ // Consolidate Merchant items
+ // 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_MERCHANT_ITEMS);
+
+ if (outbox_id == mRootFolderId)
+ {
+ llinfos << "Merov : Inventory warning: Merchant items folder already set" << llendl;
+ llwarns << "Inventory warning: Merchant items folder already set" << llendl;
+ return;
+ }
+ mRootFolderId = outbox_id;
+
+ // No longer need to observe new category creation
+ if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
+ {
+ gInventory.removeObserver(mCategoryAddedObserver);
+ delete mCategoryAddedObserver;
+ mCategoryAddedObserver = NULL;
+ }
+ llassert(!mCategoryAddedObserver);
+
+ // Create observer for merchant items 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(mRootFolderId, boost::bind(&LLFloaterMerchantItems::onChanged, this));
+ llassert(mCategoriesObserver);
+
+ // Set up the merchant items inventory view
+ LLInventoryPanel* inventory_panel = mInventoryPanel.get();
+ if (inventory_panel)
+ {
+ delete inventory_panel;
+ }
+ inventory_panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_merchant_items_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
+ mInventoryPanel = inventory_panel->getInventoryPanelHandle();
+ llassert(mInventoryPanel.get() != NULL);
+
+ // Reshape the inventory to the proper size
+ LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect();
+ inventory_panel->setShape(inventory_placeholder_rect);
+
+ // Set the sort order newest to oldest
+ inventory_panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ inventory_panel->getFilter().markDefault();
+
+ // Get the content of the merchant items folder
+ fetchContents();
+}
+
+void LLFloaterMerchantItems::initializeMarketPlace()
+{
+ // *TODO : What do we need to do really once the merchant items folder has been created?
+ //
+ // Initialize the marketplace import API
+ //
+ //LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
+
+ //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();
+ //}
+}
+
+S32 LLFloaterMerchantItems::getFolderCount()
+{
+ if (mInventoryPanel.get() && mRootFolderId.notNull())
+ {
+ LLInventoryModel::cat_array_t * cats;
+ LLInventoryModel::item_array_t * items;
+ gInventory.getDirectDescendentsOf(mRootFolderId, cats, items);
+
+ return (cats->count() + items->count());
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void LLFloaterMerchantItems::updateView()
+{
+ LLInventoryPanel* panel = mInventoryPanel.get();
+
+ if (getFolderCount() > 0)
+ {
+ panel->setVisible(TRUE);
+ mInventoryPlaceholder->setVisible(FALSE);
+ mTopLevelDropZone->setVisible(TRUE);
+ }
+ else
+ {
+ if (panel)
+ {
+ panel->setVisible(FALSE);
+ }
+
+ // Show the drop zone if there is an outbox folder
+ mTopLevelDropZone->setVisible(mRootFolderId.notNull());
+
+ std::string text;
+ std::string title;
+ std::string tooltip;
+
+ const LLSD& subs = getMarketplaceStringSubstitutions();
+ U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus();
+
+ // *TODO : check those messages and create better appropriate ones in strings.xml
+ if (mRootFolderId.notNull())
+ {
+ // Does the outbox needs recreation?
+ if ((panel == NULL) || !gInventory.getCategory(mRootFolderId))
+ {
+ setup();
+ }
+ // "Merchant items is empty!" message strings
+ text = LLTrans::getString("InventoryMerchantItemsNoItems", subs);
+ title = LLTrans::getString("InventoryMerchantItemsNoItemsTitle");
+ tooltip = LLTrans::getString("InventoryMerchantItemsNoItemsTooltip");
+ }
+ else if (mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING)
+ {
+ // "Initializing!" message strings
+ text = LLTrans::getString("InventoryOutboxInitializing", subs);
+ title = LLTrans::getString("InventoryOutboxInitializingTitle");
+ tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip");
+ }
+ else if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT)
+ {
+ // "Not a merchant!" message strings
+ text = LLTrans::getString("InventoryOutboxNotMerchant", subs);
+ title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
+ tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
+ }
+ else
+ {
+ // "Errors!" message strings
+ text = LLTrans::getString("InventoryOutboxError", subs);
+ title = LLTrans::getString("InventoryOutboxErrorTitle");
+ tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ }
+
+ mInventoryText->setValue(text);
+ mInventoryTitle->setValue(title);
+ mInventoryPlaceholder->getParent()->setToolTip(tooltip);
+ }
+}
+
+bool LLFloaterMerchantItems::isAccepted(EAcceptance accept)
+{
+ // *TODO : Need a bit more test on what we accept: depends of what and where...
+ return (accept >= ACCEPT_YES_COPY_SINGLE);
+}
+
+
+BOOL LLFloaterMerchantItems::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ if ((mInventoryPanel.get() == NULL) ||
+ mRootFolderId.isNull())
+ {
+ return FALSE;
+ }
+
+ LLView * handled_view = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ BOOL handled = (handled_view != NULL);
+
+ // Determine if the mouse is inside the inventory panel itself or just within the floater
+ bool pointInInventoryPanel = false;
+ bool pointInInventoryPanelChild = false;
+ LLInventoryPanel* panel = mInventoryPanel.get();
+ LLFolderView* root_folder = panel->getRootFolder();
+ if (panel->getVisible())
+ {
+ S32 inv_x, inv_y;
+ localPointToOtherView(x, y, &inv_x, &inv_y, panel);
+
+ pointInInventoryPanel = panel->getRect().pointInRect(inv_x, inv_y);
+
+ LLView * inventory_panel_child_at_point = panel->childFromPoint(inv_x, inv_y, true);
+ pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder);
+ }
+
+ // Pass all drag and drop for this floater to the outbox inventory control
+ if (!handled || !isAccepted(*accept))
+ {
+ // Handle the drag and drop directly to the root of the outbox if we're not in the inventory panel
+ // (otherwise the inventory panel itself will handle the drag and drop operation, without any override)
+ if (!pointInInventoryPanel)
+ {
+ handled = root_folder->handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
+
+ mTopLevelDropZone->setBackgroundVisible(handled && !drop && isAccepted(*accept));
+ }
+ else
+ {
+ mTopLevelDropZone->setBackgroundVisible(!pointInInventoryPanelChild);
+ }
+
+ return handled;
+}
+
+BOOL LLFloaterMerchantItems::handleHover(S32 x, S32 y, MASK mask)
+{
+ mTopLevelDropZone->setBackgroundVisible(FALSE);
+
+ return LLFloater::handleHover(x, y, mask);
+}
+
+void LLFloaterMerchantItems::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mTopLevelDropZone->setBackgroundVisible(FALSE);
+
+ LLFloater::onMouseLeave(x, y, mask);
+}
+
+void LLFloaterMerchantItems::onChanged()
+{
+ LLViewerInventoryCategory* category = gInventory.getCategory(mRootFolderId);
+ if (mRootFolderId.notNull() && category)
+ {
+ fetchContents();
+ updateView();
+ }
+ else
+ {
+ clean();
+ }
+}
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index 40519c8fd2..b63faa860b 100755
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -1,7 +1,8 @@
/**
* @file llfloateroutbox.h
- * @brief LLFloaterOutbox
- * class definition
+ * @brief Implementation of the merchant outbox window and of the merchant items window
+ *
+ * *TODO : Eventually, take out all the merchant outbox stuff and rename that file to llfloatermerchantitems
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -113,4 +114,58 @@ private:
LLWindowShade * mWindowShade;
};
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFloaterMerchantItems
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFloaterMerchantItems : public LLFloater
+{
+public:
+ LLFloaterMerchantItems(const LLSD& key);
+ ~LLFloaterMerchantItems();
+
+ void initializeMarketPlace();
+
+ // virtuals
+ BOOL postBuild();
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void showNotification(const LLNotificationPtr& notification);
+
+ BOOL handleHover(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+protected:
+ void setup();
+ void clean();
+ void fetchContents();
+
+ void onClose(bool app_quitting);
+ void onOpen(const LLSD& key);
+ void onFocusReceived();
+ void onChanged();
+
+ bool isAccepted(EAcceptance accept);
+
+ void updateView();
+
+private:
+ S32 getFolderCount();
+
+ LLInventoryCategoriesObserver * mCategoriesObserver;
+ LLInventoryCategoryAddedObserver * mCategoryAddedObserver;
+
+ LLView * mInventoryPlaceholder;
+ LLTextBox * mInventoryText;
+ LLTextBox * mInventoryTitle;
+
+ LLUUID mRootFolderId;
+ LLHandle<LLInventoryPanel> mInventoryPanel;
+ LLPanel * mTopLevelDropZone;
+};
+
#endif // LL_LLFLOATEROUTBOX_H
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 81ee7ac07e..c1607fbbc0 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -288,6 +288,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_MERCHANT_ITEMS));
}
// set the filter for the empty folder if the debug setting is on
@@ -1489,5 +1490,6 @@ namespace LLInitParam
declare(LLFolderType::lookup(LLFolderType::FT_INBOX) , LLFolderType::FT_INBOX);
declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX);
declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT);
+ declare(LLFolderType::lookup(LLFolderType::FT_MERCHANT_ITEMS) , LLFolderType::FT_MERCHANT_ITEMS);
}
}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index a8eeddb798..f55de790d8 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -243,6 +243,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>);
}
LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);
+ LLFloaterReg::add("merchant_items", "floater_merchant_items.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMerchantItems>);
LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index 991f6b40e6..413814cec0 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -140,6 +140,8 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
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));
+
+ addEntry(LLFolderType::FT_MERCHANT_ITEMS, new ViewerFolderEntry("Merchant items", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, false, "default"));
diff --git a/indra/newview/skins/default/xui/en/floater_merchant_items.xml b/indra/newview/skins/default/xui/en/floater_merchant_items.xml
new file mode 100755
index 0000000000..2e54ed2ce3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_merchant_items.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<floater
+ positioning="cascading"
+ can_close="true"
+ can_resize="true"
+ height="440"
+ help_topic="floater_merchant_items"
+ min_width="300"
+ min_height="200"
+ name="floater_merchant_items"
+ save_rect="true"
+ save_visibility="false"
+ reuse_instance="true"
+ title="MERCHANT ITEMS"
+ width="333">
+ <panel
+ follows="all"
+ layout="topleft"
+ left="0"
+ top="0"
+ label=""
+ height="440"
+ width="333">
+ <panel
+ follows="all"
+ left="10"
+ bottom="370"
+ width="313"
+ top="0"
+ bg_opaque_color="InventoryBackgroundColor">
+ <panel
+ name="merchant_items_inventory_placeholder_panel"
+ follows="all"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="308"
+ height="370"
+ bg_opaque_color="InventoryBackgroundColor">
+ <text
+ name="merchant_items_inventory_placeholder_title"
+ type="string"
+ follows="top|left|right"
+ layout="topleft"
+ top="10"
+ left="0"
+ width="308"
+ height="25"
+ wrap="true"
+ halign="center"
+ font="SansSerifBold">
+ Loading...
+ </text>
+ <text
+ name="merchant_items_inventory_placeholder_text"
+ type="string"
+ follows="top|left|right"
+ layout="topleft"
+ top="35"
+ left="0"
+ width="308"
+ height="130"
+ wrap="true"
+ halign="left" />
+ </panel>
+ </panel>
+ <panel
+ follows="bottom|left|right"
+ left="10"
+ bottom="435"
+ width="313"
+ top="370">
+ <panel
+ name="merchant_items_generic_drag_target"
+ mouse_opaque="false"
+ follows="all"
+ top="5"
+ left="5"
+ width="303"
+ height="25"
+ background_visible="false"
+ bg_alpha_color="EmphasisColor_35"
+ border="true"
+ bevel_style="in"
+ visible="true">
+ <text
+ type="string"
+ follows="all"
+ layout="topleft"
+ top="6"
+ height="20"
+ left="5"
+ width="293"
+ halign="center"
+ font="SansSerifMedium"
+ font_shadow="hard"
+ valign="top">
+ Drag items you want to sell
+ </text>
+ </panel>
+ </panel>
+ <layout_stack name="import_progress_indicator" orientation="vertical" left="0" height="440" top="0" width="333" follows="all" visible="false">
+ <layout_panel />
+ <layout_panel height="24" auto_resize="false">
+ <layout_stack orientation="horizontal" left="0" height="24" top="0" width="333" follows="all">
+ <layout_panel width="0" />
+ <layout_panel width="24" auto_resize="false">
+ <loading_indicator
+ height="24"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="24" />
+ </layout_panel>
+ <layout_panel width="0" />
+ </layout_stack>
+ </layout_panel>
+ <layout_panel />
+ </layout_stack>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 64de010eb5..2dc974eff1 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -181,6 +181,13 @@
function="Floater.ToggleOrBringToFront"
parameter="outbox" />
</menu_item_call>
+ <menu_item_call
+ label="Merchant Items..."
+ name="MerchantItems">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="merchant_items" />
+ </menu_item_call>
<menu_item_call
label="Account dashboard..."
name="Manage My Account">
diff --git a/indra/newview/skins/default/xui/en/panel_merchant_items_inventory.xml b/indra/newview/skins/default/xui/en/panel_merchant_items_inventory.xml
new file mode 100755
index 0000000000..a013516267
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_merchant_items_inventory.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<inventory_panel
+ name="inventory_merchant_items"
+ start_folder.name="Merchant items"
+ show_empty_message="false"
+ show_load_status="false"
+ start_folder.type="merchant"
+ follows="all" layout="topleft"
+ top="0" left="0" height="165" width="308"
+ top_pad="0"
+ bg_opaque_color="DkGray2"
+ bg_alpha_color="DkGray2"
+ background_visible="true"
+ border="false"
+ bevel_style="none"
+ show_item_link_overlays="true"
+ tool_tip="Drag and drop items here to sell them"
+ scroll.reserve_scroll_corner="false">
+ <folder folder_arrow_image="Folder_Arrow"
+ folder_indentation="8"
+ item_height="20"
+ item_top_pad="4"
+ selection_image="Rounded_Square"
+ left_pad="5"
+ icon_pad="2"
+ icon_width="16"
+ text_pad="1"
+ text_pad_right="4"
+ arrow_size="12"
+ max_folder_item_overlap="2"/>
+ <item allow_open="false"/>
+</inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9300652eaa..515e912ee5 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2219,6 +2219,11 @@ We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace
<string name="InventoryOutboxError">
The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
</string>
+ <string name="InventoryMerchantItemsNoItemsTitle">Your Merchant Items folder is empty.</string>
+ <string name="InventoryMerchantItemsNoItemsTooltip"></string>
+ <string name="InventoryMerchantItemsNoItems">
+ Drag folders to this area to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace].
+ </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>