PageRenderTime 220ms CodeModel.GetById 31ms app.highlight 168ms RepoModel.GetById 1ms app.codeStats 2ms

/indra/newview/llfloatertools.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1930 lines | 1471 code | 274 blank | 185 comment | 296 complexity | 070352a9ccc929d05d8b6459d20b9a0a MD5 | raw file

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

   1/** 
   2 * @file llfloatertools.cpp
   3 * @brief The edit tools, including move, position, land, etc.
   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 "llfloatertools.h"
  30
  31#include "llfontgl.h"
  32#include "llcoord.h"
  33//#include "llgl.h"
  34
  35#include "llagent.h"
  36#include "llagentcamera.h"
  37#include "llbutton.h"
  38#include "llcheckboxctrl.h"
  39#include "lldraghandle.h"
  40#include "llerror.h"
  41#include "llfloaterbuildoptions.h"
  42#include "llfloatermediasettings.h"
  43#include "llfloateropenobject.h"
  44#include "llfloaterobjectweights.h"
  45#include "llfloaterreg.h"
  46#include "llfocusmgr.h"
  47#include "llmediaentry.h"
  48#include "llmediactrl.h"
  49#include "llmenugl.h"
  50#include "llnotificationsutil.h"
  51#include "llpanelcontents.h"
  52#include "llpanelface.h"
  53#include "llpanelland.h"
  54#include "llpanelobjectinventory.h"
  55#include "llpanelobject.h"
  56#include "llpanelvolume.h"
  57#include "llpanelpermissions.h"
  58#include "llparcel.h"
  59#include "llradiogroup.h"
  60#include "llresmgr.h"
  61#include "llselectmgr.h"
  62#include "llslider.h"
  63#include "llstatusbar.h"
  64#include "lltabcontainer.h"
  65#include "lltextbox.h"
  66#include "lltoolbrush.h"
  67#include "lltoolcomp.h"
  68#include "lltooldraganddrop.h"
  69#include "lltoolface.h"
  70#include "lltoolfocus.h"
  71#include "lltoolgrab.h"
  72#include "lltoolgrab.h"
  73#include "lltoolindividual.h"
  74#include "lltoolmgr.h"
  75#include "lltoolpie.h"
  76#include "lltoolpipette.h"
  77#include "lltoolplacer.h"
  78#include "lltoolselectland.h"
  79#include "lltrans.h"
  80#include "llui.h"
  81#include "llviewercontrol.h"
  82#include "llviewerjoystick.h"
  83#include "llviewerregion.h"
  84#include "llviewermenu.h"
  85#include "llviewerparcelmgr.h"
  86#include "llviewerwindow.h"
  87#include "llvovolume.h"
  88#include "lluictrlfactory.h"
  89#include "llmeshrepository.h"
  90
  91// Globals
  92LLFloaterTools *gFloaterTools = NULL;
  93bool LLFloaterTools::sShowObjectCost = true;
  94
  95const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
  96{
  97	std::string("General"), 	// PANEL_GENERAL,
  98	std::string("Object"), 	// PANEL_OBJECT,
  99	std::string("Features"),	// PANEL_FEATURES,
 100	std::string("Texture"),	// PANEL_FACE,
 101	std::string("Content"),	// PANEL_CONTENTS,
 102};
 103
 104
 105// Local prototypes
 106void commit_select_component(void *data);
 107void click_show_more(void*);
 108void click_popup_info(void*);
 109void click_popup_done(void*);
 110void click_popup_minimize(void*);
 111void click_popup_rotate_left(void*);
 112void click_popup_rotate_reset(void*);
 113void click_popup_rotate_right(void*);
 114void commit_slider_dozer_force(LLUICtrl *);
 115void click_apply_to_selection(void*);
 116void commit_radio_group_focus(LLUICtrl* ctrl);
 117void commit_radio_group_move(LLUICtrl* ctrl);
 118void commit_radio_group_edit(LLUICtrl* ctrl);
 119void commit_radio_group_land(LLUICtrl* ctrl);
 120void commit_slider_zoom(LLUICtrl *ctrl);
 121
 122/**
 123 * Class LLLandImpactsObserver
 124 *
 125 * An observer class to monitor parcel selection and update
 126 * the land impacts data from a parcel containing the selected object.
 127 */
 128class LLLandImpactsObserver : public LLParcelObserver
 129{
 130public:
 131	virtual void changed()
 132	{
 133		LLFloaterTools* tools_floater = LLFloaterReg::getTypedInstance<LLFloaterTools>("build");
 134		if(tools_floater)
 135		{
 136			tools_floater->updateLandImpacts();
 137		}
 138	}
 139};
 140
 141//static
 142void*	LLFloaterTools::createPanelPermissions(void* data)
 143{
 144	LLFloaterTools* floater = (LLFloaterTools*)data;
 145	floater->mPanelPermissions = new LLPanelPermissions();
 146	return floater->mPanelPermissions;
 147}
 148//static
 149void*	LLFloaterTools::createPanelObject(void* data)
 150{
 151	LLFloaterTools* floater = (LLFloaterTools*)data;
 152	floater->mPanelObject = new LLPanelObject();
 153	return floater->mPanelObject;
 154}
 155
 156//static
 157void*	LLFloaterTools::createPanelVolume(void* data)
 158{
 159	LLFloaterTools* floater = (LLFloaterTools*)data;
 160	floater->mPanelVolume = new LLPanelVolume();
 161	return floater->mPanelVolume;
 162}
 163
 164//static
 165void*	LLFloaterTools::createPanelFace(void* data)
 166{
 167	LLFloaterTools* floater = (LLFloaterTools*)data;
 168	floater->mPanelFace = new LLPanelFace();
 169	return floater->mPanelFace;
 170}
 171
 172//static
 173void*	LLFloaterTools::createPanelContents(void* data)
 174{
 175	LLFloaterTools* floater = (LLFloaterTools*)data;
 176	floater->mPanelContents = new LLPanelContents();
 177	return floater->mPanelContents;
 178}
 179
 180//static
 181void*	LLFloaterTools::createPanelLandInfo(void* data)
 182{
 183	LLFloaterTools* floater = (LLFloaterTools*)data;
 184	floater->mPanelLandInfo = new LLPanelLandInfo();
 185	return floater->mPanelLandInfo;
 186}
 187
 188static	const std::string	toolNames[]={
 189	"ToolCube",
 190	"ToolPrism",
 191	"ToolPyramid",
 192	"ToolTetrahedron",
 193	"ToolCylinder",
 194	"ToolHemiCylinder",
 195	"ToolCone",
 196	"ToolHemiCone",
 197	"ToolSphere",
 198	"ToolHemiSphere",
 199	"ToolTorus",
 200	"ToolTube",
 201	"ToolRing",
 202	"ToolTree",
 203	"ToolGrass"};
 204LLPCode toolData[]={
 205	LL_PCODE_CUBE,
 206	LL_PCODE_PRISM,
 207	LL_PCODE_PYRAMID,
 208	LL_PCODE_TETRAHEDRON,
 209	LL_PCODE_CYLINDER,
 210	LL_PCODE_CYLINDER_HEMI,
 211	LL_PCODE_CONE,
 212	LL_PCODE_CONE_HEMI,
 213	LL_PCODE_SPHERE,
 214	LL_PCODE_SPHERE_HEMI,
 215	LL_PCODE_TORUS,
 216	LLViewerObject::LL_VO_SQUARE_TORUS,
 217	LLViewerObject::LL_VO_TRIANGLE_TORUS,
 218	LL_PCODE_LEGACY_TREE,
 219	LL_PCODE_LEGACY_GRASS};
 220
 221BOOL	LLFloaterTools::postBuild()
 222{	
 223	// Hide until tool selected
 224	setVisible(FALSE);
 225
 226	// Since we constantly show and hide this during drags, don't
 227	// make sounds on visibility changes.
 228	setSoundFlags(LLView::SILENT);
 229
 230	getDragHandle()->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") );
 231
 232	LLRect rect;
 233	mBtnFocus			= getChild<LLButton>("button focus");//btn;
 234	mBtnMove			= getChild<LLButton>("button move");
 235	mBtnEdit			= getChild<LLButton>("button edit");
 236	mBtnCreate			= getChild<LLButton>("button create");
 237	mBtnLand			= getChild<LLButton>("button land" );
 238	mTextStatus			= getChild<LLTextBox>("text status");
 239	mRadioGroupFocus	= getChild<LLRadioGroup>("focus_radio_group");
 240	mRadioGroupMove		= getChild<LLRadioGroup>("move_radio_group");
 241	mRadioGroupEdit		= getChild<LLRadioGroup>("edit_radio_group");
 242	mBtnGridOptions		= getChild<LLButton>("Options...");
 243	mTitleMedia			= getChild<LLMediaCtrl>("title_media");
 244	mBtnLink			= getChild<LLButton>("link_btn");
 245	mBtnUnlink			= getChild<LLButton>("unlink_btn");
 246	
 247	mCheckSelectIndividual	= getChild<LLCheckBoxCtrl>("checkbox edit linked parts");	
 248	getChild<LLUICtrl>("checkbox edit linked parts")->setValue((BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
 249	mCheckSnapToGrid		= getChild<LLCheckBoxCtrl>("checkbox snap to grid");
 250	getChild<LLUICtrl>("checkbox snap to grid")->setValue((BOOL)gSavedSettings.getBOOL("SnapEnabled"));
 251	mCheckStretchUniform	= getChild<LLCheckBoxCtrl>("checkbox uniform");
 252	getChild<LLUICtrl>("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform"));
 253	mCheckStretchTexture	= getChild<LLCheckBoxCtrl>("checkbox stretch textures");
 254	getChild<LLUICtrl>("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
 255	mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label");
 256
 257	//
 258	// Create Buttons
 259	//
 260
 261	for(size_t t=0; t<LL_ARRAY_SIZE(toolNames); ++t)
 262	{
 263		LLButton *found = getChild<LLButton>(toolNames[t]);
 264		if(found)
 265		{
 266			found->setClickedCallback(boost::bind(&LLFloaterTools::setObjectType, toolData[t]));
 267			mButtons.push_back( found );
 268		}else{
 269			llwarns << "Tool button not found! DOA Pending." << llendl;
 270		}
 271	}
 272	mCheckCopySelection = getChild<LLCheckBoxCtrl>("checkbox copy selection");
 273	getChild<LLUICtrl>("checkbox copy selection")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopySelection"));
 274	mCheckSticky = getChild<LLCheckBoxCtrl>("checkbox sticky");
 275	getChild<LLUICtrl>("checkbox sticky")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolKeepSelected"));
 276	mCheckCopyCenters = getChild<LLCheckBoxCtrl>("checkbox copy centers");
 277	getChild<LLUICtrl>("checkbox copy centers")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopyCenters"));
 278	mCheckCopyRotates = getChild<LLCheckBoxCtrl>("checkbox copy rotates");
 279	getChild<LLUICtrl>("checkbox copy rotates")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
 280
 281	mRadioGroupLand			= getChild<LLRadioGroup>("land_radio_group");
 282	mBtnApplyToSelection	= getChild<LLButton>("button apply to selection");
 283	mSliderDozerSize		= getChild<LLSlider>("slider brush size");
 284	getChild<LLUICtrl>("slider brush size")->setValue(gSavedSettings.getF32("LandBrushSize"));
 285	mSliderDozerForce		= getChild<LLSlider>("slider force");
 286	// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
 287	getChild<LLUICtrl>("slider force")->setValue(log10(gSavedSettings.getF32("LandBrushForce")));
 288
 289	mCostTextBorder = getChild<LLViewBorder>("cost_text_border");
 290
 291	mTab = getChild<LLTabContainer>("Object Info Tabs");
 292	if(mTab)
 293	{
 294		mTab->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
 295		mTab->setBorderVisible(FALSE);
 296		mTab->selectFirstTab();
 297	}
 298
 299	mStatusText["rotate"] = getString("status_rotate");
 300	mStatusText["scale"] = getString("status_scale");
 301	mStatusText["move"] = getString("status_move");
 302	mStatusText["modifyland"] = getString("status_modifyland");
 303	mStatusText["camera"] = getString("status_camera");
 304	mStatusText["grab"] = getString("status_grab");
 305	mStatusText["place"] = getString("status_place");
 306	mStatusText["selectland"] = getString("status_selectland");
 307
 308	sShowObjectCost = gSavedSettings.getBOOL("ShowObjectRenderingCost");
 309	
 310	return TRUE;
 311}
 312
 313// Create the popupview with a dummy center.  It will be moved into place
 314// during LLViewerWindow's per-frame hover processing.
 315LLFloaterTools::LLFloaterTools(const LLSD& key)
 316:	LLFloater(key),
 317	mBtnFocus(NULL),
 318	mBtnMove(NULL),
 319	mBtnEdit(NULL),
 320	mBtnCreate(NULL),
 321	mBtnLand(NULL),
 322	mTextStatus(NULL),
 323
 324	mRadioGroupFocus(NULL),
 325	mRadioGroupMove(NULL),
 326	mRadioGroupEdit(NULL),
 327
 328	mCheckSelectIndividual(NULL),
 329
 330	mCheckSnapToGrid(NULL),
 331	mBtnGridOptions(NULL),
 332	mTitleMedia(NULL),
 333	mCheckStretchUniform(NULL),
 334	mCheckStretchTexture(NULL),
 335	mCheckStretchUniformLabel(NULL),
 336
 337	mBtnRotateLeft(NULL),
 338	mBtnRotateReset(NULL),
 339	mBtnRotateRight(NULL),
 340
 341	mBtnLink(NULL),
 342	mBtnUnlink(NULL),
 343
 344	mBtnDelete(NULL),
 345	mBtnDuplicate(NULL),
 346	mBtnDuplicateInPlace(NULL),
 347
 348	mCheckSticky(NULL),
 349	mCheckCopySelection(NULL),
 350	mCheckCopyCenters(NULL),
 351	mCheckCopyRotates(NULL),
 352	mRadioGroupLand(NULL),
 353	mSliderDozerSize(NULL),
 354	mSliderDozerForce(NULL),
 355	mBtnApplyToSelection(NULL),
 356
 357	mTab(NULL),
 358	mPanelPermissions(NULL),
 359	mPanelObject(NULL),
 360	mPanelVolume(NULL),
 361	mPanelContents(NULL),
 362	mPanelFace(NULL),
 363	mPanelLandInfo(NULL),
 364
 365	mCostTextBorder(NULL),
 366	mTabLand(NULL),
 367
 368	mLandImpactsObserver(NULL),
 369
 370	mDirty(TRUE),
 371	mNeedMediaTitle(TRUE)
 372{
 373	gFloaterTools = this;
 374
 375	setAutoFocus(FALSE);
 376	mFactoryMap["General"] = LLCallbackMap(createPanelPermissions, this);//LLPanelPermissions
 377	mFactoryMap["Object"] = LLCallbackMap(createPanelObject, this);//LLPanelObject
 378	mFactoryMap["Features"] = LLCallbackMap(createPanelVolume, this);//LLPanelVolume
 379	mFactoryMap["Texture"] = LLCallbackMap(createPanelFace, this);//LLPanelFace
 380	mFactoryMap["Contents"] = LLCallbackMap(createPanelContents, this);//LLPanelContents
 381	mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
 382	
 383	mCommitCallbackRegistrar.add("BuildTool.setTool",			boost::bind(&LLFloaterTools::setTool,this, _2));
 384	mCommitCallbackRegistrar.add("BuildTool.commitZoom",		boost::bind(&commit_slider_zoom, _1));
 385	mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus",	boost::bind(&commit_radio_group_focus, _1));
 386	mCommitCallbackRegistrar.add("BuildTool.commitRadioMove",	boost::bind(&commit_radio_group_move,_1));
 387	mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit",	boost::bind(&commit_radio_group_edit,_1));
 388
 389	mCommitCallbackRegistrar.add("BuildTool.selectComponent",	boost::bind(&commit_select_component, this));
 390	mCommitCallbackRegistrar.add("BuildTool.gridOptions",		boost::bind(&LLFloaterTools::onClickGridOptions,this));
 391	mCommitCallbackRegistrar.add("BuildTool.applyToSelection",	boost::bind(&click_apply_to_selection, this));
 392	mCommitCallbackRegistrar.add("BuildTool.commitRadioLand",	boost::bind(&commit_radio_group_land,_1));
 393	mCommitCallbackRegistrar.add("BuildTool.LandBrushForce",	boost::bind(&commit_slider_dozer_force,_1));
 394	mCommitCallbackRegistrar.add("BuildTool.AddMedia",			boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
 395	mCommitCallbackRegistrar.add("BuildTool.DeleteMedia",		boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
 396	mCommitCallbackRegistrar.add("BuildTool.EditMedia",			boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
 397
 398	mCommitCallbackRegistrar.add("BuildTool.LinkObjects",		boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
 399	mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects",		boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
 400
 401	mLandImpactsObserver = new LLLandImpactsObserver();
 402	LLViewerParcelMgr::getInstance()->addObserver(mLandImpactsObserver);
 403}
 404
 405LLFloaterTools::~LLFloaterTools()
 406{
 407	// children automatically deleted
 408	gFloaterTools = NULL;
 409
 410	LLViewerParcelMgr::getInstance()->removeObserver(mLandImpactsObserver);
 411	delete mLandImpactsObserver;
 412}
 413
 414void LLFloaterTools::setStatusText(const std::string& text)
 415{
 416	std::map<std::string, std::string>::iterator iter = mStatusText.find(text);
 417	if (iter != mStatusText.end())
 418	{
 419		mTextStatus->setText(iter->second);
 420	}
 421	else
 422	{
 423		mTextStatus->setText(text);
 424	}
 425}
 426
 427void LLFloaterTools::refresh()
 428{
 429	const S32 INFO_WIDTH = getRect().getWidth();
 430	const S32 INFO_HEIGHT = 384;
 431	LLRect object_info_rect(0, 0, INFO_WIDTH, -INFO_HEIGHT);
 432	BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
 433
 434	S32 idx_features = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_FEATURES]);
 435	S32 idx_face = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_FACE]);
 436	S32 idx_contents = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_CONTENTS]);
 437
 438	S32 selected_index = mTab->getCurrentPanelIndex();
 439
 440	if (!all_volume && (selected_index == idx_features || selected_index == idx_face ||
 441		selected_index == idx_contents))
 442	{
 443		mTab->selectFirstTab();
 444	}
 445
 446	mTab->enableTabButton(idx_features, all_volume);
 447	mTab->enableTabButton(idx_face, all_volume);
 448	mTab->enableTabButton(idx_contents, all_volume);
 449
 450	// Refresh object and prim count labels
 451	LLLocale locale(LLLocale::USER_LOCALE);
 452#if 0
 453	if (!gMeshRepo.meshRezEnabled())
 454	{		
 455		std::string obj_count_string;
 456		LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount());
 457		getChild<LLUICtrl>("selection_count")->setTextArg("[OBJ_COUNT]", obj_count_string);
 458		std::string prim_count_string;
 459		LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount());
 460		getChild<LLUICtrl>("selection_count")->setTextArg("[PRIM_COUNT]", prim_count_string);
 461
 462		// calculate selection rendering cost
 463		if (sShowObjectCost)
 464		{
 465			std::string prim_cost_string;
 466			S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
 467			LLResMgr::getInstance()->getIntegerString(prim_cost_string, render_cost);
 468			getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string);
 469		}
 470		
 471		// disable the object and prim counts if nothing selected
 472		bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty();
 473		getChildView("obj_count")->setEnabled(have_selection);
 474		getChildView("prim_count")->setEnabled(have_selection);
 475		getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost);
 476	}
 477	else
 478#endif
 479	{
 480		F32 link_cost  = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
 481		S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
 482
 483		LLCrossParcelFunctor func;
 484		if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
 485		{
 486			// Selection crosses parcel bounds.
 487			// We don't display remaining land capacity in this case.
 488			const LLStringExplicit empty_str("");
 489			childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str);
 490		}
 491		else
 492		{
 493			LLViewerObject* selected_object = mObjectSelection->getFirstObject();
 494			if (selected_object)
 495			{
 496				// Select a parcel at the currently selected object's position.
 497				LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
 498			}
 499			else
 500			{
 501				llwarns << "Failed to get selected object" << llendl;
 502			}
 503		}
 504
 505		LLStringUtil::format_map_t selection_args;
 506		selection_args["OBJ_COUNT"] = llformat("%.1d", link_count);
 507		selection_args["LAND_IMPACT"] = llformat("%.1d", (S32)link_cost);
 508
 509		std::ostringstream selection_info;
 510
 511		selection_info << getString("status_selectcount", selection_args);
 512
 513		getChild<LLTextBox>("selection_count")->setText(selection_info.str());
 514
 515		bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
 516		childSetVisible("selection_count",  have_selection);
 517		childSetVisible("remaining_capacity", have_selection);
 518		childSetVisible("selection_empty", !have_selection);
 519	}
 520
 521
 522	// Refresh child tabs
 523	mPanelPermissions->refresh();
 524	mPanelObject->refresh();
 525	mPanelVolume->refresh();
 526	mPanelFace->refresh();
 527	refreshMedia();
 528	mPanelContents->refresh();
 529	mPanelLandInfo->refresh();
 530
 531	// Refresh the advanced weights floater
 532	LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::findTypedInstance<LLFloaterObjectWeights>("object_weights");
 533	if(object_weights_floater && object_weights_floater->getVisible())
 534	{
 535		object_weights_floater->refresh();
 536	}
 537}
 538
 539void LLFloaterTools::draw()
 540{
 541	if (mDirty)
 542	{
 543		refresh();
 544		mDirty = FALSE;
 545	}
 546
 547	// grab media name/title and update the UI widget
 548	updateMediaTitle();
 549
 550	//	mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
 551	LLFloater::draw();
 552}
 553
 554void LLFloaterTools::dirty()
 555{
 556	mDirty = TRUE; 
 557	LLFloaterOpenObject* instance = LLFloaterReg::findTypedInstance<LLFloaterOpenObject>("openobject");
 558	if (instance) instance->dirty();
 559}
 560
 561// Clean up any tool state that should not persist when the
 562// floater is closed.
 563void LLFloaterTools::resetToolState()
 564{
 565	gCameraBtnZoom = TRUE;
 566	gCameraBtnOrbit = FALSE;
 567	gCameraBtnPan = FALSE;
 568
 569	gGrabBtnSpin = FALSE;
 570	gGrabBtnVertical = FALSE;
 571}
 572
 573void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 574{
 575	LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
 576
 577	// HACK to allow seeing the buttons when you have the app in a window.
 578	// Keep the visibility the same as it 
 579	if (tool == gToolNull)
 580	{
 581		return;
 582	}
 583
 584	if ( isMinimized() )
 585	{	// SL looks odd if we draw the tools while the window is minimized
 586		return;
 587	}
 588	
 589	// Focus buttons
 590	BOOL focus_visible = (	tool == LLToolCamera::getInstance() );
 591
 592	mBtnFocus	->setToggleState( focus_visible );
 593
 594	mRadioGroupFocus->setVisible( focus_visible );
 595	getChildView("slider zoom")->setVisible( focus_visible);
 596	getChildView("slider zoom")->setEnabled(gCameraBtnZoom);
 597
 598	if (!gCameraBtnOrbit &&
 599		!gCameraBtnPan &&
 600		!(mask == MASK_ORBIT) &&
 601		!(mask == (MASK_ORBIT | MASK_ALT)) &&
 602		!(mask == MASK_PAN) &&
 603		!(mask == (MASK_PAN | MASK_ALT)) )
 604	{
 605		mRadioGroupFocus->setValue("radio zoom");
 606	}
 607	else if (	gCameraBtnOrbit || 
 608				(mask == MASK_ORBIT) ||
 609				(mask == (MASK_ORBIT | MASK_ALT)) )
 610	{
 611		mRadioGroupFocus->setValue("radio orbit");
 612	}
 613	else if (	gCameraBtnPan ||
 614				(mask == MASK_PAN) ||
 615				(mask == (MASK_PAN | MASK_ALT)) )
 616	{
 617		mRadioGroupFocus->setValue("radio pan");
 618	}
 619
 620	// multiply by correction factor because volume sliders go [0, 0.5]
 621	getChild<LLUICtrl>("slider zoom")->setValue(gAgentCamera.getCameraZoomFraction() * 0.5f);
 622
 623	// Move buttons
 624	BOOL move_visible = (tool == LLToolGrab::getInstance());
 625
 626	if (mBtnMove) mBtnMove	->setToggleState( move_visible );
 627
 628	// HACK - highlight buttons for next click
 629	mRadioGroupMove->setVisible(move_visible);
 630	if (!gGrabBtnSpin && 
 631		!gGrabBtnVertical &&
 632		!(mask == MASK_VERTICAL) && 
 633		!(mask == MASK_SPIN) )
 634	{
 635		mRadioGroupMove->setValue("radio move");
 636	}
 637	else if (gGrabBtnVertical || 
 638			 (mask == MASK_VERTICAL) )
 639	{
 640		mRadioGroupMove->setValue("radio lift");
 641	}
 642	else if (gGrabBtnSpin || 
 643			 (mask == MASK_SPIN) )
 644	{
 645		mRadioGroupMove->setValue("radio spin");
 646	}
 647
 648	// Edit buttons
 649	BOOL edit_visible = tool == LLToolCompTranslate::getInstance() ||
 650						tool == LLToolCompRotate::getInstance() ||
 651						tool == LLToolCompScale::getInstance() ||
 652						tool == LLToolFace::getInstance() ||
 653						tool == LLToolIndividual::getInstance() ||
 654						tool == LLToolPipette::getInstance();
 655
 656	mBtnEdit	->setToggleState( edit_visible );
 657	mRadioGroupEdit->setVisible( edit_visible );
 658	bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
 659	getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
 660
 661	mBtnLink->setVisible(edit_visible);
 662	mBtnUnlink->setVisible(edit_visible);
 663
 664	mBtnLink->setEnabled(LLSelectMgr::instance().enableLinkObjects());
 665	mBtnUnlink->setEnabled(LLSelectMgr::instance().enableUnlinkObjects());
 666
 667	if (mCheckSelectIndividual)
 668	{
 669		mCheckSelectIndividual->setVisible(edit_visible);
 670		//mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
 671	}
 672
 673	if ( tool == LLToolCompTranslate::getInstance() )
 674	{
 675		mRadioGroupEdit->setValue("radio position");
 676	}
 677	else if ( tool == LLToolCompRotate::getInstance() )
 678	{
 679		mRadioGroupEdit->setValue("radio rotate");
 680	}
 681	else if ( tool == LLToolCompScale::getInstance() )
 682	{
 683		mRadioGroupEdit->setValue("radio stretch");
 684	}
 685	else if ( tool == LLToolFace::getInstance() )
 686	{
 687		mRadioGroupEdit->setValue("radio select face");
 688	}
 689
 690	// Snap to grid disabled for grab tool - very confusing
 691	if (mCheckSnapToGrid) mCheckSnapToGrid->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ );
 692	if (mBtnGridOptions) mBtnGridOptions->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ );
 693
 694	//mCheckSelectLinked	->setVisible( edit_visible );
 695	if (mCheckStretchUniform) mCheckStretchUniform->setVisible( edit_visible );
 696	if (mCheckStretchTexture) mCheckStretchTexture->setVisible( edit_visible );
 697	if (mCheckStretchUniformLabel) mCheckStretchUniformLabel->setVisible( edit_visible );
 698
 699	// Create buttons
 700	BOOL create_visible = (tool == LLToolCompCreate::getInstance());
 701
 702	mBtnCreate	->setToggleState(	tool == LLToolCompCreate::getInstance() );
 703
 704	if (mCheckCopySelection
 705		&& mCheckCopySelection->get())
 706	{
 707		// don't highlight any placer button
 708		for (std::vector<LLButton*>::size_type i = 0; i < mButtons.size(); i++)
 709		{
 710			mButtons[i]->setToggleState(FALSE);
 711			mButtons[i]->setVisible( create_visible );
 712		}
 713	}
 714	else
 715	{
 716		// Highlight the correct placer button
 717		for( S32 t = 0; t < (S32)mButtons.size(); t++ )
 718		{
 719			LLPCode pcode = LLToolPlacer::getObjectType();
 720			LLPCode button_pcode = toolData[t];
 721			BOOL state = (pcode == button_pcode);
 722			mButtons[t]->setToggleState( state );
 723			mButtons[t]->setVisible( create_visible );
 724		}
 725	}
 726
 727	if (mCheckSticky) mCheckSticky		->setVisible( create_visible );
 728	if (mCheckCopySelection) mCheckCopySelection	->setVisible( create_visible );
 729	if (mCheckCopyCenters) mCheckCopyCenters	->setVisible( create_visible );
 730	if (mCheckCopyRotates) mCheckCopyRotates	->setVisible( create_visible );
 731
 732	if (mCheckCopyCenters && mCheckCopySelection) mCheckCopyCenters->setEnabled( mCheckCopySelection->get() );
 733	if (mCheckCopyRotates && mCheckCopySelection) mCheckCopyRotates->setEnabled( mCheckCopySelection->get() );
 734
 735	// Land buttons
 736	BOOL land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() );
 737
 738	mCostTextBorder->setVisible(!land_visible);
 739
 740	if (mBtnLand)	mBtnLand	->setToggleState( land_visible );
 741
 742	mRadioGroupLand->setVisible( land_visible );
 743	if ( tool == LLToolSelectLand::getInstance() )
 744	{
 745		mRadioGroupLand->setValue("radio select land");
 746	}
 747	else if ( tool == LLToolBrushLand::getInstance() )
 748	{
 749		S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
 750		switch(dozer_mode)
 751		{
 752		case 0:
 753			mRadioGroupLand->setValue("radio flatten");
 754			break;
 755		case 1:
 756			mRadioGroupLand->setValue("radio raise");
 757			break;
 758		case 2:
 759			mRadioGroupLand->setValue("radio lower");
 760			break;
 761		case 3:
 762			mRadioGroupLand->setValue("radio smooth");
 763			break;
 764		case 4:
 765			mRadioGroupLand->setValue("radio noise");
 766			break;
 767		case 5:
 768			mRadioGroupLand->setValue("radio revert");
 769			break;
 770		default:
 771			break;
 772		}
 773	}
 774
 775	if (mBtnApplyToSelection)
 776	{
 777		mBtnApplyToSelection->setVisible( land_visible );
 778		mBtnApplyToSelection->setEnabled( land_visible && !LLViewerParcelMgr::getInstance()->selectionEmpty() && tool != LLToolSelectLand::getInstance());
 779	}
 780	if (mSliderDozerSize)
 781	{
 782		mSliderDozerSize	->setVisible( land_visible );
 783		getChildView("Bulldozer:")->setVisible( land_visible);
 784		getChildView("Dozer Size:")->setVisible( land_visible);
 785	}
 786	if (mSliderDozerForce)
 787	{
 788		mSliderDozerForce	->setVisible( land_visible );
 789		getChildView("Strength:")->setVisible( land_visible);
 790	}
 791
 792	bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
 793
 794	getChildView("selection_count")->setVisible(!land_visible && have_selection);
 795	getChildView("remaining_capacity")->setVisible(!land_visible && have_selection);
 796	getChildView("selection_empty")->setVisible(!land_visible && !have_selection);
 797	
 798	mTab->setVisible(!land_visible);
 799	mPanelLandInfo->setVisible(land_visible);
 800}
 801
 802
 803// virtual
 804BOOL LLFloaterTools::canClose()
 805{
 806	// don't close when quitting, so camera will stay put
 807	return !LLApp::isExiting();
 808}
 809
 810// virtual
 811void LLFloaterTools::onOpen(const LLSD& key)
 812{
 813	mParcelSelection = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
 814	mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
 815	
 816	std::string panel = key.asString();
 817	if (!panel.empty())
 818	{
 819		mTab->selectTabByName(panel);
 820	}
 821	
 822	//gMenuBarView->setItemVisible("BuildTools", TRUE);
 823}
 824
 825// virtual
 826void LLFloaterTools::onClose(bool app_quitting)
 827{
 828	mTab->setVisible(FALSE);
 829
 830	LLViewerJoystick::getInstance()->moveAvatar(false);
 831
 832	// destroy media source used to grab media title
 833	if( mTitleMedia )
 834		mTitleMedia->unloadMediaSource();
 835
 836    // Different from handle_reset_view in that it doesn't actually 
 837	//   move the camera if EditCameraMovement is not set.
 838	gAgentCamera.resetView(gSavedSettings.getBOOL("EditCameraMovement"));
 839	
 840	// exit component selection mode
 841	LLSelectMgr::getInstance()->promoteSelectionToRoot();
 842	gSavedSettings.setBOOL("EditLinkedParts", FALSE);
 843
 844	gViewerWindow->showCursor();
 845
 846	resetToolState();
 847
 848	mParcelSelection = NULL;
 849	mObjectSelection = NULL;
 850
 851	// Switch back to basic toolset
 852	LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
 853	// we were already in basic toolset, using build tools
 854	// so manually reset tool to default (pie menu tool)
 855	LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
 856
 857	//gMenuBarView->setItemVisible("BuildTools", FALSE);
 858	LLFloaterReg::hideInstance("media_settings");
 859
 860	// hide the advanced object weights floater
 861	LLFloaterReg::hideInstance("object_weights");
 862}
 863
 864void click_popup_info(void*)
 865{
 866}
 867
 868void click_popup_done(void*)
 869{
 870	handle_reset_view();
 871}
 872
 873void commit_radio_group_move(LLUICtrl* ctrl)
 874{
 875	LLRadioGroup* group = (LLRadioGroup*)ctrl;
 876	std::string selected = group->getValue().asString();
 877	if (selected == "radio move")
 878	{
 879		gGrabBtnVertical = FALSE;
 880		gGrabBtnSpin = FALSE;
 881	}
 882	else if (selected == "radio lift")
 883	{
 884		gGrabBtnVertical = TRUE;
 885		gGrabBtnSpin = FALSE;
 886	}
 887	else if (selected == "radio spin")
 888	{
 889		gGrabBtnVertical = FALSE;
 890		gGrabBtnSpin = TRUE;
 891	}
 892}
 893
 894void commit_radio_group_focus(LLUICtrl* ctrl)
 895{
 896	LLRadioGroup* group = (LLRadioGroup*)ctrl;
 897	std::string selected = group->getValue().asString();
 898	if (selected == "radio zoom")
 899	{
 900		gCameraBtnZoom = TRUE;
 901		gCameraBtnOrbit = FALSE;
 902		gCameraBtnPan = FALSE;
 903	}
 904	else if (selected == "radio orbit")
 905	{
 906		gCameraBtnZoom = FALSE;
 907		gCameraBtnOrbit = TRUE;
 908		gCameraBtnPan = FALSE;
 909	}
 910	else if (selected == "radio pan")
 911	{
 912		gCameraBtnZoom = FALSE;
 913		gCameraBtnOrbit = FALSE;
 914		gCameraBtnPan = TRUE;
 915	}
 916}
 917
 918void commit_slider_zoom(LLUICtrl *ctrl)
 919{
 920	// renormalize value, since max "volume" level is 0.5 for some reason
 921	F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
 922	gAgentCamera.setCameraZoomFraction(zoom_level);
 923}
 924
 925void click_popup_rotate_left(void*)
 926{
 927	LLSelectMgr::getInstance()->selectionRotateAroundZ( 45.f );
 928	dialog_refresh_all();
 929}
 930
 931void click_popup_rotate_reset(void*)
 932{
 933	LLSelectMgr::getInstance()->selectionResetRotation();
 934	dialog_refresh_all();
 935}
 936
 937void click_popup_rotate_right(void*)
 938{
 939	LLSelectMgr::getInstance()->selectionRotateAroundZ( -45.f );
 940	dialog_refresh_all();
 941}
 942
 943void commit_slider_dozer_force(LLUICtrl *ctrl)
 944{
 945	// the slider is logarithmic, so we exponentiate to get the actual force multiplier
 946	F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
 947	gSavedSettings.setF32("LandBrushForce", dozer_force);
 948}
 949
 950void click_apply_to_selection(void*)
 951{
 952	LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
 953}
 954
 955void commit_radio_group_edit(LLUICtrl *ctrl)
 956{
 957	S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
 958
 959	LLRadioGroup* group = (LLRadioGroup*)ctrl;
 960	std::string selected = group->getValue().asString();
 961	if (selected == "radio position")
 962	{
 963		LLFloaterTools::setEditTool( LLToolCompTranslate::getInstance() );
 964	}
 965	else if (selected == "radio rotate")
 966	{
 967		LLFloaterTools::setEditTool( LLToolCompRotate::getInstance() );
 968	}
 969	else if (selected == "radio stretch")
 970	{
 971		LLFloaterTools::setEditTool( LLToolCompScale::getInstance() );
 972	}
 973	else if (selected == "radio select face")
 974	{
 975		LLFloaterTools::setEditTool( LLToolFace::getInstance() );
 976	}
 977	gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
 978}
 979
 980void commit_radio_group_land(LLUICtrl* ctrl)
 981{
 982	LLRadioGroup* group = (LLRadioGroup*)ctrl;
 983	std::string selected = group->getValue().asString();
 984	if (selected == "radio select land")
 985	{
 986		LLFloaterTools::setEditTool( LLToolSelectLand::getInstance() );
 987	}
 988	else
 989	{
 990		LLFloaterTools::setEditTool( LLToolBrushLand::getInstance() );
 991		S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
 992		if (selected == "radio flatten")
 993			dozer_mode = 0;
 994		else if (selected == "radio raise")
 995			dozer_mode = 1;
 996		else if (selected == "radio lower")
 997			dozer_mode = 2;
 998		else if (selected == "radio smooth")
 999			dozer_mode = 3;
1000		else if (selected == "radio noise")
1001			dozer_mode = 4;
1002		else if (selected == "radio revert")
1003			dozer_mode = 5;
1004		gSavedSettings.setS32("RadioLandBrushAction", dozer_mode);
1005	}
1006}
1007
1008void commit_select_component(void *data)
1009{
1010	LLFloaterTools* floaterp = (LLFloaterTools*)data;
1011
1012	//forfeit focus
1013	if (gFocusMgr.childHasKeyboardFocus(floaterp))
1014	{
1015		gFocusMgr.setKeyboardFocus(NULL);
1016	}
1017
1018	BOOL select_individuals = floaterp->mCheckSelectIndividual->get();
1019	gSavedSettings.setBOOL("EditLinkedParts", select_individuals);
1020	floaterp->dirty();
1021
1022	if (select_individuals)
1023	{
1024		LLSelectMgr::getInstance()->demoteSelectionToIndividuals();
1025	}
1026	else
1027	{
1028		LLSelectMgr::getInstance()->promoteSelectionToRoot();
1029	}
1030}
1031
1032// static 
1033void LLFloaterTools::setObjectType( LLPCode pcode )
1034{
1035	LLToolPlacer::setObjectType( pcode );
1036	gSavedSettings.setBOOL("CreateToolCopySelection", FALSE);
1037	gFocusMgr.setMouseCapture(NULL);
1038}
1039
1040
1041void LLFloaterTools::onClickGridOptions()
1042{
1043	LLFloaterReg::showInstance("build_options");
1044	// RN: this makes grid options dependent on build tools window
1045	//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
1046}
1047
1048// static
1049void LLFloaterTools::setEditTool(void* tool_pointer)
1050{
1051	LLTool *tool = (LLTool *)tool_pointer;
1052	LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
1053}
1054
1055void LLFloaterTools::setTool(const LLSD& user_data)
1056{
1057	std::string control_name = user_data.asString();
1058	if(control_name == "Focus")
1059		LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() );
1060	else if (control_name == "Move" )
1061		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() );
1062	else if (control_name == "Edit" )
1063		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance());
1064	else if (control_name == "Create" )
1065		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance());
1066	else if (control_name == "Land" )
1067		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance());
1068	else
1069		llwarns<<" no parameter name "<<control_name<<" found!! No Tool selected!!"<< llendl;
1070}
1071
1072void LLFloaterTools::onFocusReceived()
1073{
1074	LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
1075	LLFloater::onFocusReceived();
1076}
1077
1078// Media stuff
1079void LLFloaterTools::refreshMedia()
1080{
1081	getMediaState();	
1082}
1083
1084bool LLFloaterTools::selectedMediaEditable()
1085{
1086	U32 owner_mask_on;
1087	U32 owner_mask_off;
1088	U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER, 
1089																	  &owner_mask_on, &owner_mask_off );
1090	U32 group_mask_on;
1091	U32 group_mask_off;
1092	U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP, 
1093																	  &group_mask_on, &group_mask_off );
1094	U32 everyone_mask_on;
1095	U32 everyone_mask_off;
1096	S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE, 
1097																		 &everyone_mask_on, &everyone_mask_off );
1098	
1099	bool selected_Media_editable = false;
1100	
1101	// if perms we got back are valid
1102	if ( valid_owner_perms &&
1103		valid_group_perms && 
1104		valid_everyone_perms )
1105	{
1106		
1107		if ( ( owner_mask_on & PERM_MODIFY ) ||
1108			( group_mask_on & PERM_MODIFY ) || 
1109			( group_mask_on & PERM_MODIFY ) )
1110		{
1111			selected_Media_editable = true;
1112		}
1113		else
1114			// user is NOT allowed to press the RESET button
1115		{
1116			selected_Media_editable = false;
1117		};
1118	};
1119	
1120	return selected_Media_editable;
1121}
1122
1123void LLFloaterTools::updateLandImpacts()
1124{
1125	LLParcel *parcel = mParcelSelection->getParcel();
1126	if (!parcel)
1127	{
1128		return;
1129	}
1130
1131	S32 rezzed_prims = parcel->getSimWidePrimCount();
1132	S32 total_capacity = parcel->getSimWideMaxPrimCapacity();
1133
1134	std::string remaining_capacity_str = "";
1135
1136	bool show_mesh_cost = gMeshRepo.meshRezEnabled();
1137	if (show_mesh_cost)
1138	{
1139		LLStringUtil::format_map_t remaining_capacity_args;
1140		remaining_capacity_args["LAND_CAPACITY"] = llformat("%d", total_capacity - rezzed_prims);
1141		remaining_capacity_str = getString("status_remaining_capacity", remaining_capacity_args);
1142	}
1143
1144	childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str);
1145
1146	// Update land impacts info in the weights floater
1147	LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::getTypedInstance<LLFloaterObjectWeights>("object_weights");
1148	if(object_weights_floater)
1149	{
1150		object_weights_floater->updateLandImpacts(parcel);
1151	}
1152}
1153
1154void LLFloaterTools::getMediaState()
1155{
1156	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
1157	LLViewerObject* first_object = selected_objects->getFirstObject();
1158	LLTextBox* media_info = getChild<LLTextBox>("media_info");
1159	
1160	if( !(first_object 
1161		  && first_object->getPCode() == LL_PCODE_VOLUME
1162		  &&first_object->permModify() 
1163	      ))
1164	{
1165		getChildView("Add_Media")->setEnabled(FALSE);
1166		media_info->clear();
1167		clearMediaSettings();
1168		return;
1169	}
1170	
1171	std::string url = first_object->getRegion()->getCapability("ObjectMedia");
1172	bool has_media_capability = (!url.empty());
1173	
1174	if(!has_media_capability)
1175	{
1176		getChildView("Add_Media")->setEnabled(FALSE);
1177		LL_WARNS("LLFloaterTools: media") << "Media not enabled (no capability) in this region!" << LL_ENDL;
1178		clearMediaSettings();
1179		return;
1180	}
1181	
1182	bool editable = (first_object->permModify() || selectedMediaEditable());
1183
1184	// Check modify permissions and whether any selected objects are in
1185	// the process of being fetched.  If they are, then we're not editable
1186	if (editable)
1187	{
1188		LLObjectSelection::iterator iter = selected_objects->begin(); 
1189		LLObjectSelection::iterator end = selected_objects->end();
1190		for ( ; iter != end; ++iter)
1191		{
1192			LLSelectNode* node = *iter;
1193			LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
1194			if (NULL != object)
1195			{
1196				if (!object->permModify())
1197				{
1198					LL_INFOS("LLFloaterTools: media")
1199						<< "Selection not editable due to lack of modify permissions on object id "
1200						<< object->getID() << LL_ENDL;
1201					
1202					editable = false;
1203					break;
1204				}
1205				// XXX DISABLE this for now, because when the fetch finally 
1206				// does come in, the state of this floater doesn't properly
1207				// update.  Re-selecting fixes the problem, but there is 
1208				// contention as to whether this is a sufficient solution.
1209//				if (object->isMediaDataBeingFetched())
1210//				{
1211//					LL_INFOS("LLFloaterTools: media")
1212//						<< "Selection not editable due to media data being fetched for object id "
1213//						<< object->getID() << LL_ENDL;
1214//						
1215//					editable = false;
1216//					break;
1217//				}
1218			}
1219		}
1220	}
1221
1222	// Media settings
1223	bool bool_has_media = false;
1224	struct media_functor : public LLSelectedTEGetFunctor<bool>
1225	{
1226		bool get(LLViewerObject* object, S32 face)
1227		{
1228			LLTextureEntry *te = object->getTE(face);
1229			if (te)
1230			{
1231				return te->hasMedia();
1232			}
1233			return false;
1234		}
1235	} func;
1236	
1237	// check if all faces have media(or, all dont have media)
1238	LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
1239	
1240	const LLMediaEntry default_media_data;
1241	
1242	struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
1243    {
1244		functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}	
1245
1246        LLMediaEntry get( LLViewerObject* object, S32 face )
1247        {
1248            if ( object )
1249                if ( object->getTE(face) )
1250                    if ( object->getTE(face)->getMediaData() )
1251                        return *(object->getTE(face)->getMediaData());
1252			return mMediaEntry;
1253        };
1254		
1255		const LLMediaEntry& mMediaEntry;
1256		
1257    } func_media_data(default_media_data);
1258
1259	LLMediaEntry media_data_get;
1260    LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get ));
1261	
1262	std::string multi_media_info_str = LLTrans::getString("Multiple Media");
1263	std::string media_title = "";
1264	mNeedMediaTitle = false;
1265	// update UI depending on whether "object" (prim or face) has media
1266	// and whether or not you are allowed to edit it.
1267	
1268	getChildView("Add_Media")->setEnabled(editable);
1269	// IF all the faces have media (or all dont have media)
1270	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
1271	{
1272		// TODO: get media title and set it.
1273		media_info->clear();
1274		// if identical is set, all faces are same (whether all empty or has the same media)
1275		if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) )
1276		{
1277			// Media data is valid
1278			if(media_data_get!=default_media_data)
1279			{
1280				// initial media title is the media URL (until we get the name)
1281				media_title = media_data_get.getHomeURL();
1282
1283				// kick off a navigate and flag that we need to update the title
1284				navigateToTitleMedia( media_data_get.getHomeURL() );
1285				mNeedMediaTitle = true;
1286			}
1287			// else all faces might be empty. 
1288		}
1289		else // there' re Different Medias' been set on on the faces.
1290		{
1291			media_title = multi_media_info_str;
1292			mNeedMediaTitle = false;
1293		}
1294		
1295		getChildView("media_tex")->setEnabled(bool_has_media && editable);
1296		getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable );
1297		getChildView("delete_media")->setEnabled(bool_has_media && editable );
1298		getChildView("add_media")->setEnabled(( ! bool_has_media ) && editable );
1299			// TODO: display a list of all media on the face - use 'identical' flag
1300	}
1301	else // not all face has media but at least one does.
1302	{
1303		// seleted faces have not identical value
1304		LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data );
1305	
1306		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
1307		{
1308			media_title = multi_media_info_str;
1309			mNeedMediaTitle = false;
1310		}
1311		else
1312		{
1313			// Media data is valid
1314			if(media_data_get!=default_media_data)
1315			{
1316				// initial media title is the media URL (until we get the name)
1317				media_title = media_data_get.getHomeURL();
1318
1319				// kick off a navigate and flag that we need to update the title
1320				navigateToTitleMedia( media_data_get.getHomeURL() );
1321				mNeedMediaTitle = true;
1322			}
1323		}
1324		
1325		getChildView("media_tex")->setEnabled(TRUE);
1326		getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo);
1327		getChildView("delete_media")->setEnabled(TRUE);
1328		getChildView("add_media")->setEnabled(FALSE );
1329	}
1330	media_info->setText(media_title);
1331	
1332	// load values for media settings
1333	updateMediaSettings();
1334	
1335	LLFloaterMediaSettings::initValues(mMediaSettings, editable );
1336}
1337
1338
1339//////////////////////////////////////////////////////////////////////////////
1340// called when a user wants to add media to a prim or prim face
1341void LLFloaterTools::onClickBtnAddMedia()
1342{
1343	// check if multiple faces are selected
1344	if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
1345	{
1346		LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
1347	}
1348	else
1349	{
1350		onClickBtnEditMedia();
1351	}
1352}
1353
1354// static
1355bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
1356{
1357	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1358	switch( option )
1359	{
1360		case 0:  // "Yes"
1361			gFloaterTools->onClickBtnEditMedia();
1362			break;
1363		case 1:  // "No"
1364		default:
1365			break;
1366	}
1367	return false;
1368}
1369
1370//////////////////////////////////////////////////////////////////////////////
1371// called when a user wants to edit existing media settings on a prim or prim face
1372// TODO: test if there is media on the item and only allow editing if present
1373void LLFloaterTools::onClickBtnEditMedia()
1374{
1375	refreshMedia();
1376	LLFloaterReg::showInstance("media_settings");	
1377}
1378
1379//////////////////////////////////////////////////////////////////////////////
1380// called when a user wants to delete media from a prim or prim face
1381void LLFloaterTools::onClickBtnDeleteMedia()
1382{
1383	LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
1384}
1385
1386
1387// static
1388bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
1389{
1390	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1391	switch( option )
1392	{
1393		case 0:  // "Yes"
1394			LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() );
1395			if(LLFloaterReg::instanceVisible("media_settings"))
1396			{
1397				LLFloaterReg::hideInstance("media_settings");
1398			}
1399			break;
1400			
1401		case 1:  // "No"
1402		default:
1403			break;
1404	}
1405	return false;
1406}
1407
1408//////////////////////////////////////////////////////////////////////////////
1409//
1410void LLFloaterTools::clearMediaSettings()
1411{
1412	LLFloaterMediaSettings::clearValues(false);
1413}
1414
1415//////////////////////////////////////////////////////////////////////////////
1416//
1417void LLFloaterTools::navigateToTitleMedia( const std::string url )
1418{
1419	if ( mTitleMedia )
1420	{
1421		LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
1422		if ( media_plugin )
1423		{
1424			// if it's a movie, we don't want to hear it
1425			media_plugin->setVolume( 0 );
1426		};
1427		mTitleMedia->navigateTo( url );
1428	};
1429}
1430
1431//////////////////////////////////////////////////////////////////////////////
1432//
1433void LLFloaterTools::updateMediaTitle()
1434{
1435	// only get the media name if we need it
1436	if ( ! mNeedMediaTitle )
1437		return;
1438
1439	// get plugin impl
1440	LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
1441	if ( media_plugin )
1442	{
1443		// get the media name (asynchronous - must call repeatedly)
1444		std::string media_title = media_plugin->getMediaName();
1445
1446		// only replace the title if what we get contains something
1447		if ( ! media_title.empty() )
1448		{
1449			// update the UI widget
1450			LLTextBox* media_title_field = getChild<LLTextBox>("media_info");
1451			if ( media_title_field )
1452			{
1453				media_title_field->setText( media_title );
1454
1455				// stop looking for a title when we get one
1456				// FIXME: check this is the right approach
1457				mNeedMediaTitle = false;
1458			};
1459		};
1460	};
1461}
1462
1463//////////////////////////////////////////////////////////////////////////////
1464//
1465void LLFloaterTools::updateMediaSettings()
1466{
1467    bool identical( false );
1468    std::string base_key( "" );
1469    std::string value_str( "" );
1470    int value_int = 0;
1471    bool value_bool = false;
1472	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
1473    // TODO: (CP) refactor this using something clever or boost or both !!
1474
1475    const LLMediaEntry default_media_data;
1476
1477    // controls 
1478    U8 value_u8 = default_media_data.getControls();
1479    struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
1480    {
1481		functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
1482		
1483        U8 get( LLViewerObject* object, S32 face )
1484        {
1485            if ( object )
1486                if ( object->getTE(face) )
1487                    if ( object->getTE(face)->getMediaData() )
1488                        return object->getTE(face)->getMediaData()->getControls();
1489            return mMediaEntry.getControls();
1490        };
1491		
1492		const LLMediaEntry &mMediaEntry;
1493		
1494    } func_controls(default_media_data);
1495    identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
1496    base_key = std::string( LLMediaEntry::CONTROLS_KEY );
1497    mMediaSettings[ base_key ] = value_u8;
1498    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
1499	
1500    // First click (formerly left click)
1501    value_bool = default_media_data.getFirstClickInteract();
1502    struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
1503    {
1504		functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}		
1505		
1506        bool get( LLViewerObject* object, S32 face )
1507        {
1508            if ( object )
1509                if ( object->getTE(face) )
1510                    if ( object->getTE(face)->getMediaData() )
1511                        return object->getTE(face)->getMediaData()->getFirstClickInteract();
1512            return mMediaEntry.getFirstClickInteract();
1513        };
1514		
1515		const LLMediaEntry &mMediaEntry;
1516		
1517    } func_first_click(default_media_data);
1518    identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
1519    base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
1520    mMediaSettings[ base_key ] = value_bool;
1521    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
1522	
1523    // Home URL
1524    value_str = default_media_data.getHomeURL();
1525    struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
1526    {
1527		functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}		
1528		
1529        std::string get( LLViewerObject* object, S32 face )
1530        {
1531            if ( object )
1532                if ( object->getTE(face) )
1533                    if ( object->getTE(face)->getMediaData() )
1534                        return object->getTE(face)->getMediaData()->getHomeURL();
1535            return mMediaEntry.getHomeURL();
1536        };
1537		
1538		const LLMediaEntry &mMediaEntry;
1539		
1540    } func_home_url(default_media_data);
1541    identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
1542    base_key = std::string( LLMediaEntry::HOME_URL_KEY );
1543    mMediaSettings[ base_key ] = value_str;
1544    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
1545	
1546    // Current URL
1547    value_str = default_media_data.getCurrentURL();
1548    struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
1549    {
1550		functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
1551        
1552		std::string get( LLViewerObject* object, S32 face )
1553        {
1554            if ( object )
1555                if ( object->getTE(face) )
1556                    if ( object->getTE(face)->getMediaData() )
1557                        return object->getTE(face)->getMediaData()->getCurrentURL();
1558            return mMediaEntry.getCurrentURL();
1559        };
1560		
1561		const LLMediaEntry &mMediaEntry;
1562		
1563    } func_current_url(default_media_data);
1564    identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
1565    base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
1566    mMediaSettings[ base_key ] = value_str;
1567    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
1568	
1569    // Auto zoom
1570    value_bool = default_media_data.getAutoZoom();
1571    struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
1572    {
1573		
1574		functor_getter_auto_zoom(const LLMediaEntry& entry)	: mMediaEntry(entry) {}	
1575		
1576        bool get( LLViewerObject* object, S32 face )
1577        {
1578            if ( object )
1579                if ( object->getTE(face) )
1580                    if ( object->getTE(face)->getMediaData() )
1581                        return object->getTE(face)->getMediaData()->getAutoZoom();
1582            return mMediaEntry.getAutoZoom();
1583        };
1584		
1585		const LLMediaEntry &mMediaEntry;
1586		
1587    } func_auto_zoom(default_media_data);
1588    identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
1589    base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
1590    mMediaSettings[ base_k

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