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