aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llcurrencyuimanager.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llcurrencyuimanager.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llcurrencyuimanager.cpp516
1 files changed, 516 insertions, 0 deletions
diff --git a/linden/indra/newview/llcurrencyuimanager.cpp b/linden/indra/newview/llcurrencyuimanager.cpp
new file mode 100644
index 0000000..5893836
--- /dev/null
+++ b/linden/indra/newview/llcurrencyuimanager.cpp
@@ -0,0 +1,516 @@
1/**
2 * @file llcurrencyuimanager.cpp
3 * @brief LLCurrencyUIManager class implementation
4 *
5 * Copyright (c) 2006-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "lluictrlfactory.h"
31#include "lltextbox.h"
32#include "lllineeditor.h"
33
34#include "llcurrencyuimanager.h"
35
36// viewer includes
37#include "llagent.h"
38#include "llconfirmationmanager.h"
39#include "llframetimer.h"
40#include "lllineeditor.h"
41#include "llviewchildren.h"
42#include "llxmlrpctransaction.h"
43#include "viewer.h"
44
45
46
47const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0;
48 // how long of a pause in typing a currency buy amount before an
49 // esimate is fetched from the server
50
51class LLCurrencyUIManager::Impl
52{
53public:
54 Impl(LLPanel& dialog);
55 virtual ~Impl();
56
57 LLPanel& mPanel;
58
59 bool mHidden;
60
61 bool mError;
62 std::string mErrorMessage;
63 std::string mErrorURI;
64
65 std::string mZeroMessage;
66
67 // user's choices
68 S32 mUserCurrencyBuy;
69 bool mUserEnteredCurrencyBuy;
70
71 // from website
72 bool mSiteCurrencyEstimated;
73 S32 mSiteCurrencyEstimatedCost;
74 std::string mSiteConfirm;
75
76 bool mBought;
77
78 enum TransactionType
79 {
80 TransactionNone,
81 TransactionCurrency,
82 TransactionBuy
83 };
84
85 TransactionType mTransactionType;
86 LLXMLRPCTransaction* mTransaction;
87
88 bool mCurrencyChanged;
89 LLFrameTimer mCurrencyKeyTimer;
90
91
92 void updateCurrencyInfo();
93 void finishCurrencyInfo();
94
95 void startCurrencyBuy(const std::string& password);
96 void finishCurrencyBuy();
97
98 void startTransaction(TransactionType type,
99 const char* method, LLXMLRPCValue params);
100 bool checkTransaction();
101 // return true if update needed
102
103 void setError(const std::string& message, const std::string& uri);
104 void clearError();
105
106 bool considerUpdateCurrency();
107 // return true if update needed
108 void currencyKey(S32);
109 static void onCurrencyKey(LLLineEditor* caller, void* data);
110
111 void prepare();
112 void updateUI();
113};
114
115// is potentially not fully constructed.
116LLCurrencyUIManager::Impl::Impl(LLPanel& dialog)
117 : mPanel(dialog),
118 mHidden(false),
119 mError(false),
120 mUserCurrencyBuy(1000), mUserEnteredCurrencyBuy(false),
121 mSiteCurrencyEstimated(false),
122 mBought(false),
123 mTransactionType(TransactionNone), mTransaction(0),
124 mCurrencyChanged(false)
125{
126}
127
128LLCurrencyUIManager::Impl::~Impl()
129{
130 delete mTransaction;
131}
132
133void LLCurrencyUIManager::Impl::updateCurrencyInfo()
134{
135 mSiteCurrencyEstimated = false;
136 mSiteCurrencyEstimatedCost = 0;
137 mBought = false;
138 mCurrencyChanged = false;
139
140 if (mUserCurrencyBuy == 0)
141 {
142 mSiteCurrencyEstimated = true;
143 return;
144 }
145
146 LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
147 keywordArgs.appendString("agentId",
148 gAgent.getID().getString());
149 keywordArgs.appendString("secureSessionId",
150 gAgent.getSecureSessionID().getString());
151 keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
152
153 LLXMLRPCValue params = LLXMLRPCValue::createArray();
154 params.append(keywordArgs);
155
156 startTransaction(TransactionCurrency, "getCurrencyQuote", params);
157}
158
159void LLCurrencyUIManager::Impl::finishCurrencyInfo()
160{
161 LLXMLRPCValue result = mTransaction->responseValue();
162
163 bool success = result["success"].asBool();
164 if (!success)
165 {
166 setError(
167 result["errorMessage"].asString(),
168 result["errorURI"].asString()
169 );
170 return;
171 }
172
173 LLXMLRPCValue currency = result["currency"];
174 mSiteCurrencyEstimated = true;
175 mSiteCurrencyEstimatedCost = currency["estimatedCost"].asInt();
176
177 S32 newCurrencyBuy = currency["currencyBuy"].asInt();
178 if (newCurrencyBuy != mUserCurrencyBuy)
179 {
180 mUserCurrencyBuy = newCurrencyBuy;
181 mUserEnteredCurrencyBuy = false;
182 }
183
184 mSiteConfirm = result["confirm"].asString();
185}
186
187void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
188{
189 mSiteCurrencyEstimated = false;
190 mSiteCurrencyEstimatedCost = 0;
191 mCurrencyChanged = false;
192
193 LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
194 keywordArgs.appendString("agentId",
195 gAgent.getID().getString());
196 keywordArgs.appendString("secureSessionId",
197 gAgent.getSecureSessionID().getString());
198 keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
199 keywordArgs.appendInt("estimatedCost", mSiteCurrencyEstimatedCost);
200 keywordArgs.appendString("confirm", mSiteConfirm);
201 if (!password.empty())
202 {
203 keywordArgs.appendString("password", password);
204 }
205
206 LLXMLRPCValue params = LLXMLRPCValue::createArray();
207 params.append(keywordArgs);
208
209 startTransaction(TransactionBuy, "buyCurrency", params);
210}
211
212void LLCurrencyUIManager::Impl::finishCurrencyBuy()
213{
214 LLXMLRPCValue result = mTransaction->responseValue();
215
216 bool success = result["success"].asBool();
217 if (!success)
218 {
219 setError(
220 result["errorMessage"].asString(),
221 result["errorURI"].asString()
222 );
223 }
224 else
225 {
226 mUserCurrencyBuy = 0;
227 mUserEnteredCurrencyBuy = false;
228 mBought = true;
229 }
230}
231
232void LLCurrencyUIManager::Impl::startTransaction(TransactionType type,
233 const char* method, LLXMLRPCValue params)
234{
235 static std::string transactionURI;
236 if (transactionURI.empty())
237 {
238 transactionURI = getHelperURI() + "currency.php";
239 }
240
241 delete mTransaction;
242
243 mTransactionType = type;
244 mTransaction = new LLXMLRPCTransaction(
245 transactionURI,
246 method,
247 params,
248 false /* don't use gzip */
249 );
250
251 clearError();
252}
253
254bool LLCurrencyUIManager::Impl::checkTransaction()
255{
256 if (!mTransaction)
257 {
258 return false;
259 }
260
261 if (!mTransaction->process())
262 {
263 return false;
264 }
265
266 if (mTransaction->status(NULL) != LLXMLRPCTransaction::StatusComplete)
267 {
268 setError(mTransaction->statusMessage(), mTransaction->statusURI());
269 }
270 else {
271 switch (mTransactionType)
272 {
273 case TransactionCurrency: finishCurrencyInfo(); break;
274 case TransactionBuy: finishCurrencyBuy(); break;
275 default: ;
276 }
277 }
278
279 delete mTransaction;
280 mTransaction = NULL;
281 mTransactionType = TransactionNone;
282
283 return true;
284}
285
286void LLCurrencyUIManager::Impl::setError(
287 const std::string& message, const std::string& uri)
288{
289 mError = true;
290 mErrorMessage = message;
291 mErrorURI = uri;
292}
293
294void LLCurrencyUIManager::Impl::clearError()
295{
296 mError = false;
297 mErrorMessage.clear();
298 mErrorURI.clear();
299}
300
301bool LLCurrencyUIManager::Impl::considerUpdateCurrency()
302{
303 if (mCurrencyChanged
304 && !mTransaction
305 && mCurrencyKeyTimer.getElapsedTimeF32() >= CURRENCY_ESTIMATE_FREQUENCY)
306 {
307 updateCurrencyInfo();
308 return true;
309 }
310
311 return false;
312}
313
314void LLCurrencyUIManager::Impl::currencyKey(S32 value)
315{
316 mUserEnteredCurrencyBuy = true;
317 mCurrencyKeyTimer.reset();
318
319 if (mUserCurrencyBuy == value)
320 {
321 return;
322 }
323
324 mUserCurrencyBuy = value;
325
326 if (mSiteCurrencyEstimated) {
327 mSiteCurrencyEstimated = false;
328 //cannot just simply refresh the whole UI, as the edit field will
329 // get reset and the cursor will change...
330
331 mPanel.childHide("currency_est");
332 }
333
334 mCurrencyChanged = true;
335}
336
337// static
338void LLCurrencyUIManager::Impl::onCurrencyKey(
339 LLLineEditor* caller, void* data)
340{
341 S32 value = atoi(caller->getText().c_str());
342 LLCurrencyUIManager::Impl* self = (LLCurrencyUIManager::Impl*)data;
343 self->currencyKey(value);
344}
345
346void LLCurrencyUIManager::Impl::prepare()
347{
348 LLLineEditor* lindenAmount = LLUICtrlFactory::getLineEditorByName(&mPanel,"currency_amt");
349 if (lindenAmount)
350 {
351 lindenAmount->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
352 lindenAmount->setKeystrokeCallback(onCurrencyKey);
353 lindenAmount->setCallbackUserData(this);
354 }
355}
356
357void LLCurrencyUIManager::Impl::updateUI()
358{
359 if (mHidden)
360 {
361 mPanel.childHide("currency_action");
362 mPanel.childHide("currency_amt");
363 mPanel.childHide("currency_est");
364 return;
365 }
366
367 mPanel.childShow("currency_action");
368
369 LLLineEditor* lindenAmount = LLUICtrlFactory::getLineEditorByName(&mPanel,"currency_amt");
370 if (lindenAmount)
371 {
372 lindenAmount->setVisible(true);
373 lindenAmount->setLabel(mZeroMessage);
374
375 if (!mUserEnteredCurrencyBuy)
376 {
377 if (!mZeroMessage.empty() && mUserCurrencyBuy == 0)
378 {
379 lindenAmount->setText("");
380 }
381 else
382 {
383 lindenAmount->setText(llformat("%d", mUserCurrencyBuy));
384 }
385
386 lindenAmount->selectAll();
387 }
388 }
389
390 mPanel.childSetTextArg("currency_est", "[USD]", llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
391 mPanel.childSetVisible("currency_est", mSiteCurrencyEstimated && mUserCurrencyBuy > 0);
392}
393
394
395
396LLCurrencyUIManager::LLCurrencyUIManager(LLPanel& dialog)
397 : impl(* new Impl(dialog))
398{
399}
400
401LLCurrencyUIManager::~LLCurrencyUIManager()
402{
403 delete &impl;
404}
405
406void LLCurrencyUIManager::setAmount(int amount, bool noEstimate)
407{
408 impl.mUserCurrencyBuy = amount;
409 impl.mUserEnteredCurrencyBuy = false;
410 impl.updateUI();
411
412 impl.mCurrencyChanged = !noEstimate;
413}
414
415int LLCurrencyUIManager::getAmount()
416{
417 return impl.mUserCurrencyBuy;
418}
419
420void LLCurrencyUIManager::setZeroMessage(const std::string& message)
421{
422 impl.mZeroMessage = message;
423}
424
425void LLCurrencyUIManager::setEstimate(int amount)
426{
427 impl.mSiteCurrencyEstimatedCost = amount;
428 impl.mSiteCurrencyEstimated = true;
429 impl.updateUI();
430
431 impl.mCurrencyChanged = false;
432}
433
434int LLCurrencyUIManager::getEstimate()
435{
436 return impl.mSiteCurrencyEstimated ? impl.mSiteCurrencyEstimatedCost : 0;
437}
438
439void LLCurrencyUIManager::prepare()
440{
441 impl.prepare();
442}
443
444void LLCurrencyUIManager::updateUI(bool show)
445{
446 impl.mHidden = !show;
447 impl.updateUI();
448}
449
450bool LLCurrencyUIManager::process()
451{
452 bool changed = false;
453 changed |= impl.checkTransaction();
454 changed |= impl.considerUpdateCurrency();
455 return changed;
456}
457
458void LLCurrencyUIManager::buy()
459{
460 if (!canBuy())
461 {
462 return;
463 }
464
465 // XUI:translate
466 LLConfirmationManager::confirm(impl.mSiteConfirm,
467 llformat("Buy L$ %d for approx. US$ %#.2f\n",
468 impl.mUserCurrencyBuy,
469 impl.mSiteCurrencyEstimatedCost / 100.0),
470 impl,
471 &LLCurrencyUIManager::Impl::startCurrencyBuy);
472}
473
474
475bool LLCurrencyUIManager::inProcess()
476{
477 return impl.mTransactionType != Impl::TransactionNone;
478}
479
480bool LLCurrencyUIManager::canCancel()
481{
482 return impl.mTransactionType != Impl::TransactionBuy;
483}
484
485bool LLCurrencyUIManager::canBuy()
486{
487 return impl.mTransactionType == Impl::TransactionNone
488 && impl.mSiteCurrencyEstimated
489 && impl.mUserCurrencyBuy > 0;
490}
491
492bool LLCurrencyUIManager::buying()
493{
494 return impl.mTransactionType == Impl::TransactionBuy;
495}
496
497bool LLCurrencyUIManager::bought()
498{
499 return impl.mBought;
500}
501
502bool LLCurrencyUIManager::hasError()
503{
504 return impl.mError;
505}
506
507std::string LLCurrencyUIManager::errorMessage()
508{
509 return impl.mErrorMessage;
510}
511
512std::string LLCurrencyUIManager::errorURI()
513{
514 return impl.mErrorURI;
515}
516