PageRenderTime 1860ms CodeModel.GetById 120ms app.highlight 1293ms RepoModel.GetById 159ms app.codeStats 1ms

/indra/newview/llfloaterregioninfo.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2052 lines | 1498 code | 304 blank | 250 comment | 180 complexity | e9530b9eb7491f4ac8fa146f9239f1c9 MD5 | raw file

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

   1/** 
   2 * @file llfloaterregioninfo.cpp
   3 * @author Aaron Brashears
   4 * @brief Implementation of the region info and controls floater and panels.
   5 *
   6 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
   7 * Second Life Viewer Source Code
   8 * Copyright (C) 2010, Linden Research, Inc.
   9 * 
  10 * This library is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU Lesser General Public
  12 * License as published by the Free Software Foundation;
  13 * version 2.1 of the License only.
  14 * 
  15 * This library is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * Lesser General Public License for more details.
  19 * 
  20 * You should have received a copy of the GNU Lesser General Public
  21 * License along with this library; if not, write to the Free Software
  22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  23 * 
  24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  25 * $/LicenseInfo$
  26 */
  27
  28#include "llviewerprecompiledheaders.h"
  29#include "llfloaterregioninfo.h"
  30
  31#include <algorithm>
  32#include <functional>
  33
  34#include "lldir.h"
  35#include "lldispatcher.h"
  36#include "llglheaders.h"
  37#include "llregionflags.h"
  38#include "llstl.h"
  39#include "llvfile.h"
  40#include "llxfermanager.h"
  41#include "indra_constants.h"
  42#include "message.h"
  43#include "llloadingindicator.h"
  44#include "llradiogroup.h"
  45#include "llsd.h"
  46#include "llsdserialize.h"
  47
  48#include "llagent.h"
  49#include "llappviewer.h"
  50#include "llavatarname.h"
  51#include "llfloateravatarpicker.h"
  52#include "llbutton.h" 
  53#include "llcheckboxctrl.h"
  54#include "llcombobox.h"
  55#include "lldaycyclemanager.h"
  56#include "llenvmanager.h"
  57#include "llestateinfomodel.h"
  58#include "llfilepicker.h"
  59#include "llfloatergodtools.h"	// for send_sim_wide_deletes()
  60#include "llfloatertopobjects.h" // added to fix SL-32336
  61#include "llfloatergroups.h"
  62#include "llfloaterreg.h"
  63#include "llfloaterregiondebugconsole.h"
  64#include "llfloatertelehub.h"
  65#include "llinventorymodel.h"
  66#include "lllineeditor.h"
  67#include "llnamelistctrl.h"
  68#include "llnotifications.h"
  69#include "llnotificationsutil.h"
  70#include "llregioninfomodel.h"
  71#include "llscrolllistitem.h"
  72#include "llsliderctrl.h"
  73#include "llslurl.h"
  74#include "llspinctrl.h"
  75#include "lltabcontainer.h"
  76#include "lltextbox.h"
  77#include "llinventory.h"
  78#include "lltexturectrl.h"
  79#include "lltrans.h"
  80#include "llviewercontrol.h"
  81#include "lluictrlfactory.h"
  82#include "llviewerinventory.h"
  83#include "llviewertexture.h"
  84#include "llviewertexturelist.h"
  85#include "llviewerregion.h"
  86#include "llviewerstats.h"
  87#include "llviewertexteditor.h"
  88#include "llviewerwindow.h"
  89#include "llvlcomposition.h"
  90#include "llwaterparammanager.h"
  91#include "lltrans.h"
  92#include "llagentui.h"
  93#include "llmeshrepository.h"
  94
  95const S32 TERRAIN_TEXTURE_COUNT = 4;
  96const S32 CORNER_COUNT = 4;
  97
  98#define TMP_DISABLE_WLES // STORM-1180
  99
 100///----------------------------------------------------------------------------
 101/// Local class declaration
 102///----------------------------------------------------------------------------
 103
 104class LLDispatchEstateUpdateInfo : public LLDispatchHandler
 105{
 106public:
 107	LLDispatchEstateUpdateInfo() {}
 108	virtual ~LLDispatchEstateUpdateInfo() {}
 109	virtual bool operator()(
 110		const LLDispatcher* dispatcher,
 111		const std::string& key,
 112		const LLUUID& invoice,
 113		const sparam_t& strings);
 114};
 115
 116class LLDispatchSetEstateAccess : public LLDispatchHandler
 117{
 118public:
 119	LLDispatchSetEstateAccess() {}
 120	virtual ~LLDispatchSetEstateAccess() {}
 121	virtual bool operator()(
 122		const LLDispatcher* dispatcher,
 123		const std::string& key,
 124		const LLUUID& invoice,
 125		const sparam_t& strings);
 126};
 127
 128
 129/*
 130void unpack_request_params(
 131	LLMessageSystem* msg,
 132	LLDispatcher::sparam_t& strings,
 133	LLDispatcher::iparam_t& integers)
 134{
 135	char str_buf[MAX_STRING];
 136	S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData);
 137	S32 i;
 138	for (i = 0; i < str_count; ++i)
 139	{
 140		// we treat the SParam as binary data (since it might be an 
 141		// LLUUID in compressed form which may have embedded \0's,)
 142		str_buf[0] = '\0';
 143		S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam);
 144		if (data_size >= 0)
 145		{
 146			msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam,
 147								   str_buf, data_size, i, MAX_STRING - 1);
 148			strings.push_back(std::string(str_buf, data_size));
 149		}
 150	}
 151
 152	U32 int_buf;
 153	S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData);
 154	for (i = 0; i < int_count; ++i)
 155	{
 156		msg->getU32("IntegerData", "IParam", int_buf, i);
 157		integers.push_back(int_buf);
 158	}
 159}
 160*/
 161
 162
 163
 164bool estate_dispatch_initialized = false;
 165
 166
 167///----------------------------------------------------------------------------
 168/// LLFloaterRegionInfo
 169///----------------------------------------------------------------------------
 170
 171//S32 LLFloaterRegionInfo::sRequestSerial = 0;
 172LLUUID LLFloaterRegionInfo::sRequestInvoice;
 173
 174
 175LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
 176	: LLFloater(seed)
 177{}
 178
 179BOOL LLFloaterRegionInfo::postBuild()
 180{
 181	mTab = getChild<LLTabContainer>("region_panels");
 182	mTab->setCommitCallback(boost::bind(&LLFloaterRegionInfo::onTabSelected, this, _2));
 183
 184	// contruct the panels
 185	LLPanelRegionInfo* panel;
 186	panel = new LLPanelEstateInfo;
 187	mInfoPanels.push_back(panel);
 188	panel->buildFromFile("panel_region_estate.xml");
 189	mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true));
 190
 191	panel = new LLPanelEstateCovenant;
 192	mInfoPanels.push_back(panel);
 193	panel->buildFromFile("panel_region_covenant.xml");
 194	mTab->addTabPanel(panel);
 195
 196	panel = new LLPanelRegionGeneralInfo;
 197	mInfoPanels.push_back(panel);
 198	panel->getCommitCallbackRegistrar().add("RegionInfo.ManageTelehub",	boost::bind(&LLPanelRegionInfo::onClickManageTelehub, panel));
 199	panel->buildFromFile("panel_region_general.xml");
 200	mTab->addTabPanel(panel);
 201
 202	panel = new LLPanelRegionTerrainInfo;
 203	mInfoPanels.push_back(panel);
 204	panel->buildFromFile("panel_region_terrain.xml");
 205	mTab->addTabPanel(panel);
 206
 207	panel = new LLPanelEnvironmentInfo;
 208	mInfoPanels.push_back(panel);
 209	panel->buildFromFile("panel_region_environment.xml");
 210	mTab->addTabPanel(panel);
 211
 212	panel = new LLPanelRegionDebugInfo;
 213	mInfoPanels.push_back(panel);
 214	panel->buildFromFile("panel_region_debug.xml");
 215	mTab->addTabPanel(panel);
 216
 217	gMessageSystem->setHandlerFunc(
 218		"EstateOwnerMessage", 
 219		&processEstateOwnerRequest);
 220
 221	// Request region info when agent region changes.
 222	LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this));
 223
 224	return TRUE;
 225}
 226
 227LLFloaterRegionInfo::~LLFloaterRegionInfo()
 228{}
 229
 230void LLFloaterRegionInfo::onOpen(const LLSD& key)
 231{
 232	refreshFromRegion(gAgent.getRegion());
 233	requestRegionInfo();
 234	requestMeshRezInfo();
 235}
 236
 237// static
 238void LLFloaterRegionInfo::requestRegionInfo()
 239{
 240	LLTabContainer* tab = getChild<LLTabContainer>("region_panels");
 241
 242	tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
 243	tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
 244	tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
 245	tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
 246
 247	// Must allow anyone to request the RegionInfo data
 248	// so non-owners/non-gods can see the values. 
 249	// Therefore can't use an EstateOwnerMessage JC
 250	LLMessageSystem* msg = gMessageSystem;
 251	msg->newMessage("RequestRegionInfo");
 252	msg->nextBlock("AgentData");
 253	msg->addUUID("AgentID", gAgent.getID());
 254	msg->addUUID("SessionID", gAgent.getSessionID());
 255	gAgent.sendReliableMessage();
 256}
 257
 258// static
 259void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
 260{
 261	static LLDispatcher dispatch;
 262	LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
 263	if(!floater)
 264	{
 265		return;
 266	}
 267	
 268	if (!estate_dispatch_initialized)
 269	{
 270		LLPanelEstateInfo::initDispatch(dispatch);
 271	}
 272
 273	LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
 274	LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate");
 275
 276	// unpack the message
 277	std::string request;
 278	LLUUID invoice;
 279	LLDispatcher::sparam_t strings;
 280	LLDispatcher::unpackMessage(msg, request, invoice, strings);
 281	if(invoice != getLastInvoice())
 282	{
 283		llwarns << "Mismatched Estate message: " << request << llendl;
 284		return;
 285	}
 286
 287	//dispatch the message
 288	dispatch.dispatch(request, invoice, strings);
 289
 290	LLViewerRegion* region = gAgent.getRegion();
 291	panel->updateControls(region);
 292}
 293
 294
 295// static
 296void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 297{
 298	LLPanel* panel;
 299	LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
 300	if(!floater)
 301	{
 302		return;
 303	}
 304
 305	// We need to re-request environment setting here,
 306	// otherwise after we apply (send) updated region settings we won't get them back,
 307	// so our environment won't be updated.
 308	// This is also the way to know about externally changed region environment.
 309	LLEnvManagerNew::instance().requestRegionSettings();
 310	
 311	LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
 312
 313	LLViewerRegion* region = gAgent.getRegion();
 314	BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
 315
 316	// *TODO: Replace parsing msg with accessing the region info model.
 317	LLRegionInfoModel& region_info = LLRegionInfoModel::instance();
 318
 319	// extract message
 320	std::string sim_name;
 321	std::string sim_type = LLTrans::getString("land_type_unknown");
 322	U32 region_flags;
 323	U8 agent_limit;
 324	F32 object_bonus_factor;
 325	U8 sim_access;
 326	F32 water_height;
 327	F32 terrain_raise_limit;
 328	F32 terrain_lower_limit;
 329	BOOL use_estate_sun;
 330	F32 sun_hour;
 331	msg->getString("RegionInfo", "SimName", sim_name);
 332	msg->getU32("RegionInfo", "RegionFlags", region_flags);
 333	msg->getU8("RegionInfo", "MaxAgents", agent_limit);
 334	msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
 335	msg->getU8("RegionInfo", "SimAccess", sim_access);
 336	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
 337	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit);
 338	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit);
 339	msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun);
 340	// actually the "last set" sun hour, not the current sun hour. JC
 341	msg->getF32("RegionInfo", "SunHour", sun_hour);
 342	// the only reasonable way to decide if we actually have any data is to
 343	// check to see if any of these fields have nonzero sizes
 344	if (msg->getSize("RegionInfo2", "ProductSKU") > 0 ||
 345		msg->getSize("RegionInfo2", "ProductName") > 0)
 346	{
 347		msg->getString("RegionInfo2", "ProductName", sim_type);
 348		LLTrans::findString(sim_type, sim_type); // try localizing sim product name
 349	}
 350
 351	// GENERAL PANEL
 352	panel = tab->getChild<LLPanel>("General");
 353	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
 354	panel->getChild<LLUICtrl>("region_type")->setValue(LLSD(sim_type));
 355	panel->getChild<LLUICtrl>("version_channel_text")->setValue(gLastVersionChannel);
 356
 357	panel->getChild<LLUICtrl>("block_terraform_check")->setValue((region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE );
 358	panel->getChild<LLUICtrl>("block_fly_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE );
 359	panel->getChild<LLUICtrl>("allow_damage_check")->setValue((region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE );
 360	panel->getChild<LLUICtrl>("restrict_pushobject")->setValue((region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE );
 361	panel->getChild<LLUICtrl>("allow_land_resell_check")->setValue((region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE );
 362	panel->getChild<LLUICtrl>("allow_parcel_changes_check")->setValue((region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE );
 363	panel->getChild<LLUICtrl>("block_parcel_search_check")->setValue((region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE );
 364	panel->getChild<LLUICtrl>("agent_limit_spin")->setValue(LLSD((F32)agent_limit) );
 365	panel->getChild<LLUICtrl>("object_bonus_spin")->setValue(LLSD(object_bonus_factor) );
 366	panel->getChild<LLUICtrl>("access_combo")->setValue(LLSD(sim_access) );
 367
 368
 369 	// detect teen grid for maturity
 370
 371	U32 parent_estate_id;
 372	msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id);
 373	BOOL teen_grid = (parent_estate_id == 5);  // *TODO add field to estate table and test that
 374	panel->getChildView("access_combo")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid));
 375	panel->setCtrlsEnabled(allow_modify);
 376	
 377
 378	// DEBUG PANEL
 379	panel = tab->getChild<LLPanel>("Debug");
 380
 381	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name) );
 382	panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) );
 383	panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) );
 384	panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) );
 385	panel->setCtrlsEnabled(allow_modify);
 386
 387	// TERRAIN PANEL
 388	panel = tab->getChild<LLPanel>("Terrain");
 389
 390	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
 391	panel->getChild<LLUICtrl>("water_height_spin")->setValue(region_info.mWaterHeight);
 392	panel->getChild<LLUICtrl>("terrain_raise_spin")->setValue(region_info.mTerrainRaiseLimit);
 393	panel->getChild<LLUICtrl>("terrain_lower_spin")->setValue(region_info.mTerrainLowerLimit);
 394
 395	panel->setCtrlsEnabled(allow_modify);
 396
 397	floater->refreshFromRegion( gAgent.getRegion() );
 398}
 399
 400// static
 401LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate()
 402{
 403	LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
 404	if (!floater) return NULL;
 405	LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
 406	LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate");
 407	return panel;
 408}
 409
 410// static
 411LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant()
 412{
 413	LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
 414	if (!floater) return NULL;
 415	LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
 416	LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild<LLPanel>("Covenant");
 417	return panel;
 418}
 419
 420// static
 421LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain()
 422{
 423	LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
 424	if (!floater)
 425	{
 426		llassert(floater);
 427		return NULL;
 428	}
 429
 430	LLTabContainer* tab_container = floater->getChild<LLTabContainer>("region_panels");
 431	LLPanelRegionTerrainInfo* panel =
 432		dynamic_cast<LLPanelRegionTerrainInfo*>(tab_container->getChild<LLPanel>("Terrain"));
 433	llassert(panel);
 434	return panel;
 435}
 436
 437void LLFloaterRegionInfo::onTabSelected(const LLSD& param)
 438{
 439	LLPanel* active_panel = getChild<LLPanel>(param.asString());
 440	active_panel->onOpen(LLSD());
 441}
 442
 443void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region)
 444{
 445	if (!region)
 446	{
 447		return; 
 448	}
 449
 450	// call refresh from region on all panels
 451	std::for_each(
 452		mInfoPanels.begin(),
 453		mInfoPanels.end(),
 454		llbind2nd(
 455#if LL_WINDOWS
 456			std::mem_fun1(&LLPanelRegionInfo::refreshFromRegion),
 457#else
 458			std::mem_fun(&LLPanelRegionInfo::refreshFromRegion),
 459#endif
 460			region));
 461}
 462
 463// public
 464void LLFloaterRegionInfo::refresh()
 465{
 466	for(info_panels_t::iterator iter = mInfoPanels.begin();
 467		iter != mInfoPanels.end(); ++iter)
 468	{
 469		(*iter)->refresh();
 470	}
 471}
 472
 473
 474///----------------------------------------------------------------------------
 475/// Local class implementation
 476///----------------------------------------------------------------------------
 477
 478//
 479// LLPanelRegionInfo
 480//
 481
 482LLPanelRegionInfo::LLPanelRegionInfo()
 483	: LLPanel()
 484{
 485}
 486
 487void LLPanelRegionInfo::onBtnSet()
 488{
 489	if (sendUpdate())
 490	{
 491		disableButton("apply_btn");
 492	}
 493}
 494
 495void LLPanelRegionInfo::onChangeChildCtrl(LLUICtrl* ctrl)
 496{
 497	updateChild(ctrl); // virtual function
 498}
 499
 500// Enables the "set" button if it is not already enabled
 501void LLPanelRegionInfo::onChangeAnything()
 502{
 503	enableButton("apply_btn");
 504	refresh();
 505}
 506
 507// static
 508// Enables set button on change to line editor
 509void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data)
 510{
 511	LLPanelRegionInfo* panel = dynamic_cast<LLPanelRegionInfo*>(caller->getParent());
 512	if(panel)
 513	{
 514		panel->enableButton("apply_btn");
 515		panel->refresh();
 516	}
 517}
 518
 519
 520// virtual
 521BOOL LLPanelRegionInfo::postBuild()
 522{
 523	// If the panel has an Apply button, set a callback for it.
 524	LLUICtrl* apply_btn = findChild<LLUICtrl>("apply_btn");
 525	if (apply_btn)
 526	{
 527		apply_btn->setCommitCallback(boost::bind(&LLPanelRegionInfo::onBtnSet, this));
 528	}
 529
 530	refresh();
 531	return TRUE;
 532}
 533
 534// virtual 
 535void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr)
 536{
 537}
 538
 539// virtual
 540bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region)
 541{
 542	if (region) mHost = region->getHost();
 543	return true;
 544}
 545
 546void LLPanelRegionInfo::sendEstateOwnerMessage(
 547	LLMessageSystem* msg,
 548	const std::string& request,
 549	const LLUUID& invoice,
 550	const strings_t& strings)
 551{
 552	llinfos << "Sending estate request '" << request << "'" << llendl;
 553	msg->newMessage("EstateOwnerMessage");
 554	msg->nextBlockFast(_PREHASH_AgentData);
 555	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 556	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 557	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 558	msg->nextBlock("MethodData");
 559	msg->addString("Method", request);
 560	msg->addUUID("Invoice", invoice);
 561	if(strings.empty())
 562	{
 563		msg->nextBlock("ParamList");
 564		msg->addString("Parameter", NULL);
 565	}
 566	else
 567	{
 568		strings_t::const_iterator it = strings.begin();
 569		strings_t::const_iterator end = strings.end();
 570		for(; it != end; ++it)
 571		{
 572			msg->nextBlock("ParamList");
 573			msg->addString("Parameter", *it);
 574		}
 575	}
 576	msg->sendReliable(mHost);
 577}
 578
 579void LLPanelRegionInfo::enableButton(const std::string& btn_name, BOOL enable)
 580{
 581	LLView* button = findChildView(btn_name);
 582	if (button) button->setEnabled(enable);
 583}
 584
 585void LLPanelRegionInfo::disableButton(const std::string& btn_name)
 586{
 587	LLView* button = findChildView(btn_name);
 588	if (button) button->setEnabled(FALSE);
 589}
 590
 591void LLPanelRegionInfo::initCtrl(const std::string& name)
 592{
 593	getChild<LLUICtrl>(name)->setCommitCallback(boost::bind(&LLPanelRegionInfo::onChangeAnything, this));
 594}
 595
 596void LLPanelRegionInfo::onClickManageTelehub()
 597{
 598	LLFloaterReg::hideInstance("region_info");
 599	LLFloaterReg::showInstance("telehubs");
 600}
 601
 602/////////////////////////////////////////////////////////////////////////////
 603// LLPanelRegionGeneralInfo
 604//
 605bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)
 606{
 607	BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
 608	setCtrlsEnabled(allow_modify);
 609	getChildView("apply_btn")->setEnabled(FALSE);
 610	getChildView("access_text")->setEnabled(allow_modify);
 611	// getChildView("access_combo")->setEnabled(allow_modify);
 612	// now set in processRegionInfo for teen grid detection
 613	getChildView("kick_btn")->setEnabled(allow_modify);
 614	getChildView("kick_all_btn")->setEnabled(allow_modify);
 615	getChildView("im_btn")->setEnabled(allow_modify);
 616	getChildView("manage_telehub_btn")->setEnabled(allow_modify);
 617
 618	// Data gets filled in by processRegionInfo
 619
 620	return LLPanelRegionInfo::refreshFromRegion(region);
 621}
 622
 623BOOL LLPanelRegionGeneralInfo::postBuild()
 624{
 625	// Enable the "Apply" button if something is changed. JC
 626	initCtrl("block_terraform_check");
 627	initCtrl("block_fly_check");
 628	initCtrl("allow_damage_check");
 629	initCtrl("allow_land_resell_check");
 630	initCtrl("allow_parcel_changes_check");
 631	initCtrl("agent_limit_spin");
 632	initCtrl("object_bonus_spin");
 633	initCtrl("access_combo");
 634	initCtrl("restrict_pushobject");
 635	initCtrl("block_parcel_search_check");
 636
 637	childSetAction("kick_btn", boost::bind(&LLPanelRegionGeneralInfo::onClickKick, this));
 638	childSetAction("kick_all_btn", onClickKickAll, this);
 639	childSetAction("im_btn", onClickMessage, this);
 640//	childSetAction("manage_telehub_btn", onClickManageTelehub, this);
 641
 642	return LLPanelRegionInfo::postBuild();
 643}
 644
 645void LLPanelRegionGeneralInfo::onClickKick()
 646{
 647	llinfos << "LLPanelRegionGeneralInfo::onClickKick" << llendl;
 648
 649	// this depends on the grandparent view being a floater
 650	// in order to set up floater dependency
 651	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
 652	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE);
 653	parent_floater->addDependentFloater(child_floater);
 654}
 655
 656void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids)
 657{
 658	if (ids.empty()) return;
 659	if(ids[0].notNull())
 660	{
 661		strings_t strings;
 662		// [0] = our agent id
 663		// [1] = target agent id
 664		std::string buffer;
 665		gAgent.getID().toString(buffer);
 666		strings.push_back(buffer);
 667
 668		ids[0].toString(buffer);
 669		strings.push_back(strings_t::value_type(buffer));
 670
 671		LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 672		sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings);
 673	}
 674}
 675
 676// static
 677void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata)
 678{
 679	llinfos << "LLPanelRegionGeneralInfo::onClickKickAll" << llendl;
 680	LLNotificationsUtil::add("KickUsersFromRegion", 
 681									LLSD(), 
 682									LLSD(), 
 683									boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
 684}
 685
 686bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response)
 687{
 688	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 689	if (option == 0)
 690	{
 691		strings_t strings;
 692		// [0] = our agent id
 693		std::string buffer;
 694		gAgent.getID().toString(buffer);
 695		strings.push_back(buffer);
 696
 697		LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 698		// historical message name
 699		sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings);
 700	}
 701	return false;
 702}
 703
 704// static
 705void LLPanelRegionGeneralInfo::onClickMessage(void* userdata)
 706{
 707	llinfos << "LLPanelRegionGeneralInfo::onClickMessage" << llendl;
 708	LLNotificationsUtil::add("MessageRegion", 
 709		LLSD(), 
 710		LLSD(), 
 711		boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
 712}
 713
 714// static
 715bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response)
 716{
 717	if(LLNotificationsUtil::getSelectedOption(notification, response) != 0) return false;
 718
 719	std::string text = response["message"].asString();
 720	if (text.empty()) return false;
 721
 722	llinfos << "Message to everyone: " << text << llendl;
 723	strings_t strings;
 724	// [0] grid_x, unused here
 725	// [1] grid_y, unused here
 726	// [2] agent_id of sender
 727	// [3] sender name
 728	// [4] message
 729	strings.push_back("-1");
 730	strings.push_back("-1");
 731	std::string buffer;
 732	gAgent.getID().toString(buffer);
 733	strings.push_back(buffer);
 734	std::string name;
 735	LLAgentUI::buildFullname(name);
 736	strings.push_back(strings_t::value_type(name));
 737	strings.push_back(strings_t::value_type(text));
 738	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 739	sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings);
 740	return false;
 741}
 742
 743class ConsoleRequestResponder : public LLHTTPClient::Responder
 744{
 745public:
 746	/*virtual*/
 747	void error(U32 status, const std::string& reason)
 748	{
 749		llwarns << "requesting mesh_rez_enabled failed" << llendl;
 750	}
 751};
 752
 753
 754// called if this request times out.
 755class ConsoleUpdateResponder : public LLHTTPClient::Responder
 756{
 757public:
 758	/* virtual */
 759	void error(U32 status, const std::string& reason)
 760	{
 761		llwarns << "Updating mesh enabled region setting failed" << llendl;
 762	}
 763};
 764
 765void LLFloaterRegionInfo::requestMeshRezInfo()
 766{
 767	std::string sim_console_url = gAgent.getRegion()->getCapability("SimConsoleAsync");
 768
 769	if (!sim_console_url.empty())
 770	{
 771		std::string request_str = "get mesh_rez_enabled";
 772		
 773		LLHTTPClient::post(
 774			sim_console_url,
 775			LLSD(request_str),
 776			new ConsoleRequestResponder);
 777	}
 778}
 779
 780// setregioninfo
 781// strings[0] = 'Y' - block terraform, 'N' - not
 782// strings[1] = 'Y' - block fly, 'N' - not
 783// strings[2] = 'Y' - allow damage, 'N' - not
 784// strings[3] = 'Y' - allow land sale, 'N' - not
 785// strings[4] = agent limit
 786// strings[5] = object bonus
 787// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult)
 788// strings[7] = restrict pushobject
 789// strings[8] = 'Y' - allow parcel subdivide, 'N' - not
 790// strings[9] = 'Y' - block parcel search, 'N' - allow
 791BOOL LLPanelRegionGeneralInfo::sendUpdate()
 792{
 793	llinfos << "LLPanelRegionGeneralInfo::sendUpdate()" << llendl;
 794
 795	// First try using a Cap.  If that fails use the old method.
 796	LLSD body;
 797	std::string url = gAgent.getRegion()->getCapability("DispatchRegionInfo");
 798	if (!url.empty())
 799	{
 800		body["block_terraform"] = getChild<LLUICtrl>("block_terraform_check")->getValue();
 801		body["block_fly"] = getChild<LLUICtrl>("block_fly_check")->getValue();
 802		body["allow_damage"] = getChild<LLUICtrl>("allow_damage_check")->getValue();
 803		body["allow_land_resell"] = getChild<LLUICtrl>("allow_land_resell_check")->getValue();
 804		body["agent_limit"] = getChild<LLUICtrl>("agent_limit_spin")->getValue();
 805		body["prim_bonus"] = getChild<LLUICtrl>("object_bonus_spin")->getValue();
 806		body["sim_access"] = getChild<LLUICtrl>("access_combo")->getValue();
 807		body["restrict_pushobject"] = getChild<LLUICtrl>("restrict_pushobject")->getValue();
 808		body["allow_parcel_changes"] = getChild<LLUICtrl>("allow_parcel_changes_check")->getValue();
 809		body["block_parcel_search"] = getChild<LLUICtrl>("block_parcel_search_check")->getValue();
 810
 811		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
 812	}
 813	else
 814	{
 815		strings_t strings;
 816		std::string buffer;
 817
 818		buffer = llformat("%s", (getChild<LLUICtrl>("block_terraform_check")->getValue().asBoolean() ? "Y" : "N"));
 819		strings.push_back(strings_t::value_type(buffer));
 820
 821		buffer = llformat("%s", (getChild<LLUICtrl>("block_fly_check")->getValue().asBoolean() ? "Y" : "N"));
 822		strings.push_back(strings_t::value_type(buffer));
 823
 824		buffer = llformat("%s", (getChild<LLUICtrl>("allow_damage_check")->getValue().asBoolean() ? "Y" : "N"));
 825		strings.push_back(strings_t::value_type(buffer));
 826
 827		buffer = llformat("%s", (getChild<LLUICtrl>("allow_land_resell_check")->getValue().asBoolean() ? "Y" : "N"));
 828		strings.push_back(strings_t::value_type(buffer));
 829
 830		F32 value = (F32)getChild<LLUICtrl>("agent_limit_spin")->getValue().asReal();
 831		buffer = llformat("%f", value);
 832		strings.push_back(strings_t::value_type(buffer));
 833
 834		value = (F32)getChild<LLUICtrl>("object_bonus_spin")->getValue().asReal();
 835		buffer = llformat("%f", value);
 836		strings.push_back(strings_t::value_type(buffer));
 837
 838		buffer = llformat("%d", getChild<LLUICtrl>("access_combo")->getValue().asInteger());
 839		strings.push_back(strings_t::value_type(buffer));
 840
 841		buffer = llformat("%s", (getChild<LLUICtrl>("restrict_pushobject")->getValue().asBoolean() ? "Y" : "N"));
 842		strings.push_back(strings_t::value_type(buffer));
 843
 844		buffer = llformat("%s", (getChild<LLUICtrl>("allow_parcel_changes_check")->getValue().asBoolean() ? "Y" : "N"));
 845		strings.push_back(strings_t::value_type(buffer));
 846
 847		LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 848		sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings);
 849	}
 850
 851	// if we changed access levels, tell user about it
 852	LLViewerRegion* region = gAgent.getRegion();
 853	if (region && (getChild<LLUICtrl>("access_combo")->getValue().asInteger() != region->getSimAccess()) )
 854	{
 855		LLNotificationsUtil::add("RegionMaturityChange");
 856	}	
 857
 858	return TRUE;
 859}
 860
 861/////////////////////////////////////////////////////////////////////////////
 862// LLPanelRegionDebugInfo
 863/////////////////////////////////////////////////////////////////////////////
 864BOOL LLPanelRegionDebugInfo::postBuild()
 865{
 866	LLPanelRegionInfo::postBuild();
 867	initCtrl("disable_scripts_check");
 868	initCtrl("disable_collisions_check");
 869	initCtrl("disable_physics_check");
 870
 871	childSetAction("choose_avatar_btn", boost::bind(&LLPanelRegionDebugInfo::onClickChooseAvatar, this));
 872	childSetAction("return_btn", onClickReturn, this);
 873	childSetAction("top_colliders_btn", onClickTopColliders, this);
 874	childSetAction("top_scripts_btn", onClickTopScripts, this);
 875	childSetAction("restart_btn", onClickRestart, this);
 876	childSetAction("cancel_restart_btn", onClickCancelRestart, this);
 877
 878	return TRUE;
 879}
 880
 881// virtual
 882bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region)
 883{
 884	BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
 885	setCtrlsEnabled(allow_modify);
 886	getChildView("apply_btn")->setEnabled(FALSE);
 887	getChildView("target_avatar_name")->setEnabled(FALSE);
 888	
 889	getChildView("choose_avatar_btn")->setEnabled(allow_modify);
 890	getChildView("return_scripts")->setEnabled(allow_modify && !mTargetAvatar.isNull());
 891	getChildView("return_other_land")->setEnabled(allow_modify && !mTargetAvatar.isNull());
 892	getChildView("return_estate_wide")->setEnabled(allow_modify && !mTargetAvatar.isNull());
 893	getChildView("return_btn")->setEnabled(allow_modify && !mTargetAvatar.isNull());
 894	getChildView("top_colliders_btn")->setEnabled(allow_modify);
 895	getChildView("top_scripts_btn")->setEnabled(allow_modify);
 896	getChildView("restart_btn")->setEnabled(allow_modify);
 897	getChildView("cancel_restart_btn")->setEnabled(allow_modify);
 898
 899	return LLPanelRegionInfo::refreshFromRegion(region);
 900}
 901
 902// virtual
 903BOOL LLPanelRegionDebugInfo::sendUpdate()
 904{
 905	llinfos << "LLPanelRegionDebugInfo::sendUpdate" << llendl;
 906	strings_t strings;
 907	std::string buffer;
 908
 909	buffer = llformat("%s", (getChild<LLUICtrl>("disable_scripts_check")->getValue().asBoolean() ? "Y" : "N"));
 910	strings.push_back(buffer);
 911
 912	buffer = llformat("%s", (getChild<LLUICtrl>("disable_collisions_check")->getValue().asBoolean() ? "Y" : "N"));
 913	strings.push_back(buffer);
 914
 915	buffer = llformat("%s", (getChild<LLUICtrl>("disable_physics_check")->getValue().asBoolean() ? "Y" : "N"));
 916	strings.push_back(buffer);
 917
 918	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 919	sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings);
 920	return TRUE;
 921}
 922
 923void LLPanelRegionDebugInfo::onClickChooseAvatar()
 924{
 925	LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE);
 926}
 927
 928
 929void LLPanelRegionDebugInfo::callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
 930{
 931	if (ids.empty() || names.empty()) return;
 932	mTargetAvatar = ids[0];
 933	getChild<LLUICtrl>("target_avatar_name")->setValue(LLSD(names[0].getCompleteName()));
 934	refreshFromRegion( gAgent.getRegion() );
 935}
 936
 937// static
 938void LLPanelRegionDebugInfo::onClickReturn(void* data)
 939{
 940	LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;
 941	if (panelp->mTargetAvatar.isNull()) return;
 942
 943	LLSD args;
 944	args["USER_NAME"] = panelp->getChild<LLUICtrl>("target_avatar_name")->getValue().asString();
 945	LLSD payload;
 946	payload["avatar_id"] = panelp->mTargetAvatar;
 947	
 948	U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
 949
 950	if (panelp->getChild<LLUICtrl>("return_scripts")->getValue().asBoolean())
 951	{
 952		flags |= SWD_SCRIPTED_ONLY;
 953	}
 954	
 955	if (panelp->getChild<LLUICtrl>("return_other_land")->getValue().asBoolean())
 956	{
 957		flags |= SWD_OTHERS_LAND_ONLY;
 958	}
 959	payload["flags"] = int(flags);
 960	payload["return_estate_wide"] = panelp->getChild<LLUICtrl>("return_estate_wide")->getValue().asBoolean();
 961	LLNotificationsUtil::add("EstateObjectReturn", args, payload, 
 962									boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2));
 963}
 964
 965bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response)
 966{
 967	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 968	if (option != 0) return false;
 969
 970	LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID();
 971	if (!target_avatar.isNull())
 972	{
 973		U32 flags = notification["payload"]["flags"].asInteger();
 974		bool return_estate_wide = notification["payload"]["return_estate_wide"];
 975		if (return_estate_wide)
 976		{
 977			// send as estate message - routed by spaceserver to all regions in estate
 978			strings_t strings;
 979			strings.push_back(llformat("%d", flags));
 980			strings.push_back(target_avatar.asString());
 981
 982			LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 983		
 984			sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
 985		}
 986		else
 987		{
 988			// send to this simulator only
 989  			send_sim_wide_deletes(target_avatar, flags);
 990  		}
 991	}
 992	return false;
 993}
 994
 995
 996// static
 997void LLPanelRegionDebugInfo::onClickTopColliders(void* data)
 998{
 999	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
1000	strings_t strings;
1001	strings.push_back("1");	// one physics step
1002	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1003	LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
1004	if(!instance) return;
1005	LLFloaterReg::showInstance("top_objects");
1006	instance->clearList();
1007	self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings);
1008}
1009
1010// static
1011void LLPanelRegionDebugInfo::onClickTopScripts(void* data)
1012{
1013	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
1014	strings_t strings;
1015	strings.push_back("6");	// top 5 scripts
1016	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1017	LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
1018	if(!instance) return;
1019	LLFloaterReg::showInstance("top_objects");
1020	instance->clearList();
1021	self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings);
1022}
1023
1024// static
1025void LLPanelRegionDebugInfo::onClickRestart(void* data)
1026{
1027	LLNotificationsUtil::add("ConfirmRestart", LLSD(), LLSD(), 
1028		boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2));
1029}
1030
1031bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response)
1032{
1033	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1034	if (option != 0) return false;
1035
1036	strings_t strings;
1037	strings.push_back("120");
1038	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1039	sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
1040	return false;
1041}
1042
1043// static
1044void LLPanelRegionDebugInfo::onClickCancelRestart(void* data)
1045{
1046	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
1047	strings_t strings;
1048	strings.push_back("-1");
1049	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1050	self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
1051}
1052
1053
1054BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
1055{
1056	for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
1057	{
1058		std::string buffer;
1059		buffer = llformat("texture_detail_%d", i);
1060		LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(buffer);
1061		if (!texture_ctrl) continue;
1062
1063		LLUUID image_asset_id = texture_ctrl->getImageAssetID();
1064		LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id);
1065		S32 components = img->getComponents();
1066		// Must ask for highest resolution version's width. JC
1067		S32 width = img->getFullWidth();
1068		S32 height = img->getFullHeight();
1069
1070		//llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl;
1071
1072		if (components != 3)
1073		{
1074			LLSD args;
1075			args["TEXTURE_NUM"] = i+1;
1076			args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
1077			LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
1078			return FALSE;
1079		}
1080
1081		if (width > 512 || height > 512)
1082		{
1083
1084			LLSD args;
1085			args["TEXTURE_NUM"] = i+1;
1086			args["TEXTURE_SIZE_X"] = width;
1087			args["TEXTURE_SIZE_Y"] = height;
1088			LLNotificationsUtil::add("InvalidTerrainSize", args);
1089			return FALSE;
1090			
1091		}
1092	}
1093
1094	return TRUE;
1095}
1096
1097/////////////////////////////////////////////////////////////////////////////
1098// LLPanelRegionTerrainInfo
1099/////////////////////////////////////////////////////////////////////////////
1100// Initialize statics
1101
1102BOOL LLPanelRegionTerrainInfo::postBuild()
1103{
1104	LLPanelRegionInfo::postBuild();
1105	
1106	initCtrl("water_height_spin");
1107	initCtrl("terrain_raise_spin");
1108	initCtrl("terrain_lower_spin");
1109
1110	std::string buffer;
1111	for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
1112	{
1113		buffer = llformat("texture_detail_%d", i);
1114		initCtrl(buffer);
1115	}
1116
1117	for(S32 i = 0; i < CORNER_COUNT; ++i)
1118	{
1119		buffer = llformat("height_start_spin_%d", i);
1120		initCtrl(buffer);
1121		buffer = llformat("height_range_spin_%d", i);
1122		initCtrl(buffer);
1123	}
1124
1125	childSetAction("download_raw_btn", onClickDownloadRaw, this);
1126	childSetAction("upload_raw_btn", onClickUploadRaw, this);
1127	childSetAction("bake_terrain_btn", onClickBakeTerrain, this);
1128
1129	return LLPanelRegionInfo::postBuild();
1130}
1131
1132// virtual
1133bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
1134{
1135	BOOL owner_or_god = gAgent.isGodlike() 
1136						|| (region && (region->getOwner() == gAgent.getID()));
1137	BOOL owner_or_god_or_manager = owner_or_god
1138						|| (region && region->isEstateManager());
1139	setCtrlsEnabled(owner_or_god_or_manager);
1140
1141	getChildView("apply_btn")->setEnabled(FALSE);
1142
1143	if (region)
1144	{
1145		getChild<LLUICtrl>("region_text")->setValue(LLSD(region->getName()));
1146
1147		LLVLComposition* compp = region->getComposition();
1148		LLTextureCtrl* texture_ctrl;
1149		std::string buffer;
1150		for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
1151		{
1152			buffer = llformat("texture_detail_%d", i);
1153			texture_ctrl = getChild<LLTextureCtrl>(buffer);
1154			if(texture_ctrl)
1155			{
1156				lldebugs << "Detail Texture " << i << ": "
1157						 << compp->getDetailTextureID(i) << llendl;
1158				LLUUID tmp_id(compp->getDetailTextureID(i));
1159				texture_ctrl->setImageAssetID(tmp_id);
1160			}
1161		}
1162
1163		for(S32 i = 0; i < CORNER_COUNT; ++i)
1164    	{
1165			buffer = llformat("height_start_spin_%d", i);
1166			getChild<LLUICtrl>(buffer)->setValue(LLSD(compp->getStartHeight(i)));
1167			buffer = llformat("height_range_spin_%d", i);
1168			getChild<LLUICtrl>(buffer)->setValue(LLSD(compp->getHeightRange(i)));
1169		}
1170	}
1171	else
1172	{
1173		lldebugs << "no region set" << llendl;
1174		getChild<LLUICtrl>("region_text")->setValue(LLSD(""));
1175	}
1176
1177	getChildView("download_raw_btn")->setEnabled(owner_or_god);
1178	getChildView("upload_raw_btn")->setEnabled(owner_or_god);
1179	getChildView("bake_terrain_btn")->setEnabled(owner_or_god);
1180
1181	return LLPanelRegionInfo::refreshFromRegion(region);
1182}
1183
1184
1185// virtual
1186BOOL LLPanelRegionTerrainInfo::sendUpdate()
1187{
1188	llinfos << "LLPanelRegionTerrainInfo::sendUpdate" << llendl;
1189	std::string buffer;
1190	strings_t strings;
1191	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1192
1193	// update the model
1194	LLRegionInfoModel& region_info = LLRegionInfoModel::instance();
1195	region_info.mWaterHeight = (F32) getChild<LLUICtrl>("water_height_spin")->getValue().asReal();
1196	region_info.mTerrainRaiseLimit = (F32) getChild<LLUICtrl>("terrain_raise_spin")->getValue().asReal();
1197	region_info.mTerrainLowerLimit = (F32) getChild<LLUICtrl>("terrain_lower_spin")->getValue().asReal();
1198
1199	// and sync the region with it
1200	region_info.sendRegionTerrain(invoice);
1201	
1202	// =======================================
1203	// Assemble and send texturedetail message
1204
1205	// Make sure user hasn't chosen wacky textures.
1206	if (!validateTextureSizes())
1207	{
1208		return FALSE;
1209	}
1210
1211	LLTextureCtrl* texture_ctrl;
1212	std::string id_str;
1213	LLMessageSystem* msg = gMessageSystem;
1214
1215	for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
1216	{
1217		buffer = llformat("texture_detail_%d", i);
1218		texture_ctrl = getChild<LLTextureCtrl>(buffer);
1219		if(texture_ctrl)
1220		{
1221			LLUUID tmp_id(texture_ctrl->getImageAssetID());
1222			tmp_id.toString(id_str);
1223			buffer = llformat("%d %s", i, id_str.c_str());
1224			strings.push_back(buffer);
1225		}
1226	}
1227	sendEstateOwnerMessage(msg, "texturedetail", invoice, strings);
1228	strings.clear();
1229
1230	// ========================================
1231	// Assemble and send textureheights message
1232
1233	for(S32 i = 0; i < CORNER_COUNT; ++i)
1234	{
1235		buffer = llformat("height_start_spin_%d", i);
1236		std::string buffer2 = llformat("height_range_spin_%d", i);
1237		std::string buffer3 = llformat("%d %f %f", i, (F32)getChild<LLUICtrl>(buffer)->getValue().asReal(), (F32)getChild<LLUICtrl>(buffer2)->getValue().asReal());
1238		strings.push_back(buffer3);
1239	}
1240	sendEstateOwnerMessage(msg, "textureheights", invoice, strings);
1241	strings.clear();
1242
1243	// ========================================
1244	// Send texturecommit message
1245
1246	sendEstateOwnerMessage(msg, "texturecommit", invoice, strings);
1247
1248	return TRUE;
1249}
1250
1251// static
1252void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data)
1253{
1254	LLFilePicker& picker = LLFilePicker::instance();
1255	if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw"))
1256	{
1257		llwarns << "No file" << llendl;
1258		return;
1259	}
1260	std::string filepath = picker.getFirstFile();
1261	gXferManager->expectFileForRequest(filepath);
1262
1263	LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
1264	strings_t strings;
1265	strings.push_back("download filename");
1266	strings.push_back(filepath);
1267	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1268	self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
1269}
1270
1271// static
1272void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data)
1273{
1274	LLFilePicker& picker = LLFilePicker::instance();
1275	if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW))
1276	{
1277		llwarns << "No file" << llendl;
1278		return;
1279	}
1280	std::string filepath = picker.getFirstFile();
1281	gXferManager->expectFileForTransfer(filepath);
1282
1283	LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
1284	strings_t strings;
1285	strings.push_back("upload filename");
1286	strings.push_back(filepath);
1287	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1288	self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
1289
1290	LLNotificationsUtil::add("RawUploadStarted");
1291}
1292
1293// static
1294void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data)
1295{
1296	LLNotificationsUtil::add("ConfirmBakeTerrain", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2));
1297}
1298
1299bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response)
1300{
1301	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1302	if (option != 0) return false;
1303
1304	strings_t strings;
1305	strings.push_back("bake");
1306	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
1307	sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
1308
1309	return false;
1310}
1311
1312/////////////////////////////////////////////////////////////////////////////
1313// LLPanelEstateInfo
1314//
1315
1316LLPanelEstateInfo::LLPanelEstateInfo() 
1317:	LLPanelRegionInfo(),
1318	mEstateID(0)	// invalid
1319{
1320	LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
1321	estate_info.setCommitCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
1322	estate_info.setUpdateCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
1323}
1324
1325// static
1326void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch)
1327{
1328	std::string name;
1329
1330//	name.assign("setowner");
1331//	static LLDispatchSetEstateOwner set_owner;
1332//	dispatch.addHandler(name, &set_owner);
1333
1334	name.assign("estateupdateinfo");
1335	static LLDispatchEstateUpdateInfo estate_update_info;
1336	dispatch.addHandler(name, &estate_update_info);
1337
1338	name.assign("setaccess");
1339	static LLDispatchSetEstateAccess set_access;
1340	dispatch.addHandler(name, &set_access);
1341
1342	estate_dispatch_initialized = true;
1343}
1344
1345//---------------------------------------------------------------------------
1346// Add/Remove estate access button callbacks
1347//---------------------------------------------------------------------------
1348void LLPanelEstateInfo::onClickAddAllowedAgent()
1349{
1350	LLCtrlListInterface *list = childGetListInterface("allowed_avatar_name_list");
1351	if (!list) return;
1352	if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
1353	{
1354		//args
1355
1356		LLSD args;
1357		args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
1358		LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args);
1359		return;
1360	}
1361	accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd");
1362}
1363
1364void LLPanelEstateInfo::onClickRemoveAllowedAgent()
1365{
1366	accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list");
1367}
1368
1369void LLPanelEstateInfo::onClickAddAllowedGroup()
1370{
1371	LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list");
1372	if (!list) return;
1373	if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
1374	{
1375		LLSD args;
1376		args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
1377		LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args);
1378		return;
1379	}
1380
1381	LLNotification::Params params("ChangeLindenAccess");
1382	params.functor.function(boost::bind(&LLPanelEstateInfo::addAllowedGroup, this, _1, _2));
1383	if (isLindenEstate())
1384	{
1385		LLNotifications::instance().add(params);
1386	}
1387	else
1388	{
1389		LLNotifications::instance().forceResponse(params, 0);
1390	}
1391}
1392
1393bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response)
1394{
1395	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1396	if (option != 0) return false;
1397
1398	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
1399
1400	LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
1401	if (widget)
1402	{
1403		widget->removeNoneOption();
1404		widget->setSelectGroupCallback(boost::bind(&LLPanelEstateInfo::addAllowedGroup2, this, _1));
1405		if (parent_floater)
1406		{
1407			LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
1408			widget->setOrigin(new_rect.mLeft, new_rect.mBottom);
1409			parent_floater->addDependentFloater(widget);
1410		}
1411	}
1412
1413	return false;
1414}
1415
1416void LLPanelEstateInfo::onClickRemoveAllowedGroup()
1417{
1418	accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list");
1419}
1420
1421void LLPanelEstateInfo::onClickAddBannedAgent()
1422{
1423	LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list");
1424	if (!list) return;
1425	if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
1426	{
1427		LLSD args;
1428		args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
1429		LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args);
1430		return;
1431	}
1432	accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd");
1433}
1434
1435void LLPanelEstateInfo::onClickRemoveBannedAgent()
1436{
1437	accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list");
1438}
1439
1440// static
1441void LLPanelEstateInfo::onClickAddEstateManager()
1442{
1443	LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list");
1444	if (!list) return;
1445	if (list->getItemCount() >= ESTATE_MAX_MANAGERS)
1446	{	// Tell user they can't add more managers
1447		LLSD args;
1448		args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS);
1449		LLNotificationsUtil::add("MaxManagersOnRegion", args);
1450	}
1451	else
1452	{	// Go pick managers to add
1453		accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd");
1454	}
1455}
1456
1457// static
1458void LLPanelEstateInfo::onClickRemoveEstateManager()
1459{
1460	accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list");
1461}
1462
1463//---------------------------------------------------------------------------
1464// Kick from estate methods
1465//---------------------------------------------------------------------------
1466
1467void LLPanelEstateInfo::onClickKickUser()
1468{
1469	// this depends on the grandparent view being a floater
1470	// in order to set up floater dependency
1471	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
1472	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE);
1473	parent_floater->addDependentFloater(child_floater);
1474}
1475
1476void LLPanelEstateInfo::onKickUserCommit(const uuid_vec_t& ids)
1477{
1478	if (ids.empty()) return;
1479	
1480	//Bring up a confirmation dialog
1481	LLSD args;
1482	args["EVIL_USER"] = LLSLURL("agent", ids[0], "completename").getSLURLString();
1483	LLSD payload;
1484	payload["agent_id"] = ids[0];
1485	LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, this, _1, _2));
1486
1487}
1488
1489bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response)
1490{
1491	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1492	switch(option)
1493	{
1494	case 0:
1495		{
1496			//Kick User
1497			strings_t strings;
1498			strings.push_back(notification["payload"]["agent_id"].asString());
1499
1500			sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings);
1501			break;
1502		}
1503	default:
1504		break;
1505	}
1506	return false;
1507}
1508
1509//---------------------------------------------------------------------------
1510// Core Add/Remove estate access methods
1511// TODO: INTERNATIONAL: don't build message text here;
1512// instead, create multiple translatable messages and choose
1513// one based on the status.
1514//---------------------------------------------------------------------------
1515std::string all_estates_text()
1516{
1517	LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
1518	if (!panel) return "(" + LLTrans::getString("RegionInfoError") + ")";
1519
1520	LLStringUtil::format_map_t args;
1521	std::string owner = panel->getOwnerName();
1522
1523	LLViewerRegion* region = gAgent.getRegion();
1524	if (gAgent.isGodlike())
1525	{
1526		args["[OWNER]"] = owner.c_str();
1527		return LLTrans::getString("RegionInfoAllEstatesOwnedBy", args);
1528	}
1529	else if (region && region->getOwner() == gAgent.getID())
1530	{
1531		return LLTrans::getString("RegionInfoAllEstatesYouOwn");
1532	}
1533	else if (region && region->isEstateManager())
1534	{
1535		args["[OWNER]"] = owner.c_str();
1536		return LLTrans::getString("RegionInfoAllEstatesYouManage", args);
1537	}
1538	else
1539	{
1540		return "(" + LLTrans::getString("RegionInfoError") + ")";
1541	}
1542}
1543
1544// static
1545bool LLPanelEstateInfo::isLindenEstate()
1546{
1547	U32 estate_id = LLEstateInfoModel::instance().getID();
1548	return (estate_id <= ESTATE_LAST_LINDEN);
1549}
1550
1551struct LLEstateAccessChangeInfo
1552{
1553	LLEstateAccessChangeInfo(const LLSD& sd)
1554	{
1555		mDialogName = sd["dialog_name"].asString();
1556		mOperationFlag = (U32)sd["operation"].asInteger();
1557		LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray();
1558		for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray();
1559			id_it != end_it;
1560			++id_it)
1561		{
1562			mAgentOrGroupIDs.push_back(id_it->asUUID());
1563		}
1564	}
1565
1566	const LLSD asLLSD() const
1567	{
1568		LLSD sd;
1569		sd["name"] = mDialogName;
1570		sd["operation"] = (S32)mOperationFlag;
1571		for (uuid_vec_t::const_iterator it = mAgentOrGroupIDs.begin();
1572			it != mAgentOrGroupIDs.end();
1573			++it)

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