00001
00033 #include "llviewerprecompiledheaders.h"
00034
00035 #include "llgivemoney.h"
00036
00037 #include "message.h"
00038
00039 #include "llagent.h"
00040 #include "llresmgr.h"
00041 #include "lltextbox.h"
00042 #include "lllineeditor.h"
00043 #include "llviewerobject.h"
00044 #include "llviewerobjectlist.h"
00045 #include "llviewerregion.h"
00046 #include "llviewerwindow.h"
00047 #include "llbutton.h"
00048 #include "llselectmgr.h"
00049 #include "lltransactiontypes.h"
00050 #include "llvieweruictrlfactory.h"
00051
00055
00056 const char* GIVE_MONEY_TITLE = "";
00057
00058
00059
00060
00061
00062
00063
00064 struct LLGiveMoneyInfo
00065 {
00066 LLFloaterPay* mFloater;
00067 S32 mAmount;
00068 LLGiveMoneyInfo(LLFloaterPay* floater, S32 amount) :
00069 mFloater(floater), mAmount(amount){}
00070 };
00071
00075
00076 S32 LLFloaterPay::sLastAmount = 0;
00077 const S32 MAX_AMOUNT_LENGTH = 10;
00078 const S32 FASTPAY_BUTTON_WIDTH = 80;
00079
00080
00081 LLFloaterPay::LLFloaterPay(const std::string& name,
00082 money_callback callback,
00083 const LLUUID& uuid,
00084 BOOL target_is_object) :
00085 LLFloater(name, "FloaterPayRectB", GIVE_MONEY_TITLE, RESIZE_NO,
00086 DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, DRAG_ON_TOP,
00087 MINIMIZE_NO, CLOSE_YES),
00088 mCallbackData(),
00089 mCallback(callback),
00090 mObjectNameText(NULL),
00091 mTargetUUID(uuid),
00092 mTargetIsObject(target_is_object),
00093 mTargetIsGroup(FALSE)
00094 {
00095 if (target_is_object)
00096 {
00097 gUICtrlFactory->buildFloater(this,"floater_pay_object.xml");
00098 mObjectSelection = gSelectMgr->getEditSelection();
00099 }
00100 else
00101 {
00102 gUICtrlFactory->buildFloater(this,"floater_pay.xml");
00103 }
00104
00105
00106 S32 i =0;
00107
00108 LLGiveMoneyInfo* info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0);
00109 mCallbackData.push_back(info);
00110
00111 childSetAction("fastpay 1",&LLFloaterPay::onGive,info);
00112 childSetVisible("fastpay 1", FALSE);
00113
00114 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 1");
00115 mQuickPayInfo[i] = info;
00116 ++i;
00117
00118 info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1);
00119 mCallbackData.push_back(info);
00120
00121 childSetAction("fastpay 5",&LLFloaterPay::onGive,info);
00122 childSetVisible("fastpay 5", FALSE);
00123
00124 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 5");
00125 mQuickPayInfo[i] = info;
00126 ++i;
00127
00128 info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2);
00129 mCallbackData.push_back(info);
00130
00131 childSetAction("fastpay 10",&LLFloaterPay::onGive,info);
00132 childSetVisible("fastpay 10", FALSE);
00133
00134 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 10");
00135 mQuickPayInfo[i] = info;
00136 ++i;
00137
00138 info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3);
00139 mCallbackData.push_back(info);
00140
00141 childSetAction("fastpay 20",&LLFloaterPay::onGive,info);
00142 childSetVisible("fastpay 20", FALSE);
00143
00144 mQuickPayButton[i] = LLUICtrlFactory::getButtonByName(this, "fastpay 20");
00145 mQuickPayInfo[i] = info;
00146 ++i;
00147
00148
00149 childSetVisible("amount text", FALSE);
00150
00151 LLString last_amount;
00152 if(sLastAmount > 0)
00153 {
00154 last_amount = llformat("%d", sLastAmount);
00155 }
00156
00157 childSetVisible("amount", FALSE);
00158
00159 childSetKeystrokeCallback("amount", &LLFloaterPay::onKeystroke, this);
00160 childSetText("amount", last_amount);
00161 childSetPrevalidate("amount", LLLineEditor::prevalidateNonNegativeS32);
00162
00163 info = new LLGiveMoneyInfo(this, 0);
00164 mCallbackData.push_back(info);
00165
00166 childSetAction("pay btn",&LLFloaterPay::onGive,info);
00167 setDefaultBtn("pay btn");
00168 childSetVisible("pay btn", FALSE);
00169 childSetEnabled("pay btn", (sLastAmount > 0));
00170
00171 childSetAction("cancel btn",&LLFloaterPay::onCancel,this);
00172
00173 center();
00174 open();
00175 }
00176
00177
00178 LLFloaterPay::~LLFloaterPay()
00179 {
00180 std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer());
00181
00182
00183 gCacheName->cancelCallback(mTargetUUID,onCacheOwnerName,this);
00184 }
00185
00186
00187 void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata)
00188 {
00189 LLFloaterPay* self = (LLFloaterPay*)userdata;
00190 if (self)
00191 {
00192 S32 price;
00193 LLUUID target;
00194
00195 msg->getUUIDFast(_PREHASH_ObjectData,_PREHASH_ObjectID,target);
00196 if (target != self->mTargetUUID)
00197 {
00198
00199 return;
00200 }
00201
00202 msg->getS32Fast(_PREHASH_ObjectData,_PREHASH_DefaultPayPrice,price);
00203
00204 if (PAY_PRICE_HIDE == price)
00205 {
00206 self->childSetVisible("amount", FALSE);
00207 self->childSetVisible("pay btn", FALSE);
00208 self->childSetVisible("amount text", FALSE);
00209 }
00210 else if (PAY_PRICE_DEFAULT == price)
00211 {
00212 self->childSetVisible("amount", TRUE);
00213 self->childSetVisible("pay btn", TRUE);
00214 self->childSetVisible("amount text", TRUE);
00215 }
00216 else
00217 {
00218
00219
00220
00221 self->childSetVisible("amount", TRUE);
00222 self->childSetVisible("pay btn", TRUE);
00223 self->childSetEnabled("pay btn", TRUE);
00224 self->childSetVisible("amount text", TRUE);
00225
00226 self->childSetText("amount", llformat("%d", llabs(price)));
00227 }
00228
00229 S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_ButtonData);
00230 S32 i = 0;
00231 if (num_blocks > MAX_PAY_BUTTONS) num_blocks = MAX_PAY_BUTTONS;
00232
00233 S32 max_pay_amount = 0;
00234 S32 padding_required = 0;
00235
00236 for (i=0;i<num_blocks;++i)
00237 {
00238 S32 pay_button;
00239 msg->getS32Fast(_PREHASH_ButtonData,_PREHASH_PayButton,pay_button,i);
00240 if (pay_button > 0)
00241 {
00242 LLString button_str = "L$";
00243 button_str += gResMgr->getMonetaryString( pay_button );
00244
00245 self->mQuickPayButton[i]->setLabelSelected(button_str);
00246 self->mQuickPayButton[i]->setLabelUnselected(button_str);
00247 self->mQuickPayButton[i]->setVisible(TRUE);
00248 self->mQuickPayInfo[i]->mAmount = pay_button;
00249 self->childSetVisible("fastpay text",TRUE);
00250
00251 if ( pay_button > max_pay_amount )
00252 {
00253 max_pay_amount = pay_button;
00254 }
00255 }
00256 else
00257 {
00258 self->mQuickPayButton[i]->setVisible(FALSE);
00259 }
00260 }
00261
00262
00263 LLString balance_str = "L$";
00264 balance_str += gResMgr->getMonetaryString( max_pay_amount );
00265 const LLFontGL* font = gResMgr->getRes(LLFONT_SANSSERIF);
00266 S32 new_button_width = font->getWidth( LLString(balance_str));
00267 new_button_width += ( 12 + 12 );
00268
00269
00270 const S32 threshold = 100000;
00271 if ( max_pay_amount >= threshold )
00272 {
00273 S32 num_digits_threshold = (S32)log10((double)threshold) + 1;
00274 S32 num_digits_max = (S32)log10((double)max_pay_amount) + 1;
00275
00276
00277 padding_required = ( num_digits_max - num_digits_threshold + ( num_digits_max / 3 ) ) * font->getWidth( "0" );
00278 };
00279
00280
00281 S32 button_delta = new_button_width - FASTPAY_BUTTON_WIDTH;
00282 if ( button_delta < 0 )
00283 button_delta = 0;
00284
00285
00286 for (i=0;i<num_blocks;++i)
00287 {
00288 LLRect r;
00289 r = self->mQuickPayButton[i]->getRect();
00290
00291
00292 if ( i % 2 )
00293 {
00294 r.setCenterAndSize( r.getCenterX() + ( button_delta * 3 ) / 2 ,
00295 r.getCenterY(),
00296 r.getWidth() + button_delta,
00297 r.getHeight() );
00298 }
00299 else
00300 {
00301 r.setCenterAndSize( r.getCenterX() + button_delta / 2,
00302 r.getCenterY(),
00303 r.getWidth() + button_delta,
00304 r.getHeight() );
00305 }
00306 self->mQuickPayButton[i]->setRect( r );
00307 }
00308
00309 for (i=num_blocks;i<MAX_PAY_BUTTONS;++i)
00310 {
00311 self->mQuickPayButton[i]->setVisible(FALSE);
00312 }
00313
00314 self->reshape( self->mRect.getWidth() + padding_required, self->mRect.getHeight(), FALSE );
00315 }
00316 msg->setHandlerFunc("PayPriceReply",NULL,NULL);
00317 }
00318
00319
00320 void LLFloaterPay::payViaObject(money_callback callback, const LLUUID& object_id)
00321 {
00322 LLViewerObject* object = gObjectList.findObject(object_id);
00323 if (!object) return;
00324
00325 LLFloaterPay *floater = new LLFloaterPay("Give L$", callback, object_id, TRUE);
00326 if (!floater) return;
00327
00328 LLSelectNode* node = floater->mObjectSelection->getFirstRootNode();
00329 if (!node)
00330 {
00331
00332 floater->close();
00333 return;
00334 }
00335
00336 LLHost target_region = object->getRegion()->getHost();
00337
00338 LLMessageSystem* msg = gMessageSystem;
00339 msg->newMessageFast(_PREHASH_RequestPayPrice);
00340 msg->nextBlockFast(_PREHASH_ObjectData);
00341 msg->addUUIDFast(_PREHASH_ObjectID, object_id);
00342 msg->sendReliable(target_region);
00343 msg->setHandlerFuncFast(_PREHASH_PayPriceReply, processPayPriceReply,(void **)floater);
00344
00345 LLUUID owner_id;
00346 BOOL is_group = FALSE;
00347 node->mPermissions->getOwnership(owner_id, is_group);
00348
00349 floater->childSetText("object_name_text",node->mName);
00350
00351 floater->finishPayUI(owner_id, is_group);
00352 }
00353
00354 void LLFloaterPay::payDirectly(money_callback callback,
00355 const LLUUID& target_id,
00356 BOOL is_group)
00357 {
00358 LLFloaterPay *floater = new LLFloaterPay("Give L$", callback, target_id, FALSE);
00359 if (!floater) return;
00360
00361 floater->childSetVisible("amount", TRUE);
00362 floater->childSetVisible("pay btn", TRUE);
00363 floater->childSetVisible("amount text", TRUE);
00364
00365 floater->childSetVisible("fastpay text",TRUE);
00366 for(S32 i=0;i<MAX_PAY_BUTTONS;++i)
00367 {
00368 floater->mQuickPayButton[i]->setVisible(TRUE);
00369 }
00370
00371 floater->finishPayUI(target_id, is_group);
00372 }
00373
00374 void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group)
00375 {
00376 gCacheName->get(target_id, is_group, onCacheOwnerName, (void*)this);
00377
00378
00379
00380 childSetFocus("amount", TRUE);
00381
00382 LLLineEditor* amount = LLUICtrlFactory::getLineEditorByName(this, "amount");
00383 amount->selectAll();
00384 mTargetIsGroup = is_group;
00385 }
00386
00387
00388 void LLFloaterPay::onCacheOwnerName(const LLUUID& owner_id,
00389 const char* firstname,
00390 const char* lastname,
00391 BOOL is_group,
00392 void* userdata)
00393 {
00394 LLFloaterPay* self = (LLFloaterPay*)userdata;
00395 if (!self) return;
00396
00397 if (is_group)
00398 {
00399 self->childSetVisible("payee_group",true);
00400 self->childSetVisible("payee_resident",false);
00401 }
00402 else
00403 {
00404 self->childSetVisible("payee_group",false);
00405 self->childSetVisible("payee_resident",true);
00406 }
00407
00408 self->childSetTextArg("payee_name", "[FIRST]", LLString(firstname));
00409 self->childSetTextArg("payee_name", "[LAST]", LLString(lastname));
00410 }
00411
00412
00413 void LLFloaterPay::onCancel(void* data)
00414 {
00415 LLFloaterPay* self = reinterpret_cast<LLFloaterPay*>(data);
00416 if(self)
00417 {
00418 self->close();
00419 }
00420 }
00421
00422
00423 void LLFloaterPay::onKeystroke(LLLineEditor*, void* data)
00424 {
00425 LLFloaterPay* self = reinterpret_cast<LLFloaterPay*>(data);
00426 if(self)
00427 {
00428
00429 LLString amtstr = self->childGetText("amount");
00430 self->childSetEnabled("pay btn", !amtstr.empty() && atoi(amtstr.c_str()) > 0);
00431 }
00432 }
00433
00434
00435 void LLFloaterPay::onGive(void* data)
00436 {
00437 LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data);
00438 if(info && info->mFloater)
00439 {
00440 info->mFloater->give(info->mAmount);
00441 info->mFloater->close();
00442 }
00443 }
00444
00445 void LLFloaterPay::give(S32 amount)
00446 {
00447 if(mCallback)
00448 {
00449
00450
00451 if(amount == 0)
00452 {
00453 amount = atoi(childGetText("amount").c_str());
00454 }
00455 sLastAmount = amount;
00456
00457
00458 if (mTargetIsObject)
00459 {
00460 LLViewerObject* dest_object = gObjectList.findObject(mTargetUUID);
00461 if(dest_object)
00462 {
00463 LLViewerRegion* region = dest_object->getRegion();
00464 if (region)
00465 {
00466
00467 LLSelectNode* node = mObjectSelection->getFirstRootNode();
00468 LLString object_name;
00469 if (node)
00470 {
00471 object_name = node->mName;
00472 }
00473 S32 tx_type = TRANS_PAY_OBJECT;
00474 if(dest_object->isAvatar()) tx_type = TRANS_GIFT;
00475 mCallback(mTargetUUID, region, amount, FALSE, tx_type, object_name);
00476 mObjectSelection = NULL;
00477 }
00478 }
00479 }
00480 else
00481 {
00482
00483 mCallback(mTargetUUID, gAgent.getRegion(), amount, mTargetIsGroup, TRANS_GIFT, LLString::null);
00484 }
00485 }
00486 }
00487
00491
00492