PageRenderTime 402ms CodeModel.GetById 81ms app.highlight 265ms RepoModel.GetById 36ms app.codeStats 2ms

/indra/newview/llfloaterland.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2190 lines | 1619 code | 367 blank | 204 comment | 191 complexity | a2c4dd8b628eb57b9406d692d136107c MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/** 
   2 * @file llfloaterland.cpp
   3 * @brief "About Land" floater, allowing display and editing of land parcel properties.
   4 *
   5 * $LicenseInfo:firstyear=2002&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 <sstream>
  30#include <time.h>
  31
  32#include "llfloaterland.h"
  33
  34#include "llavatarnamecache.h"
  35#include "llfocusmgr.h"
  36#include "llnotificationsutil.h"
  37#include "llparcel.h"
  38#include "message.h"
  39
  40#include "llagent.h"
  41#include "llagentaccess.h"
  42#include "llbutton.h"
  43#include "llcheckboxctrl.h"
  44#include "llcombobox.h"
  45#include "llfloaterreg.h"
  46#include "llfloateravatarpicker.h"
  47#include "llfloaterauction.h"
  48#include "llfloatergroups.h"
  49#include "llfloaterscriptlimits.h"
  50#include "llavataractions.h"
  51#include "lllineeditor.h"
  52#include "llnamelistctrl.h"
  53#include "llpanellandaudio.h"
  54#include "llpanellandmedia.h"
  55#include "llradiogroup.h"
  56#include "llresmgr.h"					// getMonetaryString
  57#include "llscrolllistctrl.h"
  58#include "llscrolllistitem.h"
  59#include "llscrolllistcell.h"
  60#include "llselectmgr.h"
  61#include "llslurl.h"
  62#include "llspinctrl.h"
  63#include "lltabcontainer.h"
  64#include "lltextbox.h"
  65#include "lltexturectrl.h"
  66#include "lluiconstants.h"
  67#include "lluictrlfactory.h"
  68#include "llviewertexturelist.h"		// LLUIImageList
  69#include "llviewermessage.h"
  70#include "llviewerparcelmgr.h"
  71#include "llviewerregion.h"
  72#include "llviewerstats.h"
  73#include "llviewertexteditor.h"
  74#include "llviewerwindow.h"
  75#include "llviewercontrol.h"
  76#include "roles_constants.h"
  77#include "lltrans.h"
  78
  79#include "llgroupactions.h"
  80
  81static std::string OWNER_ONLINE 	= "0";
  82static std::string OWNER_OFFLINE	= "1";
  83static std::string OWNER_GROUP 		= "2";
  84static std::string MATURITY 		= "[MATURITY]";
  85
  86// constants used in callbacks below - syntactic sugar.
  87static const BOOL BUY_GROUP_LAND = TRUE;
  88static const BOOL BUY_PERSONAL_LAND = FALSE;
  89LLPointer<LLParcelSelection> LLPanelLandGeneral::sSelectionForBuyPass = NULL;
  90
  91// Statics
  92LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL;
  93S32 LLFloaterLand::sLastTab = 0;
  94
  95// Local classes
  96class LLParcelSelectionObserver : public LLParcelObserver
  97{
  98public:
  99	virtual void changed() { LLFloaterLand::refreshAll(); }
 100};
 101
 102// class needed to get full access to textbox inside checkbox, because LLCheckBoxCtrl::setLabel() has string as its argument.
 103// It was introduced while implementing EXT-4706
 104class LLCheckBoxWithTBAcess	: public LLCheckBoxCtrl
 105{
 106public:
 107	LLTextBox* getTextBox()
 108	{
 109		return mLabel;
 110	}
 111};
 112
 113// inserts maturity info(icon and text) into target textbox 
 114// names_floater - pointer to floater which contains strings with maturity icons filenames
 115// str_to_parse is string in format "txt1[MATURITY]txt2" where maturity icon and text will be inserted instead of [MATURITY]
 116void insert_maturity_into_textbox(LLTextBox* target_textbox, LLFloater* names_floater, std::string str_to_parse);
 117
 118//---------------------------------------------------------------------------
 119// LLFloaterLand
 120//---------------------------------------------------------------------------
 121
 122void send_parcel_select_objects(S32 parcel_local_id, U32 return_type,
 123								uuid_list_t* return_ids = NULL)
 124{
 125	LLMessageSystem *msg = gMessageSystem;
 126
 127	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
 128	if (!region) return;
 129
 130	// Since new highlight will be coming in, drop any highlights
 131	// that exist right now.
 132	LLSelectMgr::getInstance()->unhighlightAll();
 133
 134	msg->newMessageFast(_PREHASH_ParcelSelectObjects);
 135	msg->nextBlockFast(_PREHASH_AgentData);
 136	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());
 137	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
 138	msg->nextBlockFast(_PREHASH_ParcelData);
 139	msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
 140	msg->addU32Fast(_PREHASH_ReturnType, return_type);
 141
 142	// Throw all return ids into the packet.
 143	// TODO: Check for too many ids.
 144	if (return_ids)
 145	{
 146		uuid_list_t::iterator end = return_ids->end();
 147		for (uuid_list_t::iterator it = return_ids->begin();
 148			 it != end;
 149			 ++it)
 150		{
 151			msg->nextBlockFast(_PREHASH_ReturnIDs);
 152			msg->addUUIDFast(_PREHASH_ReturnID, (*it));
 153		}
 154	}
 155	else
 156	{
 157		// Put in a null key so that the message is complete.
 158		msg->nextBlockFast(_PREHASH_ReturnIDs);
 159		msg->addUUIDFast(_PREHASH_ReturnID, LLUUID::null);
 160	}
 161
 162	msg->sendReliable(region->getHost());
 163}
 164
 165LLParcel* LLFloaterLand::getCurrentSelectedParcel()
 166{
 167	return mParcel->getParcel();
 168};
 169
 170//static
 171LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects()
 172{
 173	LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
 174	if(land_instance)
 175	{
 176		return land_instance->mPanelObjects;
 177	}
 178	else
 179	{
 180		return NULL;
 181	}
 182}
 183
 184//static
 185LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant()
 186{
 187	LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
 188	if(land_instance)
 189	{
 190		return land_instance->mPanelCovenant;
 191	}
 192	else
 193	{
 194		return NULL;
 195	}
 196}
 197
 198// static
 199void LLFloaterLand::refreshAll()
 200{
 201	LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
 202	if(land_instance)
 203	{
 204		land_instance->refresh();
 205	}
 206}
 207
 208void LLFloaterLand::onOpen(const LLSD& key)
 209{
 210	// moved from triggering show instance in llviwermenu.cpp
 211	
 212	if (LLViewerParcelMgr::getInstance()->selectionEmpty())
 213	{
 214		LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal());
 215	}
 216	
 217	// Done automatically when the selected parcel's properties arrive
 218	// (and hence we have the local id).
 219	// LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER);
 220
 221	mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
 222	
 223	// Refresh even if not over a region so we don't get an
 224	// uninitialized dialog. The dialog is 0-region aware.
 225	refresh();
 226}
 227
 228void LLFloaterLand::onVisibilityChange(const LLSD& visible)
 229{
 230	if (!visible.asBoolean())
 231	{
 232		// Might have been showing owned objects
 233		LLSelectMgr::getInstance()->unhighlightAll();
 234
 235		// Save which panel we had open
 236		sLastTab = mTabLand->getCurrentPanelIndex();
 237	}
 238}
 239
 240
 241LLFloaterLand::LLFloaterLand(const LLSD& seed)
 242:	LLFloater(seed)
 243{
 244	mFactoryMap["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this);
 245	mFactoryMap["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this);
 246	mFactoryMap["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this);
 247	mFactoryMap["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this);
 248	mFactoryMap["land_audio_panel"] =	LLCallbackMap(createPanelLandAudio, this);
 249	mFactoryMap["land_media_panel"] =	LLCallbackMap(createPanelLandMedia, this);
 250	mFactoryMap["land_access_panel"] =	LLCallbackMap(createPanelLandAccess, this);
 251
 252	sObserver = new LLParcelSelectionObserver();
 253	LLViewerParcelMgr::getInstance()->addObserver( sObserver );
 254}
 255
 256BOOL LLFloaterLand::postBuild()
 257{	
 258	setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2));
 259	
 260	LLTabContainer* tab = getChild<LLTabContainer>("landtab");
 261
 262	mTabLand = (LLTabContainer*) tab;
 263
 264	if (tab)
 265	{
 266		tab->selectTab(sLastTab);
 267	}
 268
 269	return TRUE;
 270}
 271
 272
 273// virtual
 274LLFloaterLand::~LLFloaterLand()
 275{
 276	LLViewerParcelMgr::getInstance()->removeObserver( sObserver );
 277	delete sObserver;
 278	sObserver = NULL;
 279}
 280
 281// public
 282void LLFloaterLand::refresh()
 283{
 284	mPanelGeneral->refresh();
 285	mPanelObjects->refresh();
 286	mPanelOptions->refresh();
 287	mPanelAudio->refresh();
 288	mPanelMedia->refresh();
 289	mPanelAccess->refresh();
 290	mPanelCovenant->refresh();
 291}
 292
 293
 294
 295void* LLFloaterLand::createPanelLandGeneral(void* data)
 296{
 297	LLFloaterLand* self = (LLFloaterLand*)data;
 298	self->mPanelGeneral = new LLPanelLandGeneral(self->mParcel);
 299	return self->mPanelGeneral;
 300}
 301
 302// static
 303void* LLFloaterLand::createPanelLandCovenant(void* data)
 304{
 305	LLFloaterLand* self = (LLFloaterLand*)data;
 306	self->mPanelCovenant = new LLPanelLandCovenant(self->mParcel);
 307	return self->mPanelCovenant;
 308}
 309
 310
 311// static
 312void* LLFloaterLand::createPanelLandObjects(void* data)
 313{
 314	LLFloaterLand* self = (LLFloaterLand*)data;
 315	self->mPanelObjects = new LLPanelLandObjects(self->mParcel);
 316	return self->mPanelObjects;
 317}
 318
 319// static
 320void* LLFloaterLand::createPanelLandOptions(void* data)
 321{
 322	LLFloaterLand* self = (LLFloaterLand*)data;
 323	self->mPanelOptions = new LLPanelLandOptions(self->mParcel);
 324	return self->mPanelOptions;
 325}
 326
 327// static
 328void* LLFloaterLand::createPanelLandAudio(void* data)
 329{
 330	LLFloaterLand* self = (LLFloaterLand*)data;
 331	self->mPanelAudio = new LLPanelLandAudio(self->mParcel);
 332	return self->mPanelAudio;
 333}
 334
 335// static
 336void* LLFloaterLand::createPanelLandMedia(void* data)
 337{
 338	LLFloaterLand* self = (LLFloaterLand*)data;
 339	self->mPanelMedia = new LLPanelLandMedia(self->mParcel);
 340	return self->mPanelMedia;
 341}
 342
 343// static
 344void* LLFloaterLand::createPanelLandAccess(void* data)
 345{
 346	LLFloaterLand* self = (LLFloaterLand*)data;
 347	self->mPanelAccess = new LLPanelLandAccess(self->mParcel);
 348	return self->mPanelAccess;
 349}
 350
 351//---------------------------------------------------------------------------
 352// LLPanelLandGeneral
 353//---------------------------------------------------------------------------
 354
 355
 356LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel)
 357:	LLPanel(),
 358	mUncheckedSell(FALSE),
 359	mParcel(parcel)
 360{
 361}
 362
 363BOOL LLPanelLandGeneral::postBuild()
 364{
 365	mEditName = getChild<LLLineEditor>("Name");
 366	mEditName->setCommitCallback(onCommitAny, this);	
 367	getChild<LLLineEditor>("Name")->setPrevalidate(LLTextValidate::validateASCIIPrintableNoPipe);
 368
 369	mEditDesc = getChild<LLTextEditor>("Description");
 370	mEditDesc->setCommitOnFocusLost(TRUE);
 371	mEditDesc->setCommitCallback(onCommitAny, this);	
 372	// No prevalidate function - historically the prevalidate function was broken,
 373	// allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
 374	// preserve that ability.
 375	
 376	mTextSalePending = getChild<LLTextBox>("SalePending");
 377	mTextOwnerLabel = getChild<LLTextBox>("Owner:");
 378	mTextOwner = getChild<LLTextBox>("OwnerText");
 379	
 380	mContentRating = getChild<LLTextBox>("ContentRatingText");
 381	mLandType = getChild<LLTextBox>("LandTypeText");
 382	
 383	mBtnProfile = getChild<LLButton>("Profile...");
 384	mBtnProfile->setClickedCallback(boost::bind(&LLPanelLandGeneral::onClickProfile, this));
 385
 386	
 387	mTextGroupLabel = getChild<LLTextBox>("Group:");
 388	mTextGroup = getChild<LLTextBox>("GroupText");
 389
 390	
 391	mBtnSetGroup = getChild<LLButton>("Set...");
 392	mBtnSetGroup->setCommitCallback(boost::bind(&LLPanelLandGeneral::onClickSetGroup, this));
 393
 394	
 395	mCheckDeedToGroup = getChild<LLCheckBoxCtrl>( "check deed");
 396	childSetCommitCallback("check deed", onCommitAny, this);
 397
 398	
 399	mBtnDeedToGroup = getChild<LLButton>("Deed...");
 400	mBtnDeedToGroup->setClickedCallback(onClickDeed, this);
 401
 402	
 403	mCheckContributeWithDeed = getChild<LLCheckBoxCtrl>( "check contrib");
 404	childSetCommitCallback("check contrib", onCommitAny, this);
 405
 406	
 407	
 408	mSaleInfoNotForSale = getChild<LLTextBox>("Not for sale.");
 409	
 410	mSaleInfoForSale1 = getChild<LLTextBox>("For Sale: Price L$[PRICE].");
 411
 412	
 413	mBtnSellLand = getChild<LLButton>("Sell Land...");
 414	mBtnSellLand->setClickedCallback(onClickSellLand, this);
 415	
 416	mSaleInfoForSale2 = getChild<LLTextBox>("For sale to");
 417	
 418	mSaleInfoForSaleObjects = getChild<LLTextBox>("Sell with landowners objects in parcel.");
 419	
 420	mSaleInfoForSaleNoObjects = getChild<LLTextBox>("Selling with no objects in parcel.");
 421
 422	
 423	mBtnStopSellLand = getChild<LLButton>("Cancel Land Sale");
 424	mBtnStopSellLand->setClickedCallback(onClickStopSellLand, this);
 425
 426	
 427	mTextClaimDateLabel = getChild<LLTextBox>("Claimed:");
 428	mTextClaimDate = getChild<LLTextBox>("DateClaimText");
 429
 430	
 431	mTextPriceLabel = getChild<LLTextBox>("PriceLabel");
 432	mTextPrice = getChild<LLTextBox>("PriceText");
 433
 434	
 435	mTextDwell = getChild<LLTextBox>("DwellText");
 436	
 437	mBtnBuyLand = getChild<LLButton>("Buy Land...");
 438	mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND);
 439	
 440	// note: on region change this will not be re checked, should not matter on Agni as
 441	// 99% of the time all regions will return the same caps. In case of an erroneous setting
 442	// to enabled the floater will just throw an error when trying to get it's cap
 443	std::string url = gAgent.getRegion()->getCapability("LandResources");
 444	if (!url.empty())
 445	{
 446		mBtnScriptLimits = getChild<LLButton>("Scripts...");
 447		if(mBtnScriptLimits)
 448		{
 449			mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this);
 450		}
 451	}
 452	else
 453	{
 454		mBtnScriptLimits = getChild<LLButton>("Scripts...");
 455		if(mBtnScriptLimits)
 456		{
 457			mBtnScriptLimits->setVisible(false);
 458		}
 459	}
 460	
 461	mBtnBuyGroupLand = getChild<LLButton>("Buy For Group...");
 462	mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND);
 463	
 464	
 465	mBtnBuyPass = getChild<LLButton>("Buy Pass...");
 466	mBtnBuyPass->setClickedCallback(onClickBuyPass, this);
 467
 468	mBtnReleaseLand = getChild<LLButton>("Abandon Land...");
 469	mBtnReleaseLand->setClickedCallback(onClickRelease, NULL);
 470
 471	mBtnReclaimLand = getChild<LLButton>("Reclaim Land...");
 472	mBtnReclaimLand->setClickedCallback(onClickReclaim, NULL);
 473	
 474	mBtnStartAuction = getChild<LLButton>("Linden Sale...");
 475	mBtnStartAuction->setClickedCallback(onClickStartAuction, this);
 476
 477	return TRUE;
 478}
 479
 480
 481// virtual
 482LLPanelLandGeneral::~LLPanelLandGeneral()
 483{ }
 484
 485
 486// public
 487void LLPanelLandGeneral::refresh()
 488{
 489	mBtnStartAuction->setVisible(gAgent.isGodlike());
 490
 491	LLParcel *parcel = mParcel->getParcel();
 492	bool region_owner = false;
 493	LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion();
 494	if(regionp && (regionp->getOwner() == gAgent.getID()))
 495	{
 496		region_owner = true;
 497		mBtnReleaseLand->setVisible(FALSE);
 498		mBtnReclaimLand->setVisible(TRUE);
 499	}
 500	else
 501	{
 502		mBtnReleaseLand->setVisible(TRUE);
 503		mBtnReclaimLand->setVisible(FALSE);
 504	}
 505	if (!parcel)
 506	{
 507		// nothing selected, disable panel
 508		mEditName->setEnabled(FALSE);
 509		mEditName->setText(LLStringUtil::null);
 510
 511		mEditDesc->setEnabled(FALSE);
 512		mEditDesc->setText(getString("no_selection_text"));
 513
 514		mTextSalePending->setText(LLStringUtil::null);
 515		mTextSalePending->setEnabled(FALSE);
 516
 517		mBtnDeedToGroup->setEnabled(FALSE);
 518		mBtnSetGroup->setEnabled(FALSE);
 519		mBtnStartAuction->setEnabled(FALSE);
 520
 521		mCheckDeedToGroup	->set(FALSE);
 522		mCheckDeedToGroup	->setEnabled(FALSE);
 523		mCheckContributeWithDeed->set(FALSE);
 524		mCheckContributeWithDeed->setEnabled(FALSE);
 525
 526		mTextOwner->setText(LLStringUtil::null);
 527		mContentRating->setText(LLStringUtil::null);
 528		mLandType->setText(LLStringUtil::null);
 529		mBtnProfile->setLabel(getString("profile_text"));
 530		mBtnProfile->setEnabled(FALSE);
 531
 532		mTextClaimDate->setText(LLStringUtil::null);
 533		mTextGroup->setText(LLStringUtil::null);
 534		mTextPrice->setText(LLStringUtil::null);
 535
 536		mSaleInfoForSale1->setVisible(FALSE);
 537		mSaleInfoForSale2->setVisible(FALSE);
 538		mSaleInfoForSaleObjects->setVisible(FALSE);
 539		mSaleInfoForSaleNoObjects->setVisible(FALSE);
 540		mSaleInfoNotForSale->setVisible(FALSE);
 541		mBtnSellLand->setVisible(FALSE);
 542		mBtnStopSellLand->setVisible(FALSE);
 543
 544		mTextPriceLabel->setText(LLStringUtil::null);
 545		mTextDwell->setText(LLStringUtil::null);
 546
 547		mBtnBuyLand->setEnabled(FALSE);
 548		mBtnScriptLimits->setEnabled(FALSE);
 549		mBtnBuyGroupLand->setEnabled(FALSE);
 550		mBtnReleaseLand->setEnabled(FALSE);
 551		mBtnReclaimLand->setEnabled(FALSE);
 552		mBtnBuyPass->setEnabled(FALSE);
 553	}
 554	else
 555	{
 556		// something selected, hooray!
 557		BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus());
 558		BOOL region_xfer = FALSE;
 559		if(regionp
 560		   && !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL))
 561		{
 562			region_xfer = TRUE;
 563		}
 564		
 565		if (regionp)
 566		{
 567			insert_maturity_into_textbox(mContentRating, gFloaterView->getParentFloater(this), MATURITY);
 568			mLandType->setText(regionp->getLocalizedSimProductName());
 569		}
 570
 571		// estate owner/manager cannot edit other parts of the parcel
 572		BOOL estate_manager_sellable = !parcel->getAuctionID()
 573										&& gAgent.canManageEstate()
 574										// estate manager/owner can only sell parcels owned by estate owner
 575										&& regionp
 576										&& (parcel->getOwnerID() == regionp->getOwner());
 577		BOOL owner_sellable = region_xfer && !parcel->getAuctionID()
 578							&& LLViewerParcelMgr::isParcelModifiableByAgent(
 579										parcel, GP_LAND_SET_SALE_INFO);
 580		BOOL can_be_sold = owner_sellable || estate_manager_sellable;
 581
 582		const LLUUID &owner_id = parcel->getOwnerID();
 583		BOOL is_public = parcel->isPublic();
 584
 585		// Is it owned?
 586		if (is_public)
 587		{
 588			mTextSalePending->setText(LLStringUtil::null);
 589			mTextSalePending->setEnabled(FALSE);
 590			mTextOwner->setText(getString("public_text"));
 591			mTextOwner->setEnabled(FALSE);
 592			mBtnProfile->setEnabled(FALSE);
 593			mTextClaimDate->setText(LLStringUtil::null);
 594			mTextClaimDate->setEnabled(FALSE);
 595			mTextGroup->setText(getString("none_text"));
 596			mTextGroup->setEnabled(FALSE);
 597			mBtnStartAuction->setEnabled(FALSE);
 598		}
 599		else
 600		{
 601			if(!is_leased && (owner_id == gAgent.getID()))
 602			{
 603				mTextSalePending->setText(getString("need_tier_to_modify"));
 604				mTextSalePending->setEnabled(TRUE);
 605			}
 606			else if(parcel->getAuctionID())
 607			{
 608				mTextSalePending->setText(getString("auction_id_text"));
 609				mTextSalePending->setTextArg("[ID]", llformat("%u", parcel->getAuctionID()));
 610				mTextSalePending->setEnabled(TRUE);
 611			}
 612			else
 613			{
 614				// not the owner, or it is leased
 615				mTextSalePending->setText(LLStringUtil::null);
 616				mTextSalePending->setEnabled(FALSE);
 617			}
 618			//refreshNames();
 619			mTextOwner->setEnabled(TRUE);
 620
 621			// We support both group and personal profiles
 622			mBtnProfile->setEnabled(TRUE);
 623
 624			if (parcel->getGroupID().isNull())
 625			{
 626				// Not group owned, so "Profile"
 627				mBtnProfile->setLabel(getString("profile_text"));
 628
 629				mTextGroup->setText(getString("none_text"));
 630				mTextGroup->setEnabled(FALSE);
 631			}
 632			else
 633			{
 634				// Group owned, so "Info"
 635				mBtnProfile->setLabel(getString("info_text"));
 636
 637				//mTextGroup->setText("HIPPOS!");//parcel->getGroupName());
 638				mTextGroup->setEnabled(TRUE);
 639			}
 640
 641			// Display claim date
 642			time_t claim_date = parcel->getClaimDate();
 643			std::string claim_date_str = getString("time_stamp_template");
 644			LLSD substitution;
 645			substitution["datetime"] = (S32) claim_date;
 646			LLStringUtil::format (claim_date_str, substitution);
 647			mTextClaimDate->setText(claim_date_str);
 648			mTextClaimDate->setEnabled(is_leased);
 649
 650			BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON)
 651								  && (owner_id == GOVERNOR_LINDEN_ID)
 652								  && (parcel->getAuctionID() == 0);
 653			mBtnStartAuction->setEnabled(enable_auction);
 654		}
 655
 656		// Display options
 657		BOOL can_edit_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY);
 658		mEditName->setEnabled(can_edit_identity);
 659		mEditDesc->setEnabled(can_edit_identity);
 660
 661		BOOL can_edit_agent_only = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS);
 662		mBtnSetGroup->setEnabled(can_edit_agent_only && !parcel->getIsGroupOwned());
 663
 664		const LLUUID& group_id = parcel->getGroupID();
 665
 666		// Can only allow deeding if you own it and it's got a group.
 667		BOOL enable_deed = (owner_id == gAgent.getID()
 668							&& group_id.notNull()
 669							&& gAgent.isInGroup(group_id));
 670		// You don't need special powers to allow your object to
 671		// be deeded to the group.
 672		mCheckDeedToGroup->setEnabled(enable_deed);
 673		mCheckDeedToGroup->set( parcel->getAllowDeedToGroup() );
 674		mCheckContributeWithDeed->setEnabled(enable_deed && parcel->getAllowDeedToGroup());
 675		mCheckContributeWithDeed->set(parcel->getContributeWithDeed());
 676
 677		// Actually doing the deeding requires you to have GP_LAND_DEED
 678		// powers in the group.
 679		BOOL can_deed = gAgent.hasPowerInGroup(group_id, GP_LAND_DEED);
 680		mBtnDeedToGroup->setEnabled(   parcel->getAllowDeedToGroup()
 681									&& group_id.notNull()
 682									&& can_deed
 683									&& !parcel->getIsGroupOwned()
 684									);
 685
 686		mEditName->setText( parcel->getName() );
 687		mEditDesc->setText( parcel->getDesc() );
 688
 689		BOOL for_sale = parcel->getForSale();
 690				
 691		mBtnSellLand->setVisible(FALSE);
 692		mBtnStopSellLand->setVisible(FALSE);
 693		
 694		// show pricing information
 695		S32 area;
 696		S32 claim_price;
 697		S32 rent_price;
 698		F32 dwell = DWELL_NAN;
 699		LLViewerParcelMgr::getInstance()->getDisplayInfo(&area,
 700								 &claim_price,
 701								 &rent_price,
 702								 &for_sale,
 703								 &dwell);
 704		// Area
 705		LLUIString price = getString("area_size_text");
 706		price.setArg("[AREA]", llformat("%d",area));    
 707		mTextPriceLabel->setText(getString("area_text"));
 708		mTextPrice->setText(price.getString());
 709
 710		if (dwell == DWELL_NAN)
 711		{
 712			mTextDwell->setText(LLTrans::getString("LoadingData"));
 713		}
 714		else
 715		{
 716			mTextDwell->setText(llformat("%.0f", dwell));
 717		}
 718
 719		if (for_sale)
 720		{
 721			mSaleInfoForSale1->setVisible(TRUE);
 722			mSaleInfoForSale2->setVisible(TRUE);
 723			if (parcel->getSellWithObjects())
 724			{
 725				mSaleInfoForSaleObjects->setVisible(TRUE);
 726				mSaleInfoForSaleNoObjects->setVisible(FALSE);
 727			}
 728			else
 729			{
 730				mSaleInfoForSaleObjects->setVisible(FALSE);
 731				mSaleInfoForSaleNoObjects->setVisible(TRUE);
 732			}
 733			mSaleInfoNotForSale->setVisible(FALSE);
 734
 735			F32 cost_per_sqm = 0.0f;
 736			if (area > 0)
 737			{
 738				cost_per_sqm = (F32)parcel->getSalePrice() / (F32)area;
 739			}
 740
 741			S32 price = parcel->getSalePrice();
 742			mSaleInfoForSale1->setTextArg("[PRICE]", LLResMgr::getInstance()->getMonetaryString(price));
 743			mSaleInfoForSale1->setTextArg("[PRICE_PER_SQM]", llformat("%.1f", cost_per_sqm));
 744			if (can_be_sold)
 745			{
 746				mBtnStopSellLand->setVisible(TRUE);
 747			}
 748		}
 749		else
 750		{
 751			mSaleInfoForSale1->setVisible(FALSE);
 752			mSaleInfoForSale2->setVisible(FALSE);
 753			mSaleInfoForSaleObjects->setVisible(FALSE);
 754			mSaleInfoForSaleNoObjects->setVisible(FALSE);
 755			mSaleInfoNotForSale->setVisible(TRUE);
 756			if (can_be_sold)
 757			{
 758				mBtnSellLand->setVisible(TRUE);
 759			}
 760		}
 761		
 762		refreshNames();
 763
 764		mBtnBuyLand->setEnabled(
 765			LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false));
 766		mBtnScriptLimits->setEnabled(true);
 767//			LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false));
 768		mBtnBuyGroupLand->setEnabled(
 769			LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, true));
 770
 771		if(region_owner)
 772		{
 773			mBtnReclaimLand->setEnabled(
 774				!is_public && (parcel->getOwnerID() != gAgent.getID()));
 775		}
 776		else
 777		{
 778			BOOL is_owner_release = LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_RELEASE);
 779			BOOL is_manager_release = (gAgent.canManageEstate() && 
 780									regionp && 
 781									(parcel->getOwnerID() != regionp->getOwner()));
 782			BOOL can_release = is_owner_release || is_manager_release;
 783			mBtnReleaseLand->setEnabled( can_release );
 784		}
 785
 786		BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();;
 787		mBtnBuyPass->setEnabled(use_pass);
 788	}
 789}
 790
 791// public
 792void LLPanelLandGeneral::refreshNames()
 793{
 794	LLParcel *parcel = mParcel->getParcel();
 795	if (!parcel)
 796	{
 797		mTextOwner->setText(LLStringUtil::null);
 798		mTextGroup->setText(LLStringUtil::null);
 799		return;
 800	}
 801
 802	std::string owner;
 803	if (parcel->getIsGroupOwned())
 804	{
 805		owner = getString("group_owned_text");
 806	}
 807	else
 808	{
 809		// Figure out the owner's name
 810		owner = LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
 811	}
 812
 813	if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
 814	{
 815		owner += getString("sale_pending_text");
 816	}
 817	mTextOwner->setText(owner);
 818
 819	std::string group;
 820	if (!parcel->getGroupID().isNull())
 821	{
 822		group = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
 823	}
 824	mTextGroup->setText(group);
 825
 826	if (parcel->getForSale())
 827	{
 828		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
 829		if(auth_buyer_id.notNull())
 830		{
 831		  std::string name;
 832		  name = LLSLURL("agent", auth_buyer_id, "inspect").getSLURLString();
 833		  mSaleInfoForSale2->setTextArg("[BUYER]", name);
 834		}
 835		else
 836		{
 837			mSaleInfoForSale2->setTextArg("[BUYER]", getString("anyone"));
 838		}
 839	}
 840}
 841
 842
 843// virtual
 844void LLPanelLandGeneral::draw()
 845{
 846	LLPanel::draw();
 847}
 848
 849void LLPanelLandGeneral::onClickSetGroup()
 850{
 851	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
 852
 853	LLFloaterGroupPicker* fg = 	LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
 854	if (fg)
 855	{
 856		fg->setSelectGroupCallback( boost::bind(&LLPanelLandGeneral::setGroup, this, _1 ));
 857		if (parent_floater)
 858		{
 859			LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
 860			fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
 861			parent_floater->addDependentFloater(fg);
 862		}
 863	}
 864}
 865
 866void LLPanelLandGeneral::onClickProfile()
 867{
 868	LLParcel* parcel = mParcel->getParcel();
 869	if (!parcel) return;
 870
 871	if (parcel->getIsGroupOwned())
 872	{
 873		const LLUUID& group_id = parcel->getGroupID();
 874		LLGroupActions::show(group_id);
 875	}
 876	else
 877	{
 878		const LLUUID& avatar_id = parcel->getOwnerID();
 879		LLAvatarActions::showProfile(avatar_id);
 880	}
 881}
 882
 883// public
 884void LLPanelLandGeneral::setGroup(const LLUUID& group_id)
 885{
 886	LLParcel* parcel = mParcel->getParcel();
 887	if (!parcel) return;
 888
 889	// Set parcel properties and send message
 890	parcel->setGroupID(group_id);
 891	//parcel->setGroupName(group_name);
 892	//mTextGroup->setText(group_name);
 893
 894	// Send update
 895	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate(parcel);
 896
 897	// Update UI
 898	refresh();
 899}
 900
 901// static
 902void LLPanelLandGeneral::onClickBuyLand(void* data)
 903{
 904	BOOL* for_group = (BOOL*)data;
 905	LLViewerParcelMgr::getInstance()->startBuyLand(*for_group);
 906}
 907
 908// static
 909void LLPanelLandGeneral::onClickScriptLimits(void* data)
 910{
 911	LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
 912	LLParcel* parcel = panelp->mParcel->getParcel();
 913	if(parcel != NULL)
 914	{
 915		LLFloaterReg::showInstance("script_limits");
 916	}
 917}
 918
 919// static
 920void LLPanelLandGeneral::onClickDeed(void*)
 921{
 922	//LLParcel* parcel = mParcel->getParcel();
 923	//if (parcel)
 924	//{
 925	LLViewerParcelMgr::getInstance()->startDeedLandToGroup();
 926	//}
 927}
 928
 929// static
 930void LLPanelLandGeneral::onClickRelease(void*)
 931{
 932	LLViewerParcelMgr::getInstance()->startReleaseLand();
 933}
 934
 935// static
 936void LLPanelLandGeneral::onClickReclaim(void*)
 937{
 938	lldebugs << "LLPanelLandGeneral::onClickReclaim()" << llendl;
 939	LLViewerParcelMgr::getInstance()->reclaimParcel();
 940}
 941
 942// static
 943BOOL LLPanelLandGeneral::enableBuyPass(void* data)
 944{
 945	LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
 946	LLParcel* parcel = panelp != NULL ? panelp->mParcel->getParcel() : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
 947	return (parcel != NULL) && (parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned());
 948}
 949
 950
 951// static
 952void LLPanelLandGeneral::onClickBuyPass(void* data)
 953{
 954	LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
 955	LLParcel* parcel = panelp != NULL ? panelp->mParcel->getParcel() : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
 956
 957	if (!parcel) return;
 958
 959	S32 pass_price = parcel->getPassPrice();
 960	std::string parcel_name = parcel->getName();
 961	F32 pass_hours = parcel->getPassHours();
 962
 963	std::string cost, time;
 964	cost = llformat("%d", pass_price);
 965	time = llformat("%.2f", pass_hours);
 966
 967	LLSD args;
 968	args["COST"] = cost;
 969	args["PARCEL_NAME"] = parcel_name;
 970	args["TIME"] = time;
 971	
 972	// creating pointer on selection to avoid deselection of parcel until we are done with buying pass (EXT-6464)
 973	sSelectionForBuyPass = LLViewerParcelMgr::getInstance()->getParcelSelection();
 974	LLNotificationsUtil::add("LandBuyPass", args, LLSD(), cbBuyPass);
 975}
 976
 977// static
 978void LLPanelLandGeneral::onClickStartAuction(void* data)
 979{
 980	LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
 981	LLParcel* parcelp = panelp->mParcel->getParcel();
 982	if(parcelp)
 983	{
 984		if(parcelp->getForSale())
 985		{
 986			LLNotificationsUtil::add("CannotStartAuctionAlreadyForSale");
 987		}
 988		else
 989		{
 990			//LLFloaterAuction::showInstance();
 991			LLFloaterReg::showInstance("auction");
 992		}
 993	}
 994}
 995
 996// static
 997bool LLPanelLandGeneral::cbBuyPass(const LLSD& notification, const LLSD& response)
 998{
 999	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1000	if (0 == option)
1001	{
1002		// User clicked OK
1003		LLViewerParcelMgr::getInstance()->buyPass();
1004	}
1005	// we are done with buying pass, additional selection is no longer needed
1006	sSelectionForBuyPass = NULL;
1007	return false;
1008}
1009
1010// static
1011void LLPanelLandGeneral::onCommitAny(LLUICtrl *ctrl, void *userdata)
1012{
1013	LLPanelLandGeneral *panelp = (LLPanelLandGeneral *)userdata;
1014
1015	LLParcel* parcel = panelp->mParcel->getParcel();
1016	if (!parcel)
1017	{
1018		return;
1019	}
1020
1021	// Extract data from UI
1022	std::string name = panelp->mEditName->getText();
1023	std::string desc = panelp->mEditDesc->getText();
1024
1025	// Valid data from UI
1026
1027	// Stuff data into selected parcel
1028	parcel->setName(name);
1029	parcel->setDesc(desc);
1030
1031	BOOL allow_deed_to_group= panelp->mCheckDeedToGroup->get();
1032	BOOL contribute_with_deed = panelp->mCheckContributeWithDeed->get();
1033
1034	parcel->setParcelFlag(PF_ALLOW_DEED_TO_GROUP, allow_deed_to_group);
1035	parcel->setContributeWithDeed(contribute_with_deed);
1036
1037	// Send update to server
1038	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
1039
1040	// Might have changed properties, so let's redraw!
1041	panelp->refresh();
1042}
1043
1044// static
1045void LLPanelLandGeneral::onClickSellLand(void* data)
1046{
1047	LLViewerParcelMgr::getInstance()->startSellLand();
1048}
1049
1050// static
1051void LLPanelLandGeneral::onClickStopSellLand(void* data)
1052{
1053	LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
1054	LLParcel* parcel = panelp->mParcel->getParcel();
1055
1056	parcel->setParcelFlag(PF_FOR_SALE, FALSE);
1057	parcel->setSalePrice(0);
1058	parcel->setAuthorizedBuyerID(LLUUID::null);
1059
1060	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate(parcel);
1061}
1062
1063//---------------------------------------------------------------------------
1064// LLPanelLandObjects
1065//---------------------------------------------------------------------------
1066LLPanelLandObjects::LLPanelLandObjects(LLParcelSelectionHandle& parcel)
1067	:	LLPanel(),
1068
1069		mParcel(parcel),
1070		mParcelObjectBonus(NULL),
1071		mSWTotalObjects(NULL),
1072		mObjectContribution(NULL),
1073		mTotalObjects(NULL),
1074		mOwnerObjects(NULL),
1075		mBtnShowOwnerObjects(NULL),
1076		mBtnReturnOwnerObjects(NULL),
1077		mGroupObjects(NULL),
1078		mBtnShowGroupObjects(NULL),
1079		mBtnReturnGroupObjects(NULL),
1080		mOtherObjects(NULL),
1081		mBtnShowOtherObjects(NULL),
1082		mBtnReturnOtherObjects(NULL),
1083		mSelectedObjects(NULL),
1084		mCleanOtherObjectsTime(NULL),
1085		mOtherTime(0),
1086		mBtnRefresh(NULL),
1087		mBtnReturnOwnerList(NULL),
1088		mOwnerList(NULL),
1089		mFirstReply(TRUE),
1090		mSelectedCount(0),
1091		mSelectedIsGroup(FALSE)
1092{
1093}
1094
1095
1096
1097BOOL LLPanelLandObjects::postBuild()
1098{
1099	
1100	mFirstReply = TRUE;
1101	mParcelObjectBonus = getChild<LLTextBox>("parcel_object_bonus");
1102	mSWTotalObjects = getChild<LLTextBox>("objects_available");
1103	mObjectContribution = getChild<LLTextBox>("object_contrib_text");
1104	mTotalObjects = getChild<LLTextBox>("total_objects_text");
1105	mOwnerObjects = getChild<LLTextBox>("owner_objects_text");
1106	
1107	mBtnShowOwnerObjects = getChild<LLButton>("ShowOwner");
1108	mBtnShowOwnerObjects->setClickedCallback(onClickShowOwnerObjects, this);
1109	
1110	mBtnReturnOwnerObjects = getChild<LLButton>("ReturnOwner...");
1111	mBtnReturnOwnerObjects->setClickedCallback(onClickReturnOwnerObjects, this);
1112	
1113	mGroupObjects = getChild<LLTextBox>("group_objects_text");
1114	mBtnShowGroupObjects = getChild<LLButton>("ShowGroup");
1115	mBtnShowGroupObjects->setClickedCallback(onClickShowGroupObjects, this);
1116	
1117	mBtnReturnGroupObjects = getChild<LLButton>("ReturnGroup...");
1118	mBtnReturnGroupObjects->setClickedCallback(onClickReturnGroupObjects, this);
1119	
1120	mOtherObjects = getChild<LLTextBox>("other_objects_text");
1121	mBtnShowOtherObjects = getChild<LLButton>("ShowOther");
1122	mBtnShowOtherObjects->setClickedCallback(onClickShowOtherObjects, this);
1123	
1124	mBtnReturnOtherObjects = getChild<LLButton>("ReturnOther...");
1125	mBtnReturnOtherObjects->setClickedCallback(onClickReturnOtherObjects, this);
1126	
1127	mSelectedObjects = getChild<LLTextBox>("selected_objects_text");
1128	mCleanOtherObjectsTime = getChild<LLLineEditor>("clean other time");
1129
1130	mCleanOtherObjectsTime->setFocusLostCallback(boost::bind(onLostFocus, _1, this));
1131	mCleanOtherObjectsTime->setCommitCallback(onCommitClean, this);
1132	getChild<LLLineEditor>("clean other time")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
1133	
1134	mBtnRefresh = getChild<LLButton>("Refresh List");
1135	mBtnRefresh->setClickedCallback(onClickRefresh, this);
1136	
1137	mBtnReturnOwnerList = getChild<LLButton>("Return objects...");
1138	mBtnReturnOwnerList->setClickedCallback(onClickReturnOwnerList, this);
1139
1140	mIconAvatarOnline = LLUIImageList::getInstance()->getUIImage("icon_avatar_online.tga", 0);
1141	mIconAvatarOffline = LLUIImageList::getInstance()->getUIImage("icon_avatar_offline.tga", 0);
1142	mIconGroup = LLUIImageList::getInstance()->getUIImage("icon_group.tga", 0);
1143
1144	mOwnerList = getChild<LLNameListCtrl>("owner list");
1145	mOwnerList->sortByColumnIndex(3, FALSE);
1146	childSetCommitCallback("owner list", onCommitList, this);
1147	mOwnerList->setDoubleClickCallback(onDoubleClickOwner, this);
1148	mOwnerList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
1149
1150	return TRUE;
1151}
1152
1153
1154
1155
1156// virtual
1157LLPanelLandObjects::~LLPanelLandObjects()
1158{ }
1159
1160// static
1161void LLPanelLandObjects::onDoubleClickOwner(void *userdata)
1162{
1163	LLPanelLandObjects *self = (LLPanelLandObjects *)userdata;
1164
1165	LLScrollListItem* item = self->mOwnerList->getFirstSelected();
1166	if (item)
1167	{
1168		LLUUID owner_id = item->getUUID();
1169		// Look up the selected name, for future dialog box use.
1170		const LLScrollListCell* cell;
1171		cell = item->getColumn(1);
1172		if (!cell)
1173		{
1174			return;
1175		}
1176		// Is this a group?
1177		BOOL is_group = cell->getValue().asString() == OWNER_GROUP;
1178		if (is_group)
1179		{
1180			LLGroupActions::show(owner_id);
1181		}
1182		else
1183		{
1184			LLAvatarActions::showProfile(owner_id);
1185		}
1186	}
1187}
1188
1189// public
1190void LLPanelLandObjects::refresh()
1191{
1192	LLParcel *parcel = mParcel->getParcel();
1193
1194	mBtnShowOwnerObjects->setEnabled(FALSE);
1195	mBtnShowGroupObjects->setEnabled(FALSE);
1196	mBtnShowOtherObjects->setEnabled(FALSE);
1197	mBtnReturnOwnerObjects->setEnabled(FALSE);
1198	mBtnReturnGroupObjects->setEnabled(FALSE);
1199	mBtnReturnOtherObjects->setEnabled(FALSE);
1200	mCleanOtherObjectsTime->setEnabled(FALSE);
1201	mBtnRefresh->			setEnabled(FALSE);
1202	mBtnReturnOwnerList->	setEnabled(FALSE);
1203
1204	mSelectedOwners.clear();
1205	mOwnerList->deleteAllItems();
1206	mOwnerList->setEnabled(FALSE);
1207
1208	if (!parcel)
1209	{
1210		mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", 0));
1211		mSWTotalObjects->setTextArg("[TOTAL]", llformat("%d", 0));
1212		mSWTotalObjects->setTextArg("[AVAILABLE]", llformat("%d", 0));
1213		mObjectContribution->setTextArg("[COUNT]", llformat("%d", 0));
1214		mTotalObjects->setTextArg("[COUNT]", llformat("%d", 0));
1215		mOwnerObjects->setTextArg("[COUNT]", llformat("%d", 0));
1216		mGroupObjects->setTextArg("[COUNT]", llformat("%d", 0));
1217		mOtherObjects->setTextArg("[COUNT]", llformat("%d", 0));
1218		mSelectedObjects->setTextArg("[COUNT]", llformat("%d", 0));
1219	}
1220	else
1221	{
1222		S32 sw_max = parcel->getSimWideMaxPrimCapacity();
1223		S32 sw_total = parcel->getSimWidePrimCount();
1224		S32 max = llround(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus());
1225		S32 total = parcel->getPrimCount();
1226		S32 owned = parcel->getOwnerPrimCount();
1227		S32 group = parcel->getGroupPrimCount();
1228		S32 other = parcel->getOtherPrimCount();
1229		S32 selected = parcel->getSelectedPrimCount();
1230		F32 parcel_object_bonus = parcel->getParcelPrimBonus();
1231		mOtherTime = parcel->getCleanOtherTime();
1232
1233		// Can't have more than region max tasks, regardless of parcel
1234		// object bonus factor.
1235		LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
1236		if (region)
1237		{
1238			S32 max_tasks_per_region = (S32)region->getMaxTasks();
1239			sw_max = llmin(sw_max, max_tasks_per_region);
1240			max = llmin(max, max_tasks_per_region);
1241		}
1242
1243		if (parcel_object_bonus != 1.0f)
1244		{
1245			mParcelObjectBonus->setVisible(TRUE);
1246			mParcelObjectBonus->setTextArg("[BONUS]", llformat("%.2f", parcel_object_bonus));
1247		}
1248		else
1249		{
1250			mParcelObjectBonus->setVisible(FALSE);
1251		}
1252
1253		if (sw_total > sw_max)
1254		{
1255			mSWTotalObjects->setText(getString("objects_deleted_text"));
1256			mSWTotalObjects->setTextArg("[DELETED]", llformat("%d", sw_total - sw_max));
1257		}
1258		else
1259		{
1260			mSWTotalObjects->setText(getString("objects_available_text"));
1261			mSWTotalObjects->setTextArg("[AVAILABLE]", llformat("%d", sw_max - sw_total));
1262		}
1263		mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", sw_total));
1264		mSWTotalObjects->setTextArg("[MAX]", llformat("%d", sw_max));
1265
1266		mObjectContribution->setTextArg("[COUNT]", llformat("%d", max));
1267		mTotalObjects->setTextArg("[COUNT]", llformat("%d", total));
1268		mOwnerObjects->setTextArg("[COUNT]", llformat("%d", owned));
1269		mGroupObjects->setTextArg("[COUNT]", llformat("%d", group));
1270		mOtherObjects->setTextArg("[COUNT]", llformat("%d", other));
1271		mSelectedObjects->setTextArg("[COUNT]", llformat("%d", selected));
1272		mCleanOtherObjectsTime->setText(llformat("%d", mOtherTime));
1273
1274		BOOL can_return_owned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_GROUP_OWNED);
1275		BOOL can_return_group_set = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_GROUP_SET);
1276		BOOL can_return_other = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_NON_GROUP);
1277
1278		if (can_return_owned || can_return_group_set || can_return_other)
1279		{
1280			if (owned && can_return_owned)
1281			{
1282				mBtnShowOwnerObjects->setEnabled(TRUE);
1283				mBtnReturnOwnerObjects->setEnabled(TRUE);
1284			}
1285			if (group && can_return_group_set)
1286			{
1287				mBtnShowGroupObjects->setEnabled(TRUE);
1288				mBtnReturnGroupObjects->setEnabled(TRUE);
1289			}
1290			if (other && can_return_other)
1291			{
1292				mBtnShowOtherObjects->setEnabled(TRUE);
1293				mBtnReturnOtherObjects->setEnabled(TRUE);
1294			}
1295
1296			mCleanOtherObjectsTime->setEnabled(TRUE);
1297			mBtnRefresh->setEnabled(TRUE);
1298		}
1299	}
1300}
1301
1302// virtual
1303void LLPanelLandObjects::draw()
1304{
1305	LLPanel::draw();
1306}
1307
1308void send_other_clean_time_message(S32 parcel_local_id, S32 other_clean_time)
1309{
1310	LLMessageSystem *msg = gMessageSystem;
1311
1312	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
1313	if (!region) return;
1314
1315	msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
1316	msg->nextBlockFast(_PREHASH_AgentData);
1317	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());
1318	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
1319	msg->nextBlockFast(_PREHASH_ParcelData);
1320	msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
1321	msg->addS32Fast(_PREHASH_OtherCleanTime, other_clean_time);
1322
1323	msg->sendReliable(region->getHost());
1324}
1325
1326void send_return_objects_message(S32 parcel_local_id, S32 return_type, 
1327								 uuid_list_t* owner_ids = NULL)
1328{
1329	LLMessageSystem *msg = gMessageSystem;
1330
1331	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
1332	if (!region) return;
1333
1334	msg->newMessageFast(_PREHASH_ParcelReturnObjects);
1335	msg->nextBlockFast(_PREHASH_AgentData);
1336	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());
1337	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
1338	msg->nextBlockFast(_PREHASH_ParcelData);
1339	msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
1340	msg->addU32Fast(_PREHASH_ReturnType, (U32) return_type);
1341
1342	// Dummy task id, not used
1343	msg->nextBlock("TaskIDs");
1344	msg->addUUID("TaskID", LLUUID::null);
1345
1346	// Throw all return ids into the packet.
1347	// TODO: Check for too many ids.
1348	if (owner_ids)
1349	{
1350		uuid_list_t::iterator end = owner_ids->end();
1351		for (uuid_list_t::iterator it = owner_ids->begin();
1352			 it != end;
1353			 ++it)
1354		{
1355			msg->nextBlockFast(_PREHASH_OwnerIDs);
1356			msg->addUUIDFast(_PREHASH_OwnerID, (*it));
1357		}
1358	}
1359	else
1360	{
1361		msg->nextBlockFast(_PREHASH_OwnerIDs);
1362		msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null);
1363	}
1364
1365	msg->sendReliable(region->getHost());
1366}
1367
1368bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, const LLSD& response)
1369{
1370	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1371	LLParcel *parcel = mParcel->getParcel();
1372	if (0 == option)
1373	{
1374		if (parcel)
1375		{
1376			LLUUID owner_id = parcel->getOwnerID();	
1377			LLSD args;
1378			if (owner_id == gAgentID)
1379			{
1380				LLNotificationsUtil::add("OwnedObjectsReturned");
1381			}
1382			else
1383			{
1384				args["NAME"] = LLSLURL("agent", owner_id, "completename").getSLURLString();
1385				LLNotificationsUtil::add("OtherObjectsReturned", args);
1386			}
1387			send_return_objects_message(parcel->getLocalID(), RT_OWNER);
1388		}
1389	}
1390
1391	LLSelectMgr::getInstance()->unhighlightAll();
1392	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
1393	refresh();
1394	return false;
1395}
1396
1397bool LLPanelLandObjects::callbackReturnGroupObjects(const LLSD& notification, const LLSD& response)
1398{
1399	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1400	LLParcel *parcel = mParcel->getParcel();
1401	if (0 == option)
1402	{
1403		if (parcel)
1404		{
1405			std::string group_name;
1406			gCacheName->getGroupName(parcel->getGroupID(), group_name);
1407			LLSD args;
1408			args["GROUPNAME"] = group_name;
1409			LLNotificationsUtil::add("GroupObjectsReturned", args);
1410			send_return_objects_message(parcel->getLocalID(), RT_GROUP);
1411		}
1412	}
1413	LLSelectMgr::getInstance()->unhighlightAll();
1414	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
1415	refresh();
1416	return false;
1417}
1418
1419bool LLPanelLandObjects::callbackReturnOtherObjects(const LLSD& notification, const LLSD& response)
1420{
1421	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1422	LLParcel *parcel = mParcel->getParcel();
1423	if (0 == option)
1424	{
1425		if (parcel)
1426		{
1427			LLNotificationsUtil::add("UnOwnedObjectsReturned");
1428			send_return_objects_message(parcel->getLocalID(), RT_OTHER);
1429		}
1430	}
1431	LLSelectMgr::getInstance()->unhighlightAll();
1432	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
1433	refresh();
1434	return false;
1435}
1436
1437bool LLPanelLandObjects::callbackReturnOwnerList(const LLSD& notification, const LLSD& response)
1438{
1439	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1440	LLParcel *parcel = mParcel->getParcel();
1441	if (0 == option)
1442	{
1443		if (parcel)
1444		{
1445			// Make sure we have something selected.
1446			uuid_list_t::iterator selected = mSelectedOwners.begin();
1447			if (selected != mSelectedOwners.end())
1448			{
1449				LLSD args;
1450				if (mSelectedIsGroup)
1451				{
1452					args["GROUPNAME"] = mSelectedName;
1453					LLNotificationsUtil::add("GroupObjectsReturned", args);
1454				}
1455				else
1456				{
1457					args["NAME"] = mSelectedName;
1458					LLNotificationsUtil::add("OtherObjectsReturned2", args);
1459				}
1460
1461				send_return_objects_message(parcel->getLocalID(), RT_LIST, &(mSelectedOwners));
1462			}
1463		}
1464	}
1465	LLSelectMgr::getInstance()->unhighlightAll();
1466	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
1467	refresh();
1468	return false;
1469}
1470
1471
1472// static
1473void LLPanelLandObjects::onClickReturnOwnerList(void* userdata)
1474{
1475	LLPanelLandObjects	*self = (LLPanelLandObjects *)userdata;
1476
1477	LLParcel* parcelp = self->mParcel->getParcel();
1478	if (!parcelp) return;
1479
1480	// Make sure we have something selected.
1481	if (self->mSelectedOwners.empty())
1482	{
1483		return;
1484	}
1485	//uuid_list_t::iterator selected_itr = self->mSelectedOwners.begin();
1486	//if (selected_itr == self->mSelectedOwners.end()) return;
1487
1488	send_parcel_select_objects(parcelp->getLocalID(), RT_LIST, &(self->mSelectedOwners));
1489
1490	LLSD args;
1491	args["NAME"] = self->mSelectedName;
1492	args["N"] = llformat("%d",self->mSelectedCount);
1493	if (self->mSelectedIsGroup)
1494	{
1495		LLNotificationsUtil::add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));	
1496	}
1497	else 
1498	{
1499		LLNotificationsUtil::add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));	
1500	}
1501}
1502
1503
1504// static
1505void LLPanelLandObjects::onClickRefresh(void* userdata)
1506{
1507	LLPanelLandObjects *self = (LLPanelLandObjects*)userdata;
1508
1509	LLMessageSystem *msg = gMessageSystem;
1510
1511	LLParcel* parcel = self->mParcel->getParcel();
1512	if (!parcel) return;
1513
1514	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
1515	if (!region) return;
1516
1517	// ready the list for results
1518	self->mOwnerList->deleteAllItems();
1519	self->mOwnerList->setCommentText(LLTrans::getString("Searching"));
1520	self->mOwnerList->setEnabled(FALSE);
1521	self->mFirstReply = TRUE;
1522
1523	// send the message
1524	msg->newMessageFast(_PREHASH_ParcelObjectOwnersRequest);
1525	msg->nextBlockFast(_PREHASH_AgentData);
1526	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
1527	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
1528	msg->nextBlockFast(_PREHASH_ParcelData);
1529	msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID());
1530
1531	msg->sendReliable(region->getHost());
1532}
1533
1534// static
1535void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, void **)
1536{
1537	LLPanelLandObjects* self = LLFloaterLand::getCurrentPanelLandObjects();
1538
1539	if (!self)
1540	{
1541		llwarns << "Received message for nonexistent LLPanelLandObject"
1542				<< llendl;
1543		return;
1544	}
1545	
1546	const LLFontGL* FONT = LLFontGL::getFontSansSerif();
1547
1548	// Extract all of the owners.
1549	S32 rows = msg->getNumberOfBlocksFast(_PREHASH_Data);
1550	//uuid_list_t return_ids;
1551	LLUUID	owner_id;
1552	BOOL	is_group_owned;
1553	S32		object_count;
1554	U32		most_recent_time = 0;
1555	BOOL	is_online;
1556	std::string object_count_str;
1557	//BOOL b_need_refresh = FALSE;
1558
1559	// If we were waiting for the first reply, clear the "Searching..." text.
1560	if (self->mFirstReply)
1561	{
1562		self->mOwnerList->deleteAllItems();
1563		self->mFirstReply = FALSE;
1564	}
1565
1566	for(S32 i = 0; i < rows; ++i)
1567	{
1568		msg->getUUIDFast(_PREHASH_Data, _PREHASH_OwnerID,		owner_id,		i);
1569		msg->getBOOLFast(_PREHASH_Data, _PREHASH_IsGroupOwned,	is_group_owned,	i);
1570		msg->getS32Fast (_PREHASH_Data, _PREHASH_Count,			object_count,	i);
1571		msg->getBOOLFast(_PREHASH_Data, _PREHASH_OnlineStatus,	is_online,		i);
1572		if(msg->has("DataExtended"))
1573		{
1574			msg->getU32("DataExtended", "TimeStamp", most_recent_time, i);
1575		}
1576		if (owner_id.isNull())
1577		{
1578			continue;
1579		}
1580
1581		LLNameListCtrl::NameItem item_params;
1582		item_params.value = owner_id;
1583		item_params.target = is_group_owned ? LLNameListCtrl::GROUP : LLNameListCtrl::INDIVIDUAL;
1584
1585		if (is_group_owned)
1586		{
1587			item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type");
1588			item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status");
1589		}
1590		else if (is_online)
1591		{
1592			item_params.columns.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type");
1593			item_params.columns.add().value(OWNER_ONLINE).font(FONT).column("online_status");
1594		}
1595		else  // offline
1596		{
1597			item_params.columns.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type");
1598			item_params.columns.add().value(OWNER_OFFLINE).font(FONT).column("online_status");
1599		}
1600
1601		// Placeholder for name.
1602		LLAvatarName av_name;
1603		LLAvatarNameCache::get(owner_id, &av_name);
1604		item_params.columns.add().value(av_name.getCompleteName()).font(FONT).column("name");
1605
1606		object_count_str = llformat("%d", object_count);
1607		item_params.columns.add().value(object_count_str).font(FONT).column("count");
1608		item_params.columns.add().value(LLDate((time_t)most_recent_time)).font(FONT).column("mostrecent").type("date");
1609
1610		self->mOwnerList->addNameItemRow(item_params);
1611
1612		lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent")
1613				<< ") owns " << object_count << " objects." << llendl;
1614	}
1615	// check for no results
1616	if (0 == self->mOwnerList->getItemCount())
1617	{
1618		self->mOwnerList->setCommentText(LLTrans::getString("NoneFound"));
1619	}
1620	else
1621	{
1622		self->mOwnerList->setEnabled(TRUE);
1623	}
1624}
1625
1626// static
1627void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data)
1628{
1629	LLPanelLandObjects* self = (LLPanelLandObjects*)data;
1630
1631	if (FALSE == self->mOwnerList->getCanSelect())
1632	{
1633		return;
1634	}
1635	LLScrollListItem *item = self->mOwnerList->getFirstSelected();
1636	if (item)
1637	{
1638		// Look up the selected name, for future dialog box use.
1639		const LLScrollListCell* cell;
1640		cell = item->getColumn(1);
1641		if (!cell)
1642		{
1643			return;
1644		}
1645		// Is this a group?
1646		self->mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP;
1647		cell = item->getColumn(2);
1648		self->mSelectedName = cell->getValue().asString();
1649		cell = item->getColumn(3);
1650		self->mSelectedCount = atoi(cell->getValue().asString().c_str());
1651
1652		// Set the selection, and enable the return button.
1653		self->mSelectedOwners.clear();
1654		self->mSelectedOwners.insert(item->getUUID());
1655		self->mBtnReturnOwnerList->setEnabled(TRUE);
1656
1657		// Highlight this user's objects
1658		clickShowCore(self, RT_LIST, &(self->mSelectedOwners));
1659	}
1660}
1661
1662// static
1663void LLPanelLandObjects::clickShowCore(LLPanelLandObjects* self, S32 return_type, uuid_list_t* list)
1664{
1665	LLParcel* parcel = self->mParcel->getParcel();
1666	if (!parcel) return;
1667
1668	send_parcel_select_objects(parcel->getLocalID(), return_type, list);
1669}
1670
1671// static
1672void LLPanelLandObjects::onClickShowOwnerObjects(void* userdata)
1673{
1674	clickShowCore((LLPanelLandObjects*)userdata, RT_OWNER);
1675}
1676
1677// static
1678void LLPanelLandObjects::onClickShowGroupObjects(void* userdata)
1679{
1680	clickShowCore((LLPanelLandObjects*)userdata, (RT_GROUP));
1681}
1682
1683// static
1684void LLPanelLandObjects::onClickShowOtherObjects(void* userdata)
1685{
1686	clickShowCore((LLPanelLandObjects*)userdata, RT_OTHER);
1687}
1688
1689// static
1690void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)
1691{
1692	S32 owned = 0;
1693
1694	LLPanelLandObjects* panelp = (LLPanelLandObjects*)userdata;
1695	LLParcel* parcel = panelp->mParcel->getParcel();
1696	if (!parcel) return;
1697
1698	owned = parcel->getOwnerPrimCount();
1699
1700	send_parcel_select_objects(parcel->getLocalID(), RT_OWNER);
1701
1702	LLUUID owner_id = parcel->getOwnerID();
1703	
1704	LLSD args;
1705	args

Large files files are truncated, but you can click here to view the full file