PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llpanelmarketplaceoutbox.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 363 lines | 252 code | 72 blank | 39 comment | 22 complexity | c3c664ed3fb0c124a9bf20d9f151ffc7 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llpanelmarketplaceoutbox.cpp
  3. * @brief Panel for marketplace outbox
  4. *
  5. * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llpanelmarketplaceoutbox.h"
  28. #include "llpanelmarketplaceoutboxinventory.h"
  29. #include "llappviewer.h"
  30. #include "llbutton.h"
  31. #include "llcoros.h"
  32. #include "lleventcoro.h"
  33. #include "llfloatersidepanelcontainer.h"
  34. #include "llinventorypanel.h"
  35. #include "llloadingindicator.h"
  36. #include "llnotificationsutil.h"
  37. #include "llpanelmarketplaceinbox.h"
  38. #include "llsdutil.h"
  39. #include "llsidepanelinventory.h"
  40. #include "lltimer.h"
  41. #include "llviewernetwork.h"
  42. #include "llagent.h"
  43. #include "llviewermedia.h"
  44. #include "llfolderview.h"
  45. #include "llinventoryfunctions.h"
  46. static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox");
  47. const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultParams()
  48. {
  49. return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceOutbox>();
  50. }
  51. // protected
  52. LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox(const Params& p)
  53. : LLPanel(p)
  54. , mInventoryPanel(NULL)
  55. , mSyncButton(NULL)
  56. , mSyncIndicator(NULL)
  57. , mSyncInProgress(false)
  58. {
  59. }
  60. LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox()
  61. {
  62. }
  63. // virtual
  64. BOOL LLPanelMarketplaceOutbox::postBuild()
  65. {
  66. LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceOutbox::handleLoginComplete, this));
  67. LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this));
  68. return TRUE;
  69. }
  70. void LLPanelMarketplaceOutbox::handleLoginComplete()
  71. {
  72. mSyncButton = getChild<LLButton>("outbox_sync_btn");
  73. mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this));
  74. mSyncButton->setEnabled(!isOutboxEmpty());
  75. mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator");
  76. }
  77. void LLPanelMarketplaceOutbox::onFocusReceived()
  78. {
  79. LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
  80. if (sidepanel_inventory)
  81. {
  82. sidepanel_inventory->clearSelections(true, true, false);
  83. }
  84. }
  85. void LLPanelMarketplaceOutbox::onSelectionChange()
  86. {
  87. LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
  88. if (sidepanel_inventory)
  89. {
  90. sidepanel_inventory->updateVerbs();
  91. }
  92. }
  93. LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
  94. {
  95. LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel");
  96. LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent();
  97. mInventoryPanel =
  98. LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
  99. outbox_inventory_parent,
  100. LLInventoryPanel::child_registry_t::instance());
  101. llassert(mInventoryPanel);
  102. // Reshape the inventory to the proper size
  103. LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect();
  104. mInventoryPanel->setShape(inventory_placeholder_rect);
  105. // Set the sort order newest to oldest
  106. mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
  107. mInventoryPanel->getFilter()->markDefault();
  108. // Set selection callback for proper update of inventory status buttons
  109. mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this));
  110. // Set up the note to display when the outbox is empty
  111. mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryOutboxNoItems");
  112. // Hide the placeholder text
  113. outbox_inventory_placeholder->setVisible(FALSE);
  114. return mInventoryPanel;
  115. }
  116. BOOL LLPanelMarketplaceOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
  117. EDragAndDropType cargo_type,
  118. void* cargo_data,
  119. EAcceptance* accept,
  120. std::string& tooltip_msg)
  121. {
  122. BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
  123. if (!handled && mInventoryPanel && mInventoryPanel->getRootFolder())
  124. {
  125. handled = mInventoryPanel->getRootFolder()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
  126. if (handled)
  127. {
  128. mInventoryPanel->getRootFolder()->setDragAndDropThisFrame();
  129. }
  130. }
  131. return handled;
  132. }
  133. bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
  134. {
  135. return (getTotalItemCount() == 0);
  136. }
  137. bool LLPanelMarketplaceOutbox::isSyncInProgress() const
  138. {
  139. return mSyncInProgress;
  140. }
  141. std::string gTimeDelayDebugFunc = "";
  142. void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
  143. {
  144. waitForEventOn(self, "mainloop");
  145. LLTimer delayTimer;
  146. delayTimer.reset();
  147. delayTimer.setTimerExpirySec(5.0f);
  148. while (!delayTimer.hasExpired())
  149. {
  150. waitForEventOn(self, "mainloop");
  151. }
  152. outboxPanel->onSyncComplete(true, LLSD::emptyMap());
  153. gTimeDelayDebugFunc = "";
  154. }
  155. class LLInventorySyncResponder : public LLHTTPClient::Responder
  156. {
  157. public:
  158. LLInventorySyncResponder(LLPanelMarketplaceOutbox * outboxPanel)
  159. : LLCurl::Responder()
  160. , mOutboxPanel(outboxPanel)
  161. {
  162. }
  163. void completed(U32 status, const std::string& reason, const LLSD& content)
  164. {
  165. llinfos << "inventory_import complete status: " << status << ", reason: " << reason << llendl;
  166. if (isGoodStatus(status))
  167. {
  168. // Complete success
  169. llinfos << "success" << llendl;
  170. }
  171. else
  172. {
  173. llwarns << "failed" << llendl;
  174. }
  175. mOutboxPanel->onSyncComplete(isGoodStatus(status), content);
  176. }
  177. private:
  178. LLPanelMarketplaceOutbox * mOutboxPanel;
  179. };
  180. void LLPanelMarketplaceOutbox::onSyncButtonClicked()
  181. {
  182. // Get the sync animation going
  183. mSyncInProgress = true;
  184. updateSyncButtonStatus();
  185. // Make the url for the inventory import request
  186. std::string url = "https://marketplace.secondlife.com/";
  187. if (!LLGridManager::getInstance()->isInProductionGrid())
  188. {
  189. std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
  190. url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
  191. // TEMP for Jim's pdp
  192. //url = "http://pdp24.lindenlab.com:3000/";
  193. }
  194. url += "api/1/users/";
  195. url += gAgent.getID().getString();
  196. url += "/inventory_import";
  197. llinfos << "http get: " << url << llendl;
  198. LLHTTPClient::get(url, new LLInventorySyncResponder(this), LLViewerMedia::getHeaders());
  199. // Set a timer (for testing only)
  200. //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
  201. }
  202. void LLPanelMarketplaceOutbox::onSyncComplete(bool goodStatus, const LLSD& content)
  203. {
  204. mSyncInProgress = false;
  205. updateSyncButtonStatus();
  206. const LLSD& errors_list = content["errors"];
  207. if (goodStatus && (errors_list.size() == 0))
  208. {
  209. LLNotificationsUtil::add("OutboxUploadComplete", LLSD::emptyMap(), LLSD::emptyMap());
  210. }
  211. else
  212. {
  213. LLNotificationsUtil::add("OutboxUploadHadErrors", LLSD::emptyMap(), LLSD::emptyMap());
  214. }
  215. llinfos << "Marketplace upload llsd:" << llendl;
  216. llinfos << ll_pretty_print_sd(content) << llendl;
  217. llinfos << llendl;
  218. const LLSD& imported_list = content["imported"];
  219. LLSD::array_const_iterator it = imported_list.beginArray();
  220. for ( ; it != imported_list.endArray(); ++it)
  221. {
  222. LLUUID imported_folder = (*it).asUUID();
  223. llinfos << "Successfully uploaded folder " << imported_folder.asString() << " to marketplace." << llendl;
  224. }
  225. for (it = errors_list.beginArray(); it != errors_list.endArray(); ++it)
  226. {
  227. const LLSD& item_error_map = (*it);
  228. LLUUID error_folder = item_error_map["folder_id"].asUUID();
  229. const std::string& error_string = item_error_map["identifier"].asString();
  230. LLUUID error_item = item_error_map["item_id"].asUUID();
  231. const std::string& error_item_name = item_error_map["item_name"].asString();
  232. const std::string& error_message = item_error_map["message"].asString();
  233. llinfos << "Error item " << error_folder.asString() << ", " << error_string << ", "
  234. << error_item.asString() << ", " << error_item_name << ", " << error_message << llendl;
  235. LLFolderViewFolder * item_folder = mInventoryPanel->getRootFolder()->getFolderByID(error_folder);
  236. LLOutboxFolderViewFolder * outbox_item_folder = dynamic_cast<LLOutboxFolderViewFolder *>(item_folder);
  237. llassert(outbox_item_folder);
  238. outbox_item_folder->setErrorString(error_string);
  239. }
  240. }
  241. void LLPanelMarketplaceOutbox::updateSyncButtonStatus()
  242. {
  243. if (isSyncInProgress())
  244. {
  245. mSyncButton->setVisible(false);
  246. mSyncIndicator->setVisible(true);
  247. mSyncIndicator->reset();
  248. mSyncIndicator->start();
  249. }
  250. else
  251. {
  252. mSyncIndicator->stop();
  253. mSyncIndicator->setVisible(false);
  254. mSyncButton->setVisible(true);
  255. mSyncButton->setEnabled(!isOutboxEmpty());
  256. }
  257. }
  258. U32 LLPanelMarketplaceOutbox::getTotalItemCount() const
  259. {
  260. U32 item_count = 0;
  261. if (mInventoryPanel)
  262. {
  263. const LLFolderViewFolder * outbox_folder = mInventoryPanel->getRootFolder();
  264. if (outbox_folder)
  265. {
  266. item_count += outbox_folder->getFoldersCount();
  267. }
  268. }
  269. return item_count;
  270. }
  271. void LLPanelMarketplaceOutbox::draw()
  272. {
  273. const U32 item_count = getTotalItemCount();
  274. const bool not_empty = (item_count > 0);
  275. if (not_empty)
  276. {
  277. std::string item_count_str = llformat("%d", item_count);
  278. LLStringUtil::format_map_t args;
  279. args["[NUM]"] = item_count_str;
  280. getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelWithArg", args));
  281. }
  282. else
  283. {
  284. getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelNoArg"));
  285. }
  286. if (!isSyncInProgress())
  287. {
  288. mSyncButton->setEnabled(not_empty);
  289. }
  290. LLPanel::draw();
  291. }