aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llgivemoney.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/llgivemoney.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 'linden/indra/newview/llgivemoney.cpp')
-rw-r--r--linden/indra/newview/llgivemoney.cpp487
1 files changed, 487 insertions, 0 deletions
diff --git a/linden/indra/newview/llgivemoney.cpp b/linden/indra/newview/llgivemoney.cpp
new file mode 100644
index 0000000..ce8cc06
--- /dev/null
+++ b/linden/indra/newview/llgivemoney.cpp
@@ -0,0 +1,487 @@
1/**
2 * @file llgivemoney.cpp
3 * @author Aaron Brashears, Kelly Washington, James Cook
4 * @brief Implementation of the LLFloaterPay class.
5 *
6 * Copyright (c) 2002-2007, Linden Research, Inc.
7 *
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "llviewerprecompiledheaders.h"
30
31#include "llgivemoney.h"
32
33#include "message.h"
34
35#include "llagent.h"
36#include "llresmgr.h"
37#include "lltextbox.h"
38#include "lllineeditor.h"
39#include "llviewerobject.h"
40#include "llviewerobjectlist.h"
41#include "llviewerregion.h"
42#include "llviewerwindow.h"
43#include "llbutton.h"
44#include "llselectmgr.h"
45#include "lltransactiontypes.h"
46#include "llvieweruictrlfactory.h"
47
48///----------------------------------------------------------------------------
49/// Local function declarations, constants, enums, and typedefs
50///----------------------------------------------------------------------------
51
52const char* GIVE_MONEY_TITLE = ""; // Dialog contains text "Pay"
53
54//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55// Class LLGiveMoneyInfo
56//
57// A small class used to track callback information
58//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59
60struct LLGiveMoneyInfo
61{
62 LLFloaterPay* mFloater;
63 S32 mAmount;
64 LLGiveMoneyInfo(LLFloaterPay* floater, S32 amount) :
65 mFloater(floater), mAmount(amount){}
66};
67
68///----------------------------------------------------------------------------
69/// Class LLFloaterPay
70///----------------------------------------------------------------------------
71
72S32 LLFloaterPay::sLastAmount = 0;
73const S32 MAX_AMOUNT_LENGTH = 10;
74const S32 FASTPAY_BUTTON_WIDTH = 80;
75
76// Default constructor
77LLFloaterPay::LLFloaterPay(const std::string& name,
78 money_callback callback,
79 const LLUUID& uuid,
80 BOOL target_is_object) :
81 LLFloater(name, "FloaterPayRectB", GIVE_MONEY_TITLE, RESIZE_NO,
82 DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, DRAG_ON_TOP,
83 MINIMIZE_NO, CLOSE_YES),
84 mCallbackData(),
85 mCallback(callback),
86 mObjectNameText(NULL),
87 mTargetUUID(uuid),
88 mTargetIsObject(target_is_object),
89 mTargetIsGroup(FALSE)
90{
91 if (target_is_object)
92 {
93 gUICtrlFactory->buildFloater(this,"floater_pay_object.xml");
94 }
95 else
96 {
97 gUICtrlFactory->buildFloater(this,"floater_pay.xml");
98 }
99
100
101 S32 i =0;
102
103 LLGiveMoneyInfo* info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0);
104 mCallbackData.push_back(info);
105
106 childSetAction("fastpay 1",&LLFloaterPay::onGive,info);
107 childSetVisible("fastpay 1", FALSE);
108
109 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 1");
110 mQuickPayInfo[i] = info;
111 ++i;
112
113 info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1);
114 mCallbackData.push_back(info);
115
116 childSetAction("fastpay 5",&LLFloaterPay::onGive,info);
117 childSetVisible("fastpay 5", FALSE);
118
119 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 5");
120 mQuickPayInfo[i] = info;
121 ++i;
122
123 info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2);
124 mCallbackData.push_back(info);
125
126 childSetAction("fastpay 10",&LLFloaterPay::onGive,info);
127 childSetVisible("fastpay 10", FALSE);
128
129 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 10");
130 mQuickPayInfo[i] = info;
131 ++i;
132
133 info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3);
134 mCallbackData.push_back(info);
135
136 childSetAction("fastpay 20",&LLFloaterPay::onGive,info);
137 childSetVisible("fastpay 20", FALSE);
138
139 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 20");
140 mQuickPayInfo[i] = info;
141 ++i;
142
143
144 childSetVisible("amount text", FALSE);
145
146 LLString last_amount;
147 if(sLastAmount > 0)
148 {
149 last_amount = llformat("%d", sLastAmount);
150 }
151
152 childSetVisible("amount", FALSE);
153
154 childSetKeystrokeCallback("amount", &LLFloaterPay::onKeystroke, this);
155 childSetText("amount", last_amount);
156 childSetPrevalidate("desc", LLLineEditor::prevalidatePositiveS32);
157
158 info = new LLGiveMoneyInfo(this, 0);
159 mCallbackData.push_back(info);
160
161 childSetAction("pay btn",&LLFloaterPay::onGive,info);
162 setDefaultBtn("pay btn");
163 childSetVisible("pay btn", FALSE);
164 childSetEnabled("pay btn", (sLastAmount > 0));
165
166 childSetAction("cancel btn",&LLFloaterPay::onCancel,this);
167
168 center();
169 open();
170}
171
172// Destroys the object
173LLFloaterPay::~LLFloaterPay()
174{
175 std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer());
176}
177
178// static
179void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata)
180{
181 LLFloaterPay* self = (LLFloaterPay*)userdata;
182 if (self)
183 {
184 S32 price;
185 LLUUID target;
186
187 msg->getUUIDFast(_PREHASH_ObjectData,_PREHASH_ObjectID,target);
188 if (target != self->mTargetUUID)
189 {
190 // This is a message for a different object's pay info
191 return;
192 }
193
194 msg->getS32Fast(_PREHASH_ObjectData,_PREHASH_DefaultPayPrice,price);
195
196 if (PAY_PRICE_HIDE == price)
197 {
198 self->childSetVisible("amount", FALSE);
199 self->childSetVisible("pay btn", FALSE);
200 self->childSetVisible("amount text", FALSE);
201 }
202 else if (PAY_PRICE_DEFAULT == price)
203 {
204 self->childSetVisible("amount", TRUE);
205 self->childSetVisible("pay btn", TRUE);
206 self->childSetVisible("amount text", TRUE);
207 }
208 else
209 {
210 // PAY_PRICE_HIDE and PAY_PRICE_DEFAULT are negative values
211 // So we take the absolute value here after we have checked for those cases
212
213 self->childSetVisible("amount", TRUE);
214 self->childSetVisible("pay btn", TRUE);
215 self->childSetEnabled("pay btn", TRUE);
216 self->childSetVisible("amount text", TRUE);
217
218 self->childSetText("amount", llformat("%d", llabs(price)));
219 }
220
221 S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_ButtonData);
222 S32 i = 0;
223 if (num_blocks > MAX_PAY_BUTTONS) num_blocks = MAX_PAY_BUTTONS;
224
225 S32 max_pay_amount = 0;
226 S32 padding_required = 0;
227
228 for (i=0;i<num_blocks;++i)
229 {
230 S32 pay_button;
231 msg->getS32Fast(_PREHASH_ButtonData,_PREHASH_PayButton,pay_button,i);
232 if (pay_button > 0)
233 {
234 LLString button_str;
235 gResMgr->getMonetaryString( button_str, pay_button );
236
237 self->mQuickPayButton[i]->setLabelSelected(button_str.c_str());
238 self->mQuickPayButton[i]->setLabelUnselected(button_str.c_str());
239 self->mQuickPayButton[i]->setVisible(TRUE);
240 self->mQuickPayInfo[i]->mAmount = pay_button;
241 self->childSetVisible("fastpay text",TRUE);
242
243 if ( pay_button > max_pay_amount )
244 {
245 max_pay_amount = pay_button;
246 }
247 }
248 else
249 {
250 self->mQuickPayButton[i]->setVisible(FALSE);
251 }
252 }
253
254 // build a string containing the maximum value and calc nerw button width from it.
255 LLString balance_str;
256 gResMgr->getMonetaryString( balance_str, max_pay_amount );
257 const LLFontGL* font = gResMgr->getRes(LLFONT_SANSSERIF);
258 S32 new_button_width = font->getWidth( LLString(balance_str));
259 new_button_width += ( 12 + 12 ); // padding
260
261 // dialong is sized for 2 digit pay amounts - larger pay values need to be scaled
262 const S32 threshold = 100000;
263 if ( max_pay_amount >= threshold )
264 {
265 S32 num_digits_threshold = (S32)log10((double)threshold) + 1;
266 S32 num_digits_max = (S32)log10((double)max_pay_amount) + 1;
267
268 // calculate the extra width required by 2 buttons with max amount and some commas
269 padding_required = ( num_digits_max - num_digits_threshold + ( num_digits_max / 3 ) ) * font->getWidth( "0" );
270 };
271
272 // change in button width
273 S32 button_delta = new_button_width - FASTPAY_BUTTON_WIDTH;
274 if ( button_delta < 0 )
275 button_delta = 0;
276
277 // now we know the maximum amount, we can resize all the buttons to be
278 for (i=0;i<num_blocks;++i)
279 {
280 LLRect r;
281 r = self->mQuickPayButton[i]->getRect();
282
283 // RHS button colum needs to move further because LHS changed too
284 if ( i % 2 )
285 {
286 r.setCenterAndSize( r.getCenterX() + ( button_delta * 3 ) / 2 ,
287 r.getCenterY(),
288 r.getWidth() + button_delta,
289 r.getHeight() );
290 }
291 else
292 {
293 r.setCenterAndSize( r.getCenterX() + button_delta / 2,
294 r.getCenterY(),
295 r.getWidth() + button_delta,
296 r.getHeight() );
297 }
298 self->mQuickPayButton[i]->setRect( r );
299 }
300
301 for (i=num_blocks;i<MAX_PAY_BUTTONS;++i)
302 {
303 self->mQuickPayButton[i]->setVisible(FALSE);
304 }
305
306 self->reshape( self->mRect.getWidth() + padding_required, self->mRect.getHeight(), FALSE );
307 }
308 msg->setHandlerFunc("PayPriceReply",NULL,NULL);
309}
310
311// static
312void LLFloaterPay::payViaObject(money_callback callback, const LLUUID& object_id)
313{
314 LLViewerObject* object = gObjectList.findObject(object_id);
315 if (!object) return;
316
317 LLSelectNode* node = gSelectMgr->getFirstRootNode();
318 if (!node) return;
319
320 LLFloaterPay *floater = new LLFloaterPay("Give Money", callback, object_id, TRUE);
321 if (!floater) return;
322
323 LLHost target_region = object->getRegion()->getHost();
324
325 LLMessageSystem* msg = gMessageSystem;
326 msg->newMessageFast(_PREHASH_RequestPayPrice);
327 msg->nextBlockFast(_PREHASH_ObjectData);
328 msg->addUUIDFast(_PREHASH_ObjectID, object_id);
329 msg->sendReliable(target_region);
330 msg->setHandlerFuncFast(_PREHASH_PayPriceReply, processPayPriceReply,(void **)floater);
331
332 LLUUID owner_id;
333 BOOL is_group = FALSE;
334 node->mPermissions->getOwnership(owner_id, is_group);
335
336 floater->childSetText("object_name_text",node->mName);
337
338 floater->finishPayUI(owner_id, is_group);
339}
340
341void LLFloaterPay::payDirectly(money_callback callback,
342 const LLUUID& target_id,
343 BOOL is_group)
344{
345 LLFloaterPay *floater = new LLFloaterPay("Give Money", callback, target_id, FALSE);
346 if (!floater) return;
347
348 floater->childSetVisible("amount", TRUE);
349 floater->childSetVisible("pay btn", TRUE);
350 floater->childSetVisible("amount text", TRUE);
351
352 floater->childSetVisible("fastpay text",TRUE);
353 for(S32 i=0;i<MAX_PAY_BUTTONS;++i)
354 {
355 floater->mQuickPayButton[i]->setVisible(TRUE);
356 }
357
358 floater->finishPayUI(target_id, is_group);
359}
360
361void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group)
362{
363 gCacheName->get(target_id, is_group, onCacheOwnerName, (void*)this);
364
365 // Make sure the amount field has focus
366
367 childSetFocus("amount", TRUE);
368
369 LLLineEditor* amount = LLUICtrlFactory::getLineEditorByName(this, "amount");
370 amount->selectAll();
371 mTargetIsGroup = is_group;
372}
373
374// static
375void LLFloaterPay::onCacheOwnerName(const LLUUID& owner_id,
376 const char* firstname,
377 const char* lastname,
378 BOOL is_group,
379 void* userdata)
380{
381 LLFloaterPay* self = (LLFloaterPay*)userdata;
382 if (!self) return;
383
384 if (is_group)
385 {
386 self->childSetVisible("payee_group",true);
387 self->childSetVisible("payee_resident",false);
388 }
389 else
390 {
391 self->childSetVisible("payee_group",false);
392 self->childSetVisible("payee_resident",true);
393 }
394
395 self->childSetTextArg("payee_name", "[FIRST]", firstname);
396 self->childSetTextArg("payee_name", "[LAST]", lastname);
397}
398
399// static
400void LLFloaterPay::onCancel(void* data)
401{
402 LLFloaterPay* self = reinterpret_cast<LLFloaterPay*>(data);
403 if(self)
404 {
405 if (self->mTargetIsObject)
406 {
407 gSelectMgr->deselectAll();
408 }
409 self->close();
410 }
411}
412
413// static
414void LLFloaterPay::onKeystroke(LLLineEditor*, void* data)
415{
416 LLFloaterPay* self = reinterpret_cast<LLFloaterPay*>(data);
417 if(self)
418 {
419 if (!self->childGetText("amount").empty())
420 {
421 self->childSetEnabled("pay btn", TRUE);
422 }
423 else
424 {
425 self->childSetEnabled("pay btn", FALSE);
426 }
427 }
428}
429
430// static
431void LLFloaterPay::onGive(void* data)
432{
433 LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data);
434 if(info && info->mFloater)
435 {
436 info->mFloater->give(info->mAmount);
437 info->mFloater->close();
438 }
439}
440
441void LLFloaterPay::give(S32 amount)
442{
443 if(mCallback)
444 {
445 // if the amount is 0, that menas that we should use the
446 // text field.
447 if(amount == 0)
448 {
449 amount = atoi(childGetText("amount").c_str());
450 }
451 sLastAmount = amount;
452
453 // Try to pay an object.
454 if (mTargetIsObject)
455 {
456 LLViewerObject* dest_object = gObjectList.findObject(mTargetUUID);
457 if(dest_object)
458 {
459 LLViewerRegion* region = dest_object->getRegion();
460 if (region)
461 {
462 // Find the name of the root object
463 LLSelectNode* node = gSelectMgr->getFirstRootNode();
464 LLString object_name;
465 if (node)
466 {
467 object_name = node->mName;
468 }
469 S32 tx_type = TRANS_PAY_OBJECT;
470 if(dest_object->isAvatar()) tx_type = TRANS_GIFT;
471 mCallback(mTargetUUID, region, amount, FALSE, tx_type, object_name);
472 gSelectMgr->deselectAll();
473 }
474 }
475 }
476 else
477 {
478 // just transfer the money
479 mCallback(mTargetUUID, gAgent.getRegion(), amount, mTargetIsGroup, TRANS_GIFT, LLString::null);
480 }
481 }
482}
483
484///----------------------------------------------------------------------------
485/// Local function definitions
486///----------------------------------------------------------------------------
487