PageRenderTime 407ms CodeModel.GetById 141ms app.highlight 118ms RepoModel.GetById 144ms 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
  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
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llpanelmarketplaceoutbox.h"
 30#include "llpanelmarketplaceoutboxinventory.h"
 31
 32#include "llappviewer.h"
 33#include "llbutton.h"
 34#include "llcoros.h"
 35#include "lleventcoro.h"
 36#include "llfloatersidepanelcontainer.h"
 37#include "llinventorypanel.h"
 38#include "llloadingindicator.h"
 39#include "llnotificationsutil.h"
 40#include "llpanelmarketplaceinbox.h"
 41#include "llsdutil.h"
 42#include "llsidepanelinventory.h"
 43#include "lltimer.h"
 44#include "llviewernetwork.h"
 45#include "llagent.h"
 46#include "llviewermedia.h"
 47#include "llfolderview.h"
 48#include "llinventoryfunctions.h"
 49
 50static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox");
 51
 52const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultParams() 
 53{ 
 54	return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceOutbox>(); 
 55}
 56
 57// protected
 58LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox(const Params& p)
 59	: LLPanel(p)
 60	, mInventoryPanel(NULL)
 61	, mSyncButton(NULL)
 62	, mSyncIndicator(NULL)
 63	, mSyncInProgress(false)
 64{
 65}
 66
 67LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox()
 68{
 69}
 70
 71// virtual
 72BOOL LLPanelMarketplaceOutbox::postBuild()
 73{
 74	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceOutbox::handleLoginComplete, this));
 75	
 76	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this));
 77
 78	return TRUE;
 79}
 80
 81void LLPanelMarketplaceOutbox::handleLoginComplete()
 82{
 83	mSyncButton = getChild<LLButton>("outbox_sync_btn");
 84	mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this));
 85	mSyncButton->setEnabled(!isOutboxEmpty());
 86	
 87	mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator");
 88}
 89
 90void LLPanelMarketplaceOutbox::onFocusReceived()
 91{
 92	LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
 93	if (sidepanel_inventory)
 94	{
 95		sidepanel_inventory->clearSelections(true, true, false);
 96	}
 97}
 98
 99void LLPanelMarketplaceOutbox::onSelectionChange()
100{
101	LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
102	if (sidepanel_inventory)
103	{
104		sidepanel_inventory->updateVerbs();
105	}
106}
107
108LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
109{
110	LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel");
111	LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent();
112	
113	mInventoryPanel = 
114		LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
115														  outbox_inventory_parent,
116														  LLInventoryPanel::child_registry_t::instance());
117	
118	llassert(mInventoryPanel);
119	
120	// Reshape the inventory to the proper size
121	LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect();
122	mInventoryPanel->setShape(inventory_placeholder_rect);
123	
124	// Set the sort order newest to oldest
125	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	
126	mInventoryPanel->getFilter()->markDefault();
127
128	// Set selection callback for proper update of inventory status buttons
129	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this));
130	
131	// Set up the note to display when the outbox is empty
132	mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryOutboxNoItems");
133	
134	// Hide the placeholder text
135	outbox_inventory_placeholder->setVisible(FALSE);
136	
137	return mInventoryPanel;
138}
139
140BOOL LLPanelMarketplaceOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
141								   EDragAndDropType cargo_type,
142								   void* cargo_data,
143								   EAcceptance* accept,
144								   std::string& tooltip_msg)
145{
146	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
147
148	if (!handled && mInventoryPanel && mInventoryPanel->getRootFolder())
149	{
150		handled = mInventoryPanel->getRootFolder()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
151
152		if (handled)
153		{
154			mInventoryPanel->getRootFolder()->setDragAndDropThisFrame();
155		}
156	}
157
158	return handled;
159}
160
161bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
162{
163	return (getTotalItemCount() == 0);
164}
165
166bool LLPanelMarketplaceOutbox::isSyncInProgress() const
167{
168	return mSyncInProgress;
169}
170
171
172std::string gTimeDelayDebugFunc = "";
173
174void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
175{
176	waitForEventOn(self, "mainloop");
177
178	LLTimer delayTimer;
179	delayTimer.reset();
180	delayTimer.setTimerExpirySec(5.0f);
181
182	while (!delayTimer.hasExpired())
183	{
184		waitForEventOn(self, "mainloop");
185	}
186
187	outboxPanel->onSyncComplete(true, LLSD::emptyMap());
188
189	gTimeDelayDebugFunc = "";
190}
191
192
193class LLInventorySyncResponder : public LLHTTPClient::Responder
194{
195public:
196	LLInventorySyncResponder(LLPanelMarketplaceOutbox * outboxPanel)
197		: LLCurl::Responder()
198		, mOutboxPanel(outboxPanel)
199	{
200	}
201
202	void completed(U32 status, const std::string& reason, const LLSD& content)
203	{
204		llinfos << "inventory_import complete status: " << status << ", reason: " << reason << llendl;
205
206		if (isGoodStatus(status))
207		{
208			// Complete success
209			llinfos << "success" << llendl;
210		}	
211		else
212		{
213			llwarns << "failed" << llendl;
214		}
215
216		mOutboxPanel->onSyncComplete(isGoodStatus(status), content);
217	}
218
219private:
220	LLPanelMarketplaceOutbox *	mOutboxPanel;
221};
222
223void LLPanelMarketplaceOutbox::onSyncButtonClicked()
224{
225	// Get the sync animation going
226	mSyncInProgress = true;
227	updateSyncButtonStatus();
228
229	// Make the url for the inventory import request
230	std::string url = "https://marketplace.secondlife.com/";
231
232	if (!LLGridManager::getInstance()->isInProductionGrid())
233	{
234		std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
235		url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
236
237		// TEMP for Jim's pdp
238		//url = "http://pdp24.lindenlab.com:3000/";
239	}
240	
241	url += "api/1/users/";
242	url += gAgent.getID().getString();
243	url += "/inventory_import";
244
245	llinfos << "http get:  " << url << llendl;
246	LLHTTPClient::get(url, new LLInventorySyncResponder(this), LLViewerMedia::getHeaders());
247
248	// Set a timer (for testing only)
249    //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
250}
251
252void LLPanelMarketplaceOutbox::onSyncComplete(bool goodStatus, const LLSD& content)
253{
254	mSyncInProgress = false;
255	updateSyncButtonStatus();
256	
257	const LLSD& errors_list = content["errors"];
258
259	if (goodStatus && (errors_list.size() == 0))
260	{
261		LLNotificationsUtil::add("OutboxUploadComplete", LLSD::emptyMap(), LLSD::emptyMap());
262	}
263	else
264	{
265		LLNotificationsUtil::add("OutboxUploadHadErrors", LLSD::emptyMap(), LLSD::emptyMap());
266	}
267
268	llinfos << "Marketplace upload llsd:" << llendl;
269	llinfos << ll_pretty_print_sd(content) << llendl;
270	llinfos << llendl;
271
272	const LLSD& imported_list = content["imported"];
273	LLSD::array_const_iterator it = imported_list.beginArray();
274	for ( ; it != imported_list.endArray(); ++it)
275	{
276		LLUUID imported_folder = (*it).asUUID();
277		llinfos << "Successfully uploaded folder " << imported_folder.asString() << " to marketplace." << llendl;
278	}
279
280	for (it = errors_list.beginArray(); it != errors_list.endArray(); ++it)
281	{
282		const LLSD& item_error_map = (*it);
283
284		LLUUID error_folder = item_error_map["folder_id"].asUUID();
285		const std::string& error_string = item_error_map["identifier"].asString();
286		LLUUID error_item = item_error_map["item_id"].asUUID();
287		const std::string& error_item_name = item_error_map["item_name"].asString();
288		const std::string& error_message = item_error_map["message"].asString();
289
290		llinfos << "Error item " << error_folder.asString() << ", " << error_string << ", "
291				<< error_item.asString() << ", " << error_item_name << ", " << error_message << llendl;
292		
293		LLFolderViewFolder * item_folder = mInventoryPanel->getRootFolder()->getFolderByID(error_folder);
294		LLOutboxFolderViewFolder * outbox_item_folder = dynamic_cast<LLOutboxFolderViewFolder *>(item_folder);
295
296		llassert(outbox_item_folder);
297
298		outbox_item_folder->setErrorString(error_string);
299	}
300}
301
302void LLPanelMarketplaceOutbox::updateSyncButtonStatus()
303{
304	if (isSyncInProgress())
305	{
306		mSyncButton->setVisible(false);
307
308		mSyncIndicator->setVisible(true);
309		mSyncIndicator->reset();
310		mSyncIndicator->start();
311	}
312	else
313	{
314		mSyncIndicator->stop();
315		mSyncIndicator->setVisible(false);
316
317		mSyncButton->setVisible(true);
318		mSyncButton->setEnabled(!isOutboxEmpty());
319	}
320}
321
322U32 LLPanelMarketplaceOutbox::getTotalItemCount() const
323{
324	U32 item_count = 0;
325
326	if (mInventoryPanel)
327	{
328		const LLFolderViewFolder * outbox_folder = mInventoryPanel->getRootFolder();
329
330		if (outbox_folder)
331		{
332			item_count += outbox_folder->getFoldersCount();
333		}
334	}
335
336	return item_count;
337}
338
339void LLPanelMarketplaceOutbox::draw()
340{
341	const U32 item_count = getTotalItemCount();
342	const bool not_empty = (item_count > 0);
343
344	if (not_empty)
345	{
346		std::string item_count_str = llformat("%d", item_count);
347
348		LLStringUtil::format_map_t args;
349		args["[NUM]"] = item_count_str;
350		getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelWithArg", args));
351	}
352	else
353	{
354		getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelNoArg"));
355	}
356	
357	if (!isSyncInProgress())
358	{
359		mSyncButton->setEnabled(not_empty);
360	}
361	
362	LLPanel::draw();
363}