diff options
-rw-r--r-- | indra/newview/llfloateroutbox.cpp | 309 | ||||
-rw-r--r-- | indra/newview/llfloateroutbox.h | 44 | ||||
-rw-r--r-- | indra/newview/llmarketplacefunctions.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llsidepanelinventory.cpp | 2 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_merchant_outbox.xml | 137 |
5 files changed, 416 insertions, 83 deletions
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp index 8fea3d674e..79cd90ba1c 100644 --- a/indra/newview/llfloateroutbox.cpp +++ b/indra/newview/llfloateroutbox.cpp @@ -29,40 +29,333 @@ #include "llfloateroutbox.h" #include "llfloaterreg.h" +#include "llfolderview.h" +#include "llinventoryobserver.h" +#include "llinventorypanel.h" +#include "llloadingindicator.h" +#include "llmarketplacefunctions.h" +#include "llnotificationsutil.h" +#include "lltextbox.h" #include "lltransientfloatermgr.h" +#include "lltrans.h" +#include "llviewernetwork.h" ///---------------------------------------------------------------------------- +/// LLOutboxAddedObserver helper class +///---------------------------------------------------------------------------- + +class LLOutboxAddedObserver : public LLInventoryCategoryAddedObserver +{ +public: + LLOutboxAddedObserver(LLFloaterOutbox * outboxFloater) + : LLInventoryCategoryAddedObserver() + , mOutboxFloater(outboxFloater) + { + } + + 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_OUTBOX) + { + mOutboxFloater->setupOutbox(added_category->getUUID()); + } + } + } + +private: + LLFloaterOutbox * mOutboxFloater; +}; + +///---------------------------------------------------------------------------- /// LLFloaterOutbox ///---------------------------------------------------------------------------- LLFloaterOutbox::LLFloaterOutbox(const LLSD& key) : LLFloater(key) - , mPanelOutboxInventory(NULL) + , mCategoriesObserver(NULL) + , mCategoryAddedObserver(NULL) + , mOutboxId(LLUUID::null) + , mOutboxInventoryPanel(NULL) + , mOutboxItemCount(0) + , mInventoryDisablePanel(NULL) + , mInventoryFolderCountText(NULL) + , mInventoryImportInProgress(NULL) + , mInventoryPlaceholder(NULL) + , mInventoryText(NULL) + , mInventoryTitle(NULL) + , mImportButton(NULL) { - LLTransientFloaterMgr::getInstance()->addControlView(this); } LLFloaterOutbox::~LLFloaterOutbox() { - LLTransientFloaterMgr::getInstance()->removeControlView(this); +// delete mCategoriesObserver; +// delete mCategoryAddedObserver; } BOOL LLFloaterOutbox::postBuild() { + mInventoryDisablePanel = getChild<LLView>("outbox_inventory_disable_panel"); + mInventoryFolderCountText = getChild<LLTextBox>("outbox_folder_count"); + mInventoryImportInProgress = getChild<LLLoadingIndicator>("import_progress_indicator"); + mInventoryPlaceholder = getChild<LLView>("outbox_inventory_placeholder_panel"); + mInventoryText = mInventoryPlaceholder->getChild<LLTextBox>("outbox_inventory_placeholder_text"); + mInventoryTitle = mInventoryPlaceholder->getChild<LLTextBox>("outbox_inventory_placeholder_title"); + + mImportButton = getChild<LLButton>("outbox_import_btn"); + mImportButton->setCommitCallback(boost::bind(&LLFloaterOutbox::onImportButtonClicked, this)); + return TRUE; } void LLFloaterOutbox::onOpen(const LLSD& key) { - //LLFirstUse::useInventory(); + // + // Initialize the marketplace import API + // + + LLMarketplaceInventoryImporter::getInstance()->initialize(); + LLMarketplaceInventoryImporter::getInstance()->setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1)); + LLMarketplaceInventoryImporter::getInstance()->setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2)); + + // + // Look for an outbox and set up the inventory API + // + + const bool do_not_create_folder = false; + const bool do_not_find_in_library = false; + + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); + + if (outbox_id.isNull()) + { + // Observe category creation to catch outbox creation + mCategoryAddedObserver = new LLOutboxAddedObserver(this); + gInventory.addObserver(mCategoryAddedObserver); + } + else + { + setupOutbox(outbox_id); + } + + updateView(); +} + +void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId) +{ + llassert(mOutboxId.isNull()); + llassert(mCategoriesObserver == NULL); + + mOutboxId = outboxId; + + // No longer need to observe new category creation + if (mCategoryAddedObserver != NULL) + { + gInventory.removeObserver(mCategoryAddedObserver); + } + + // Create observer for outbox modifications + mCategoriesObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mCategoriesObserver); + + mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); + + // + // Set up the outbox inventory view + // + + mOutboxInventoryPanel = + LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", + mInventoryPlaceholder->getParent(), + LLInventoryPanel::child_registry_t::instance()); + + llassert(mOutboxInventoryPanel); + + // Reshape the inventory to the proper size + LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect(); + mOutboxInventoryPanel->setShape(inventory_placeholder_rect); + + // Set the sort order newest to oldest + mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE); + mOutboxInventoryPanel->getFilter()->markDefault(); + + // Set selection callback for proper update of inventory status buttons + //mOutboxInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this)); + + // Set up the note to display when the outbox is empty + mOutboxInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryOutboxNoItems"); +} + +void LLFloaterOutbox::updateView() +{ + if (mOutboxItemCount > 0) + { + mOutboxInventoryPanel->setVisible(TRUE); + mInventoryPlaceholder->setVisible(FALSE); + } + else + { + mOutboxInventoryPanel->setVisible(FALSE); + mInventoryPlaceholder->setVisible(TRUE); + + std::string outbox_text; + std::string outbox_title; + std::string outbox_tooltip; + + if (mOutboxId.notNull()) + { + outbox_text = LLTrans::getString("InventoryOutboxNoItems"); + outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip"); + } + else + { + // + // The string to become a merchant contains 3 URL's which need the domain name patched in. + // + + std::string domain = "secondlife.com"; + + if (!LLGridManager::getInstance()->isInProductionGrid()) + { + std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); + domain = llformat("%s.lindenlab.com", utf8str_tolower(gridLabel).c_str()); + } + + LLStringUtil::format_map_t domain_arg; + domain_arg["[DOMAIN_NAME]"] = domain; + + std::string marketplace_url = LLTrans::getString("MarketplaceURL", domain_arg); + std::string marketplace_url_create = LLTrans::getString("MarketplaceURL_CreateStore", domain_arg); + std::string marketplace_url_info = LLTrans::getString("MarketplaceURL_LearnMore", domain_arg); + + LLStringUtil::format_map_t args1, args2, args3; + args1["[MARKETPLACE_URL]"] = marketplace_url; + args2["[LEARN_MORE_URL]"] = marketplace_url_info; + args3["[CREATE_STORE_URL]"] = marketplace_url_create; + + // NOTE: This is dumb, ridiculous and very finicky. The order of these is very important + // to have these three string substitutions work properly. + outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", args1); + LLStringUtil::format(outbox_text, args2); + LLStringUtil::format(outbox_text, args3); + + outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip"); + } + + mInventoryText->setValue(outbox_text); + mInventoryTitle->setValue(outbox_title); + mInventoryPlaceholder->getParent()->setToolTip(outbox_tooltip); + } +} + +BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + // Pass drag and drop to this floater to the outbox inventory control + + S32 local_x = x - mOutboxInventoryPanel->getRect().mLeft; + S32 local_y = y - mOutboxInventoryPanel->getRect().mBottom; + + return mOutboxInventoryPanel->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); +} + +void LLFloaterOutbox::onImportButtonClicked() +{ + LLMarketplaceInventoryImporter::instance().triggerImport(); +} + +void LLFloaterOutbox::onOutboxChanged() +{ + llassert(!mOutboxId.isNull()); + + U32 item_count = 0; + + const LLFolderViewFolder * outbox_folder = mOutboxInventoryPanel->getRootFolder(); + + if (outbox_folder) + { + item_count += outbox_folder->getFoldersCount(); + item_count += outbox_folder->getItemsCount(); + } + + mOutboxItemCount = item_count; + + switch (mOutboxItemCount) + { + case 0: mInventoryFolderCountText->setText(getString("OutboxFolderCount0")); break; + case 1: mInventoryFolderCountText->setText(getString("OutboxFolderCount1")); break; + default: + { + std::string item_count_str = llformat("%d", mOutboxItemCount); + + LLStringUtil::format_map_t args; + args["[NUM]"] = item_count_str; + + mInventoryFolderCountText->setText(getString("OutboxFolderCountN", args)); + break; + } + } + + mImportButton->setEnabled(mOutboxItemCount > 0); + + updateView(); } -void LLFloaterOutbox::onClose(bool app_quitting) +void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content) { - LLFloater::onClose(app_quitting); - if (mKey.asInteger() > 1) + 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 { - destroy(); + 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 LLFloaterOutbox::importStatusChanged(bool inProgress) +{ + if (inProgress) + { + mImportButton->setEnabled(false); + + mInventoryDisablePanel->setVisible(true); + + mInventoryImportInProgress->setVisible(true); + mInventoryImportInProgress->reset(); + mInventoryImportInProgress->start(); + } + else + { + mImportButton->setEnabled(mOutboxItemCount > 0); + + mInventoryDisablePanel->setVisible(false); + + mInventoryImportInProgress->stop(); + mInventoryImportInProgress->setVisible(false); + } +} + diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h index cb5c2be81c..1e8567ef12 100644 --- a/indra/newview/llfloateroutbox.h +++ b/indra/newview/llfloateroutbox.h @@ -31,7 +31,15 @@ #include "llfloater.h" #include "llfoldertype.h" + +class LLButton; +class LLInventoryCategoriesObserver; +class LLInventoryCategoryAddedObserver; class LLInventoryPanel; +class LLLoadingIndicator; +class LLTextBox; +class LLView; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFloaterOutbox @@ -42,15 +50,43 @@ class LLFloaterOutbox : public LLFloater public: LLFloaterOutbox(const LLSD& key); ~LLFloaterOutbox(); + + void setupOutbox(const LLUUID& outboxId); + // virtuals BOOL postBuild(); + void onOpen(const LLSD& key); + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); - // Inherited functionality - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); +protected: + void importReportResults(U32 status, const LLSD& content); + void importStatusChanged(bool inProgress); + + void onImportButtonClicked(); + void onOutboxChanged(); + + void updateView(); private: - LLInventoryPanel* mPanelOutboxInventory; + LLInventoryCategoriesObserver * mCategoriesObserver; + LLInventoryCategoryAddedObserver * mCategoryAddedObserver; + + LLUUID mOutboxId; + LLInventoryPanel * mOutboxInventoryPanel; + U32 mOutboxItemCount; + + LLView * mInventoryDisablePanel; + LLTextBox * mInventoryFolderCountText; + LLLoadingIndicator * mInventoryImportInProgress; + LLView * mInventoryPlaceholder; + LLTextBox * mInventoryText; + LLTextBox * mInventoryTitle; + + LLButton * mImportButton; }; #endif // LL_LLFLOATEROUTBOX_H diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index b9e02a36b4..9c67c589b8 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -55,6 +55,7 @@ namespace LLMarketplaceImport static std::string sMarketplaceCookie = ""; static bool sImportInProgress = false; + static bool sImportPostPending = false; static bool sImportGetPending = false; static U32 sImportResultStatus = 0; static LLSD sImportResults = LLSD::emptyMap(); @@ -106,6 +107,7 @@ namespace LLMarketplaceImport void completed(U32 status, const std::string& reason, const LLSD& content) { sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); + sImportPostPending = false; sImportResultStatus = status; } }; @@ -185,7 +187,7 @@ namespace LLMarketplaceImport bool resultPending() { - return sImportGetPending; + return (sImportPostPending || sImportGetPending); } U32 getResultStatus() @@ -226,7 +228,8 @@ namespace LLMarketplaceImport void triggerImport() { - sImportInProgress = true; + sImportInProgress = true; + sImportPostPending = true; sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING; sImportResults = LLSD::emptyMap(); diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 19a81b93bf..9c551be2d5 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -926,7 +926,7 @@ U32 LLSidepanelInventory::getSelectedCount() { selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList(); - count += selection_list.size(); + count += selection_list.size(); } if ((count == 0) && mOutboxEnabled && (mInventoryPanelOutbox != NULL)) diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml index 2f8a83c072..86e27cbc71 100644 --- a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml +++ b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml @@ -3,90 +3,33 @@ open_positioning="cascading" can_close="true" can_resize="true" - height="400" + height="440" help_topic="floater_merchant_outbox" - min_width="333" - min_height="440" + min_width="300" + min_height="240" name="floater_merchant_outbox" save_rect="true" save_visibility="true" reuse_instance="true" title="MERCHANT OUTBOX" width="333" > + <string name="OutboxFolderCount0">0 folders</string> + <string name="OutboxFolderCount1">1 folder</string> + <string name="OutboxFolderCountN">[NUM] folders</string> <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> + height="440" + width="333"> <panel follows="all" left="10" bottom="400" - width="308" - top="35" + width="313" + top="0" bg_opaque_color="InventoryBackgroundColor" background_visible="true" background_opaque="true" @@ -98,7 +41,7 @@ top="0" left="0" width="308" - height="365" + height="400" bg_opaque_color="InventoryBackgroundColor" background_visible="true" background_opaque="true" @@ -130,5 +73,63 @@ halign="left" /> </panel> </panel> + <panel + name="outbox_inventory_disable_panel" + follows="all" + left="0" + bottom="440" + width="333" + top="0" + bg_opaque_color="White_50" + background_visible="true" + background_opaque="true" + visible="false" + /> + <loading_indicator + follows="all" + height="65" + layout="topleft" + left="140" + name="import_progress_indicator" + top="180" + visible="false" + width="45" /> + <panel + follows="bottom|left|right" + left="10" + bottom="435" + width="313" + top="405" + bg_opaque_color="InventoryBackgroundColor" + background_visible="true" + background_opaque="true" + > + <text + name="outbox_folder_count" + type="string" + follows="all" + layout="topleft" + top="7" + left="5" + width="100" + height="20" + wrap="true" + halign="left" + valign="baseline" + font="SansSerifBold" /> + <button + label="Send to Marketplace" + tool_tip="Push to my Marketplace Storefront" + is_toggle="false" + name="outbox_import_btn" + follows="bottom|right" + tab_stop="false" + halign="center" + top="3" + left="110" + height="25" + width="200" + enabled="false" /> + </panel> </panel> </floater> |