123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203 |
- /**
- * @file llfloaterbuyland.cpp
- * @brief LLFloaterBuyLand class implementation
- *
- * $LicenseInfo:firstyear=2005&license=viewergpl$
- *
- * Copyright (c) 2005-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llfloaterbuyland.h"
- #include "llcachename.h"
- #include "llcheckboxctrl.h"
- #include "llcombobox.h"
- #include "llconfirmationmanager.h"
- #include "lltextbox.h"
- #include "lluictrlfactory.h"
- #include "llxmlrpctransaction.h"
- #include "llagent.h"
- #include "llcurrencyuimanager.h"
- #include "llgridmanager.h"
- //MK
- #include "mkrlinterface.h"
- //mk
- #include "llstatusbar.h"
- #include "lltexturectrl.h"
- #include "llviewerregion.h"
- #include "llviewertexteditor.h"
- #include "llweb.h"
- #include "roles_constants.h"
- #if LL_WINDOWS
- // Passing 'this' during construction generates a warning. The callee only uses
- // the pointer to hold a reference to 'this' which is already valid, so this
- // call does the correct thing. Disable the warning so that we can compile
- // without generating a warning.
- #pragma warning(disable : 4355)
- #endif
- constexpr F32 GROUP_LAND_BONUS_FACTOR = 1.1f;
- //static
- LLParcelSelectionObserver* LLFloaterBuyLand::sParcelObserver = NULL;
- ///////////////////////////////////////////////////////////////////////////////
- // Observer methods
- ///////////////////////////////////////////////////////////////////////////////
- void LLFloaterBuyLand::SelectionObserver::changed()
- {
- LLFloaterBuyLand* self = LLFloaterBuyLand::findInstance();
- if (self)
- {
- if (gViewerParcelMgr.selectionEmpty())
- {
- self->close();
- }
- else
- {
- self->setParcel(gViewerParcelMgr.getSelectionRegion(),
- gViewerParcelMgr.getParcelSelection());
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Public (and static) interface methods
- ///////////////////////////////////////////////////////////////////////////////
- //static
- void LLFloaterBuyLand::buyLand(LLViewerRegion* region,
- LLParcelSelectionHandle parcel,
- bool is_for_group)
- {
- if (is_for_group && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
- {
- gNotifications.add("OnlyOfficerCanBuyLand");
- return;
- }
- LLFloaterBuyLand* self = getInstance();
- if (self)
- {
- self->setForGroup(is_for_group);
- self->setParcel(region, parcel);
- self->open();
- }
- }
- //static
- void LLFloaterBuyLand::updateCovenantText(const std::string& string,
- const LLUUID& asset_id)
- {
- LLFloaterBuyLand* self = findInstance();
- if (self)
- {
- self->setCovenantText(string, asset_id);
- }
- }
- //static
- void LLFloaterBuyLand::updateEstateName(const std::string& name)
- {
- LLFloaterBuyLand* self = findInstance();
- if (self)
- {
- self->setEstateName(name);
- }
- }
- //static
- void LLFloaterBuyLand::updateLastModified(const std::string& text)
- {
- LLFloaterBuyLand* self = findInstance();
- if (self)
- {
- self->setLastModified(text);
- }
- }
- //static
- void LLFloaterBuyLand::updateEstateOwnerName(const std::string& name)
- {
- LLFloaterBuyLand* self = findInstance();
- if (self)
- {
- self->setEstateOwnerName(name);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // LLFloaterBuyLand proper
- ///////////////////////////////////////////////////////////////////////////////
- LLFloaterBuyLand::LLFloaterBuyLand(const LLSD&)
- : mParcelSelection(NULL),
- mParcelBuyInfo(NULL),
- mTransaction(NULL),
- mCurrency(*this),
- mBought(false),
- mParcelValid(false),
- mSiteValid(false)
- {
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_land.xml",
- NULL, false);
- }
- //virtual
- LLFloaterBuyLand::~LLFloaterBuyLand()
- {
- if (sParcelObserver)
- {
- gViewerParcelMgr.removeSelectionObserver(sParcelObserver);
- delete sParcelObserver;
- sParcelObserver = NULL;
- }
- if (mTransaction)
- {
- delete mTransaction;
- mTransaction = NULL;
- }
- if (mParcelBuyInfo)
- {
- gViewerParcelMgr.deleteParcelBuy(mParcelBuyInfo);
- mParcelBuyInfo = NULL;
- }
- // Release the selection handle
- mParcelSelection = NULL;
- }
- //virtual
- bool LLFloaterBuyLand::postBuild()
- {
- mCurrency.prepare();
- childSetAction("buy_btn", onClickBuy, this);
- childSetAction("cancel_btn", onClickCancel, this);
- childSetAction("error_web", onClickErrorWeb, this);
- if (!sParcelObserver)
- {
- sParcelObserver = new SelectionObserver;
- gViewerParcelMgr.addSelectionObserver(sParcelObserver);
- }
- center();
- return true;
- }
- void LLFloaterBuyLand::updateAgentInfo()
- {
- mAgentCommittedTier = gStatusBarp->getSquareMetersCommitted();
- mAgentCashBalance = gStatusBarp->getBalance();
- // *TODO: This is an approximation, we should send this value down to the
- // viewer. See SL-10728 for details.
- mAgentHasNeverOwnedLand = mAgentCommittedTier == 0;
- }
- void LLFloaterBuyLand::updateParcelInfo()
- {
- LLParcel* parcel = mParcelSelection->getParcel();
- if (!parcel) return; // Paranoia
- mParcelValid = parcel && mRegion;
- mParcelIsForSale = false;
- mParcelIsGroupLand = false;
- mParcelGroupContribution = 0;
- mParcelPrice = 0;
- mParcelActualArea = 0;
- mParcelBillableArea = 0;
- mParcelSupportedObjects = 0;
- mParcelSoldWithObjects = false;
- mParcelLocation.clear();
- mParcelSnapshot.setNull();
- mParcelSellerName.clear();
- mCanBuy = false;
- mCannotBuyIsError = false;
- if (!mParcelValid)
- {
- mCannotBuyReason = getString("no_land_selected");
- return;
- }
- if (mParcelSelection->getMultipleOwners())
- {
- mCannotBuyReason = getString("multiple_parcels_selected");
- return;
- }
- const LLUUID& parcel_owner = parcel->getOwnerID();
- mIsClaim = parcel->isPublic();
- if (!mIsClaim)
- {
- mParcelActualArea = parcel->getArea();
- mParcelIsForSale = parcel->getForSale();
- mParcelIsGroupLand = parcel->getIsGroupOwned();
- mParcelPrice = mParcelIsForSale ? parcel->getSalePrice() : 0;
- if (mParcelIsGroupLand)
- {
- LLUUID group_id = parcel->getGroupID();
- mParcelGroupContribution = gAgent.getGroupContribution(group_id);
- }
- }
- else
- {
- mParcelActualArea = mParcelSelection->getClaimableArea();
- mParcelIsForSale = true;
- mParcelPrice = mParcelActualArea * parcel->getClaimPricePerMeter();
- }
- mParcelBillableArea = ll_round(mRegion->getBillableFactor() *
- mParcelActualArea);
- mParcelSupportedObjects = ll_round(parcel->getMaxPrimCapacity() *
- parcel->getParcelPrimBonus());
- // Cannot have more than region max tasks, regardless of parcel object
- // bonus factor.
- LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
- if (region)
- {
- S32 max_tasks_per_region = (S32)region->getMaxTasks();
- mParcelSupportedObjects = llmin(mParcelSupportedObjects,
- max_tasks_per_region);
- }
- mParcelSoldWithObjects = parcel->getSellWithObjects();
- LLVector3 center = parcel->getCenterpoint();
- mParcelLocation = llformat("%s %d,%d", mRegion->getName().c_str(),
- (S32)center[VX], (S32)center[VY]);
- mParcelSnapshot = parcel->getSnapshotID();
- updateNames();
- bool got_the_cash = mParcelPrice <= mAgentCashBalance;
- S32 missing_cash = got_the_cash ? 0 : mParcelPrice - mAgentCashBalance;
- mCurrency.setAmount(missing_cash, true);
- mCurrency.setZeroMessage(got_the_cash ? getString("none_needed")
- : LLStringUtil::null);
- // Check that we can buy the land
- if (mIsForGroup && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
- {
- mCannotBuyReason = getString("cant_buy_for_group");
- return;
- }
- if (!mIsClaim)
- {
- const LLUUID& authorized_buyer = parcel->getAuthorizedBuyerID();
- const LLUUID buyer = gAgentID;
- const LLUUID new_owner = mIsForGroup ? gAgent.getGroupID() : buyer;
- if (!mParcelIsForSale ||
- (mParcelPrice == 0 && authorized_buyer.isNull()))
- {
- mCannotBuyReason = getString("parcel_not_for_sale");
- return;
- }
- if (parcel_owner == new_owner)
- {
- if (mIsForGroup)
- {
- mCannotBuyReason = getString("group_already_owns");
- }
- else
- {
- mCannotBuyReason = getString("you_already_own");
- }
- return;
- }
- if (authorized_buyer.notNull() && buyer != authorized_buyer)
- {
- mCannotBuyReason = getString("set_to_sell_to_other");
- return;
- }
- }
- else
- {
- if (mParcelActualArea == 0)
- {
- mCannotBuyReason = getString("no_public_land");
- return;
- }
- if (mParcelSelection->hasOthersSelected())
- {
- // Policy: Must not have someone else's land selected
- mCannotBuyReason = getString("not_owned_by_you");
- return;
- }
- }
- mCanBuy = true;
- }
- void LLFloaterBuyLand::updateCovenantInfo()
- {
- LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
- if (!region) return;
- LLTextBox* region_name = getChild<LLTextBox>("region_name_text");
- region_name->setText(region->getName());
- LLTextBox* region_type = getChild<LLTextBox>("region_type_text");
- region_type->setText(region->getSimProductName());
- LLTextBox* resellable_txt = getChild<LLTextBox>("resellable_clause");
- if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
- {
- resellable_txt->setText(getString("can_not_resell"));
- }
- else
- {
- resellable_txt->setText(getString("can_resell"));
- }
- LLTextBox* changeable_txt = getChild<LLTextBox>("changeable_clause");
- if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
- {
- changeable_txt->setText(getString("can_change"));
- }
- else
- {
- changeable_txt->setText(getString("can_not_change"));
- }
- LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
- check->set(false);
- check->setEnabled(true);
- check->setCommitCallback(onChangeAgreeCovenant);
- check->setCallbackUserData(this);
- childHide("covenant_text");
- // Send EstateCovenantInfo message
- region->sendEstateCovenantRequest();
- }
- void LLFloaterBuyLand::setCovenantText(const std::string& string,
- const LLUUID& asset_id)
- {
- LLViewerTextEditor* editor =
- getChild<LLViewerTextEditor>("covenant_editor");
- editor->setHandleEditKeysDirectly(false);
- editor->setText(string);
- LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
- if (asset_id.isNull())
- {
- check->set(true);
- check->setEnabled(false);
- refreshUI();
- // Remove the line stating that you must agree
- childHide("covenant_text");
- }
- else
- {
- check->setEnabled(true);
- // Show the line stating that you must agree
- childShow("covenant_text");
- }
- }
- void LLFloaterBuyLand::setEstateName(const std::string& name)
- {
- LLTextBox* box = getChild<LLTextBox>("estate_name_text");
- if (box) box->setText(name);
- }
- void LLFloaterBuyLand::setLastModified(const std::string& text)
- {
- LLTextBox* editor = getChild<LLTextBox>("covenant_timestamp_text");
- editor->setText(text);
- }
- void LLFloaterBuyLand::setEstateOwnerName(const std::string& name)
- {
- LLTextBox* box = getChild<LLTextBox>("estate_owner_text");
- box->setText(name);
- }
- void LLFloaterBuyLand::updateWebSiteInfo()
- {
- S32 askBillableArea = mIsForGroup ? 0 : mParcelBillableArea;
- S32 askCurrencyBuy = mCurrency.getAmount();
- if (mTransaction && mTransactionType == TransactionPreflight &&
- mPreflightAskBillableArea == askBillableArea &&
- mPreflightAskCurrencyBuy == askCurrencyBuy)
- {
- return;
- }
- mPreflightAskBillableArea = askBillableArea;
- mPreflightAskCurrencyBuy = askCurrencyBuy;
- #if 0 // enable this code if you want the details to blank while we're talking
- // to the web site... it's kind of jarring.
- mSiteValid = false;
- mSiteMembershipUpgrade = false;
- mSiteMembershipAction = "(waiting)";
- mSiteMembershipPlanIDs.clear();
- mSiteMembershipPlanNames.clear();
- mSiteLandUseUpgrade = false;
- mSiteLandUseAction = "(waiting)";
- mSiteCurrencyEstimated = false;
- mSiteCurrencyEstimatedCost = 0;
- #endif
- LLSD params = LLSD::emptyMap();
- params["agentId"] = gAgentID.asString();
- params["secureSessionId"] = gAgent.getSecureSessionID().asString();
- params["language"] = LLUI::getLanguage();
- params["billableArea"] = mPreflightAskBillableArea;
- params["currencyBuy"] = mPreflightAskCurrencyBuy;
- startTransaction(TransactionPreflight, params);
- }
- void LLFloaterBuyLand::finishWebSiteInfo()
- {
- const LLSD& result = mTransaction->response();
- mSiteValid = result["success"].asBoolean();
- if (!mSiteValid)
- {
- tellUserError(result["errorMessage"].asString(),
- result["errorURI"].asString());
- return;
- }
- const LLSD& membership = result["membership"];
- mSiteMembershipUpgrade = membership["upgrade"].asBoolean();
- mSiteMembershipAction = membership["action"].asString();
- mSiteMembershipPlanIDs.clear();
- mSiteMembershipPlanNames.clear();
- const LLSD& levels = membership["levels"];
- for (auto it = levels.beginArray(); it != levels.endArray(); ++it)
- {
- const LLSD& level = *it;
- mSiteMembershipPlanIDs.emplace_back(level["id"].asString());
- mSiteMembershipPlanNames.emplace_back(level["description"].asString());
- }
- mUserPlanChoice = 0;
- const LLSD& landUse = result["landUse"];
- mSiteLandUseUpgrade = landUse["upgrade"].asBoolean();
- mSiteLandUseAction = landUse["action"].asString();
- const LLSD& currency = result["currency"];
- if (currency.has("estimatedCost"))
- {
- mCurrency.setUSDEstimate(currency["estimatedCost"].asInteger());
- }
- if (currency.has("estimatedLocalCost"))
- {
- mCurrency.setLocalEstimate(currency["estimatedLocalCost"].asString());
- }
- mSiteConfirm = result["confirm"].asString();
- }
- void LLFloaterBuyLand::runWebSitePrep(const std::string& password)
- {
- if (!mCanBuy)
- {
- return;
- }
- bool remove_contrib = childGetValue("remove_contribution").asBoolean();
- mParcelBuyInfo = gViewerParcelMgr.setupParcelBuy(gAgentID, gAgentSessionID,
- gAgent.getGroupID(),
- mIsForGroup, mIsClaim,
- remove_contrib);
- if (mParcelBuyInfo && !mSiteMembershipUpgrade && !mSiteLandUseUpgrade &&
- mCurrency.getAmount() == 0 && mSiteConfirm != "password")
- {
- sendBuyLand();
- return;
- }
- std::string new_level = "noChange";
- if (mSiteMembershipUpgrade)
- {
- LLComboBox* levels = getChild<LLComboBox>( "account_level");
- if (levels)
- {
- mUserPlanChoice = levels->getCurrentIndex();
- new_level = mSiteMembershipPlanIDs[mUserPlanChoice];
- }
- }
- LLSD params = LLSD::emptyMap();
- params["agentId"] = gAgentID.asString();
- params["secureSessionId"] = gAgent.getSecureSessionID().asString();
- params["language"] = LLUI::getLanguage();
- params["levelId"] = new_level;
- params["billableArea"] = mIsForGroup ? 0 : mParcelBillableArea;
- params["currencyBuy"] = mCurrency.getAmount();
- params["estimatedCost"] = mCurrency.getUSDEstimate();
- params["estimatedLocalCost"] = mCurrency.getLocalEstimate();
- params["confirm"] = mSiteConfirm;
- if (!password.empty())
- {
- params["password"] = password;
- }
- startTransaction(TransactionBuy, params);
- }
- void LLFloaterBuyLand::finishWebSitePrep()
- {
- const LLSD& result = mTransaction->response();
- bool success = result["success"].asBoolean();
- if (!success)
- {
- tellUserError(result["errorMessage"].asString(),
- result["errorURI"].asString());
- return;
- }
- sendBuyLand();
- }
- void LLFloaterBuyLand::sendBuyLand()
- {
- if (mParcelBuyInfo)
- {
- gViewerParcelMgr.sendParcelBuy(mParcelBuyInfo);
- gViewerParcelMgr.deleteParcelBuy(mParcelBuyInfo);
- mBought = true;
- }
- }
- //static
- void LLFloaterBuyLand::callbackCacheName(const LLUUID&, const std::string&,
- bool)
- {
- LLFloaterBuyLand* self = findInstance();
- if (self)
- {
- self->updateNames();
- }
- }
- void LLFloaterBuyLand::updateNames()
- {
- LLParcel* parcelp = mParcelSelection->getParcel();
- if (!parcelp)
- {
- mParcelSellerName.clear();
- return;
- }
- if (mIsClaim)
- {
- mParcelSellerName = "Linden Lab";
- }
- else if (parcelp->getIsGroupOwned())
- {
- const LLUUID& group_id = parcelp->getGroupID();
- if (gCacheNamep &&
- !gCacheNamep->getGroupName(group_id, mParcelSellerName))
- {
- gCacheNamep->get(group_id, true, callbackCacheName);
- }
- }
- else
- {
- const LLUUID& owner_id = parcelp->getOwnerID();
- if (gCacheNamep &&
- !gCacheNamep->getFullName(owner_id, mParcelSellerName))
- {
- gCacheNamep->get(owner_id, false, callbackCacheName);
- }
- }
- //MK
- if (gRLenabled &&
- (gRLInterface.mContainsShownames ||
- gRLInterface.mContainsShownametags))
- {
- mParcelSellerName = gRLInterface.getDummyName(mParcelSellerName);
- }
- //mk
- }
- void LLFloaterBuyLand::startTransaction(TransactionType type,
- const LLSD& params)
- {
- if (mTransaction)
- {
- delete mTransaction;
- mTransaction = NULL;
- }
- mTransactionType = type;
- // Select a URI and method appropriate for the transaction type.
- static std::string transaction_uri;
- if (transaction_uri.empty())
- {
- transaction_uri = LLGridManager::getInstance()->getHelperURI() +
- "landtool.php";
- }
- const char* method;
- switch (mTransactionType)
- {
- case TransactionPreflight:
- method = "preflightBuyLandPrep";
- break;
- case TransactionBuy:
- method = "buyLandPrep";
- break;
- default:
- llwarns << "Unknown transaction type !" << llendl;
- return;
- }
- mTransaction = new LLXMLRPCTransaction(transaction_uri, method, params);
- }
- bool LLFloaterBuyLand::checkTransaction()
- {
- if (!mTransaction)
- {
- return false;
- }
- if (!mTransaction->process())
- {
- return false;
- }
- if (mTransaction->status(NULL) != LLXMLRPCTransaction::StatusComplete)
- {
- tellUserError(mTransaction->statusMessage(),
- mTransaction->statusURI());
- }
- else
- {
- switch (mTransactionType)
- {
- case TransactionPreflight:
- finishWebSiteInfo();
- break;
- case TransactionBuy:
- finishWebSitePrep();
- break;
- default:
- break;
- }
- }
- delete mTransaction;
- mTransaction = NULL;
- return true;
- }
- void LLFloaterBuyLand::tellUserError(const std::string& message,
- const std::string& uri)
- {
- mCanBuy = false;
- mCannotBuyIsError = true;
- mCannotBuyReason = getString("fetching_error");
- mCannotBuyReason += message;
- mCannotBuyURI = uri;
- }
- void LLFloaterBuyLand::setParcel(LLViewerRegion* region,
- LLParcelSelectionHandle parcel)
- {
- if (mTransaction && mTransactionType == TransactionBuy)
- {
- // The user is buying, do not change the selection
- return;
- }
- mRegion = region;
- mParcelSelection = parcel;
- updateAgentInfo();
- updateParcelInfo();
- updateCovenantInfo();
- if (mCanBuy)
- {
- updateWebSiteInfo();
- }
- refreshUI();
- }
- void LLFloaterBuyLand::setForGroup(bool forGroup)
- {
- mIsForGroup = forGroup;
- }
- //virtual
- void LLFloaterBuyLand::draw()
- {
- bool dirty = checkTransaction();
- dirty |= mCurrency.process();
- if (mBought)
- {
- close();
- }
- else if (dirty)
- {
- if (mCanBuy && mCurrency.hasError())
- {
- tellUserError(mCurrency.errorMessage(), mCurrency.errorURI());
- }
- refreshUI();
- }
- LLFloater::draw();
- }
- //virtual
- bool LLFloaterBuyLand::canClose()
- {
- bool can_close = !mTransaction &&
- (mCurrency.canCancel() ||
- mTransactionType != TransactionBuy);
- if (!can_close)
- {
- // Explain to the user why they cannot do this, see DEV-9605
- gNotifications.add("CannotCloseFloaterBuyLand");
- }
- return can_close;
- }
- //virtual
- void LLFloaterBuyLand::setMinimized(bool minimize)
- {
- bool restored = isMinimized() && !minimize;
- LLFloater::setMinimized(minimize);
- if (restored)
- {
- refreshUI();
- }
- }
- void LLFloaterBuyLand::refreshUI()
- {
- std::string message;
- // Section zero: title area
- {
- LLTextureCtrl* snapshot = getChild<LLTextureCtrl>("info_image");
- if (mParcelValid)
- {
- snapshot->setImageAssetID(mParcelSnapshot);
- childSetText("info_parcel", mParcelLocation);
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d", mParcelActualArea);
- string_args["[AMOUNT2]"] = llformat("%d", mParcelSupportedObjects);
- childSetText("info_size",
- getString("meters_supports_object", string_args));
- F32 cost_per_sqm = 0.0f;
- if (mParcelActualArea > 0)
- {
- cost_per_sqm = (F32)mParcelPrice / (F32)mParcelActualArea;
- }
- LLStringUtil::format_map_t info_price_args;
- info_price_args["[PRICE]"] = llformat("%d", mParcelPrice);
- info_price_args["[PRICE_PER_SQM]"] = llformat("%.1f", cost_per_sqm);
- if (mParcelSoldWithObjects)
- {
- info_price_args["[SOLD_WITH_OBJECTS]"] =
- getString("sold_with_objects");
- }
- else
- {
- info_price_args["[SOLD_WITH_OBJECTS]"] =
- getString("sold_without_objects");
- }
- childSetText("info_price",
- getString("info_price_string", info_price_args));
- childSetVisible("info_price", mParcelIsForSale);
- }
- else
- {
- snapshot->setImageAssetID(LLUUID::null);
- childSetText("info_parcel", getString("no_parcel_selected"));
- childSetText("info_size", LLStringUtil::null);
- childSetText("info_price", LLStringUtil::null);
- }
- if (mCanBuy)
- {
- // "Buying land for group:" or "Buying this land will:"
- message = mIsForGroup ? getString("buying_for_group")
- : getString("buying_will");
- }
- else
- {
- // "Cannot buy now:" or "Not for sale:"
- message = mCannotBuyIsError ? getString("cannot_buy_now")
- : getString("not_for_sale");
- }
- childSetText("info_action", message);
- }
- bool showing_error = !mCanBuy || !mSiteValid;
- // Error section
- if (showing_error)
- {
- childSetBadge("step_error",
- mCannotBuyIsError ? BADGE_ERROR : BADGE_WARN);
- LLTextBox* msgbox = getChild<LLTextBox>("error_message");
- if (msgbox)
- {
- msgbox->setVisible(true);
- msgbox->setWrappedText(!mCanBuy ? mCannotBuyReason
- : "(waiting for data)");
- }
- childSetVisible("error_web",
- mCannotBuyIsError && !mCannotBuyURI.empty());
- }
- else
- {
- childHide("step_error");
- childHide("error_message");
- childHide("error_web");
- }
- // Section one: account
- if (!showing_error)
- {
- childSetBadge("step_1",
- mSiteMembershipUpgrade ? BADGE_NOTE : BADGE_OK);
- childSetText("account_action", mSiteMembershipAction);
- childSetText("account_reason",
- mSiteMembershipUpgrade ? getString("must_upgrade")
- : getString("cant_own_land"));
- LLComboBox* levels = getChild<LLComboBox>( "account_level");
- if (levels)
- {
- levels->setVisible(mSiteMembershipUpgrade);
- levels->removeall();
- for (std::vector<std::string>::const_iterator
- i = mSiteMembershipPlanNames.begin(),
- end = mSiteMembershipPlanNames.end();
- i != end; ++i)
- {
- levels->add(*i);
- }
- levels->setCurrentByIndex(mUserPlanChoice);
- }
- childShow("step_1");
- childShow("account_action");
- childShow("account_reason");
- }
- else
- {
- childHide("step_1");
- childHide("account_action");
- childHide("account_reason");
- childHide("account_level");
- }
- // Section two: land use fees
- if (!showing_error)
- {
- childSetBadge("step_2", mSiteLandUseUpgrade ? BADGE_NOTE : BADGE_OK);
- childSetText("land_use_action", mSiteLandUseAction);
- if (mIsForGroup)
- {
- LLStringUtil::format_map_t string_args;
- string_args["[GROUP]"] = std::string(gAgent.mGroupName);
- message = getString("insufficient_land_credits", string_args);
- }
- else
- {
- LLStringUtil::format_map_t string_args;
- string_args["[BUYER]"] = llformat("%d", mAgentCommittedTier);
- message = getString("land_holdings", string_args);
- }
- if (!mParcelValid)
- {
- message += "(no parcel selected)";
- }
- else if (mParcelBillableArea == mParcelActualArea)
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d ", mParcelActualArea);
- message += getString("parcel_meters", string_args);
- }
- else if (mParcelBillableArea > mParcelActualArea)
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d ", mParcelBillableArea);
- message += getString("premium_land", string_args);
- }
- else
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d ", mParcelBillableArea);
- message += getString("discounted_land", string_args);
- }
- childSetWrappedText("land_use_reason", message);
- childShow("step_2");
- childShow("land_use_action");
- childShow("land_use_reason");
- }
- else
- {
- childHide("step_2");
- childHide("land_use_action");
- childHide("land_use_reason");
- }
- // Section three: purchase & currency
- S32 final_balance = mAgentCashBalance + mCurrency.getAmount() - mParcelPrice;
- bool enough_money = final_balance >= 0;
- bool can_pay = mAgentCashBalance >= mParcelPrice;
- S32 min_contrib = llceil((F32)mParcelBillableArea / GROUP_LAND_BONUS_FACTOR);
- bool groupContributionEnough = mParcelGroupContribution >= min_contrib;
- mCurrency.updateUI(!showing_error && !can_pay);
- if (!showing_error)
- {
- childSetBadge("step_3",
- !enough_money ? BADGE_WARN
- : mCurrency.getAmount() > 0 ? BADGE_NOTE
- : BADGE_OK);
- childSetText("purchase_action",
- llformat("Pay L$ %d to %s for this land", mParcelPrice,
- mParcelSellerName.c_str()));
- childSetVisible("purchase_action", mParcelValid);
- std::string reasonString;
- if (can_pay)
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance);
- childSetText("currency_reason",
- getString("have_enough_lindens", string_args));
- }
- else
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance);
- string_args["[AMOUNT2]"] =
- llformat("%d", mParcelPrice - mAgentCashBalance);
- childSetText("currency_reason",
- getString("not_enough_lindens", string_args));
- childSetTextArg("currency_est", "[LOCAL_AMOUNT]",
- mCurrency.getLocalEstimate());
- }
- if (enough_money)
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d", final_balance);
- childSetText("currency_balance",
- getString("balance_left", string_args));
- }
- else
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] =
- llformat("%d", mParcelPrice - mAgentCashBalance);
- childSetText("currency_balance",
- getString("balance_needed", string_args));
- }
- childSetValue("remove_contribution", LLSD(groupContributionEnough));
- childSetEnabled("remove_contribution", groupContributionEnough);
- childSetLabelArg("remove_contribution", "[AMOUNT]",
- llformat("%d", min_contrib));
- childSetVisible("remove_contribution",
- mParcelIsGroupLand && mParcelGroupContribution > 0);
- childShow("step_3");
- childShow("purchase_action");
- childShow("currency_reason");
- childShow("currency_balance");
- }
- else
- {
- childHide("step_3");
- childHide("purchase_action");
- childHide("currency_reason");
- childHide("currency_balance");
- childHide("remove_contribution");
- }
- bool agrees_to_covenant = false;
- LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
- if (check)
- {
- agrees_to_covenant = check->get();
- }
- childSetEnabled("buy_btn",
- mCanBuy && mSiteValid && enough_money && !mTransaction &&
- agrees_to_covenant);
- }
- void LLFloaterBuyLand::startBuyPreConfirm()
- {
- std::string action;
- if (mSiteMembershipUpgrade)
- {
- action += mSiteMembershipAction;
- action += "\n";
- LLComboBox* levels = getChild<LLComboBox>( "account_level");
- if (levels)
- {
- action += " * ";
- action += mSiteMembershipPlanNames[levels->getCurrentIndex()];
- action += "\n";
- }
- }
- if (mSiteLandUseUpgrade)
- {
- action += mSiteLandUseAction;
- action += "\n";
- }
- if (mCurrency.getAmount() > 0)
- {
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d", mCurrency.getAmount());
- string_args["[LOCAL_AMOUNT]"] = mCurrency.getLocalEstimate();
- action += getString("buy_for_US", string_args);
- }
- LLStringUtil::format_map_t string_args;
- string_args["[AMOUNT]"] = llformat("%d", mParcelPrice);
- string_args["[SELLER]"] = mParcelSellerName;
- action += getString("pay_to_for_land", string_args);
- LLConfirmationManager::confirm(mSiteConfirm, action, *this,
- &LLFloaterBuyLand::startBuyPostConfirm);
- }
- void LLFloaterBuyLand::startBuyPostConfirm(const std::string& password)
- {
- runWebSitePrep(password);
- mCanBuy = false;
- mCannotBuyReason = getString("processing");
- refreshUI();
- }
- //static
- void LLFloaterBuyLand::onChangeAgreeCovenant(LLUICtrl*, void* data)
- {
- LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
- if (self)
- {
- self->refreshUI();
- }
- }
- //static
- void LLFloaterBuyLand::onClickBuy(void* data)
- {
- LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
- if (self)
- {
- self->startBuyPreConfirm();
- }
- }
- //static
- void LLFloaterBuyLand::onClickCancel(void* data)
- {
- LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
- if (self)
- {
- self->close();
- }
- }
- //static
- void LLFloaterBuyLand::onClickErrorWeb(void* data)
- {
- LLFloaterBuyLand* self = (LLFloaterBuyLand*)data;
- if (self)
- {
- LLWeb::loadURLExternal(self->mCannotBuyURI);
- self->close();
- }
- }
|