Does not compile now. llviewerregion.cpp wasn't touched. Other changes elsewhere in the code (like in llstartup.cpp) might still be needed.
1399 lines
34 KiB
C++
1399 lines
34 KiB
C++
/**
|
|
* @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"
|
|
|
|
// viewer includes
|
|
#include "llagent.h"
|
|
#include "llbutton.h"
|
|
#include "llcachename.h"
|
|
#include "llcheckboxctrl.h"
|
|
#include "llcombobox.h"
|
|
#include "llconfirmationmanager.h"
|
|
#include "llcurrencyuimanager.h"
|
|
#include "llfloater.h"
|
|
#include "llfloatertools.h"
|
|
#include "llframetimer.h"
|
|
#include "lliconctrl.h"
|
|
#include "lllineeditor.h"
|
|
#include "llnotificationsutil.h"
|
|
#include "llparcel.h"
|
|
#include "llstatusbar.h"
|
|
#include "lltextbox.h"
|
|
#include "lltexturectrl.h"
|
|
#include "llviewchildren.h"
|
|
#include "llviewercontrol.h"
|
|
#include "lluictrlfactory.h"
|
|
#include "llviewerparcelmgr.h"
|
|
#include "llviewerregion.h"
|
|
#include "llviewertexteditor.h"
|
|
#include "llviewerwindow.h"
|
|
#include "llweb.h"
|
|
#include "llwindow.h"
|
|
#include "llworld.h"
|
|
#include "llxmlrpctransaction.h"
|
|
#include "llviewernetwork.h"
|
|
#include "roles_constants.h"
|
|
|
|
#include "hippogridmanager.h"
|
|
|
|
// NOTE: This is duplicated in lldatamoney.cpp ...
|
|
const F32 GROUP_LAND_BONUS_FACTOR = 1.1f;
|
|
const F64 CURRENCY_ESTIMATE_FREQUENCY = 0.5;
|
|
// how long of a pause in typing a currency buy amount before an
|
|
// esimate is fetched from the server
|
|
|
|
class LLFloaterBuyLandUI
|
|
: public LLFloater
|
|
{
|
|
private:
|
|
LLFloaterBuyLandUI();
|
|
virtual ~LLFloaterBuyLandUI();
|
|
|
|
LLViewerRegion* mRegion;
|
|
LLParcelSelectionHandle mParcel;
|
|
bool mIsClaim;
|
|
bool mIsForGroup;
|
|
|
|
bool mCanBuy;
|
|
bool mCannotBuyIsError;
|
|
std::string mCannotBuyReason;
|
|
std::string mCannotBuyURI;
|
|
|
|
bool mBought;
|
|
|
|
// information about the agent
|
|
S32 mAgentCommittedTier;
|
|
S32 mAgentCashBalance;
|
|
bool mAgentHasNeverOwnedLand;
|
|
|
|
// information about the parcel
|
|
bool mParcelValid;
|
|
bool mParcelIsForSale;
|
|
bool mParcelIsGroupLand;
|
|
S32 mParcelGroupContribution;
|
|
S32 mParcelPrice;
|
|
S32 mParcelActualArea;
|
|
S32 mParcelBillableArea;
|
|
S32 mParcelSupportedObjects;
|
|
bool mParcelSoldWithObjects;
|
|
std::string mParcelLocation;
|
|
LLUUID mParcelSnapshot;
|
|
std::string mParcelSellerName;
|
|
|
|
// user's choices
|
|
S32 mUserPlanChoice;
|
|
|
|
// from website
|
|
bool mSiteValid;
|
|
bool mSiteMembershipUpgrade;
|
|
std::string mSiteMembershipAction;
|
|
std::vector<std::string>
|
|
mSiteMembershipPlanIDs;
|
|
std::vector<std::string>
|
|
mSiteMembershipPlanNames;
|
|
bool mSiteLandUseUpgrade;
|
|
std::string mSiteLandUseAction;
|
|
std::string mSiteConfirm;
|
|
|
|
// values in current Preflight transaction... used to avoid extra
|
|
// preflights when the parcel manager goes update crazy
|
|
S32 mPreflightAskBillableArea;
|
|
S32 mPreflightAskCurrencyBuy;
|
|
|
|
LLViewChildren mChildren;
|
|
LLCurrencyUIManager mCurrency;
|
|
|
|
enum TransactionType
|
|
{
|
|
TransactionPreflight,
|
|
TransactionCurrency,
|
|
TransactionBuy
|
|
};
|
|
LLXMLRPCTransaction* mTransaction;
|
|
TransactionType mTransactionType;
|
|
|
|
LLViewerParcelMgr::ParcelBuyInfo* mParcelBuyInfo;
|
|
|
|
static LLFloaterBuyLandUI* sInstance;
|
|
|
|
public:
|
|
static LLFloaterBuyLandUI* soleInstance(bool createIfNeeded);
|
|
|
|
void setForGroup(bool is_for_group);
|
|
void setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel);
|
|
|
|
void updateAgentInfo();
|
|
void updateParcelInfo();
|
|
void updateCovenantInfo();
|
|
static void onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data);
|
|
void updateCovenantText(const std::string& string, const LLUUID &asset_id);
|
|
void updateEstateName(const std::string& name);
|
|
void updateLastModified(const std::string& text);
|
|
void updateEstateOwnerName(const std::string& name);
|
|
void updateWebSiteInfo();
|
|
void finishWebSiteInfo();
|
|
|
|
void runWebSitePrep(const std::string& password);
|
|
void finishWebSitePrep();
|
|
void sendBuyLand();
|
|
|
|
void updateNames();
|
|
|
|
void refreshUI();
|
|
|
|
void startTransaction(TransactionType type, LLXMLRPCValue params);
|
|
bool checkTransaction();
|
|
|
|
void tellUserError(const std::string& message, const std::string& uri);
|
|
|
|
virtual BOOL postBuild();
|
|
|
|
void startBuyPreConfirm();
|
|
void startBuyPostConfirm(const std::string& password);
|
|
|
|
static void onClickBuy(void* data);
|
|
static void onClickCancel(void* data);
|
|
static void onClickErrorWeb(void* data);
|
|
|
|
virtual void draw();
|
|
virtual BOOL canClose();
|
|
virtual void onClose(bool app_quitting);
|
|
/*virtual*/ void setMinimized(BOOL b);
|
|
|
|
private:
|
|
class SelectionObserver : public LLParcelObserver
|
|
{
|
|
public:
|
|
virtual void changed();
|
|
};
|
|
};
|
|
|
|
static void cacheNameUpdateRefreshesBuyLand(const LLUUID& id, const std::string& full_name, bool is_group)
|
|
{
|
|
LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(false);
|
|
if (ui)
|
|
{
|
|
ui->updateNames();
|
|
}
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLand::buyLand(
|
|
LLViewerRegion* region, LLParcelSelectionHandle parcel, bool is_for_group)
|
|
{
|
|
if(is_for_group && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
|
|
{
|
|
LLNotificationsUtil::add("OnlyOfficerCanBuyLand");
|
|
return;
|
|
}
|
|
|
|
LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(true);
|
|
ui->setForGroup(is_for_group);
|
|
ui->setParcel(region, parcel);
|
|
ui->open(); /*Flawfinder: ignore*/
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLand::updateCovenantText(const std::string& string, const LLUUID &asset_id)
|
|
{
|
|
LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
|
|
if (floater)
|
|
{
|
|
floater->updateCovenantText(string, asset_id);
|
|
}
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLand::updateEstateName(const std::string& name)
|
|
{
|
|
LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
|
|
if (floater)
|
|
{
|
|
floater->updateEstateName(name);
|
|
}
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLand::updateLastModified(const std::string& text)
|
|
{
|
|
LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
|
|
if (floater)
|
|
{
|
|
floater->updateLastModified(text);
|
|
}
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLand::updateEstateOwnerName(const std::string& name)
|
|
{
|
|
LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
|
|
if (floater)
|
|
{
|
|
floater->updateEstateOwnerName(name);
|
|
}
|
|
}
|
|
|
|
// static
|
|
BOOL LLFloaterBuyLand::isOpen()
|
|
{
|
|
LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
|
|
if (floater)
|
|
{
|
|
return floater->getVisible();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// static
|
|
LLFloaterBuyLandUI* LLFloaterBuyLandUI::sInstance = NULL;
|
|
|
|
// static
|
|
LLFloaterBuyLandUI* LLFloaterBuyLandUI::soleInstance(bool createIfNeeded)
|
|
{
|
|
#if !LL_RELEASE_FOR_DOWNLOAD
|
|
if (createIfNeeded)
|
|
{
|
|
delete sInstance;
|
|
sInstance = NULL;
|
|
}
|
|
#endif
|
|
if (!sInstance && createIfNeeded)
|
|
{
|
|
sInstance = new LLFloaterBuyLandUI();
|
|
|
|
LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_land.xml");
|
|
sInstance->center();
|
|
|
|
static bool observingCacheName = false;
|
|
if (!observingCacheName)
|
|
{
|
|
gCacheName->addObserver(cacheNameUpdateRefreshesBuyLand);
|
|
observingCacheName = true;
|
|
}
|
|
|
|
static SelectionObserver* parcelSelectionObserver = NULL;
|
|
if (!parcelSelectionObserver)
|
|
{
|
|
parcelSelectionObserver = new SelectionObserver;
|
|
LLViewerParcelMgr::getInstance()->addObserver(parcelSelectionObserver);
|
|
}
|
|
}
|
|
|
|
return sInstance;
|
|
}
|
|
|
|
|
|
#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
|
|
LLFloaterBuyLandUI::LLFloaterBuyLandUI()
|
|
: LLFloater(std::string("Buy Land")),
|
|
mParcel(0),
|
|
mBought(false),
|
|
mParcelValid(false), mSiteValid(false),
|
|
mChildren(*this), mCurrency(*this), mTransaction(0),
|
|
mParcelBuyInfo(0)
|
|
{
|
|
}
|
|
|
|
LLFloaterBuyLandUI::~LLFloaterBuyLandUI()
|
|
{
|
|
LLViewerParcelMgr::getInstance()->deleteParcelBuy(&mParcelBuyInfo);
|
|
delete mTransaction;
|
|
|
|
if (sInstance == this)
|
|
{
|
|
sInstance = NULL;
|
|
}
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::SelectionObserver::changed()
|
|
{
|
|
LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(false);
|
|
if (ui)
|
|
{
|
|
if (LLViewerParcelMgr::getInstance()->selectionEmpty())
|
|
{
|
|
ui->close();
|
|
}
|
|
else {
|
|
ui->setParcel(
|
|
LLViewerParcelMgr::getInstance()->getSelectionRegion(),
|
|
LLViewerParcelMgr::getInstance()->getParcelSelection());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void LLFloaterBuyLandUI::updateAgentInfo()
|
|
{
|
|
mAgentCommittedTier = gStatusBar->getSquareMetersCommitted();
|
|
mAgentCashBalance = gStatusBar->getBalance();
|
|
|
|
// *TODO: This is an approximation, we should send this value down
|
|
// to the viewer. See SL-10728 for details.
|
|
mAgentHasNeverOwnedLand = mAgentCommittedTier == 0;
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::updateParcelInfo()
|
|
{
|
|
LLParcel* parcel = mParcel->getParcel();
|
|
mParcelValid = parcel && mRegion;
|
|
mParcelIsForSale = false;
|
|
mParcelIsGroupLand = false;
|
|
mParcelGroupContribution = 0;
|
|
mParcelPrice = 0;
|
|
mParcelActualArea = 0;
|
|
mParcelBillableArea = 0;
|
|
mParcelSupportedObjects = 0;
|
|
mParcelSoldWithObjects = false;
|
|
mParcelLocation = "";
|
|
mParcelSnapshot.setNull();
|
|
mParcelSellerName = "";
|
|
|
|
mCanBuy = false;
|
|
mCannotBuyIsError = false;
|
|
|
|
if (!mParcelValid)
|
|
{
|
|
mCannotBuyReason = getString("no_land_selected");
|
|
return;
|
|
}
|
|
|
|
if (mParcel->getMultipleOwners())
|
|
{
|
|
mCannotBuyReason = getString("multiple_parcels_selected");
|
|
return;
|
|
}
|
|
|
|
const LLUUID& parcelOwner = 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 = mParcel->getClaimableArea();
|
|
mParcelIsForSale = true;
|
|
mParcelPrice = mParcelActualArea * parcel->getClaimPricePerMeter();
|
|
}
|
|
|
|
mParcelBillableArea =
|
|
llround(mRegion->getBillableFactor() * mParcelActualArea);
|
|
|
|
mParcelSupportedObjects = llround(
|
|
parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus());
|
|
// Can't have more than region max tasks, regardless of parcel
|
|
// object bonus factor.
|
|
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->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(),
|
|
(int)center[VX], (int)center[VY]
|
|
);
|
|
|
|
mParcelSnapshot = parcel->getSnapshotID();
|
|
|
|
updateNames();
|
|
|
|
bool haveEnoughCash = mParcelPrice <= mAgentCashBalance;
|
|
S32 cashBuy = haveEnoughCash ? 0 : (mParcelPrice - mAgentCashBalance);
|
|
mCurrency.setAmount(cashBuy, true);
|
|
mCurrency.setZeroMessage(haveEnoughCash ? getString("none_needed") : LLStringUtil::null);
|
|
|
|
// checks that we can buy the land
|
|
|
|
if(mIsForGroup && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
|
|
{
|
|
mCannotBuyReason = getString("cant_buy_for_group");
|
|
return;
|
|
}
|
|
|
|
if (!mIsClaim)
|
|
{
|
|
const LLUUID& authorizedBuyer = parcel->getAuthorizedBuyerID();
|
|
const LLUUID buyer = gAgent.getID();
|
|
const LLUUID newOwner = mIsForGroup ? gAgent.getGroupID() : buyer;
|
|
|
|
if (!mParcelIsForSale
|
|
|| (mParcelPrice == 0 && authorizedBuyer.isNull()))
|
|
{
|
|
|
|
mCannotBuyReason = getString("parcel_not_for_sale");
|
|
return;
|
|
}
|
|
|
|
if (parcelOwner == newOwner)
|
|
{
|
|
if (mIsForGroup)
|
|
{
|
|
mCannotBuyReason = getString("group_already_owns");
|
|
}
|
|
else
|
|
{
|
|
mCannotBuyReason = getString("you_already_own");
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!authorizedBuyer.isNull() && buyer != authorizedBuyer)
|
|
{
|
|
// Maybe the parcel is set for sale to a group we are in.
|
|
bool authorized_group =
|
|
gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED)
|
|
&& gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO);
|
|
|
|
if (!authorized_group)
|
|
{
|
|
mCannotBuyReason = getString("set_to_sell_to_other");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (mParcelActualArea == 0)
|
|
{
|
|
mCannotBuyReason = getString("no_public_land");
|
|
return;
|
|
}
|
|
|
|
if (mParcel->hasOthersSelected())
|
|
{
|
|
// Policy: Must not have someone else's land selected
|
|
mCannotBuyReason = getString("not_owned_by_you");
|
|
return;
|
|
}
|
|
}
|
|
|
|
mCanBuy = true;
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::updateCovenantInfo()
|
|
{
|
|
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
|
if(!region) return;
|
|
|
|
LLTextBox* region_name = getChild<LLTextBox>("region_name_text");
|
|
if (region_name)
|
|
{
|
|
region_name->setText(region->getName());
|
|
}
|
|
|
|
LLTextBox* region_type = getChild<LLTextBox>("region_type_text");
|
|
if (region_type)
|
|
{
|
|
region_type->setText(region->getLocalizedSimProductName());
|
|
}
|
|
|
|
LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
|
|
if (resellable_clause)
|
|
{
|
|
if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
|
|
{
|
|
resellable_clause->setText(getString("can_not_resell"));
|
|
}
|
|
else
|
|
{
|
|
resellable_clause->setText(getString("can_resell"));
|
|
}
|
|
}
|
|
|
|
LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
|
|
if (changeable_clause)
|
|
{
|
|
if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
|
|
{
|
|
changeable_clause->setText(getString("can_change"));
|
|
}
|
|
else
|
|
{
|
|
changeable_clause->setText(getString("can_not_change"));
|
|
}
|
|
}
|
|
|
|
LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
|
|
if(check)
|
|
{
|
|
check->set(false);
|
|
check->setEnabled(true);
|
|
check->setCallbackUserData(this);
|
|
check->setCommitCallback(onChangeAgreeCovenant);
|
|
}
|
|
|
|
LLTextBox* box = getChild<LLTextBox>("covenant_text");
|
|
if(box)
|
|
{
|
|
box->setVisible(FALSE);
|
|
}
|
|
|
|
// send EstateCovenantInfo message
|
|
LLMessageSystem *msg = gMessageSystem;
|
|
msg->newMessage("EstateCovenantRequest");
|
|
msg->nextBlockFast(_PREHASH_AgentData);
|
|
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
|
msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
|
|
msg->sendReliable(region->getHost());
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data)
|
|
{
|
|
LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)user_data;
|
|
if(self)
|
|
{
|
|
self->refreshUI();
|
|
}
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::updateCovenantText(const std::string &string, const LLUUID& asset_id)
|
|
{
|
|
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("covenant_editor");
|
|
if (editor)
|
|
{
|
|
editor->setHandleEditKeysDirectly(FALSE);
|
|
editor->setText(string);
|
|
|
|
LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
|
|
LLTextBox* box = getChild<LLTextBox>("covenant_text");
|
|
if(check && box)
|
|
{
|
|
if (asset_id.isNull())
|
|
{
|
|
check->set(true);
|
|
check->setEnabled(false);
|
|
refreshUI();
|
|
|
|
// remove the line stating that you must agree
|
|
box->setVisible(FALSE);
|
|
}
|
|
else
|
|
{
|
|
check->setEnabled(true);
|
|
|
|
// remove the line stating that you must agree
|
|
box->setVisible(TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::updateEstateName(const std::string& name)
|
|
{
|
|
LLTextBox* box = getChild<LLTextBox>("estate_name_text");
|
|
if (box) box->setText(name);
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::updateLastModified(const std::string& text)
|
|
{
|
|
LLTextBox* editor = getChild<LLTextBox>("covenant_timestamp_text");
|
|
if (editor) editor->setText(text);
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::updateEstateOwnerName(const std::string& name)
|
|
{
|
|
LLTextBox* box = getChild<LLTextBox>("estate_owner_text");
|
|
if (box) box->setText(name);
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::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
|
|
|
|
LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
|
|
keywordArgs.appendString("agentId", gAgent.getID().asString());
|
|
keywordArgs.appendString(
|
|
"secureSessionId",
|
|
gAgent.getSecureSessionID().asString());
|
|
keywordArgs.appendInt("billableArea", mPreflightAskBillableArea);
|
|
keywordArgs.appendInt("currencyBuy", mPreflightAskCurrencyBuy);
|
|
|
|
LLXMLRPCValue params = LLXMLRPCValue::createArray();
|
|
params.append(keywordArgs);
|
|
|
|
startTransaction(TransactionPreflight, params);
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::finishWebSiteInfo()
|
|
{
|
|
|
|
LLXMLRPCValue result = mTransaction->responseValue();
|
|
|
|
mSiteValid = result["success"].asBool();
|
|
if (!mSiteValid)
|
|
{
|
|
tellUserError(
|
|
result["errorMessage"].asString(),
|
|
result["errorURI"].asString()
|
|
);
|
|
return;
|
|
}
|
|
|
|
LLXMLRPCValue membership = result["membership"];
|
|
mSiteMembershipUpgrade = membership["upgrade"].asBool();
|
|
mSiteMembershipAction = membership["action"].asString();
|
|
mSiteMembershipPlanIDs.clear();
|
|
mSiteMembershipPlanNames.clear();
|
|
LLXMLRPCValue levels = membership["levels"];
|
|
for (LLXMLRPCValue level = levels.rewind();
|
|
level.isValid();
|
|
level = levels.next())
|
|
{
|
|
mSiteMembershipPlanIDs.push_back(level["id"].asString());
|
|
mSiteMembershipPlanNames.push_back(level["description"].asString());
|
|
}
|
|
mUserPlanChoice = 0;
|
|
|
|
LLXMLRPCValue landUse = result["landUse"];
|
|
mSiteLandUseUpgrade = landUse["upgrade"].asBool();
|
|
mSiteLandUseAction = landUse["action"].asString();
|
|
|
|
LLXMLRPCValue currency = result["currency"];
|
|
mCurrency.setEstimate(currency["estimatedCost"].asInt());
|
|
|
|
mSiteConfirm = result["confirm"].asString();
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::runWebSitePrep(const std::string& password)
|
|
{
|
|
if (!mCanBuy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BOOL remove_contribution = childGetValue("remove_contribution").asBoolean();
|
|
mParcelBuyInfo = LLViewerParcelMgr::getInstance()->setupParcelBuy(gAgent.getID(), gAgent.getSessionID(),
|
|
gAgent.getGroupID(), mIsForGroup, mIsClaim, remove_contribution);
|
|
|
|
if (mParcelBuyInfo
|
|
&& !mSiteMembershipUpgrade
|
|
&& !mSiteLandUseUpgrade
|
|
&& mCurrency.getAmount() == 0
|
|
&& mSiteConfirm != "password")
|
|
{
|
|
sendBuyLand();
|
|
return;
|
|
}
|
|
|
|
|
|
std::string newLevel = "noChange";
|
|
|
|
if (mSiteMembershipUpgrade)
|
|
{
|
|
LLComboBox* levels = getChild<LLComboBox>( "account_level");
|
|
if (levels)
|
|
{
|
|
mUserPlanChoice = levels->getCurrentIndex();
|
|
newLevel = mSiteMembershipPlanIDs[mUserPlanChoice];
|
|
}
|
|
}
|
|
|
|
LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
|
|
keywordArgs.appendString("agentId", gAgent.getID().asString());
|
|
keywordArgs.appendString(
|
|
"secureSessionId",
|
|
gAgent.getSecureSessionID().asString());
|
|
keywordArgs.appendString("levelId", newLevel);
|
|
keywordArgs.appendInt("billableArea",
|
|
mIsForGroup ? 0 : mParcelBillableArea);
|
|
keywordArgs.appendInt("currencyBuy", mCurrency.getAmount());
|
|
keywordArgs.appendInt("estimatedCost", mCurrency.getEstimate());
|
|
keywordArgs.appendString("confirm", mSiteConfirm);
|
|
if (!password.empty())
|
|
{
|
|
keywordArgs.appendString("password", password);
|
|
}
|
|
|
|
LLXMLRPCValue params = LLXMLRPCValue::createArray();
|
|
params.append(keywordArgs);
|
|
|
|
startTransaction(TransactionBuy, params);
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::finishWebSitePrep()
|
|
{
|
|
LLXMLRPCValue result = mTransaction->responseValue();
|
|
|
|
bool success = result["success"].asBool();
|
|
if (!success)
|
|
{
|
|
tellUserError(
|
|
result["errorMessage"].asString(),
|
|
result["errorURI"].asString()
|
|
);
|
|
return;
|
|
}
|
|
|
|
sendBuyLand();
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::sendBuyLand()
|
|
{
|
|
if (mParcelBuyInfo)
|
|
{
|
|
LLViewerParcelMgr::getInstance()->sendParcelBuy(mParcelBuyInfo);
|
|
LLViewerParcelMgr::getInstance()->deleteParcelBuy(&mParcelBuyInfo);
|
|
mBought = true;
|
|
}
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::updateNames()
|
|
{
|
|
LLParcel* parcelp = mParcel->getParcel();
|
|
|
|
if (!parcelp)
|
|
{
|
|
mParcelSellerName = LLStringUtil::null;
|
|
return;
|
|
}
|
|
|
|
if (mIsClaim)
|
|
{
|
|
mParcelSellerName = "Linden Lab";
|
|
}
|
|
else if (parcelp->getIsGroupOwned())
|
|
{
|
|
gCacheName->getGroupName(parcelp->getGroupID(), mParcelSellerName);
|
|
}
|
|
else
|
|
{
|
|
gCacheName->getFullName(parcelp->getOwnerID(), mParcelSellerName);
|
|
}
|
|
}
|
|
|
|
|
|
void LLFloaterBuyLandUI::startTransaction(TransactionType type,
|
|
LLXMLRPCValue params)
|
|
{
|
|
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 = LLViewerLogin::getInstance()->getHelperURI() + "landtool.php";
|
|
}
|
|
|
|
const char* method;
|
|
switch (mTransactionType)
|
|
{
|
|
case TransactionPreflight:
|
|
method = "preflightBuyLandPrep";
|
|
break;
|
|
case TransactionBuy:
|
|
method = "buyLandPrep";
|
|
break;
|
|
default:
|
|
llwarns << "LLFloaterBuyLandUI: Unknown transaction type!" << llendl;
|
|
return;
|
|
}
|
|
|
|
mTransaction = new LLXMLRPCTransaction(
|
|
transaction_uri,
|
|
method,
|
|
params,
|
|
false /* don't use gzip */
|
|
);
|
|
}
|
|
|
|
bool LLFloaterBuyLandUI::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: ;
|
|
}
|
|
}
|
|
|
|
delete mTransaction;
|
|
mTransaction = NULL;
|
|
|
|
return true;
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::tellUserError(
|
|
const std::string& message, const std::string& uri)
|
|
{
|
|
mCanBuy = false;
|
|
mCannotBuyIsError = true;
|
|
mCannotBuyReason = getString("fetching_error");
|
|
mCannotBuyReason += message;
|
|
mCannotBuyURI = uri;
|
|
}
|
|
|
|
|
|
// virtual
|
|
BOOL LLFloaterBuyLandUI::postBuild()
|
|
{
|
|
mCurrency.prepare();
|
|
|
|
childSetAction("buy_btn", onClickBuy, this);
|
|
childSetAction("cancel_btn", onClickCancel, this);
|
|
childSetAction("error_web", onClickErrorWeb, this);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel)
|
|
{
|
|
if (mTransaction && mTransactionType == TransactionBuy)
|
|
{
|
|
// the user is buying, don't change the selection
|
|
return;
|
|
}
|
|
|
|
mRegion = region;
|
|
mParcel = parcel;
|
|
|
|
updateAgentInfo();
|
|
updateParcelInfo();
|
|
updateCovenantInfo();
|
|
if (mCanBuy)
|
|
{
|
|
updateWebSiteInfo();
|
|
}
|
|
refreshUI();
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::setForGroup(bool forGroup)
|
|
{
|
|
mIsForGroup = forGroup;
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::draw()
|
|
{
|
|
LLFloater::draw();
|
|
|
|
bool needsUpdate = false;
|
|
needsUpdate |= checkTransaction();
|
|
needsUpdate |= mCurrency.process();
|
|
|
|
if (mBought)
|
|
{
|
|
close();
|
|
}
|
|
else if (needsUpdate)
|
|
{
|
|
if (mCanBuy && mCurrency.hasError())
|
|
{
|
|
tellUserError(mCurrency.errorMessage(), mCurrency.errorURI());
|
|
}
|
|
|
|
refreshUI();
|
|
}
|
|
}
|
|
|
|
// virtual
|
|
BOOL LLFloaterBuyLandUI::canClose()
|
|
{
|
|
bool can_close = (mTransaction ? FALSE : TRUE) && mCurrency.canCancel();
|
|
if (!can_close)
|
|
{
|
|
// explain to user why they can't do this, see DEV-9605
|
|
LLNotificationsUtil::add("CannotCloseFloaterBuyLand");
|
|
}
|
|
return can_close;
|
|
}
|
|
|
|
// virtual
|
|
void LLFloaterBuyLandUI::setMinimized(BOOL minimize)
|
|
{
|
|
bool restored = (isMinimized() && !minimize);
|
|
LLFloater::setMinimized(minimize);
|
|
if (restored)
|
|
{
|
|
refreshUI();
|
|
}
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::onClose(bool app_quitting)
|
|
{
|
|
LLFloater::onClose(app_quitting);
|
|
destroy();
|
|
}
|
|
|
|
|
|
void LLFloaterBuyLandUI::refreshUI()
|
|
{
|
|
// section zero: title area
|
|
{
|
|
LLTextureCtrl* snapshot = getChild<LLTextureCtrl>("info_image");
|
|
if (snapshot)
|
|
{
|
|
snapshot->setImageAssetID(
|
|
mParcelValid ? mParcelSnapshot : LLUUID::null);
|
|
}
|
|
|
|
if (mParcelValid)
|
|
{
|
|
childSetText("info_parcel", mParcelLocation);
|
|
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[AMOUNT]"] = llformat("%d", mParcelActualArea);
|
|
string_args["[AMOUNT2]"] = llformat("%d", mParcelSupportedObjects);
|
|
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
|
|
|
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;
|
|
}
|
|
|
|
string_args["[PRICE]"] = llformat("%d", mParcelPrice);
|
|
string_args["[PRICE_PER_SQM]"] = llformat("%.1f", cost_per_sqm);
|
|
if (mParcelSoldWithObjects)
|
|
{
|
|
string_args["[SOLD_WITH_OBJECTS]"] = getString("sold_with_objects");
|
|
}
|
|
else
|
|
{
|
|
string_args["[SOLD_WITH_OBJECTS]"] = getString("sold_without_objects");
|
|
}
|
|
childSetText("info_price", getString("info_price_string", string_args));
|
|
childSetVisible("info_price", mParcelIsForSale);
|
|
}
|
|
else
|
|
{
|
|
childSetText("info_parcel", getString("no_parcel_selected"));
|
|
childSetText("info_size", LLStringUtil::null);
|
|
childSetText("info_price", LLStringUtil::null);
|
|
}
|
|
|
|
childSetText("info_action",
|
|
mCanBuy
|
|
?
|
|
mIsForGroup
|
|
? getString("buying_for_group")//"Buying land for group:"
|
|
: getString("buying_will")//"Buying this land will:"
|
|
:
|
|
mCannotBuyIsError
|
|
? getString("cannot_buy_now")//"Cannot buy now:"
|
|
: getString("not_for_sale")//"Not for sale:"
|
|
|
|
);
|
|
}
|
|
|
|
bool showingError = !mCanBuy || !mSiteValid;
|
|
|
|
// error section
|
|
if (showingError)
|
|
{
|
|
mChildren.setBadge(std::string("step_error"),
|
|
mCannotBuyIsError
|
|
? LLViewChildren::BADGE_ERROR
|
|
: LLViewChildren::BADGE_WARN);
|
|
|
|
LLTextBox* message = getChild<LLTextBox>("error_message");
|
|
if (message)
|
|
{
|
|
message->setVisible(true);
|
|
message->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 (!showingError)
|
|
{
|
|
mChildren.setBadge(std::string("step_1"),
|
|
mSiteMembershipUpgrade
|
|
? LLViewChildren::BADGE_NOTE
|
|
: LLViewChildren::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();
|
|
i != mSiteMembershipPlanNames.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 (!showingError)
|
|
{
|
|
mChildren.setBadge(std::string("step_2"),
|
|
mSiteLandUseUpgrade
|
|
? LLViewChildren::BADGE_NOTE
|
|
: LLViewChildren::BADGE_OK);
|
|
childSetText("land_use_action", mSiteLandUseAction);
|
|
|
|
std::string message;
|
|
|
|
if (mIsForGroup)
|
|
{
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[GROUP]"] = std::string(gAgent.getGroupName());
|
|
|
|
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 finalBalance = mAgentCashBalance + mCurrency.getAmount() - mParcelPrice;
|
|
bool willHaveEnough = finalBalance >= 0;
|
|
bool haveEnough = mAgentCashBalance >= mParcelPrice;
|
|
S32 minContribution = llceil((F32)mParcelBillableArea / GROUP_LAND_BONUS_FACTOR);
|
|
bool groupContributionEnough = mParcelGroupContribution >= minContribution;
|
|
|
|
mCurrency.updateUI(!showingError && !haveEnough);
|
|
|
|
if (!showingError)
|
|
{
|
|
mChildren.setBadge(std::string("step_3"),
|
|
!willHaveEnough
|
|
? LLViewChildren::BADGE_WARN
|
|
: mCurrency.getAmount() > 0
|
|
? LLViewChildren::BADGE_NOTE
|
|
: LLViewChildren::BADGE_OK);
|
|
|
|
childSetText("purchase_action",
|
|
llformat(
|
|
"Pay %s %d to %s for this land",
|
|
gHippoGridManager->getConnectedGrid()->getCurrencySymbol().c_str(),
|
|
mParcelPrice,
|
|
mParcelSellerName.c_str()
|
|
));
|
|
childSetVisible("purchase_action", mParcelValid);
|
|
|
|
std::string reasonString;
|
|
|
|
if (haveEnough)
|
|
{
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance);
|
|
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
|
|
|
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);
|
|
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
|
|
|
childSetText("currency_reason", getString("not_enough_lindens", string_args));
|
|
|
|
childSetTextArg("currency_est", "[AMOUNT2]", llformat("%#.2f", mCurrency.getEstimate() / 100.0));
|
|
}
|
|
|
|
if (willHaveEnough)
|
|
{
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[AMOUNT]"] = llformat("%d", finalBalance);
|
|
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
|
|
|
childSetText("currency_balance", getString("balance_left", string_args));
|
|
|
|
}
|
|
else
|
|
{
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[AMOUNT]"] = llformat("%d", mParcelPrice - mAgentCashBalance);
|
|
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
|
|
|
childSetText("currency_balance", getString("balance_needed", string_args));
|
|
|
|
}
|
|
|
|
childSetValue("remove_contribution", LLSD(groupContributionEnough));
|
|
childSetEnabled("remove_contribution", groupContributionEnough);
|
|
bool showRemoveContribution = mParcelIsGroupLand
|
|
&& (mParcelGroupContribution > 0);
|
|
childSetLabelArg("remove_contribution", "[AMOUNT]",
|
|
llformat("%d", minContribution));
|
|
childSetVisible("remove_contribution", showRemoveContribution);
|
|
|
|
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_group_donation");
|
|
}
|
|
|
|
|
|
bool agrees_to_covenant = false;
|
|
LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
|
|
if (check)
|
|
{
|
|
agrees_to_covenant = check->get();
|
|
}
|
|
|
|
childSetEnabled("buy_btn",
|
|
mCanBuy && mSiteValid && willHaveEnough && !mTransaction && agrees_to_covenant);
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::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["[AMOUNT2]"] = llformat("%#.2f", mCurrency.getEstimate() / 100.0);
|
|
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
|
|
|
action += getString("buy_for_US", string_args);
|
|
}
|
|
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[AMOUNT]"] = llformat("%d", mParcelPrice);
|
|
string_args["[SELLER]"] = mParcelSellerName;
|
|
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
|
action += getString("pay_to_for_land", string_args);
|
|
|
|
|
|
LLConfirmationManager::confirm(mSiteConfirm,
|
|
action,
|
|
*this,
|
|
&LLFloaterBuyLandUI::startBuyPostConfirm);
|
|
}
|
|
|
|
void LLFloaterBuyLandUI::startBuyPostConfirm(const std::string& password)
|
|
{
|
|
runWebSitePrep(password);
|
|
|
|
mCanBuy = false;
|
|
mCannotBuyReason = getString("processing");
|
|
refreshUI();
|
|
}
|
|
|
|
|
|
// static
|
|
void LLFloaterBuyLandUI::onClickBuy(void* data)
|
|
{
|
|
LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data;
|
|
self->startBuyPreConfirm();
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLandUI::onClickCancel(void* data)
|
|
{
|
|
LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data;
|
|
self->close();
|
|
}
|
|
|
|
// static
|
|
void LLFloaterBuyLandUI::onClickErrorWeb(void* data)
|
|
{
|
|
LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data;
|
|
LLWeb::loadURLExternal(self->mCannotBuyURI);
|
|
self->close();
|
|
}
|
|
|
|
|
|
|