llfloaterbuyland.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. /**
  2. * @file llfloaterbuyland.cpp
  3. * @brief LLFloaterBuyLand class implementation
  4. *
  5. * $LicenseInfo:firstyear=2005&license=viewergpl$
  6. *
  7. * Copyright (c) 2005-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llfloaterbuyland.h"
  34. #include "llcachename.h"
  35. #include "llcheckboxctrl.h"
  36. #include "llcombobox.h"
  37. #include "llconfirmationmanager.h"
  38. #include "lltextbox.h"
  39. #include "lluictrlfactory.h"
  40. #include "llxmlrpctransaction.h"
  41. #include "llagent.h"
  42. #include "llcurrencyuimanager.h"
  43. #include "llgridmanager.h"
  44. //MK
  45. #include "mkrlinterface.h"
  46. //mk
  47. #include "llstatusbar.h"
  48. #include "lltexturectrl.h"
  49. #include "llviewerregion.h"
  50. #include "llviewertexteditor.h"
  51. #include "llweb.h"
  52. #include "roles_constants.h"
  53. #if LL_WINDOWS
  54. // Passing 'this' during construction generates a warning. The callee only uses
  55. // the pointer to hold a reference to 'this' which is already valid, so this
  56. // call does the correct thing. Disable the warning so that we can compile
  57. // without generating a warning.
  58. #pragma warning(disable : 4355)
  59. #endif
  60. constexpr F32 GROUP_LAND_BONUS_FACTOR = 1.1f;
  61. //static
  62. LLParcelSelectionObserver* LLFloaterBuyLand::sParcelObserver = NULL;
  63. ///////////////////////////////////////////////////////////////////////////////
  64. // Observer methods
  65. ///////////////////////////////////////////////////////////////////////////////
  66. void LLFloaterBuyLand::SelectionObserver::changed()
  67. {
  68. LLFloaterBuyLand* self = LLFloaterBuyLand::findInstance();
  69. if (self)
  70. {
  71. if (gViewerParcelMgr.selectionEmpty())
  72. {
  73. self->close();
  74. }
  75. else
  76. {
  77. self->setParcel(gViewerParcelMgr.getSelectionRegion(),
  78. gViewerParcelMgr.getParcelSelection());
  79. }
  80. }
  81. }
  82. ///////////////////////////////////////////////////////////////////////////////
  83. // Public (and static) interface methods
  84. ///////////////////////////////////////////////////////////////////////////////
  85. //static
  86. void LLFloaterBuyLand::buyLand(LLViewerRegion* region,
  87. LLParcelSelectionHandle parcel,
  88. bool is_for_group)
  89. {
  90. if (is_for_group && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
  91. {
  92. gNotifications.add("OnlyOfficerCanBuyLand");
  93. return;
  94. }
  95. LLFloaterBuyLand* self = getInstance();
  96. if (self)
  97. {
  98. self->setForGroup(is_for_group);
  99. self->setParcel(region, parcel);
  100. self->open();
  101. }
  102. }
  103. //static
  104. void LLFloaterBuyLand::updateCovenantText(const std::string& string,
  105. const LLUUID& asset_id)
  106. {
  107. LLFloaterBuyLand* self = findInstance();
  108. if (self)
  109. {
  110. self->setCovenantText(string, asset_id);
  111. }
  112. }
  113. //static
  114. void LLFloaterBuyLand::updateEstateName(const std::string& name)
  115. {
  116. LLFloaterBuyLand* self = findInstance();
  117. if (self)
  118. {
  119. self->setEstateName(name);
  120. }
  121. }
  122. //static
  123. void LLFloaterBuyLand::updateLastModified(const std::string& text)
  124. {
  125. LLFloaterBuyLand* self = findInstance();
  126. if (self)
  127. {
  128. self->setLastModified(text);
  129. }
  130. }
  131. //static
  132. void LLFloaterBuyLand::updateEstateOwnerName(const std::string& name)
  133. {
  134. LLFloaterBuyLand* self = findInstance();
  135. if (self)
  136. {
  137. self->setEstateOwnerName(name);
  138. }
  139. }
  140. ///////////////////////////////////////////////////////////////////////////////
  141. // LLFloaterBuyLand proper
  142. ///////////////////////////////////////////////////////////////////////////////
  143. LLFloaterBuyLand::LLFloaterBuyLand(const LLSD&)
  144. : mParcelSelection(NULL),
  145. mParcelBuyInfo(NULL),
  146. mTransaction(NULL),
  147. mCurrency(*this),
  148. mBought(false),
  149. mParcelValid(false),
  150. mSiteValid(false)
  151. {
  152. LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_land.xml",
  153. NULL, false);
  154. }
  155. //virtual
  156. LLFloaterBuyLand::~LLFloaterBuyLand()
  157. {
  158. if (sParcelObserver)
  159. {
  160. gViewerParcelMgr.removeSelectionObserver(sParcelObserver);
  161. delete sParcelObserver;
  162. sParcelObserver = NULL;
  163. }
  164. if (mTransaction)
  165. {
  166. delete mTransaction;
  167. mTransaction = NULL;
  168. }
  169. if (mParcelBuyInfo)
  170. {
  171. gViewerParcelMgr.deleteParcelBuy(mParcelBuyInfo);
  172. mParcelBuyInfo = NULL;
  173. }
  174. // Release the selection handle
  175. mParcelSelection = NULL;
  176. }
  177. //virtual
  178. bool LLFloaterBuyLand::postBuild()
  179. {
  180. mCurrency.prepare();
  181. childSetAction("buy_btn", onClickBuy, this);
  182. childSetAction("cancel_btn", onClickCancel, this);
  183. childSetAction("error_web", onClickErrorWeb, this);
  184. if (!sParcelObserver)
  185. {
  186. sParcelObserver = new SelectionObserver;
  187. gViewerParcelMgr.addSelectionObserver(sParcelObserver);
  188. }
  189. center();
  190. return true;
  191. }
  192. void LLFloaterBuyLand::updateAgentInfo()
  193. {
  194. mAgentCommittedTier = gStatusBarp->getSquareMetersCommitted();
  195. mAgentCashBalance = gStatusBarp->getBalance();
  196. // *TODO: This is an approximation, we should send this value down to the
  197. // viewer. See SL-10728 for details.
  198. mAgentHasNeverOwnedLand = mAgentCommittedTier == 0;
  199. }
  200. void LLFloaterBuyLand::updateParcelInfo()
  201. {
  202. LLParcel* parcel = mParcelSelection->getParcel();
  203. if (!parcel) return; // Paranoia
  204. mParcelValid = parcel && mRegion;
  205. mParcelIsForSale = false;
  206. mParcelIsGroupLand = false;
  207. mParcelGroupContribution = 0;
  208. mParcelPrice = 0;
  209. mParcelActualArea = 0;
  210. mParcelBillableArea = 0;
  211. mParcelSupportedObjects = 0;
  212. mParcelSoldWithObjects = false;
  213. mParcelLocation.clear();
  214. mParcelSnapshot.setNull();
  215. mParcelSellerName.clear();
  216. mCanBuy = false;
  217. mCannotBuyIsError = false;
  218. if (!mParcelValid)
  219. {
  220. mCannotBuyReason = getString("no_land_selected");
  221. return;
  222. }
  223. if (mParcelSelection->getMultipleOwners())
  224. {
  225. mCannotBuyReason = getString("multiple_parcels_selected");
  226. return;
  227. }
  228. const LLUUID& parcel_owner = parcel->getOwnerID();
  229. mIsClaim = parcel->isPublic();
  230. if (!mIsClaim)
  231. {
  232. mParcelActualArea = parcel->getArea();
  233. mParcelIsForSale = parcel->getForSale();
  234. mParcelIsGroupLand = parcel->getIsGroupOwned();
  235. mParcelPrice = mParcelIsForSale ? parcel->getSalePrice() : 0;
  236. if (mParcelIsGroupLand)
  237. {
  238. LLUUID group_id = parcel->getGroupID();
  239. mParcelGroupContribution = gAgent.getGroupContribution(group_id);
  240. }
  241. }
  242. else
  243. {
  244. mParcelActualArea = mParcelSelection->getClaimableArea();
  245. mParcelIsForSale = true;
  246. mParcelPrice = mParcelActualArea * parcel->getClaimPricePerMeter();
  247. }
  248. mParcelBillableArea = ll_round(mRegion->getBillableFactor() *
  249. mParcelActualArea);
  250. mParcelSupportedObjects = ll_round(parcel->getMaxPrimCapacity() *
  251. parcel->getParcelPrimBonus());
  252. // Cannot have more than region max tasks, regardless of parcel object
  253. // bonus factor.
  254. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  255. if (region)
  256. {
  257. S32 max_tasks_per_region = (S32)region->getMaxTasks();
  258. mParcelSupportedObjects = llmin(mParcelSupportedObjects,
  259. max_tasks_per_region);
  260. }
  261. mParcelSoldWithObjects = parcel->getSellWithObjects();
  262. LLVector3 center = parcel->getCenterpoint();
  263. mParcelLocation = llformat("%s %d,%d", mRegion->getName().c_str(),
  264. (S32)center[VX], (S32)center[VY]);
  265. mParcelSnapshot = parcel->getSnapshotID();
  266. updateNames();
  267. bool got_the_cash = mParcelPrice <= mAgentCashBalance;
  268. S32 missing_cash = got_the_cash ? 0 : mParcelPrice - mAgentCashBalance;
  269. mCurrency.setAmount(missing_cash, true);
  270. mCurrency.setZeroMessage(got_the_cash ? getString("none_needed")
  271. : LLStringUtil::null);
  272. // Check that we can buy the land
  273. if (mIsForGroup && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
  274. {
  275. mCannotBuyReason = getString("cant_buy_for_group");
  276. return;
  277. }
  278. if (!mIsClaim)
  279. {
  280. const LLUUID& authorized_buyer = parcel->getAuthorizedBuyerID();
  281. const LLUUID buyer = gAgentID;
  282. const LLUUID new_owner = mIsForGroup ? gAgent.getGroupID() : buyer;
  283. if (!mParcelIsForSale ||
  284. (mParcelPrice == 0 && authorized_buyer.isNull()))
  285. {
  286. mCannotBuyReason = getString("parcel_not_for_sale");
  287. return;
  288. }
  289. if (parcel_owner == new_owner)
  290. {
  291. if (mIsForGroup)
  292. {
  293. mCannotBuyReason = getString("group_already_owns");
  294. }
  295. else
  296. {
  297. mCannotBuyReason = getString("you_already_own");
  298. }
  299. return;
  300. }
  301. if (authorized_buyer.notNull() && buyer != authorized_buyer)
  302. {
  303. mCannotBuyReason = getString("set_to_sell_to_other");
  304. return;
  305. }
  306. }
  307. else
  308. {
  309. if (mParcelActualArea == 0)
  310. {
  311. mCannotBuyReason = getString("no_public_land");
  312. return;
  313. }
  314. if (mParcelSelection->hasOthersSelected())
  315. {
  316. // Policy: Must not have someone else's land selected
  317. mCannotBuyReason = getString("not_owned_by_you");
  318. return;
  319. }
  320. }
  321. mCanBuy = true;
  322. }
  323. void LLFloaterBuyLand::updateCovenantInfo()
  324. {
  325. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  326. if (!region) return;
  327. LLTextBox* region_name = getChild<LLTextBox>("region_name_text");
  328. region_name->setText(region->getName());
  329. LLTextBox* region_type = getChild<LLTextBox>("region_type_text");
  330. region_type->setText(region->getSimProductName());
  331. LLTextBox* resellable_txt = getChild<LLTextBox>("resellable_clause");
  332. if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
  333. {
  334. resellable_txt->setText(getString("can_not_resell"));
  335. }
  336. else
  337. {
  338. resellable_txt->setText(getString("can_resell"));
  339. }
  340. LLTextBox* changeable_txt = getChild<LLTextBox>("changeable_clause");
  341. if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
  342. {
  343. changeable_txt->setText(getString("can_change"));
  344. }
  345. else
  346. {
  347. changeable_txt->setText(getString("can_not_change"));
  348. }
  349. LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
  350. check->set(false);
  351. check->setEnabled(true);
  352. check->setCommitCallback(onChangeAgreeCovenant);
  353. check->setCallbackUserData(this);
  354. childHide("covenant_text");
  355. // Send EstateCovenantInfo message
  356. region->sendEstateCovenantRequest();
  357. }
  358. void LLFloaterBuyLand::setCovenantText(const std::string& string,
  359. const LLUUID& asset_id)
  360. {
  361. LLViewerTextEditor* editor =
  362. getChild<LLViewerTextEditor>("covenant_editor");
  363. editor->setHandleEditKeysDirectly(false);
  364. editor->setText(string);
  365. LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
  366. if (asset_id.isNull())
  367. {
  368. check->set(true);
  369. check->setEnabled(false);
  370. refreshUI();
  371. // Remove the line stating that you must agree
  372. childHide("covenant_text");
  373. }
  374. else
  375. {
  376. check->setEnabled(true);
  377. // Show the line stating that you must agree
  378. childShow("covenant_text");
  379. }
  380. }
  381. void LLFloaterBuyLand::setEstateName(const std::string& name)
  382. {
  383. LLTextBox* box = getChild<LLTextBox>("estate_name_text");
  384. if (box) box->setText(name);
  385. }
  386. void LLFloaterBuyLand::setLastModified(const std::string& text)
  387. {
  388. LLTextBox* editor = getChild<LLTextBox>("covenant_timestamp_text");
  389. editor->setText(text);
  390. }
  391. void LLFloaterBuyLand::setEstateOwnerName(const std::string& name)
  392. {
  393. LLTextBox* box = getChild<LLTextBox>("estate_owner_text");
  394. box->setText(name);
  395. }
  396. void LLFloaterBuyLand::updateWebSiteInfo()
  397. {
  398. S32 askBillableArea = mIsForGroup ? 0 : mParcelBillableArea;
  399. S32 askCurrencyBuy = mCurrency.getAmount();
  400. if (mTransaction && mTransactionType == TransactionPreflight &&
  401. mPreflightAskBillableArea == askBillableArea &&
  402. mPreflightAskCurrencyBuy == askCurrencyBuy)
  403. {
  404. return;
  405. }
  406. mPreflightAskBillableArea = askBillableArea;
  407. mPreflightAskCurrencyBuy = askCurrencyBuy;
  408. #if 0 // enable this code if you want the details to blank while we're talking
  409. // to the web site... it's kind of jarring.
  410. mSiteValid = false;
  411. mSiteMembershipUpgrade = false;
  412. mSiteMembershipAction = "(waiting)";
  413. mSiteMembershipPlanIDs.clear();
  414. mSiteMembershipPlanNames.clear();
  415. mSiteLandUseUpgrade = false;
  416. mSiteLandUseAction = "(waiting)";
  417. mSiteCurrencyEstimated = false;
  418. mSiteCurrencyEstimatedCost = 0;
  419. #endif
  420. LLSD params = LLSD::emptyMap();
  421. params["agentId"] = gAgentID.asString();
  422. params["secureSessionId"] = gAgent.getSecureSessionID().asString();
  423. params["language"] = LLUI::getLanguage();
  424. params["billableArea"] = mPreflightAskBillableArea;
  425. params["currencyBuy"] = mPreflightAskCurrencyBuy;
  426. startTransaction(TransactionPreflight, params);
  427. }
  428. void LLFloaterBuyLand::finishWebSiteInfo()
  429. {
  430. const LLSD& result = mTransaction->response();
  431. mSiteValid = result["success"].asBoolean();
  432. if (!mSiteValid)
  433. {
  434. tellUserError(result["errorMessage"].asString(),
  435. result["errorURI"].asString());
  436. return;
  437. }
  438. const LLSD& membership = result["membership"];
  439. mSiteMembershipUpgrade = membership["upgrade"].asBoolean();
  440. mSiteMembershipAction = membership["action"].asString();
  441. mSiteMembershipPlanIDs.clear();
  442. mSiteMembershipPlanNames.clear();
  443. const LLSD& levels = membership["levels"];
  444. for (auto it = levels.beginArray(); it != levels.endArray(); ++it)
  445. {
  446. const LLSD& level = *it;
  447. mSiteMembershipPlanIDs.emplace_back(level["id"].asString());
  448. mSiteMembershipPlanNames.emplace_back(level["description"].asString());
  449. }
  450. mUserPlanChoice = 0;
  451. const LLSD& landUse = result["landUse"];
  452. mSiteLandUseUpgrade = landUse["upgrade"].asBoolean();
  453. mSiteLandUseAction = landUse["action"].asString();
  454. const LLSD& currency = result["currency"];
  455. if (currency.has("estimatedCost"))
  456. {
  457. mCurrency.setUSDEstimate(currency["estimatedCost"].asInteger());
  458. }
  459. if (currency.has("estimatedLocalCost"))
  460. {
  461. mCurrency.setLocalEstimate(currency["estimatedLocalCost"].asString());
  462. }
  463. mSiteConfirm = result["confirm"].asString();
  464. }
  465. void LLFloaterBuyLand::runWebSitePrep(const std::string& password)
  466. {
  467. if (!mCanBuy)
  468. {
  469. return;
  470. }
  471. bool remove_contrib = childGetValue("remove_contribution").asBoolean();
  472. mParcelBuyInfo = gViewerParcelMgr.setupParcelBuy(gAgentID, gAgentSessionID,
  473. gAgent.getGroupID(),
  474. mIsForGroup, mIsClaim,
  475. remove_contrib);
  476. if (mParcelBuyInfo && !mSiteMembershipUpgrade && !mSiteLandUseUpgrade &&
  477. mCurrency.getAmount() == 0 && mSiteConfirm != "password")
  478. {
  479. sendBuyLand();
  480. return;
  481. }
  482. std::string new_level = "noChange";
  483. if (mSiteMembershipUpgrade)
  484. {
  485. LLComboBox* levels = getChild<LLComboBox>( "account_level");
  486. if (levels)
  487. {
  488. mUserPlanChoice = levels->getCurrentIndex();
  489. new_level = mSiteMembershipPlanIDs[mUserPlanChoice];
  490. }
  491. }
  492. LLSD params = LLSD::emptyMap();
  493. params["agentId"] = gAgentID.asString();
  494. params["secureSessionId"] = gAgent.getSecureSessionID().asString();
  495. params["language"] = LLUI::getLanguage();
  496. params["levelId"] = new_level;
  497. params["billableArea"] = mIsForGroup ? 0 : mParcelBillableArea;
  498. params["currencyBuy"] = mCurrency.getAmount();
  499. params["estimatedCost"] = mCurrency.getUSDEstimate();
  500. params["estimatedLocalCost"] = mCurrency.getLocalEstimate();
  501. params["confirm"] = mSiteConfirm;
  502. if (!password.empty())
  503. {
  504. params["password"] = password;
  505. }
  506. startTransaction(TransactionBuy, params);
  507. }
  508. void LLFloaterBuyLand::finishWebSitePrep()
  509. {
  510. const LLSD& result = mTransaction->response();
  511. bool success = result["success"].asBoolean();
  512. if (!success)
  513. {
  514. tellUserError(result["errorMessage"].asString(),
  515. result["errorURI"].asString());
  516. return;
  517. }
  518. sendBuyLand();
  519. }
  520. void LLFloaterBuyLand::sendBuyLand()
  521. {
  522. if (mParcelBuyInfo)
  523. {
  524. gViewerParcelMgr.sendParcelBuy(mParcelBuyInfo);
  525. gViewerParcelMgr.deleteParcelBuy(mParcelBuyInfo);
  526. mBought = true;
  527. }
  528. }
  529. //static
  530. void LLFloaterBuyLand::callbackCacheName(const LLUUID&, const std::string&,
  531. bool)
  532. {
  533. LLFloaterBuyLand* self = findInstance();
  534. if (self)
  535. {
  536. self->updateNames();
  537. }
  538. }
  539. void LLFloaterBuyLand::updateNames()
  540. {
  541. LLParcel* parcelp = mParcelSelection->getParcel();
  542. if (!parcelp)
  543. {
  544. mParcelSellerName.clear();
  545. return;
  546. }
  547. if (mIsClaim)
  548. {
  549. mParcelSellerName = "Linden Lab";
  550. }
  551. else if (parcelp->getIsGroupOwned())
  552. {
  553. const LLUUID& group_id = parcelp->getGroupID();
  554. if (gCacheNamep &&
  555. !gCacheNamep->getGroupName(group_id, mParcelSellerName))
  556. {
  557. gCacheNamep->get(group_id, true, callbackCacheName);
  558. }
  559. }
  560. else
  561. {
  562. const LLUUID& owner_id = parcelp->getOwnerID();
  563. if (gCacheNamep &&
  564. !gCacheNamep->getFullName(owner_id, mParcelSellerName))
  565. {
  566. gCacheNamep->get(owner_id, false, callbackCacheName);
  567. }
  568. }
  569. //MK
  570. if (gRLenabled &&
  571. (gRLInterface.mContainsShownames ||
  572. gRLInterface.mContainsShownametags))
  573. {
  574. mParcelSellerName = gRLInterface.getDummyName(mParcelSellerName);
  575. }
  576. //mk
  577. }
  578. void LLFloaterBuyLand::startTransaction(TransactionType type,
  579. const LLSD& params)
  580. {
  581. if (mTransaction)
  582. {
  583. delete mTransaction;
  584. mTransaction = NULL;
  585. }
  586. mTransactionType = type;
  587. // Select a URI and method appropriate for the transaction type.
  588. static std::string transaction_uri;
  589. if (transaction_uri.empty())
  590. {
  591. transaction_uri = LLGridManager::getInstance()->getHelperURI() +
  592. "landtool.php";
  593. }
  594. const char* method;
  595. switch (mTransactionType)
  596. {
  597. case TransactionPreflight:
  598. method = "preflightBuyLandPrep";
  599. break;
  600. case TransactionBuy:
  601. method = "buyLandPrep";
  602. break;
  603. default:
  604. llwarns << "Unknown transaction type !" << llendl;
  605. return;
  606. }
  607. mTransaction = new LLXMLRPCTransaction(transaction_uri, method, params);
  608. }
  609. bool LLFloaterBuyLand::checkTransaction()
  610. {
  611. if (!mTransaction)
  612. {
  613. return false;
  614. }
  615. if (!mTransaction->process())
  616. {
  617. return false;
  618. }
  619. if (mTransaction->status(NULL) != LLXMLRPCTransaction::StatusComplete)
  620. {
  621. tellUserError(mTransaction->statusMessage(),
  622. mTransaction->statusURI());
  623. }
  624. else
  625. {
  626. switch (mTransactionType)
  627. {
  628. case TransactionPreflight:
  629. finishWebSiteInfo();
  630. break;
  631. case TransactionBuy:
  632. finishWebSitePrep();
  633. break;
  634. default:
  635. break;
  636. }
  637. }
  638. delete mTransaction;
  639. mTransaction = NULL;
  640. return true;
  641. }
  642. void LLFloaterBuyLand::tellUserError(const std::string& message,
  643. const std::string& uri)
  644. {
  645. mCanBuy = false;
  646. mCannotBuyIsError = true;
  647. mCannotBuyReason = getString("fetching_error");
  648. mCannotBuyReason += message;
  649. mCannotBuyURI = uri;
  650. }
  651. void LLFloaterBuyLand::setParcel(LLViewerRegion* region,
  652. LLParcelSelectionHandle parcel)
  653. {
  654. if (mTransaction && mTransactionType == TransactionBuy)
  655. {
  656. // The user is buying, do not change the selection
  657. return;
  658. }
  659. mRegion = region;
  660. mParcelSelection = parcel;
  661. updateAgentInfo();
  662. updateParcelInfo();
  663. updateCovenantInfo();
  664. if (mCanBuy)
  665. {
  666. updateWebSiteInfo();
  667. }
  668. refreshUI();
  669. }
  670. void LLFloaterBuyLand::setForGroup(bool forGroup)
  671. {
  672. mIsForGroup = forGroup;
  673. }
  674. //virtual
  675. void LLFloaterBuyLand::draw()
  676. {
  677. bool dirty = checkTransaction();
  678. dirty |= mCurrency.process();
  679. if (mBought)
  680. {
  681. close();
  682. }
  683. else if (dirty)
  684. {
  685. if (mCanBuy && mCurrency.hasError())
  686. {
  687. tellUserError(mCurrency.errorMessage(), mCurrency.errorURI());
  688. }
  689. refreshUI();
  690. }
  691. LLFloater::draw();
  692. }
  693. //virtual
  694. bool LLFloaterBuyLand::canClose()
  695. {
  696. bool can_close = !mTransaction &&
  697. (mCurrency.canCancel() ||
  698. mTransactionType != TransactionBuy);
  699. if (!can_close)
  700. {
  701. // Explain to the user why they cannot do this, see DEV-9605
  702. gNotifications.add("CannotCloseFloaterBuyLand");
  703. }
  704. return can_close;
  705. }
  706. //virtual
  707. void LLFloaterBuyLand::setMinimized(bool minimize)
  708. {
  709. bool restored = isMinimized() && !minimize;
  710. LLFloater::setMinimized(minimize);
  711. if (restored)
  712. {
  713. refreshUI();
  714. }
  715. }
  716. void LLFloaterBuyLand::refreshUI()
  717. {
  718. std::string message;
  719. // Section zero: title area
  720. {
  721. LLTextureCtrl* snapshot = getChild<LLTextureCtrl>("info_image");
  722. if (mParcelValid)
  723. {
  724. snapshot->setImageAssetID(mParcelSnapshot);
  725. childSetText("info_parcel", mParcelLocation);
  726. LLStringUtil::format_map_t string_args;
  727. string_args["[AMOUNT]"] = llformat("%d", mParcelActualArea);
  728. string_args["[AMOUNT2]"] = llformat("%d", mParcelSupportedObjects);
  729. childSetText("info_size",
  730. getString("meters_supports_object", string_args));
  731. F32 cost_per_sqm = 0.0f;
  732. if (mParcelActualArea > 0)
  733. {
  734. cost_per_sqm = (F32)mParcelPrice / (F32)mParcelActualArea;
  735. }
  736. LLStringUtil::format_map_t info_price_args;
  737. info_price_args["[PRICE]"] = llformat("%d", mParcelPrice);
  738. info_price_args["[PRICE_PER_SQM]"] = llformat("%.1f", cost_per_sqm);
  739. if (mParcelSoldWithObjects)
  740. {
  741. info_price_args["[SOLD_WITH_OBJECTS]"] =
  742. getString("sold_with_objects");
  743. }
  744. else
  745. {
  746. info_price_args["[SOLD_WITH_OBJECTS]"] =
  747. getString("sold_without_objects");
  748. }
  749. childSetText("info_price",
  750. getString("info_price_string", info_price_args));
  751. childSetVisible("info_price", mParcelIsForSale);
  752. }
  753. else
  754. {
  755. snapshot->setImageAssetID(LLUUID::null);
  756. childSetText("info_parcel", getString("no_parcel_selected"));
  757. childSetText("info_size", LLStringUtil::null);
  758. childSetText("info_price", LLStringUtil::null);
  759. }
  760. if (mCanBuy)
  761. {
  762. // "Buying land for group:" or "Buying this land will:"
  763. message = mIsForGroup ? getString("buying_for_group")
  764. : getString("buying_will");
  765. }
  766. else
  767. {
  768. // "Cannot buy now:" or "Not for sale:"
  769. message = mCannotBuyIsError ? getString("cannot_buy_now")
  770. : getString("not_for_sale");
  771. }
  772. childSetText("info_action", message);
  773. }
  774. bool showing_error = !mCanBuy || !mSiteValid;
  775. // Error section
  776. if (showing_error)
  777. {
  778. childSetBadge("step_error",
  779. mCannotBuyIsError ? BADGE_ERROR : BADGE_WARN);
  780. LLTextBox* msgbox = getChild<LLTextBox>("error_message");
  781. if (msgbox)
  782. {
  783. msgbox->setVisible(true);
  784. msgbox->setWrappedText(!mCanBuy ? mCannotBuyReason
  785. : "(waiting for data)");
  786. }
  787. childSetVisible("error_web",
  788. mCannotBuyIsError && !mCannotBuyURI.empty());
  789. }
  790. else
  791. {
  792. childHide("step_error");
  793. childHide("error_message");
  794. childHide("error_web");
  795. }
  796. // Section one: account
  797. if (!showing_error)
  798. {
  799. childSetBadge("step_1",
  800. mSiteMembershipUpgrade ? BADGE_NOTE : BADGE_OK);
  801. childSetText("account_action", mSiteMembershipAction);
  802. childSetText("account_reason",
  803. mSiteMembershipUpgrade ? getString("must_upgrade")
  804. : getString("cant_own_land"));
  805. LLComboBox* levels = getChild<LLComboBox>( "account_level");
  806. if (levels)
  807. {
  808. levels->setVisible(mSiteMembershipUpgrade);
  809. levels->removeall();
  810. for (std::vector<std::string>::const_iterator
  811. i = mSiteMembershipPlanNames.begin(),
  812. end = mSiteMembershipPlanNames.end();
  813. i != end; ++i)
  814. {
  815. levels->add(*i);
  816. }
  817. levels->setCurrentByIndex(mUserPlanChoice);
  818. }
  819. childShow("step_1");
  820. childShow("account_action");
  821. childShow("account_reason");
  822. }
  823. else
  824. {
  825. childHide("step_1");
  826. childHide("account_action");
  827. childHide("account_reason");
  828. childHide("account_level");
  829. }
  830. // Section two: land use fees
  831. if (!showing_error)
  832. {
  833. childSetBadge("step_2", mSiteLandUseUpgrade ? BADGE_NOTE : BADGE_OK);
  834. childSetText("land_use_action", mSiteLandUseAction);
  835. if (mIsForGroup)
  836. {
  837. LLStringUtil::format_map_t string_args;
  838. string_args["[GROUP]"] = std::string(gAgent.mGroupName);
  839. message = getString("insufficient_land_credits", string_args);
  840. }
  841. else
  842. {
  843. LLStringUtil::format_map_t string_args;
  844. string_args["[BUYER]"] = llformat("%d", mAgentCommittedTier);
  845. message = getString("land_holdings", string_args);
  846. }
  847. if (!mParcelValid)
  848. {
  849. message += "(no parcel selected)";
  850. }
  851. else if (mParcelBillableArea == mParcelActualArea)
  852. {
  853. LLStringUtil::format_map_t string_args;
  854. string_args["[AMOUNT]"] = llformat("%d ", mParcelActualArea);
  855. message += getString("parcel_meters", string_args);
  856. }
  857. else if (mParcelBillableArea > mParcelActualArea)
  858. {
  859. LLStringUtil::format_map_t string_args;
  860. string_args["[AMOUNT]"] = llformat("%d ", mParcelBillableArea);
  861. message += getString("premium_land", string_args);
  862. }
  863. else
  864. {
  865. LLStringUtil::format_map_t string_args;
  866. string_args["[AMOUNT]"] = llformat("%d ", mParcelBillableArea);
  867. message += getString("discounted_land", string_args);
  868. }
  869. childSetWrappedText("land_use_reason", message);
  870. childShow("step_2");
  871. childShow("land_use_action");
  872. childShow("land_use_reason");
  873. }
  874. else
  875. {
  876. childHide("step_2");
  877. childHide("land_use_action");
  878. childHide("land_use_reason");
  879. }
  880. // Section three: purchase & currency
  881. S32 final_balance = mAgentCashBalance + mCurrency.getAmount() - mParcelPrice;
  882. bool enough_money = final_balance >= 0;
  883. bool can_pay = mAgentCashBalance >= mParcelPrice;
  884. S32 min_contrib = llceil((F32)mParcelBillableArea / GROUP_LAND_BONUS_FACTOR);
  885. bool groupContributionEnough = mParcelGroupContribution >= min_contrib;
  886. mCurrency.updateUI(!showing_error && !can_pay);
  887. if (!showing_error)
  888. {
  889. childSetBadge("step_3",
  890. !enough_money ? BADGE_WARN
  891. : mCurrency.getAmount() > 0 ? BADGE_NOTE
  892. : BADGE_OK);
  893. childSetText("purchase_action",
  894. llformat("Pay L$ %d to %s for this land", mParcelPrice,
  895. mParcelSellerName.c_str()));
  896. childSetVisible("purchase_action", mParcelValid);
  897. std::string reasonString;
  898. if (can_pay)
  899. {
  900. LLStringUtil::format_map_t string_args;
  901. string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance);
  902. childSetText("currency_reason",
  903. getString("have_enough_lindens", string_args));
  904. }
  905. else
  906. {
  907. LLStringUtil::format_map_t string_args;
  908. string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance);
  909. string_args["[AMOUNT2]"] =
  910. llformat("%d", mParcelPrice - mAgentCashBalance);
  911. childSetText("currency_reason",
  912. getString("not_enough_lindens", string_args));
  913. childSetTextArg("currency_est", "[LOCAL_AMOUNT]",
  914. mCurrency.getLocalEstimate());
  915. }
  916. if (enough_money)
  917. {
  918. LLStringUtil::format_map_t string_args;
  919. string_args["[AMOUNT]"] = llformat("%d", final_balance);
  920. childSetText("currency_balance",
  921. getString("balance_left", string_args));
  922. }
  923. else
  924. {
  925. LLStringUtil::format_map_t string_args;
  926. string_args["[AMOUNT]"] =
  927. llformat("%d", mParcelPrice - mAgentCashBalance);
  928. childSetText("currency_balance",
  929. getString("balance_needed", string_args));
  930. }
  931. childSetValue("remove_contribution", LLSD(groupContributionEnough));
  932. childSetEnabled("remove_contribution", groupContributionEnough);
  933. childSetLabelArg("remove_contribution", "[AMOUNT]",
  934. llformat("%d", min_contrib));
  935. childSetVisible("remove_contribution",
  936. mParcelIsGroupLand && mParcelGroupContribution > 0);
  937. childShow("step_3");
  938. childShow("purchase_action");
  939. childShow("currency_reason");
  940. childShow("currency_balance");
  941. }
  942. else
  943. {
  944. childHide("step_3");
  945. childHide("purchase_action");
  946. childHide("currency_reason");
  947. childHide("currency_balance");
  948. childHide("remove_contribution");
  949. }
  950. bool agrees_to_covenant = false;
  951. LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
  952. if (check)
  953. {
  954. agrees_to_covenant = check->get();
  955. }
  956. childSetEnabled("buy_btn",
  957. mCanBuy && mSiteValid && enough_money && !mTransaction &&
  958. agrees_to_covenant);
  959. }
  960. void LLFloaterBuyLand::startBuyPreConfirm()
  961. {
  962. std::string action;
  963. if (mSiteMembershipUpgrade)
  964. {
  965. action += mSiteMembershipAction;
  966. action += "\n";
  967. LLComboBox* levels = getChild<LLComboBox>( "account_level");
  968. if (levels)
  969. {
  970. action += " * ";
  971. action += mSiteMembershipPlanNames[levels->getCurrentIndex()];
  972. action += "\n";
  973. }
  974. }
  975. if (mSiteLandUseUpgrade)
  976. {
  977. action += mSiteLandUseAction;
  978. action += "\n";
  979. }
  980. if (mCurrency.getAmount() > 0)
  981. {
  982. LLStringUtil::format_map_t string_args;
  983. string_args["[AMOUNT]"] = llformat("%d", mCurrency.getAmount());
  984. string_args["[LOCAL_AMOUNT]"] = mCurrency.getLocalEstimate();
  985. action += getString("buy_for_US", string_args);
  986. }
  987. LLStringUtil::format_map_t string_args;
  988. string_args["[AMOUNT]"] = llformat("%d", mParcelPrice);
  989. string_args["[SELLER]"] = mParcelSellerName;
  990. action += getString("pay_to_for_land", string_args);
  991. LLConfirmationManager::confirm(mSiteConfirm, action, *this,
  992. &LLFloaterBuyLand::startBuyPostConfirm);
  993. }
  994. void LLFloaterBuyLand::startBuyPostConfirm(const std::string& password)
  995. {
  996. runWebSitePrep(password);
  997. mCanBuy = false;
  998. mCannotBuyReason = getString("processing");
  999. refreshUI();
  1000. }
  1001. //static
  1002. void LLFloaterBuyLand::onChangeAgreeCovenant(LLUICtrl*, void* data)
  1003. {
  1004. LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
  1005. if (self)
  1006. {
  1007. self->refreshUI();
  1008. }
  1009. }
  1010. //static
  1011. void LLFloaterBuyLand::onClickBuy(void* data)
  1012. {
  1013. LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
  1014. if (self)
  1015. {
  1016. self->startBuyPreConfirm();
  1017. }
  1018. }
  1019. //static
  1020. void LLFloaterBuyLand::onClickCancel(void* data)
  1021. {
  1022. LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
  1023. if (self)
  1024. {
  1025. self->close();
  1026. }
  1027. }
  1028. //static
  1029. void LLFloaterBuyLand::onClickErrorWeb(void* data)
  1030. {
  1031. LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
  1032. if (self)
  1033. {
  1034. LLWeb::loadURLExternal(self->mCannotBuyURI);
  1035. self->close();
  1036. }
  1037. }