summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llview.cpp5
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/app_settings/commands.xml10
-rw-r--r--indra/newview/llappviewer.cpp4
-rw-r--r--indra/newview/llfloateroutbox.cpp68
-rw-r--r--indra/newview/llfloateroutbox.h56
-rw-r--r--indra/newview/llinventorybridge.cpp2
-rw-r--r--indra/newview/llmarketplacefunctions.cpp340
-rw-r--r--indra/newview/llmarketplacefunctions.h84
-rw-r--r--indra/newview/llpanelmarketplaceoutbox.cpp231
-rw-r--r--indra/newview/llpanelmarketplaceoutbox.h19
-rw-r--r--indra/newview/llsidepanelinventory.cpp2
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermedia.cpp128
-rw-r--r--indra/newview/skins/default/textures/textures.xml1
-rw-r--r--indra/newview/skins/default/textures/toolbar_icons/outbox.pngbin0 -> 2987 bytes
-rw-r--r--indra/newview/skins/default/xui/en/floater_merchant_outbox.xml134
-rw-r--r--indra/newview/skins/default/xui/en/floater_toybox.xml12
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml18
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
21 files changed, 845 insertions, 281 deletions
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 486babb0ab..d2966fbe98 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1090,6 +1090,11 @@ void LLView::drawChildren()
{
child_list_reverse_iter_t child = child_iter++;
LLView *viewp = *child;
+
+ if (viewp == NULL)
+ {
+ continue;
+ }
if (viewp->getVisible() && viewp->getRect().isValid())
{
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6b2fe1e45a..0a4874ae92 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -216,6 +216,7 @@ set(viewer_SOURCE_FILES
llfloaternotificationsconsole.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
+ llfloateroutbox.cpp
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
@@ -314,6 +315,7 @@ set(viewer_SOURCE_FILES
llmaniprotate.cpp
llmanipscale.cpp
llmaniptranslate.cpp
+ llmarketplacefunctions.cpp
llmediactrl.cpp
llmediadataclient.cpp
llmemoryview.cpp
@@ -770,6 +772,7 @@ set(viewer_HEADER_FILES
llfloaternotificationsconsole.h
llfloaterobjectweights.h
llfloateropenobject.h
+ llfloateroutbox.h
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
@@ -868,6 +871,7 @@ set(viewer_HEADER_FILES
llmaniprotate.h
llmanipscale.h
llmaniptranslate.h
+ llmarketplacefunctions.h
llmediactrl.h
llmediadataclient.h
llmemoryview.h
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index a44b895f7b..c12d22adc3 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -135,6 +135,16 @@
is_running_function="Floater.IsOpen"
is_running_parameters="moveview"
/>
+ <command name="outbox"
+ available_in_toybox="true"
+ icon="Command_Outbox_Icon"
+ label_ref="Command_Outbox_Label"
+ tooltip_ref="Command_Outbox_Tooltip"
+ execute_function="Floater.ToggleOrBringToFront"
+ execute_parameters="outbox"
+ is_running_function="Floater.IsOpen"
+ is_running_parameters="outbox"
+ />
<command name="people"
available_in_toybox="true"
icon="Command_People_Icon"
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index cbaddd74c4..401e9ef600 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -45,6 +45,7 @@
#include "llwindow.h"
#include "llviewerstats.h"
#include "llviewerstatsrecorder.h"
+#include "llmarketplacefunctions.h"
#include "llmd5.h"
#include "llmeshrepository.h"
#include "llpumpio.h"
@@ -4393,6 +4394,9 @@ void LLAppViewer::idle()
// update media focus
LLViewerMediaFocus::getInstance()->update();
+
+ // Update marketplace importer
+ LLMarketplaceInventoryImporter::update();
// objects and camera should be in sync, do LOD calculations now
{
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
new file mode 100644
index 0000000000..8fea3d674e
--- /dev/null
+++ b/indra/newview/llfloateroutbox.cpp
@@ -0,0 +1,68 @@
+/**
+ * @file llfloateroutbox.cpp
+ * @brief Implementation of the merchant outbox window
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloateroutbox.h"
+
+#include "llfloaterreg.h"
+#include "lltransientfloatermgr.h"
+
+
+///----------------------------------------------------------------------------
+/// LLFloaterOutbox
+///----------------------------------------------------------------------------
+
+LLFloaterOutbox::LLFloaterOutbox(const LLSD& key)
+ : LLFloater(key)
+ , mPanelOutboxInventory(NULL)
+{
+ LLTransientFloaterMgr::getInstance()->addControlView(this);
+}
+
+LLFloaterOutbox::~LLFloaterOutbox()
+{
+ LLTransientFloaterMgr::getInstance()->removeControlView(this);
+}
+
+BOOL LLFloaterOutbox::postBuild()
+{
+ return TRUE;
+}
+
+void LLFloaterOutbox::onOpen(const LLSD& key)
+{
+ //LLFirstUse::useInventory();
+}
+
+void LLFloaterOutbox::onClose(bool app_quitting)
+{
+ LLFloater::onClose(app_quitting);
+ if (mKey.asInteger() > 1)
+ {
+ destroy();
+ }
+}
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
new file mode 100644
index 0000000000..cb5c2be81c
--- /dev/null
+++ b/indra/newview/llfloateroutbox.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloateroutbox.h
+ * @brief LLFloaterOutbox
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATEROUTBOX_H
+#define LL_LLFLOATEROUTBOX_H
+
+#include "llfloater.h"
+#include "llfoldertype.h"
+
+class LLInventoryPanel;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFloaterOutbox
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFloaterOutbox : public LLFloater
+{
+public:
+ LLFloaterOutbox(const LLSD& key);
+ ~LLFloaterOutbox();
+
+ BOOL postBuild();
+
+ // Inherited functionality
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onClose(bool app_quitting);
+
+private:
+ LLInventoryPanel* mPanelOutboxInventory;
+};
+
+#endif // LL_LLFLOATEROUTBOX_H
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 0c092e9a56..017dabe2ad 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -71,7 +71,7 @@
#include "llwearablelist.h"
// Marketplace outbox current disabled
-#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 0 // keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_PANEL
+#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1 // keep in sync with ENABLE_MERCHANT_OUTBOX_PANEL
typedef std::pair<LLUUID, LLUUID> two_uuids_t;
typedef std::list<two_uuids_t> two_uuids_list_t;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
new file mode 100644
index 0000000000..b9e02a36b4
--- /dev/null
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -0,0 +1,340 @@
+/**
+ * @file llmarketplacefunctions.cpp
+ * @brief Implementation of assorted functions related to the marketplace
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmarketplacefunctions.h"
+
+#include "llagent.h"
+#include "llhttpclient.h"
+#include "llviewermedia.h"
+#include "llviewernetwork.h"
+
+
+//
+// Helpers
+//
+
+namespace LLMarketplaceImport
+{
+ // Basic interface for this namespace
+
+ bool inProgress();
+ bool resultPending();
+ U32 getResultStatus();
+ const LLSD& getResults();
+
+ void establishMarketplaceSessionCookie();
+ void pollStatus();
+ void triggerImport();
+
+ // Internal state variables
+
+ static std::string sMarketplaceCookie = "";
+ static bool sImportInProgress = false;
+ static bool sImportGetPending = false;
+ static U32 sImportResultStatus = 0;
+ static LLSD sImportResults = LLSD::emptyMap();
+
+
+ // Internal helper functions
+
+ std::string getBaseURL()
+ {
+ std::string url = "https://marketplace.secondlife.com/";
+
+ if (!LLGridManager::getInstance()->isInProductionGrid())
+ {
+ std::string gridLabel = utf8str_tolower(LLGridManager::getInstance()->getGridLabel());
+
+ if (gridLabel == "damballah")
+ {
+ url = "https://marketplace.secondlife-staging.com/";
+ }
+ else
+ {
+ url = llformat("https://marketplace.%s.lindenlab.com/", gridLabel.c_str());
+ }
+ }
+
+ url += "api/1/";
+ url += gAgent.getID().getString();
+ url += "/inventory/";
+
+ return url;
+ }
+
+ std::string getInventoryImportURL()
+ {
+ std::string url = getBaseURL();
+
+ url += "import/";
+
+ return url;
+ }
+
+ // Responders
+
+ class LLImportPostResponder : public LLHTTPClient::Responder
+ {
+ public:
+ LLImportPostResponder() : LLCurl::Responder() {}
+
+ void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE);
+ sImportResultStatus = status;
+ }
+ };
+
+ class LLImportGetResponder : public LLHTTPClient::Responder
+ {
+ public:
+ LLImportGetResponder() : LLCurl::Responder() {}
+
+ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+ {
+ sMarketplaceCookie = content["set-cookie"].asString();
+ }
+
+ void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
+ sImportGetPending = false;
+ sImportResultStatus = status;
+ sImportResults = content;
+ }
+ };
+
+ // Coroutine testing
+/*
+ std::string gTimeDelayDebugFunc = "";
+
+ void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
+ {
+ waitForEventOn(self, "mainloop");
+
+ LLTimer delayTimer;
+ delayTimer.reset();
+ delayTimer.setTimerExpirySec(5.0f);
+
+ while (!delayTimer.hasExpired())
+ {
+ waitForEventOn(self, "mainloop");
+ }
+
+ outboxPanel->onImportPostComplete(MarketplaceErrorCodes::IMPORT_DONE, LLSD::emptyMap());
+
+ gTimeDelayDebugFunc = "";
+ }
+
+ std::string gImportPollingFunc = "";
+
+ void importPoll(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
+ {
+ waitForEventOn(self, "mainloop");
+
+ while (outboxPanel->isImportInProgress())
+ {
+ LLTimer delayTimer;
+ delayTimer.reset();
+ delayTimer.setTimerExpirySec(5.0f);
+
+ while (!delayTimer.hasExpired())
+ {
+ waitForEventOn(self, "mainloop");
+ }
+
+ //outboxPanel->
+ }
+
+ gImportPollingFunc = "";
+ }
+
+*/
+
+ // Basic API
+
+ bool inProgress()
+ {
+ return sImportInProgress;
+ }
+
+ bool resultPending()
+ {
+ return sImportGetPending;
+ }
+
+ U32 getResultStatus()
+ {
+ return sImportResultStatus;
+ }
+
+ const LLSD& getResults()
+ {
+ return sImportResults;
+ }
+
+ void establishMarketplaceSessionCookie()
+ {
+ sImportInProgress = true;
+ sImportGetPending = true;
+
+ std::string url = getInventoryImportURL();
+
+ LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders());
+ }
+
+ void pollStatus()
+ {
+ sImportGetPending = true;
+
+ std::string url = getInventoryImportURL();
+
+ // Make the headers for the post
+ LLSD headers = LLSD::emptyMap();
+ headers["Accept"] = "*/*";
+ headers["Cookie"] = sMarketplaceCookie;
+ headers["Content-Type"] = "application/xml";
+ headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();
+
+ LLHTTPClient::get(url, new LLImportGetResponder(), headers);
+ }
+
+ void triggerImport()
+ {
+ sImportInProgress = true;
+ sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING;
+ sImportResults = LLSD::emptyMap();
+
+ std::string url = getInventoryImportURL();
+
+ // Make the headers for the post
+ LLSD headers = LLSD::emptyMap();
+ headers["Accept"] = "*/*";
+ headers["Connection"] = "Keep-Alive";
+ headers["Cookie"] = sMarketplaceCookie;
+ headers["Content-Type"] = "application/xml";
+ headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();
+
+ LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
+
+ // Set a timer (for testing only)
+ //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
+ }
+}
+
+
+//
+// Interface class
+//
+
+
+//static
+void LLMarketplaceInventoryImporter::update()
+{
+ if (instanceExists())
+ {
+ LLMarketplaceInventoryImporter::instance().updateImport();
+ }
+}
+
+LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
+ : mImportInProgress(false)
+ , mInitialized(false)
+ , mStatusChangedSignal(NULL)
+ , mStatusReportSignal(NULL)
+{
+}
+
+void LLMarketplaceInventoryImporter::initialize()
+{
+ if (!mInitialized)
+ {
+ LLMarketplaceImport::establishMarketplaceSessionCookie();
+ }
+}
+
+boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb)
+{
+ if (mStatusChangedSignal == NULL)
+ {
+ mStatusChangedSignal = new status_changed_signal_t();
+ }
+
+ return mStatusChangedSignal->connect(cb);
+}
+
+boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb)
+{
+ if (mStatusReportSignal == NULL)
+ {
+ mStatusReportSignal = new status_report_signal_t();
+ }
+
+ return mStatusReportSignal->connect(cb);
+}
+
+bool LLMarketplaceInventoryImporter::triggerImport()
+{
+ LLMarketplaceImport::triggerImport();
+
+ return LLMarketplaceImport::inProgress();
+}
+
+void LLMarketplaceInventoryImporter::updateImport()
+{
+ const bool in_progress = LLMarketplaceImport::inProgress();
+
+ if (in_progress && !LLMarketplaceImport::resultPending())
+ {
+ LLMarketplaceImport::pollStatus();
+ }
+
+ if (mImportInProgress != in_progress)
+ {
+ mImportInProgress = in_progress;
+
+ if (mStatusChangedSignal)
+ {
+ (*mStatusChangedSignal)(mImportInProgress);
+ }
+
+ // If we are no longer in progress, report results
+ if (!mImportInProgress && mStatusReportSignal)
+ {
+ if (mInitialized)
+ {
+ (*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+ }
+ else
+ {
+ mInitialized = true;
+ }
+ }
+ }
+}
+
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
new file mode 100644
index 0000000000..5ca0bdfe77
--- /dev/null
+++ b/indra/newview/llmarketplacefunctions.h
@@ -0,0 +1,84 @@
+/**
+ * @file llmarketplacefunctions.h
+ * @brief Miscellaneous marketplace-related functions and classes
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMARKETPLACEFUNCTIONS_H
+#define LL_LLMARKETPLACEFUNCTIONS_H
+
+
+#include <llsd.h>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llsingleton.h"
+
+
+namespace MarketplaceErrorCodes
+{
+ enum eCode
+ {
+ IMPORT_DONE = 200,
+ IMPORT_PROCESSING = 202,
+ IMPORT_DONE_WITH_ERRORS = 409,
+ IMPORT_JOB_FAILED = 410,
+ };
+}
+
+
+class LLMarketplaceInventoryImporter
+ : public LLSingleton<LLMarketplaceInventoryImporter>
+{
+public:
+ static void update();
+
+ LLMarketplaceInventoryImporter();
+
+ void initialize();
+
+ typedef boost::signals2::signal<void (bool)> status_changed_signal_t;
+ typedef boost::signals2::signal<void (U32, const LLSD&)> status_report_signal_t;
+
+ boost::signals2::connection setStatusChangedCallback(const status_changed_signal_t::slot_type& cb);
+ boost::signals2::connection setStatusReportCallback(const status_report_signal_t::slot_type& cb);
+
+ bool triggerImport();
+ bool isImportInProgress() const { return mImportInProgress; }
+
+protected:
+ void updateImport();
+
+private:
+ bool mImportInProgress;
+ bool mInitialized;
+
+ status_changed_signal_t * mStatusChangedSignal;
+ status_report_signal_t * mStatusReportSignal;
+};
+
+
+
+#endif // LL_LLMARKETPLACEFUNCTIONS_H
+
diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp
index 12960fd0d6..e3af7fd906 100644
--- a/indra/newview/llpanelmarketplaceoutbox.cpp
+++ b/indra/newview/llpanelmarketplaceoutbox.cpp
@@ -36,6 +36,7 @@
#include "llfloatersidepanelcontainer.h"
#include "llinventorypanel.h"
#include "llloadingindicator.h"
+#include "llmarketplacefunctions.h"
#include "llnotificationsutil.h"
#include "llpanelmarketplaceinbox.h"
#include "llsdutil.h"
@@ -47,6 +48,11 @@
#include "llfolderview.h"
#include "llinventoryfunctions.h"
+
+// Turn this on to get a bunch of console output for marketplace API calls, headers and status
+#define DEBUG_MARKETPLACE_HTTP_API 0
+
+
static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox");
const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultParams()
@@ -58,9 +64,9 @@ const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultPara
LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox(const Params& p)
: LLPanel(p)
, mInventoryPanel(NULL)
- , mSyncButton(NULL)
- , mSyncIndicator(NULL)
- , mSyncInProgress(false)
+ , mImportButton(NULL)
+ , mImportIndicator(NULL)
+ , mOutboxButton(NULL)
{
}
@@ -80,11 +86,13 @@ BOOL LLPanelMarketplaceOutbox::postBuild()
void LLPanelMarketplaceOutbox::handleLoginComplete()
{
- mSyncButton = getChild<LLButton>("outbox_sync_btn");
- mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this));
- mSyncButton->setEnabled(!isOutboxEmpty());
+ mImportButton = getChild<LLButton>("outbox_import_btn");
+ mImportButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onImportButtonClicked, this));
+ mImportButton->setEnabled(!isOutboxEmpty());
- mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator");
+ mImportIndicator = getChild<LLLoadingIndicator>("outbox_import_indicator");
+
+ mOutboxButton = getChild<LLButton>("outbox_btn");
}
void LLPanelMarketplaceOutbox::onFocusReceived()
@@ -134,9 +142,44 @@ LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
// Hide the placeholder text
outbox_inventory_placeholder->setVisible(FALSE);
+ // Set up marketplace importer
+ LLMarketplaceInventoryImporter::getInstance()->initialize();
+ LLMarketplaceInventoryImporter::getInstance()->setStatusChangedCallback(boost::bind(&LLPanelMarketplaceOutbox::importStatusChanged, this, _1));
+ LLMarketplaceInventoryImporter::getInstance()->setStatusReportCallback(boost::bind(&LLPanelMarketplaceOutbox::importReportResults, this, _1, _2));
+
+ updateImportButtonStatus();
+
return mInventoryPanel;
}
+void LLPanelMarketplaceOutbox::importReportResults(U32 status, const LLSD& content)
+{
+ if (status == MarketplaceErrorCodes::IMPORT_DONE)
+ {
+ LLNotificationsUtil::add("OutboxImportComplete", LLSD::emptyMap(), LLSD::emptyMap());
+ }
+ else if (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS)
+ {
+ LLNotificationsUtil::add("OutboxImportHadErrors", LLSD::emptyMap(), LLSD::emptyMap());
+ }
+ else
+ {
+ char status_string[16];
+ sprintf(status_string, "%d", status);
+
+ LLSD subs;
+ subs["ERROR_CODE"] = status_string;
+
+ //llassert(status == MarketplaceErrorCodes::IMPORT_JOB_FAILED);
+ LLNotificationsUtil::add("OutboxImportFailed", LLSD::emptyMap(), LLSD::emptyMap());
+ }
+}
+
+void LLPanelMarketplaceOutbox::importStatusChanged(bool inProgress)
+{
+ updateImportButtonStatus();
+}
+
BOOL LLPanelMarketplaceOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
@@ -163,159 +206,23 @@ bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
return (getTotalItemCount() == 0);
}
-bool LLPanelMarketplaceOutbox::isSyncInProgress() const
+void LLPanelMarketplaceOutbox::updateImportButtonStatus()
{
- return mSyncInProgress;
-}
-
-
-std::string gTimeDelayDebugFunc = "";
-
-void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
-{
- waitForEventOn(self, "mainloop");
-
- LLTimer delayTimer;
- delayTimer.reset();
- delayTimer.setTimerExpirySec(5.0f);
-
- while (!delayTimer.hasExpired())
- {
- waitForEventOn(self, "mainloop");
- }
-
- outboxPanel->onSyncComplete(true, LLSD::emptyMap());
-
- gTimeDelayDebugFunc = "";
-}
-
-
-class LLInventorySyncResponder : public LLHTTPClient::Responder
-{
-public:
- LLInventorySyncResponder(LLPanelMarketplaceOutbox * outboxPanel)
- : LLCurl::Responder()
- , mOutboxPanel(outboxPanel)
- {
- }
-
- void completed(U32 status, const std::string& reason, const LLSD& content)
+ if (LLMarketplaceInventoryImporter::instance().isImportInProgress())
{
- llinfos << "inventory_import complete status: " << status << ", reason: " << reason << llendl;
+ mImportButton->setVisible(false);
- if (isGoodStatus(status))
- {
- // Complete success
- llinfos << "success" << llendl;
- }
- else
- {
- llwarns << "failed" << llendl;
- }
-
- mOutboxPanel->onSyncComplete(isGoodStatus(status), content);
- }
-
-private:
- LLPanelMarketplaceOutbox * mOutboxPanel;
-};
-
-void LLPanelMarketplaceOutbox::onSyncButtonClicked()
-{
- // Get the sync animation going
- mSyncInProgress = true;
- updateSyncButtonStatus();
-
- // Make the url for the inventory import request
- std::string url = "https://marketplace.secondlife.com/";
-
- if (!LLGridManager::getInstance()->isInProductionGrid())
- {
- std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
- url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
-
- // TEMP for Jim's pdp
- //url = "http://pdp24.lindenlab.com:3000/";
- }
-
- url += "api/1/users/";
- url += gAgent.getID().getString();
- url += "/inventory_import";
-
- llinfos << "http get: " << url << llendl;
- LLHTTPClient::get(url, new LLInventorySyncResponder(this), LLViewerMedia::getHeaders());
-
- // Set a timer (for testing only)
- //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
-}
-
-void LLPanelMarketplaceOutbox::onSyncComplete(bool goodStatus, const LLSD& content)
-{
- mSyncInProgress = false;
- updateSyncButtonStatus();
-
- const LLSD& errors_list = content["errors"];
-
- if (goodStatus && (errors_list.size() == 0))
- {
- LLNotificationsUtil::add("OutboxUploadComplete", LLSD::emptyMap(), LLSD::emptyMap());
- }
- else
- {
- LLNotificationsUtil::add("OutboxUploadHadErrors", LLSD::emptyMap(), LLSD::emptyMap());
- }
-
- llinfos << "Marketplace upload llsd:" << llendl;
- llinfos << ll_pretty_print_sd(content) << llendl;
- llinfos << llendl;
-
- const LLSD& imported_list = content["imported"];
- LLSD::array_const_iterator it = imported_list.beginArray();
- for ( ; it != imported_list.endArray(); ++it)
- {
- LLUUID imported_folder = (*it).asUUID();
- llinfos << "Successfully uploaded folder " << imported_folder.asString() << " to marketplace." << llendl;
- }
-
- for (it = errors_list.beginArray(); it != errors_list.endArray(); ++it)
- {
- const LLSD& item_error_map = (*it);
-
- LLUUID error_folder = item_error_map["folder_id"].asUUID();
- const std::string& error_string = item_error_map["identifier"].asString();
- LLUUID error_item = item_error_map["item_id"].asUUID();
- const std::string& error_item_name = item_error_map["item_name"].asString();
- const std::string& error_message = item_error_map["message"].asString();
-
- llinfos << "Error item " << error_folder.asString() << ", " << error_string << ", "
- << error_item.asString() << ", " << error_item_name << ", " << error_message << llendl;
-
- LLFolderViewFolder * item_folder = mInventoryPanel->getRootFolder()->getFolderByID(error_folder);
- LLOutboxFolderViewFolder * outbox_item_folder = dynamic_cast<LLOutboxFolderViewFolder *>(item_folder);
-
- llassert(outbox_item_folder);
-
- outbox_item_folder->setErrorString(error_string);
- }
-}
-
-void LLPanelMarketplaceOutbox::updateSyncButtonStatus()
-{
- if (isSyncInProgress())
- {
- mSyncButton->setVisible(false);
-
- mSyncIndicator->setVisible(true);
- mSyncIndicator->reset();
- mSyncIndicator->start();
+ mImportIndicator->setVisible(true);
+ mImportIndicator->reset();
+ mImportIndicator->start();
}
else
{
- mSyncIndicator->stop();
- mSyncIndicator->setVisible(false);
+ mImportIndicator->stop();
+ mImportIndicator->setVisible(false);
- mSyncButton->setVisible(true);
- mSyncButton->setEnabled(!isOutboxEmpty());
+ mImportButton->setVisible(true);
+ mImportButton->setEnabled(!isOutboxEmpty());
}
}
@@ -330,12 +237,21 @@ U32 LLPanelMarketplaceOutbox::getTotalItemCount() const
if (outbox_folder)
{
item_count += outbox_folder->getFoldersCount();
+ item_count += outbox_folder->getItemsCount();
}
}
return item_count;
}
+void LLPanelMarketplaceOutbox::onImportButtonClicked()
+{
+ LLMarketplaceInventoryImporter::instance().triggerImport();
+
+ // Get the import animation going
+ updateImportButtonStatus();
+}
+
void LLPanelMarketplaceOutbox::draw()
{
const U32 item_count = getTotalItemCount();
@@ -347,16 +263,11 @@ void LLPanelMarketplaceOutbox::draw()
LLStringUtil::format_map_t args;
args["[NUM]"] = item_count_str;
- getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelWithArg", args));
+ mOutboxButton->setLabel(getString("OutboxLabelWithArg", args));
}
else
{
- getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelNoArg"));
- }
-
- if (!isSyncInProgress())
- {
- mSyncButton->setEnabled(not_empty);
+ mOutboxButton->setLabel(getString("OutboxLabelNoArg"));
}
LLPanel::draw();
diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h
index c6b4a5abe2..6f038118b3 100644
--- a/indra/newview/llpanelmarketplaceoutbox.h
+++ b/indra/newview/llpanelmarketplaceoutbox.h
@@ -59,9 +59,6 @@ public:
U32 getTotalItemCount() const;
bool isOutboxEmpty() const;
- bool isSyncInProgress() const;
-
- void onSyncComplete(bool goodStatus, const LLSD& content);
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -70,19 +67,23 @@ public:
std::string& tooltip_msg);
protected:
- void onSyncButtonClicked();
- void updateSyncButtonStatus();
+ void onImportButtonClicked();
+ void updateImportButtonStatus();
void handleLoginComplete();
void onFocusReceived();
void onSelectionChange();
-
+
+ void importReportResults(U32 status, const LLSD& content);
+ void importStatusChanged(bool inProgress);
+
private:
LLInventoryPanel * mInventoryPanel;
- LLButton * mSyncButton;
- LLLoadingIndicator * mSyncIndicator;
- bool mSyncInProgress;
+ LLButton * mImportButton;
+ LLLoadingIndicator * mImportIndicator;
+
+ LLButton * mOutboxButton;
};
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 9d069c3996..19a81b93bf 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -69,7 +69,7 @@ static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_
#define AUTO_EXPAND_INBOX 0
// Temporarily disabling the outbox until we straighten out the API
-#define ENABLE_MERCHANT_OUTBOX_PANEL 0 // keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
+#define ENABLE_MERCHANT_OUTBOX_PANEL 1 // keep in sync with ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
static const char * const INBOX_BUTTON_NAME = "inbox_btn";
static const char * const OUTBOX_BUTTON_NAME = "outbox_btn";
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 8406f639df..01650881f9 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -83,6 +83,7 @@
#include "llfloaternotificationsconsole.h"
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
+#include "llfloateroutbox.h"
#include "llfloaterpay.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
@@ -238,6 +239,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
+ LLFloaterReg::add("outbox", "floater_merchant_outbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutbox>);
LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
LLFloaterPayUtil::registerFloater();
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 263d8b4146..eb7a4aa538 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -26,51 +26,50 @@
#include "llviewerprecompiledheaders.h"
+#include "llviewermedia.h"
+
#include "llagent.h"
#include "llagentcamera.h"
-#include "llviewermedia.h"
-#include "llviewermediafocus.h"
-#include "llmimetypes.h"
+#include "llappviewer.h"
+#include "llaudioengine.h" // for gAudiop
+#include "llcallbacklist.h"
+#include "lldir.h"
+#include "lldiriterator.h"
+#include "llevent.h" // LLSimpleListener
+#include "llfilepicker.h"
+#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
+#include "llfocusmgr.h"
+#include "llkeyboard.h"
+#include "lllogininstance.h"
+#include "llmarketplacefunctions.h"
#include "llmediaentry.h"
+#include "llmimetypes.h"
+#include "llmutelist.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpanelprofile.h"
+#include "llparcel.h"
+#include "llpluginclassmedia.h"
+#include "llplugincookiestore.h"
+#include "llurldispatcher.h"
+#include "lluuid.h"
#include "llversioninfo.h"
+#include "llviewermediafocus.h"
#include "llviewercontrol.h"
-#include "llviewertexture.h"
+#include "llviewernetwork.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewertexture.h"
#include "llviewertexturelist.h"
-#include "llvovolume.h"
-#include "llpluginclassmedia.h"
-#include "llplugincookiestore.h"
#include "llviewerwindow.h"
-#include "llfocusmgr.h"
-#include "llcallbacklist.h"
-#include "llparcel.h"
-#include "llaudioengine.h" // for gAudiop
-#include "llurldispatcher.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
-#include "llviewerregion.h"
+#include "llvovolume.h"
#include "llwebprofile.h"
#include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!
-#include "llfilepicker.h"
-#include "llnotifications.h"
-#include "lldir.h"
-#include "lldiriterator.h"
-#include "llevent.h" // LLSimpleListener
-#include "llnotificationsutil.h"
-#include "lluuid.h"
-#include "llkeyboard.h"
-#include "llmutelist.h"
-#include "llpanelprofile.h"
-#include "llappviewer.h"
-#include "lllogininstance.h"
-//#include "llfirstuse.h"
-#include "llviewernetwork.h"
#include "llwindow.h"
-
-#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
-
#include <boost/bind.hpp> // for SkinFolder listener
#include <boost/signals2.hpp>
@@ -1387,75 +1386,11 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom
}
-// This is defined in two files but I don't want to create a dependence between this and llsidepanelinventory
-// just to be able to temporarily disable the outbox.
-#define ENABLE_INVENTORY_DISPLAY_OUTBOX 0 // keep in sync with ENABLE_MERCHANT_OUTBOX_PANEL, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
-
-class LLInventoryUserStatusResponder : public LLHTTPClient::Responder
-{
-public:
- LLInventoryUserStatusResponder()
- : LLCurl::Responder()
- {
- }
-
- void completed(U32 status, const std::string& reason, const LLSD& content)
- {
- if (isGoodStatus(status))
- {
- std::string merchantStatus = content[gAgent.getID().getString()].asString();
- llinfos << "Marketplace merchant status: " << merchantStatus << llendl;
-
- // Save the merchant status before turning on the display
- gSavedSettings.setString("InventoryMarketplaceUserStatus", merchantStatus);
-
- // Complete success
- gSavedSettings.setBOOL("InventoryDisplayInbox", true);
-
-#if ENABLE_INVENTORY_DISPLAY_OUTBOX
- gSavedSettings.setBOOL("InventoryDisplayOutbox", true);
-#endif
- }
- else if (status == 401)
- {
- // API is available for use but OpenID authorization failed
- gSavedSettings.setBOOL("InventoryDisplayInbox", true);
- }
- else
- {
- // API in unavailable
- llinfos << "Marketplace API is unavailable -- Inbox may be disabled, status = " << status << ", reason = " << reason << llendl;
- }
- }
-};
-
-
-void doOnetimeEarlyHTTPRequests()
-{
- std::string url = "https://marketplace.secondlife.com/";
-
- if (!LLGridManager::getInstance()->isInProductionGrid())
- {
- std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
- url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
-
- // TEMP for Jim's pdp
- //url = "http://pdp24.lindenlab.com:3000/";
- }
-
- url += "api/1/users/";
- url += gAgent.getID().getString();
- url += "/user_status";
-
- llinfos << "http get: " << url << llendl;
- LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), LLViewerMedia::getHeaders());
-}
-
-
LLSD LLViewerMedia::getHeaders()
{
LLSD headers = LLSD::emptyMap();
headers["Accept"] = "*/*";
+ headers["Content-Type"] = "application/xml";
headers["Cookie"] = sOpenIDCookie;
headers["User-Agent"] = getCurrentUserAgent();
@@ -1510,9 +1445,6 @@ void LLViewerMedia::setOpenIDCookie()
LLHTTPClient::get(profile_url,
new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
headers);
-
- // FUI: No longer perform the user_status query
- //doOnetimeEarlyHTTPRequests();
}
}
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 8702ebde2a..5da1276881 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -137,6 +137,7 @@ with the same filename but different name
<texture name="Command_MiniCart_Icon" file_name="toolbar_icons/mini_cart.png" preload="true" />
<texture name="Command_MiniMap_Icon" file_name="toolbar_icons/mini_map.png" preload="true" />
<texture name="Command_Move_Icon" file_name="toolbar_icons/move.png" preload="true" />
+ <texture name="Command_Outbox_Icon" file_name="toolbar_icons/outbox.png" preload="true" />
<texture name="Command_People_Icon" file_name="toolbar_icons/people.png" preload="true" />
<texture name="Command_Picks_Icon" file_name="toolbar_icons/picks.png" preload="true" />
<texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" />
diff --git a/indra/newview/skins/default/textures/toolbar_icons/outbox.png b/indra/newview/skins/default/textures/toolbar_icons/outbox.png
new file mode 100644
index 0000000000..9fcf46794d
--- /dev/null
+++ b/indra/newview/skins/default/textures/toolbar_icons/outbox.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
new file mode 100644
index 0000000000..2f8a83c072
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<floater
+ open_positioning="cascading"
+ can_close="true"
+ can_resize="true"
+ height="400"
+ help_topic="floater_merchant_outbox"
+ min_width="333"
+ min_height="440"
+ name="floater_merchant_outbox"
+ save_rect="true"
+ save_visibility="true"
+ reuse_instance="true"
+ title="MERCHANT OUTBOX"
+ width="333" >
+ <panel
+ follows="all"
+ layout="topleft"
+ left="0"
+ name="marketplace_outbox"
+ class="panel_marketplace_outbox"
+ top="0"
+ label=""
+ height="400"
+ width="330">
+ <string name="OutboxLabelWithArg">Merchant outbox ([NUM])</string>
+ <string name="OutboxLabelNoArg">Merchant outbox</string>
+ <button
+ label="Merchant outbox"
+ font="SansSerifMedium"
+ name="outbox_btn"
+ height="35"
+ width="308"
+ image_unselected="MarketplaceBtn_Off"
+ image_selected="MarketplaceBtn_Selected"
+ halign="left"
+ handle_right_mouse="false"
+ follows="top|left|right"
+ is_toggle="true"
+ tab_stop="false"
+ pad_left="35"
+ top="0"
+ left="10" />
+ <button
+ image_unselected="OutboxPush_Off"
+ image_selected="OutboxPush_Selected"
+ image_hover_selected="OutboxPush_Selected_Over"
+ image_hover_unselected="OutboxPush_Over"
+ image_disabled_selected="OutboxPush_Selected_Disabled"
+ image_disabled="OutboxPush_Disabled"
+ image_pressed="OutboxPush_Press"
+ image_pressed_selected="OutboxPush_Selected_Press"
+ label=""
+ tool_tip="Push to my Marketplace Storefront"
+ is_toggle="false"
+ name="outbox_sync_btn"
+ follows="top|right"
+ tab_stop="false"
+ halign="center"
+ top="6"
+ left="-50"
+ height="23"
+ width="32"
+ enabled="false" />
+ <loading_indicator
+ follows="top|right"
+ name="outbox_sync_indicator"
+ top="6"
+ left="-50"
+ height="23"
+ width="32"
+ images_per_sec="1.15"
+ tab_stop="false"
+ visible="false">
+ <images>
+ <image name="OutboxPush_Progress_1"/>
+ <image name="OutboxPush_Progress_2"/>
+ <image name="OutboxPush_Progress_3"/>
+ <image name="OutboxPush_Progress_4"/>
+ <image name="OutboxPush_Progress_5"/>
+ <image name="OutboxPush_Progress_6"/>
+ </images>
+ </loading_indicator>
+ <panel
+ follows="all"
+ left="10"
+ bottom="400"
+ width="308"
+ top="35"
+ bg_opaque_color="InventoryBackgroundColor"
+ background_visible="true"
+ background_opaque="true"
+ >
+ <panel
+ name="outbox_inventory_placeholder_panel"
+ follows="all"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="308"
+ height="365"
+ bg_opaque_color="InventoryBackgroundColor"
+ background_visible="true"
+ background_opaque="true"
+ >
+ <text
+ name="outbox_inventory_placeholder_title"
+ type="string"
+ follows="all"
+ layout="topleft"
+ top="10"
+ left="0"
+ width="308"
+ height="25"
+ wrap="true"
+ halign="center"
+ font="SansSerifBold">
+ Loading...
+ </text>
+ <text
+ name="outbox_inventory_placeholder_text"
+ type="string"
+ follows="all"
+ layout="topleft"
+ top="35"
+ left="0"
+ width="308"
+ height="130"
+ wrap="true"
+ halign="left" />
+ </panel>
+ </panel>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml
index 493d44a9cf..72e6187a14 100644
--- a/indra/newview/skins/default/xui/en/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/en/floater_toybox.xml
@@ -5,7 +5,7 @@
can_minimize="false"
can_resize="false"
default_tab_group="1"
- height="330"
+ height="375"
help_topic="toybox"
layout="topleft"
legacy_header_height="18"
@@ -46,7 +46,7 @@
Buttons will appear as shown or as icon-only depending on each toolbar's settings.
</text>
<toolbar
- bottom="265"
+ bottom="310"
button_display_mode="icons_with_text"
follows="all"
left="20"
@@ -82,11 +82,11 @@
<panel
bevel_style="none"
border="true"
- bottom="266"
+ bottom="311"
follows="left|bottom|right"
left="20"
right="-20"
- top="266" />
+ top="311" />
<button
follows="left|bottom|right"
height="23"
@@ -95,7 +95,7 @@
layout="topleft"
left="185"
name="btn_clear_all"
- top="285"
+ top="330"
width="130">
<button.commit_callback function="Toybox.ClearAll" />
</button>
@@ -107,7 +107,7 @@
layout="topleft"
left="335"
name="btn_restore_defaults"
- top="285"
+ top="330"
width="130">
<button.commit_callback function="Toybox.RestoreDefaults" />
</button>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d925bf8f96..8d0d76b58e 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -213,9 +213,9 @@ Save changes to current clothing/body part?
<notification
icon="alertmodal.tga"
- name="OutboxUploadComplete"
+ name="OutboxImportComplete"
type="alertmodal">
-Marketplace upload complete.
+Marketplace import complete.
<usetemplate
name="okbutton"
yestext="Hooray!"/>
@@ -223,14 +223,24 @@ Marketplace upload complete.
<notification
icon="alertmodal.tga"
- name="OutboxUploadHadErrors"
+ name="OutboxImportHadErrors"
type="alertmodal">
-Marketplace upload completed with errors! Please correct the problems in your outbox and retry. Thanks.
+Marketplace import completed with errors! Please correct the problems in your outbox and retry. Thanks.
<usetemplate
name="okbutton"
yestext="Boo!"/>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ name="OutboxImportFailed"
+ type="alertmodal">
+Marketplace import failed with error [ERROR_CODE]! Please try again later. Thanks.
+ <usetemplate
+ name="okbutton"
+ yestext="Rats!"/>
+ </notification>
+
<notification
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index b52784d6bc..9f3c57fa0f 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -205,7 +205,7 @@
label=""
tool_tip="Push to my Marketplace Storefront"
is_toggle="false"
- name="outbox_sync_btn"
+ name="outbox_import_btn"
follows="top|right"
tab_stop="false"
halign="center"
@@ -216,7 +216,7 @@
enabled="false" />
<loading_indicator
follows="top|right"
- name="outbox_sync_indicator"
+ name="outbox_import_indicator"
top="6"
left="-50"
height="23"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c25d1f57d6..b8d5f93320 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3675,6 +3675,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Marketplace_Label">Marketplace</string>
<string name="Command_MiniMap_Label">Mini-map</string>
<string name="Command_Move_Label">Walk / run / fly</string>
+ <string name="Command_Outbox_Label">Merchant outbox</string>
<string name="Command_People_Label">People</string>
<string name="Command_Picks_Label">Picks</string>
<string name="Command_Places_Label">Places</string>
@@ -3700,6 +3701,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Marketplace_Tooltip">Go shopping</string>
<string name="Command_MiniMap_Tooltip">Show nearby people</string>
<string name="Command_Move_Tooltip">Moving your avatar</string>
+ <string name="Command_Outbox_Tooltip">Transfer items to your marketplace for sale</string>
<string name="Command_People_Tooltip">Friends, groups, and nearby people</string>
<string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>
<string name="Command_Places_Tooltip">Places you've saved</string>