diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llcurrencyuimanager.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 516 |
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 | |||
47 | const 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 | |||
51 | class LLCurrencyUIManager::Impl | ||
52 | { | ||
53 | public: | ||
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. | ||
116 | LLCurrencyUIManager::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 | |||
128 | LLCurrencyUIManager::Impl::~Impl() | ||
129 | { | ||
130 | delete mTransaction; | ||
131 | } | ||
132 | |||
133 | void 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 | |||
159 | void 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 | |||
187 | void 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 | |||
212 | void 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 | |||
232 | void 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 | |||
254 | bool 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 | |||
286 | void LLCurrencyUIManager::Impl::setError( | ||
287 | const std::string& message, const std::string& uri) | ||
288 | { | ||
289 | mError = true; | ||
290 | mErrorMessage = message; | ||
291 | mErrorURI = uri; | ||
292 | } | ||
293 | |||
294 | void LLCurrencyUIManager::Impl::clearError() | ||
295 | { | ||
296 | mError = false; | ||
297 | mErrorMessage.clear(); | ||
298 | mErrorURI.clear(); | ||
299 | } | ||
300 | |||
301 | bool 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 | |||
314 | void 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 | ||
338 | void 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 | |||
346 | void 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 | |||
357 | void 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 | |||
396 | LLCurrencyUIManager::LLCurrencyUIManager(LLPanel& dialog) | ||
397 | : impl(* new Impl(dialog)) | ||
398 | { | ||
399 | } | ||
400 | |||
401 | LLCurrencyUIManager::~LLCurrencyUIManager() | ||
402 | { | ||
403 | delete &impl; | ||
404 | } | ||
405 | |||
406 | void 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 | |||
415 | int LLCurrencyUIManager::getAmount() | ||
416 | { | ||
417 | return impl.mUserCurrencyBuy; | ||
418 | } | ||
419 | |||
420 | void LLCurrencyUIManager::setZeroMessage(const std::string& message) | ||
421 | { | ||
422 | impl.mZeroMessage = message; | ||
423 | } | ||
424 | |||
425 | void LLCurrencyUIManager::setEstimate(int amount) | ||
426 | { | ||
427 | impl.mSiteCurrencyEstimatedCost = amount; | ||
428 | impl.mSiteCurrencyEstimated = true; | ||
429 | impl.updateUI(); | ||
430 | |||
431 | impl.mCurrencyChanged = false; | ||
432 | } | ||
433 | |||
434 | int LLCurrencyUIManager::getEstimate() | ||
435 | { | ||
436 | return impl.mSiteCurrencyEstimated ? impl.mSiteCurrencyEstimatedCost : 0; | ||
437 | } | ||
438 | |||
439 | void LLCurrencyUIManager::prepare() | ||
440 | { | ||
441 | impl.prepare(); | ||
442 | } | ||
443 | |||
444 | void LLCurrencyUIManager::updateUI(bool show) | ||
445 | { | ||
446 | impl.mHidden = !show; | ||
447 | impl.updateUI(); | ||
448 | } | ||
449 | |||
450 | bool LLCurrencyUIManager::process() | ||
451 | { | ||
452 | bool changed = false; | ||
453 | changed |= impl.checkTransaction(); | ||
454 | changed |= impl.considerUpdateCurrency(); | ||
455 | return changed; | ||
456 | } | ||
457 | |||
458 | void 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 | |||
475 | bool LLCurrencyUIManager::inProcess() | ||
476 | { | ||
477 | return impl.mTransactionType != Impl::TransactionNone; | ||
478 | } | ||
479 | |||
480 | bool LLCurrencyUIManager::canCancel() | ||
481 | { | ||
482 | return impl.mTransactionType != Impl::TransactionBuy; | ||
483 | } | ||
484 | |||
485 | bool LLCurrencyUIManager::canBuy() | ||
486 | { | ||
487 | return impl.mTransactionType == Impl::TransactionNone | ||
488 | && impl.mSiteCurrencyEstimated | ||
489 | && impl.mUserCurrencyBuy > 0; | ||
490 | } | ||
491 | |||
492 | bool LLCurrencyUIManager::buying() | ||
493 | { | ||
494 | return impl.mTransactionType == Impl::TransactionBuy; | ||
495 | } | ||
496 | |||
497 | bool LLCurrencyUIManager::bought() | ||
498 | { | ||
499 | return impl.mBought; | ||
500 | } | ||
501 | |||
502 | bool LLCurrencyUIManager::hasError() | ||
503 | { | ||
504 | return impl.mError; | ||
505 | } | ||
506 | |||
507 | std::string LLCurrencyUIManager::errorMessage() | ||
508 | { | ||
509 | return impl.mErrorMessage; | ||
510 | } | ||
511 | |||
512 | std::string LLCurrencyUIManager::errorURI() | ||
513 | { | ||
514 | return impl.mErrorURI; | ||
515 | } | ||
516 | |||