PageRenderTime 123ms CodeModel.GetById 10ms app.highlight 103ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llfloaterbuyland.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1381 lines | 1088 code | 215 blank | 78 comment | 130 complexity | 7e60350f4994172fb97b4f50a0c72857 MD5 | raw file
   1/** 
   2 * @file llfloaterbuyland.cpp
   3 * @brief LLFloaterBuyLand class implementation
   4 *
   5 * $LicenseInfo:firstyear=2005&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28
  29#include "llfloaterbuyland.h"
  30
  31// viewer includes
  32#include "llagent.h"
  33#include "llbutton.h"
  34#include "llcachename.h"
  35#include "llcheckboxctrl.h"
  36#include "llcombobox.h"
  37#include "llconfirmationmanager.h"
  38#include "llcurrencyuimanager.h"
  39#include "llfloater.h"
  40#include "llfloaterreg.h"
  41#include "llfloatertools.h"
  42#include "llframetimer.h"
  43#include "lliconctrl.h"
  44#include "lllineeditor.h"
  45#include "llnotificationsutil.h"
  46#include "llparcel.h"
  47#include "llslurl.h"
  48#include "llstatusbar.h"
  49#include "lltextbox.h"
  50#include "lltexturectrl.h"
  51#include "lltrans.h"
  52#include "llviewchildren.h"
  53#include "llviewercontrol.h"
  54#include "lluictrlfactory.h"
  55#include "llviewerparcelmgr.h"
  56#include "llviewerregion.h"
  57#include "llviewertexteditor.h"
  58#include "llviewerwindow.h"
  59#include "llweb.h"
  60#include "llwindow.h"
  61#include "llworld.h"
  62#include "llxmlrpctransaction.h"
  63#include "llviewernetwork.h"
  64#include "roles_constants.h"
  65
  66// NOTE: This is duplicated in lldatamoney.cpp ...
  67const F32 GROUP_LAND_BONUS_FACTOR = 1.1f;
  68const F64 CURRENCY_ESTIMATE_FREQUENCY = 0.5;
  69	// how long of a pause in typing a currency buy amount before an
  70	// estimate is fetched from the server
  71
  72class LLFloaterBuyLandUI
  73:	public LLFloater
  74{
  75public:
  76	LLFloaterBuyLandUI(const LLSD& key);
  77	virtual ~LLFloaterBuyLandUI();
  78	
  79	/*virtual*/ void onClose(bool app_quitting);
  80
  81	// Left padding for maturity rating icon.
  82	static const S32 ICON_PAD = 2;
  83
  84private:
  85	class SelectionObserver : public LLParcelObserver
  86	{
  87	public:
  88		SelectionObserver(LLFloaterBuyLandUI* floater) : mFloater(floater) {}
  89		virtual void changed();
  90	private:
  91		LLFloaterBuyLandUI* mFloater;
  92	};
  93	
  94private:
  95	SelectionObserver mParcelSelectionObserver;
  96	LLViewerRegion*	mRegion;
  97	LLParcelSelectionHandle mParcel;
  98	bool			mIsClaim;
  99	bool			mIsForGroup;
 100
 101	bool			mCanBuy;
 102	bool			mCannotBuyIsError;
 103	std::string		mCannotBuyReason;
 104	std::string		mCannotBuyURI;
 105	
 106	bool			mBought;
 107	
 108	// information about the agent
 109	S32				mAgentCommittedTier;
 110	S32				mAgentCashBalance;
 111	bool			mAgentHasNeverOwnedLand;
 112	
 113	// information about the parcel
 114	bool			mParcelValid;
 115	bool			mParcelIsForSale;
 116	bool			mParcelIsGroupLand;
 117	S32				mParcelGroupContribution;
 118	S32				mParcelPrice;
 119	S32				mParcelActualArea;
 120	S32				mParcelBillableArea;
 121	S32				mParcelSupportedObjects;
 122	bool			mParcelSoldWithObjects;
 123	std::string		mParcelLocation;
 124	LLUUID			mParcelSnapshot;
 125	std::string		mParcelSellerName;
 126	
 127	// user's choices
 128	S32				mUserPlanChoice;
 129	
 130	// from website
 131	bool			mSiteValid;
 132	bool			mSiteMembershipUpgrade;
 133	std::string		mSiteMembershipAction;
 134	std::vector<std::string>
 135					mSiteMembershipPlanIDs;
 136	std::vector<std::string>
 137					mSiteMembershipPlanNames;
 138	bool			mSiteLandUseUpgrade;
 139	std::string		mSiteLandUseAction;
 140	std::string		mSiteConfirm;
 141	
 142	// values in current Preflight transaction... used to avoid extra
 143	// preflights when the parcel manager goes update crazy
 144	S32				mPreflightAskBillableArea;
 145	S32				mPreflightAskCurrencyBuy;
 146
 147	LLViewChildren		mChildren;
 148	LLCurrencyUIManager	mCurrency;
 149	
 150	enum TransactionType
 151	{
 152		TransactionPreflight,
 153		TransactionCurrency,
 154		TransactionBuy
 155	};
 156	LLXMLRPCTransaction* mTransaction;
 157	TransactionType		 mTransactionType;
 158	
 159	LLViewerParcelMgr::ParcelBuyInfo*	mParcelBuyInfo;
 160	
 161public:
 162	void setForGroup(bool is_for_group);
 163	void setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel);
 164		
 165	void updateAgentInfo();
 166	void updateParcelInfo();
 167	void updateCovenantInfo();
 168	static void onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data);
 169	void updateFloaterCovenantText(const std::string& string, const LLUUID &asset_id);
 170	void updateFloaterEstateName(const std::string& name);
 171	void updateFloaterLastModified(const std::string& text);
 172	void updateFloaterEstateOwnerName(const std::string& name);
 173	void updateWebSiteInfo();
 174	void finishWebSiteInfo();
 175	
 176	void runWebSitePrep(const std::string& password);
 177	void finishWebSitePrep();
 178	void sendBuyLand();
 179
 180	void updateNames();
 181	// Name cache callback
 182	void updateGroupName(const LLUUID& id,
 183						 const std::string& name,
 184						 bool is_group);
 185	
 186	void refreshUI();
 187	
 188	void startTransaction(TransactionType type, const LLXMLRPCValue& params);
 189	bool checkTransaction();
 190	
 191	void tellUserError(const std::string& message, const std::string& uri);
 192
 193	virtual BOOL postBuild();
 194	
 195	void startBuyPreConfirm();
 196	void startBuyPostConfirm(const std::string& password);
 197
 198	void onClickBuy();
 199	void onClickCancel();
 200	 void onClickErrorWeb();
 201	
 202	virtual void draw();
 203	virtual BOOL canClose();
 204
 205	void onVisibilityChange ( const LLSD& new_visibility );
 206	
 207};
 208
 209// static
 210void LLFloaterBuyLand::buyLand(
 211	LLViewerRegion* region, LLParcelSelectionHandle parcel, bool is_for_group)
 212{
 213	if(is_for_group && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
 214	{
 215		LLNotificationsUtil::add("OnlyOfficerCanBuyLand");
 216		return;
 217	}
 218
 219	LLFloaterBuyLandUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyLandUI>("buy_land");
 220	if (ui)
 221	{
 222		ui->setForGroup(is_for_group);
 223		ui->setParcel(region, parcel);
 224	}
 225}
 226
 227// static
 228void LLFloaterBuyLand::updateCovenantText(const std::string& string, const LLUUID &asset_id)
 229{
 230	LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
 231	if (floater)
 232	{
 233		floater->updateFloaterCovenantText(string, asset_id);
 234	}
 235}
 236
 237// static
 238void LLFloaterBuyLand::updateEstateName(const std::string& name)
 239{
 240	LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
 241	if (floater)
 242	{
 243		floater->updateFloaterEstateName(name);
 244	}
 245}
 246
 247// static
 248void LLFloaterBuyLand::updateLastModified(const std::string& text)
 249{
 250	LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
 251	if (floater)
 252	{
 253		floater->updateFloaterLastModified(text);
 254	}
 255}
 256
 257// static
 258void LLFloaterBuyLand::updateEstateOwnerName(const std::string& name)
 259{
 260	LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
 261	if (floater)
 262	{
 263		floater->updateFloaterEstateOwnerName(name);
 264	}
 265}
 266
 267// static
 268LLFloater* LLFloaterBuyLand::buildFloater(const LLSD& key)
 269{
 270	LLFloaterBuyLandUI* floater = new LLFloaterBuyLandUI(key);
 271	return floater;
 272}
 273
 274//----------------------------------------------------------------------------
 275// LLFloaterBuyLandUI
 276//----------------------------------------------------------------------------
 277
 278#if LL_WINDOWS
 279// passing 'this' during construction generates a warning. The callee
 280// only uses the pointer to hold a reference to 'this' which is
 281// already valid, so this call does the correct thing. Disable the
 282// warning so that we can compile without generating a warning.
 283#pragma warning(disable : 4355)
 284#endif 
 285LLFloaterBuyLandUI::LLFloaterBuyLandUI(const LLSD& key)
 286:	LLFloater(LLSD()),
 287	mParcelSelectionObserver(this),
 288	mParcel(0),
 289	mBought(false),
 290	mParcelValid(false), mSiteValid(false),
 291	mChildren(*this), mCurrency(*this), mTransaction(0),
 292	mParcelBuyInfo(0)
 293{
 294	LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver);
 295	
 296}
 297
 298LLFloaterBuyLandUI::~LLFloaterBuyLandUI()
 299{
 300	LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver);
 301	LLViewerParcelMgr::getInstance()->deleteParcelBuy(&mParcelBuyInfo);
 302	
 303	delete mTransaction;
 304}
 305
 306// virtual
 307void LLFloaterBuyLandUI::onClose(bool app_quitting)
 308{
 309	// This object holds onto observer, transactions, and parcel state.
 310	// Despite being single_instance, destroy it to call destructors and clean
 311	// everything up.
 312	setVisible(FALSE);
 313	destroy();
 314}
 315
 316void LLFloaterBuyLandUI::SelectionObserver::changed()
 317{
 318	if (LLViewerParcelMgr::getInstance()->selectionEmpty())
 319	{
 320		mFloater->closeFloater();
 321	}
 322	else
 323	{
 324		mFloater->setParcel(LLViewerParcelMgr::getInstance()->getSelectionRegion(),
 325							LLViewerParcelMgr::getInstance()->getParcelSelection());
 326	}
 327}
 328
 329
 330void LLFloaterBuyLandUI::updateAgentInfo()
 331{
 332	mAgentCommittedTier = gStatusBar->getSquareMetersCommitted();
 333	mAgentCashBalance = gStatusBar->getBalance();
 334
 335	// *TODO: This is an approximation, we should send this value down
 336	// to the viewer. See SL-10728 for details.
 337	mAgentHasNeverOwnedLand = mAgentCommittedTier == 0;
 338}
 339
 340void LLFloaterBuyLandUI::updateParcelInfo()
 341{
 342	LLParcel* parcel = mParcel->getParcel();
 343	mParcelValid = parcel && mRegion;
 344	mParcelIsForSale = false;
 345	mParcelIsGroupLand = false;
 346	mParcelGroupContribution = 0;
 347	mParcelPrice = 0;
 348	mParcelActualArea = 0;
 349	mParcelBillableArea = 0;
 350	mParcelSupportedObjects = 0;
 351	mParcelSoldWithObjects = false;
 352	mParcelLocation = "";
 353	mParcelSnapshot.setNull();
 354	mParcelSellerName = "";
 355	
 356	mCanBuy = false;
 357	mCannotBuyIsError = false;
 358	
 359	if (!mParcelValid)
 360	{
 361		mCannotBuyReason = getString("no_land_selected");
 362		return;
 363	}
 364	
 365	if (mParcel->getMultipleOwners())
 366	{
 367		mCannotBuyReason = getString("multiple_parcels_selected");
 368		return;
 369	}
 370
 371	const LLUUID& parcelOwner = parcel->getOwnerID();
 372	
 373	mIsClaim = parcel->isPublic();
 374	if (!mIsClaim)
 375	{
 376		mParcelActualArea = parcel->getArea();
 377		mParcelIsForSale = parcel->getForSale();
 378		mParcelIsGroupLand = parcel->getIsGroupOwned();
 379		mParcelPrice = mParcelIsForSale ? parcel->getSalePrice() : 0;
 380		
 381		if (mParcelIsGroupLand)
 382		{
 383			LLUUID group_id = parcel->getGroupID();
 384			mParcelGroupContribution = gAgent.getGroupContribution(group_id);
 385		}
 386	}
 387	else
 388	{
 389		mParcelActualArea = mParcel->getClaimableArea();
 390		mParcelIsForSale = true;
 391		mParcelPrice = mParcelActualArea * parcel->getClaimPricePerMeter();
 392	}
 393
 394	mParcelBillableArea =
 395		llround(mRegion->getBillableFactor() * mParcelActualArea);
 396
 397 	mParcelSupportedObjects = llround(
 398		parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()); 
 399 	// Can't have more than region max tasks, regardless of parcel 
 400 	// object bonus factor. 
 401 	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); 
 402 	if(region) 
 403 	{ 
 404		S32 max_tasks_per_region = (S32)region->getMaxTasks(); 
 405		mParcelSupportedObjects = llmin(
 406			mParcelSupportedObjects, max_tasks_per_region); 
 407 	} 
 408
 409	mParcelSoldWithObjects = parcel->getSellWithObjects();
 410
 411	
 412	LLVector3 center = parcel->getCenterpoint();
 413	mParcelLocation = llformat("%s %d,%d",
 414				mRegion->getName().c_str(),
 415				(int)center[VX], (int)center[VY]
 416				);
 417	
 418	mParcelSnapshot = parcel->getSnapshotID();
 419	
 420	updateNames();
 421	
 422	bool haveEnoughCash = mParcelPrice <= mAgentCashBalance;
 423	S32 cashBuy = haveEnoughCash ? 0 : (mParcelPrice - mAgentCashBalance);
 424	mCurrency.setAmount(cashBuy, true);
 425	mCurrency.setZeroMessage(haveEnoughCash ? getString("none_needed") : LLStringUtil::null);
 426
 427	// checks that we can buy the land
 428
 429	if(mIsForGroup && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
 430	{
 431		mCannotBuyReason = getString("cant_buy_for_group");
 432		return;
 433	}
 434
 435	if (!mIsClaim)
 436	{
 437		const LLUUID& authorizedBuyer = parcel->getAuthorizedBuyerID();
 438		const LLUUID buyer = gAgent.getID();
 439		const LLUUID newOwner = mIsForGroup ? gAgent.getGroupID() : buyer;
 440
 441		if (!mParcelIsForSale
 442			|| (mParcelPrice == 0  &&  authorizedBuyer.isNull()))
 443		{
 444			
 445			mCannotBuyReason = getString("parcel_not_for_sale");
 446			return;
 447		}
 448
 449		if (parcelOwner == newOwner)
 450		{
 451			if (mIsForGroup)
 452			{
 453				mCannotBuyReason = getString("group_already_owns");
 454			}
 455			else
 456			{
 457				mCannotBuyReason = getString("you_already_own");
 458			}
 459			return;
 460		}
 461
 462		if (!authorizedBuyer.isNull() && buyer != authorizedBuyer)
 463		{
 464			// Maybe the parcel is set for sale to a group we are in.
 465			bool authorized_group =
 466				gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED)
 467				&& gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO);
 468
 469			if (!authorized_group)
 470			{
 471				mCannotBuyReason = getString("set_to_sell_to_other");
 472				return;
 473			}
 474		}
 475	}
 476	else
 477	{
 478		if (mParcelActualArea == 0)
 479		{
 480			mCannotBuyReason = getString("no_public_land");
 481			return;
 482		}
 483
 484		if (mParcel->hasOthersSelected())
 485		{
 486			// Policy: Must not have someone else's land selected
 487			mCannotBuyReason = getString("not_owned_by_you");
 488			return;
 489		}
 490	}
 491
 492	mCanBuy = true;
 493}
 494
 495void LLFloaterBuyLandUI::updateCovenantInfo()
 496{
 497	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
 498	if(!region) return;
 499
 500	U8 sim_access = region->getSimAccess();
 501	std::string rating = LLViewerRegion::accessToString(sim_access);
 502	
 503	LLTextBox* region_name = getChild<LLTextBox>("region_name_text");
 504	if (region_name)
 505	{
 506		std::string region_name_txt = region->getName() + " ("+rating +")";
 507		region_name->setText(region_name_txt);
 508
 509		LLIconCtrl* rating_icon = getChild<LLIconCtrl>("rating_icon");
 510		LLRect rect = rating_icon->getRect();
 511		S32 region_name_width = llmin(region_name->getRect().getWidth(), region_name->getTextBoundingRect().getWidth());
 512		S32 icon_left_pad = region_name->getRect().mLeft + region_name_width + ICON_PAD;
 513		region_name->setToolTip(region_name->getText());
 514		rating_icon->setRect(rect.setOriginAndSize(icon_left_pad, rect.mBottom, rect.getWidth(), rect.getHeight()));
 515
 516		switch(sim_access)
 517		{
 518		case SIM_ACCESS_PG:
 519			rating_icon->setValue(getString("icon_PG"));
 520			break;
 521
 522		case SIM_ACCESS_ADULT:
 523			rating_icon->setValue(getString("icon_R"));
 524			break;
 525
 526		default:
 527			rating_icon->setValue(getString("icon_M"));
 528		}
 529	}
 530
 531	LLTextBox* region_type = getChild<LLTextBox>("region_type_text");
 532	if (region_type)
 533	{
 534		region_type->setText(region->getLocalizedSimProductName());
 535		region_type->setToolTip(region->getLocalizedSimProductName());
 536	}
 537	
 538	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
 539	if (resellable_clause)
 540	{
 541		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
 542		{
 543			resellable_clause->setText(getString("can_not_resell"));
 544		}
 545		else
 546		{
 547			resellable_clause->setText(getString("can_resell"));
 548		}
 549	}
 550	
 551	LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
 552	if (changeable_clause)
 553	{
 554		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
 555		{
 556			changeable_clause->setText(getString("can_change"));
 557		}
 558		else
 559		{
 560			changeable_clause->setText(getString("can_not_change"));
 561		}
 562	}
 563
 564	LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
 565	if(check)
 566	{
 567		check->set(false);
 568		check->setEnabled(true);
 569		check->setCommitCallback(onChangeAgreeCovenant, this);
 570	}
 571
 572	LLTextBox* box = getChild<LLTextBox>("covenant_text");
 573	if(box)
 574	{
 575		box->setVisible(FALSE);
 576	}
 577	
 578	// send EstateCovenantInfo message
 579	LLMessageSystem *msg = gMessageSystem;
 580	msg->newMessage("EstateCovenantRequest");
 581	msg->nextBlockFast(_PREHASH_AgentData);
 582	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());
 583	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
 584	msg->sendReliable(region->getHost());
 585}
 586
 587// static
 588void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data)
 589{
 590	LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)user_data;
 591	if(self)
 592	{
 593		self->refreshUI();
 594	}
 595}
 596
 597void LLFloaterBuyLandUI::updateFloaterCovenantText(const std::string &string, const LLUUID& asset_id)
 598{
 599	LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("covenant_editor");
 600	editor->setText(string);
 601
 602	LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
 603	LLTextBox* box = getChild<LLTextBox>("covenant_text");
 604	if (asset_id.isNull())
 605	{
 606		check->set(true);
 607		check->setEnabled(false);
 608		refreshUI();
 609
 610		// remove the line stating that you must agree
 611		box->setVisible(FALSE);
 612	}
 613	else
 614	{
 615		check->setEnabled(true);
 616
 617		// remove the line stating that you must agree
 618		box->setVisible(TRUE);
 619	}
 620}
 621
 622void LLFloaterBuyLandUI::updateFloaterEstateName(const std::string& name)
 623{
 624	LLTextBox* box = getChild<LLTextBox>("estate_name_text");
 625	box->setText(name);
 626	box->setToolTip(name);
 627}
 628
 629void LLFloaterBuyLandUI::updateFloaterLastModified(const std::string& text)
 630{
 631	LLTextBox* editor = getChild<LLTextBox>("covenant_timestamp_text");
 632	if (editor) editor->setText(text);
 633}
 634
 635void LLFloaterBuyLandUI::updateFloaterEstateOwnerName(const std::string& name)
 636{
 637	LLTextBox* box = getChild<LLTextBox>("estate_owner_text");
 638	if (box) box->setText(name);
 639}
 640
 641void LLFloaterBuyLandUI::updateWebSiteInfo()
 642{
 643	S32 askBillableArea = mIsForGroup ? 0 : mParcelBillableArea;
 644	S32 askCurrencyBuy = mCurrency.getAmount();
 645	
 646	if (mTransaction && mTransactionType == TransactionPreflight
 647	&&  mPreflightAskBillableArea == askBillableArea
 648	&&  mPreflightAskCurrencyBuy == askCurrencyBuy)
 649	{
 650		return;
 651	}
 652	
 653	mPreflightAskBillableArea = askBillableArea;
 654	mPreflightAskCurrencyBuy = askCurrencyBuy;
 655	
 656#if 0
 657	// enable this code if you want the details to blank while we're talking
 658	// to the web site... it's kind of jarring
 659	mSiteValid = false;
 660	mSiteMembershipUpgrade = false;
 661	mSiteMembershipAction = "(waiting)";
 662	mSiteMembershipPlanIDs.clear();
 663	mSiteMembershipPlanNames.clear();
 664	mSiteLandUseUpgrade = false;
 665	mSiteLandUseAction = "(waiting)";
 666	mSiteCurrencyEstimated = false;
 667	mSiteCurrencyEstimatedCost = 0;
 668#endif
 669	
 670	LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
 671	keywordArgs.appendString("agentId", gAgent.getID().asString());
 672	keywordArgs.appendString(
 673		"secureSessionId",
 674		gAgent.getSecureSessionID().asString());
 675	keywordArgs.appendString("language", LLUI::getLanguage());
 676	keywordArgs.appendInt("billableArea", mPreflightAskBillableArea);
 677	keywordArgs.appendInt("currencyBuy", mPreflightAskCurrencyBuy);
 678	
 679	LLXMLRPCValue params = LLXMLRPCValue::createArray();
 680	params.append(keywordArgs);
 681	
 682	startTransaction(TransactionPreflight, params);
 683}
 684
 685void LLFloaterBuyLandUI::finishWebSiteInfo()
 686{
 687	
 688	LLXMLRPCValue result = mTransaction->responseValue();
 689
 690	mSiteValid = result["success"].asBool();
 691	if (!mSiteValid)
 692	{
 693		tellUserError(
 694			result["errorMessage"].asString(),
 695			result["errorURI"].asString()
 696		);
 697		return;
 698	}
 699	
 700	LLXMLRPCValue membership = result["membership"];
 701	mSiteMembershipUpgrade = membership["upgrade"].asBool();
 702	mSiteMembershipAction = membership["action"].asString();
 703	mSiteMembershipPlanIDs.clear();
 704	mSiteMembershipPlanNames.clear();
 705	LLXMLRPCValue levels = membership["levels"];
 706	for (LLXMLRPCValue level = levels.rewind();
 707		level.isValid();
 708		level = levels.next())
 709	{
 710		mSiteMembershipPlanIDs.push_back(level["id"].asString());
 711		mSiteMembershipPlanNames.push_back(level["description"].asString());
 712	}
 713	mUserPlanChoice = 0;
 714
 715	LLXMLRPCValue landUse = result["landUse"];
 716	mSiteLandUseUpgrade = landUse["upgrade"].asBool();
 717	mSiteLandUseAction = landUse["action"].asString();
 718
 719	LLXMLRPCValue currency = result["currency"];
 720	if (currency["estimatedCost"].isValid())
 721	{
 722		mCurrency.setUSDEstimate(currency["estimatedCost"].asInt());
 723	}
 724	if (currency["estimatedLocalCost"].isValid())
 725	{
 726		mCurrency.setLocalEstimate(currency["estimatedLocalCost"].asString());
 727	}
 728
 729	mSiteConfirm = result["confirm"].asString();
 730}
 731
 732void LLFloaterBuyLandUI::runWebSitePrep(const std::string& password)
 733{
 734	if (!mCanBuy)
 735	{
 736		return;
 737	}
 738	
 739	BOOL remove_contribution = getChild<LLUICtrl>("remove_contribution")->getValue().asBoolean();
 740	mParcelBuyInfo = LLViewerParcelMgr::getInstance()->setupParcelBuy(gAgent.getID(), gAgent.getSessionID(),
 741						gAgent.getGroupID(), mIsForGroup, mIsClaim, remove_contribution);
 742
 743	if (mParcelBuyInfo
 744		&& !mSiteMembershipUpgrade
 745		&& !mSiteLandUseUpgrade
 746		&& mCurrency.getAmount() == 0
 747		&& mSiteConfirm != "password")
 748	{
 749		sendBuyLand();
 750		return;
 751	}
 752
 753
 754	std::string newLevel = "noChange";
 755	
 756	if (mSiteMembershipUpgrade)
 757	{
 758		LLComboBox* levels = getChild<LLComboBox>( "account_level");
 759		if (levels)
 760		{
 761			mUserPlanChoice = levels->getCurrentIndex();
 762			newLevel = mSiteMembershipPlanIDs[mUserPlanChoice];
 763		}
 764	}
 765	
 766	LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
 767	keywordArgs.appendString("agentId", gAgent.getID().asString());
 768	keywordArgs.appendString(
 769		"secureSessionId",
 770		gAgent.getSecureSessionID().asString());
 771	keywordArgs.appendString("language", LLUI::getLanguage());
 772	keywordArgs.appendString("levelId", newLevel);
 773	keywordArgs.appendInt("billableArea",
 774		mIsForGroup ? 0 : mParcelBillableArea);
 775	keywordArgs.appendInt("currencyBuy", mCurrency.getAmount());
 776	keywordArgs.appendInt("estimatedCost", mCurrency.getUSDEstimate());
 777	keywordArgs.appendString("estimatedLocalCost", mCurrency.getLocalEstimate());
 778	keywordArgs.appendString("confirm", mSiteConfirm);
 779	if (!password.empty())
 780	{
 781		keywordArgs.appendString("password", password);
 782	}
 783	
 784	LLXMLRPCValue params = LLXMLRPCValue::createArray();
 785	params.append(keywordArgs);
 786	
 787	startTransaction(TransactionBuy, params);
 788}
 789
 790void LLFloaterBuyLandUI::finishWebSitePrep()
 791{
 792	LLXMLRPCValue result = mTransaction->responseValue();
 793
 794	bool success = result["success"].asBool();
 795	if (!success)
 796	{
 797		tellUserError(
 798			result["errorMessage"].asString(),
 799			result["errorURI"].asString()
 800		);
 801		return;
 802	}
 803	
 804	sendBuyLand();
 805}
 806
 807void LLFloaterBuyLandUI::sendBuyLand()
 808{
 809	if (mParcelBuyInfo)
 810	{
 811		LLViewerParcelMgr::getInstance()->sendParcelBuy(mParcelBuyInfo);
 812		LLViewerParcelMgr::getInstance()->deleteParcelBuy(&mParcelBuyInfo);
 813		mBought = true;
 814	}
 815}
 816
 817void LLFloaterBuyLandUI::updateNames()
 818{
 819	LLParcel* parcelp = mParcel->getParcel();
 820
 821	if (!parcelp)
 822	{
 823		mParcelSellerName = LLStringUtil::null;
 824		return;
 825	}
 826	
 827	if (mIsClaim)
 828	{
 829		mParcelSellerName = "Linden Lab";
 830	}
 831	else if (parcelp->getIsGroupOwned())
 832	{
 833		gCacheName->getGroup(parcelp->getGroupID(),
 834			boost::bind(&LLFloaterBuyLandUI::updateGroupName, this,
 835				_1, _2, _3));
 836	}
 837	else
 838	{
 839		mParcelSellerName = LLSLURL("agent", parcelp->getOwnerID(), "completename").getSLURLString();
 840	}
 841}
 842
 843void LLFloaterBuyLandUI::updateGroupName(const LLUUID& id,
 844						 const std::string& name,
 845						 bool is_group)
 846{
 847	LLParcel* parcelp = mParcel->getParcel();
 848	if (parcelp
 849		&& parcelp->getGroupID() == id)
 850	{
 851		// request is current
 852		mParcelSellerName = name;
 853	}
 854}
 855
 856void LLFloaterBuyLandUI::startTransaction(TransactionType type, const LLXMLRPCValue& params)
 857{
 858	delete mTransaction;
 859	mTransaction = NULL;
 860
 861	mTransactionType = type;
 862
 863	// Select a URI and method appropriate for the transaction type.
 864	static std::string transaction_uri;
 865	if (transaction_uri.empty())
 866	{
 867		transaction_uri = LLGridManager::getInstance()->getHelperURI() + "landtool.php";
 868	}
 869	
 870	const char* method;
 871	switch (mTransactionType)
 872	{
 873		case TransactionPreflight:
 874			method = "preflightBuyLandPrep";
 875			break;
 876		case TransactionBuy:
 877			method = "buyLandPrep";
 878			break;
 879		default:
 880			llwarns << "LLFloaterBuyLandUI: Unknown transaction type!" << llendl;
 881			return;
 882	}
 883
 884	mTransaction = new LLXMLRPCTransaction(
 885		transaction_uri,
 886		method,
 887		params,
 888		false /* don't use gzip */
 889		);
 890}
 891
 892bool LLFloaterBuyLandUI::checkTransaction()
 893{
 894	if (!mTransaction)
 895	{
 896		return false;
 897	}
 898	
 899	if (!mTransaction->process())
 900	{
 901		return false;
 902	}
 903
 904	if (mTransaction->status(NULL) != LLXMLRPCTransaction::StatusComplete)
 905	{
 906		tellUserError(mTransaction->statusMessage(), mTransaction->statusURI());
 907	}
 908	else {
 909		switch (mTransactionType)
 910		{	
 911			case TransactionPreflight:	finishWebSiteInfo();	break;
 912			case TransactionBuy:		finishWebSitePrep();	break;
 913			default: ;
 914		}
 915	}
 916	
 917	delete mTransaction;
 918	mTransaction = NULL;
 919	
 920	return true;
 921}
 922
 923void LLFloaterBuyLandUI::tellUserError(
 924	const std::string& message, const std::string& uri)
 925{
 926	mCanBuy = false;
 927	mCannotBuyIsError = true;
 928	mCannotBuyReason = getString("fetching_error");
 929	mCannotBuyReason += message;
 930	mCannotBuyURI = uri;
 931}
 932
 933
 934// virtual
 935BOOL LLFloaterBuyLandUI::postBuild()
 936{
 937	setVisibleCallback(boost::bind(&LLFloaterBuyLandUI::onVisibilityChange, this, _2));
 938	
 939	mCurrency.prepare();
 940	
 941	getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickBuy, this));
 942	getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickCancel, this));
 943	getChild<LLUICtrl>("error_web")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickErrorWeb, this));
 944
 945	center();
 946	
 947	return TRUE;
 948}
 949
 950void LLFloaterBuyLandUI::setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel)
 951{
 952	if (mTransaction &&  mTransactionType == TransactionBuy)
 953	{
 954		// the user is buying, don't change the selection
 955		return;
 956	}
 957	
 958	mRegion = region;
 959	mParcel = parcel;
 960
 961	updateAgentInfo();
 962	updateParcelInfo();
 963	updateCovenantInfo();
 964	if (mCanBuy)
 965	{
 966		updateWebSiteInfo();
 967	}
 968	refreshUI();
 969}
 970
 971void LLFloaterBuyLandUI::setForGroup(bool forGroup)
 972{
 973	mIsForGroup = forGroup;
 974}
 975
 976void LLFloaterBuyLandUI::draw()
 977{
 978	LLFloater::draw();
 979	
 980	bool needsUpdate = false;
 981	needsUpdate |= checkTransaction();
 982	needsUpdate |= mCurrency.process();
 983	
 984	if (mBought)
 985	{
 986		closeFloater();
 987	}
 988	else if (needsUpdate)
 989	{
 990		if (mCanBuy && mCurrency.hasError())
 991		{
 992			tellUserError(mCurrency.errorMessage(), mCurrency.errorURI());
 993		}
 994		
 995		refreshUI();
 996	}
 997}
 998
 999// virtual
1000BOOL LLFloaterBuyLandUI::canClose()
1001{
1002	bool can_close = (mTransaction ? FALSE : TRUE) && mCurrency.canCancel();
1003	if (!can_close)
1004	{
1005		// explain to user why they can't do this, see DEV-9605
1006		LLNotificationsUtil::add("CannotCloseFloaterBuyLand");
1007	}
1008	return can_close;
1009}
1010
1011void LLFloaterBuyLandUI::onVisibilityChange ( const LLSD& new_visibility )
1012{
1013	if (new_visibility.asBoolean())
1014	{
1015		refreshUI();
1016	}
1017}
1018
1019void LLFloaterBuyLandUI::refreshUI()
1020{
1021	// section zero: title area
1022	{
1023		LLTextureCtrl* snapshot = getChild<LLTextureCtrl>("info_image");
1024		if (snapshot)
1025		{
1026			snapshot->setImageAssetID(
1027				mParcelValid ? mParcelSnapshot : LLUUID::null);
1028		}
1029		
1030		if (mParcelValid)
1031		{
1032			getChild<LLUICtrl>("info_parcel")->setValue(mParcelLocation);
1033
1034			LLStringUtil::format_map_t string_args;
1035			string_args["[AMOUNT]"] = llformat("%d", mParcelActualArea);
1036			string_args["[AMOUNT2]"] = llformat("%d", mParcelSupportedObjects);
1037		
1038			getChild<LLUICtrl>("info_size")->setValue(getString("meters_supports_object", string_args));
1039
1040			F32 cost_per_sqm = 0.0f;
1041			if (mParcelActualArea > 0)
1042			{
1043				cost_per_sqm = (F32)mParcelPrice / (F32)mParcelActualArea;
1044			}
1045
1046			LLStringUtil::format_map_t info_price_args;
1047			info_price_args["[PRICE]"] = llformat("%d", mParcelPrice);
1048			info_price_args["[PRICE_PER_SQM]"] = llformat("%.1f", cost_per_sqm);
1049			if (mParcelSoldWithObjects)
1050			{
1051				info_price_args["[SOLD_WITH_OBJECTS]"] = getString("sold_with_objects");
1052			}
1053			else
1054			{
1055				info_price_args["[SOLD_WITH_OBJECTS]"] = getString("sold_without_objects");
1056			}
1057			getChild<LLUICtrl>("info_price")->setValue(getString("info_price_string", info_price_args));
1058			getChildView("info_price")->setVisible( mParcelIsForSale);
1059		}
1060		else
1061		{
1062			getChild<LLUICtrl>("info_parcel")->setValue(getString("no_parcel_selected"));
1063			getChild<LLUICtrl>("info_size")->setValue(LLStringUtil::null);
1064			getChild<LLUICtrl>("info_price")->setValue(LLStringUtil::null);
1065		}
1066		
1067		getChild<LLUICtrl>("info_action")->setValue(
1068			mCanBuy
1069				?
1070					mIsForGroup
1071						? getString("buying_for_group")//"Buying land for group:"
1072						: getString("buying_will")//"Buying this land will:"
1073				: 
1074					mCannotBuyIsError
1075						? getString("cannot_buy_now")//"Cannot buy now:"
1076						: getString("not_for_sale")//"Not for sale:"
1077
1078			);
1079	}
1080	
1081	bool showingError = !mCanBuy || !mSiteValid;
1082	
1083	// error section
1084	if (showingError)
1085	{
1086		mChildren.setBadge(std::string("step_error"),
1087			mCannotBuyIsError
1088				? LLViewChildren::BADGE_ERROR
1089				: LLViewChildren::BADGE_WARN);
1090		
1091		LLTextBox* message = getChild<LLTextBox>("error_message");
1092		if (message)
1093		{
1094			message->setVisible(true);
1095			message->setValue(LLSD(!mCanBuy ? mCannotBuyReason : "(waiting for data)"));
1096		}
1097
1098		getChildView("error_web")->setVisible(mCannotBuyIsError && !mCannotBuyURI.empty());
1099	}
1100	else
1101	{
1102		getChildView("step_error")->setVisible(FALSE);
1103		getChildView("error_message")->setVisible(FALSE);
1104		getChildView("error_web")->setVisible(FALSE);
1105	}
1106	
1107	
1108	// section one: account
1109	if (!showingError)
1110	{
1111		mChildren.setBadge(std::string("step_1"),
1112			mSiteMembershipUpgrade
1113				? LLViewChildren::BADGE_NOTE
1114				: LLViewChildren::BADGE_OK);
1115		getChild<LLUICtrl>("account_action")->setValue(mSiteMembershipAction);
1116		getChild<LLUICtrl>("account_reason")->setValue( 
1117			mSiteMembershipUpgrade
1118				?	getString("must_upgrade")
1119				:	getString("cant_own_land")
1120			);
1121		
1122		LLComboBox* levels = getChild<LLComboBox>( "account_level");
1123		if (levels)
1124		{
1125			levels->setVisible(mSiteMembershipUpgrade);
1126			
1127			levels->removeall();
1128			for(std::vector<std::string>::const_iterator i
1129					= mSiteMembershipPlanNames.begin();
1130				i != mSiteMembershipPlanNames.end();
1131				++i)
1132			{
1133				levels->add(*i);
1134			}
1135			
1136			levels->setCurrentByIndex(mUserPlanChoice);
1137		}
1138
1139		getChildView("step_1")->setVisible(TRUE);
1140		getChildView("account_action")->setVisible(TRUE);
1141		getChildView("account_reason")->setVisible(TRUE);
1142	}
1143	else
1144	{
1145		getChildView("step_1")->setVisible(FALSE);
1146		getChildView("account_action")->setVisible(FALSE);
1147		getChildView("account_reason")->setVisible(FALSE);
1148		getChildView("account_level")->setVisible(FALSE);
1149	}
1150	
1151	// section two: land use fees
1152	if (!showingError)
1153	{
1154		mChildren.setBadge(std::string("step_2"),
1155			mSiteLandUseUpgrade
1156				? LLViewChildren::BADGE_NOTE
1157				: LLViewChildren::BADGE_OK);
1158		getChild<LLUICtrl>("land_use_action")->setValue(mSiteLandUseAction);
1159		
1160		std::string message;
1161		
1162		if (mIsForGroup)
1163		{
1164			LLStringUtil::format_map_t string_args;
1165			string_args["[GROUP]"] = std::string(gAgent.getGroupName());
1166
1167			message += getString("insufficient_land_credits", string_args);
1168				
1169		}
1170		else
1171		{
1172			LLStringUtil::format_map_t string_args;
1173			string_args["[BUYER]"] = llformat("%d", mAgentCommittedTier);
1174			message += getString("land_holdings", string_args);
1175		}
1176		
1177		if (!mParcelValid)
1178		{
1179			message += LLTrans::getString("sentences_separator") + getString("no_parcel_selected");
1180		}
1181		else if (mParcelBillableArea == mParcelActualArea)
1182		{
1183			LLStringUtil::format_map_t string_args;
1184			string_args["[AMOUNT]"] = llformat("%d ", mParcelActualArea);
1185			message += LLTrans::getString("sentences_separator") + getString("parcel_meters", string_args);
1186		}
1187		else
1188		{
1189
1190			if (mParcelBillableArea > mParcelActualArea)
1191			{	
1192				LLStringUtil::format_map_t string_args;
1193				string_args["[AMOUNT]"] = llformat("%d ", mParcelBillableArea);
1194				message += LLTrans::getString("sentences_separator") + getString("premium_land", string_args);
1195			}
1196			else
1197			{
1198				LLStringUtil::format_map_t string_args;
1199				string_args["[AMOUNT]"] = llformat("%d ", mParcelBillableArea);
1200				message += LLTrans::getString("sentences_separator") + getString("discounted_land", string_args);
1201			}
1202		}
1203
1204		getChild<LLUICtrl>("land_use_reason")->setValue(message);
1205
1206		getChildView("step_2")->setVisible(TRUE);
1207		getChildView("land_use_action")->setVisible(TRUE);
1208		getChildView("land_use_reason")->setVisible(TRUE);
1209	}
1210	else
1211	{
1212		getChildView("step_2")->setVisible(FALSE);
1213		getChildView("land_use_action")->setVisible(FALSE);
1214		getChildView("land_use_reason")->setVisible(FALSE);
1215	}
1216	
1217	// section three: purchase & currency
1218	S32 finalBalance = mAgentCashBalance + mCurrency.getAmount() - mParcelPrice;
1219	bool willHaveEnough = finalBalance >= 0;
1220	bool haveEnough = mAgentCashBalance >= mParcelPrice;
1221	S32 minContribution = llceil((F32)mParcelBillableArea / GROUP_LAND_BONUS_FACTOR);
1222	bool groupContributionEnough = mParcelGroupContribution >= minContribution;
1223	
1224	mCurrency.updateUI(!showingError  &&  !haveEnough);
1225
1226	if (!showingError)
1227	{
1228		mChildren.setBadge(std::string("step_3"),
1229			!willHaveEnough
1230				? LLViewChildren::BADGE_WARN
1231				: mCurrency.getAmount() > 0
1232					? LLViewChildren::BADGE_NOTE
1233					: LLViewChildren::BADGE_OK);
1234			
1235		LLStringUtil::format_map_t string_args;
1236		string_args["[AMOUNT]"] = llformat("%d", mParcelPrice);
1237		string_args["[SELLER]"] = mParcelSellerName;
1238		getChild<LLUICtrl>("purchase_action")->setValue(getString("pay_to_for_land", string_args));
1239		getChildView("purchase_action")->setVisible( mParcelValid);
1240		
1241		std::string reasonString;
1242
1243		if (haveEnough)
1244		{
1245			LLStringUtil::format_map_t string_args;
1246			string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance);
1247
1248			getChild<LLUICtrl>("currency_reason")->setValue(getString("have_enough_lindens", string_args));
1249		}
1250		else
1251		{
1252			LLStringUtil::format_map_t string_args;
1253			string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance);
1254			string_args["[AMOUNT2]"] = llformat("%d", mParcelPrice - mAgentCashBalance);
1255			
1256			getChild<LLUICtrl>("currency_reason")->setValue(getString("not_enough_lindens", string_args));
1257
1258			getChild<LLUICtrl>("currency_est")->setTextArg("[LOCAL_AMOUNT]", mCurrency.getLocalEstimate());
1259		}
1260		
1261		if (willHaveEnough)
1262		{
1263			LLStringUtil::format_map_t string_args;
1264			string_args["[AMOUNT]"] = llformat("%d", finalBalance);
1265
1266			getChild<LLUICtrl>("currency_balance")->setValue(getString("balance_left", string_args));
1267
1268		}
1269		else
1270		{
1271			LLStringUtil::format_map_t string_args;
1272			string_args["[AMOUNT]"] = llformat("%d", mParcelPrice - mAgentCashBalance);
1273	
1274			getChild<LLUICtrl>("currency_balance")->setValue(getString("balance_needed", string_args));
1275			
1276		}
1277
1278		getChild<LLUICtrl>("remove_contribution")->setValue(LLSD(groupContributionEnough));
1279		getChildView("remove_contribution")->setEnabled(groupContributionEnough);
1280		bool showRemoveContribution = mParcelIsGroupLand
1281							&& (mParcelGroupContribution > 0);
1282		getChildView("remove_contribution")->setLabelArg("[AMOUNT]",
1283							llformat("%d", minContribution));
1284		getChildView("remove_contribution")->setVisible( showRemoveContribution);
1285
1286		getChildView("step_3")->setVisible(TRUE);
1287		getChildView("purchase_action")->setVisible(TRUE);
1288		getChildView("currency_reason")->setVisible(TRUE);
1289		getChildView("currency_balance")->setVisible(TRUE);
1290	}
1291	else
1292	{
1293		getChildView("step_3")->setVisible(FALSE);
1294		getChildView("purchase_action")->setVisible(FALSE);
1295		getChildView("currency_reason")->setVisible(FALSE);
1296		getChildView("currency_balance")->setVisible(FALSE);
1297		getChildView("remove_group_donation")->setVisible(FALSE);
1298	}
1299
1300
1301	bool agrees_to_covenant = false;
1302	LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
1303	if (check)
1304	{
1305	    agrees_to_covenant = check->get();
1306	}
1307
1308	getChildView("buy_btn")->setEnabled(mCanBuy  &&  mSiteValid  &&  willHaveEnough  &&  !mTransaction && agrees_to_covenant);
1309}
1310
1311void LLFloaterBuyLandUI::startBuyPreConfirm()
1312{
1313	std::string action;
1314	
1315	if (mSiteMembershipUpgrade)
1316	{
1317		action += mSiteMembershipAction;
1318		action += "\n";
1319
1320		LLComboBox* levels = getChild<LLComboBox>( "account_level");
1321		if (levels)
1322		{
1323			action += " * ";
1324			action += mSiteMembershipPlanNames[levels->getCurrentIndex()];
1325			action += "\n";
1326		}
1327	}
1328	if (mSiteLandUseUpgrade)
1329	{
1330		action += mSiteLandUseAction;
1331		action += "\n";
1332	}
1333	if (mCurrency.getAmount() > 0)
1334	{
1335		LLStringUtil::format_map_t string_args;
1336		string_args["[AMOUNT]"] = llformat("%d", mCurrency.getAmount());
1337		string_args["[LOCAL_AMOUNT]"] = mCurrency.getLocalEstimate();
1338		
1339		action += getString("buy_for_US", string_args);
1340	}
1341
1342	LLStringUtil::format_map_t string_args;
1343	string_args["[AMOUNT]"] = llformat("%d", mParcelPrice);
1344	string_args["[SELLER]"] = mParcelSellerName;
1345	action += getString("pay_to_for_land", string_args);
1346		
1347	
1348	LLConfirmationManager::confirm(mSiteConfirm,
1349		action,
1350		*this,
1351		&LLFloaterBuyLandUI::startBuyPostConfirm);
1352}
1353
1354void LLFloaterBuyLandUI::startBuyPostConfirm(const std::string& password)
1355{
1356	runWebSitePrep(password);
1357	
1358	mCanBuy = false;
1359	mCannotBuyReason = getString("processing");
1360	refreshUI();
1361}
1362
1363
1364void LLFloaterBuyLandUI::onClickBuy()
1365{
1366	startBuyPreConfirm();
1367}
1368
1369void LLFloaterBuyLandUI::onClickCancel()
1370{
1371	closeFloater();
1372}
1373
1374void LLFloaterBuyLandUI::onClickErrorWeb()
1375{
1376	LLWeb::loadURLExternal(mCannotBuyURI);
1377	closeFloater();
1378}
1379
1380
1381