PageRenderTime 895ms CodeModel.GetById 121ms app.highlight 659ms RepoModel.GetById 96ms app.codeStats 1ms

/indra/newview/llfloaterpreference.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2053 lines | 1501 code | 317 blank | 235 comment | 230 complexity | 35f5f0ed35b6c50aad182a4d3e57f0d6 MD5 | raw file

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

   1/** 
   2 * @file llfloaterpreference.cpp
   3 * @brief Global preferences with and without persistence.
   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/*
  28 * App-wide preferences.  Note that these are not per-user,
  29 * because we need to load many preferences before we have
  30 * a login name.
  31 */
  32
  33#include "llviewerprecompiledheaders.h"
  34
  35#include "llfloaterpreference.h"
  36
  37#include "message.h"
  38
  39#include "llagent.h"
  40#include "llavatarconstants.h"
  41#include "llcheckboxctrl.h"
  42#include "llcolorswatch.h"
  43#include "llcombobox.h"
  44#include "llcommandhandler.h"
  45#include "lldirpicker.h"
  46#include "lleventtimer.h"
  47#include "llfeaturemanager.h"
  48#include "llfocusmgr.h"
  49//#include "llfirstuse.h"
  50#include "llfloaterreg.h"
  51#include "llfloaterabout.h"
  52#include "llfloaterhardwaresettings.h"
  53#include "llfloatersidepanelcontainer.h"
  54#include "llimfloater.h"
  55#include "llkeyboard.h"
  56#include "llmodaldialog.h"
  57#include "llnavigationbar.h"
  58#include "llnearbychat.h"
  59#include "llnotifications.h"
  60#include "llnotificationsutil.h"
  61#include "llnotificationtemplate.h"
  62#include "llpanellogin.h"
  63#include "llpanelvoicedevicesettings.h"
  64#include "llradiogroup.h"
  65#include "llsearchcombobox.h"
  66#include "llsky.h"
  67#include "llscrolllistctrl.h"
  68#include "llscrolllistitem.h"
  69#include "llsliderctrl.h"
  70#include "lltabcontainer.h"
  71#include "lltrans.h"
  72#include "llviewercontrol.h"
  73#include "llviewercamera.h"
  74#include "llviewerwindow.h"
  75#include "llviewermessage.h"
  76#include "llviewershadermgr.h"
  77#include "llviewerthrottle.h"
  78#include "llvotree.h"
  79#include "llvosky.h"
  80
  81// linden library includes
  82#include "llavatarnamecache.h"
  83#include "llerror.h"
  84#include "llfontgl.h"
  85#include "llrect.h"
  86#include "llstring.h"
  87
  88// project includes
  89
  90#include "llbutton.h"
  91#include "llflexibleobject.h"
  92#include "lllineeditor.h"
  93#include "llresmgr.h"
  94#include "llspinctrl.h"
  95#include "llstartup.h"
  96#include "lltextbox.h"
  97#include "llui.h"
  98#include "llviewerobjectlist.h"
  99#include "llvoavatar.h"
 100#include "llvovolume.h"
 101#include "llwindow.h"
 102#include "llworld.h"
 103#include "pipeline.h"
 104#include "lluictrlfactory.h"
 105#include "llviewermedia.h"
 106#include "llpluginclassmedia.h"
 107#include "llteleporthistorystorage.h"
 108#include "llproxy.h"
 109
 110#include "lllogininstance.h"        // to check if logged in yet
 111#include "llsdserialize.h"
 112
 113const F32 MAX_USER_FAR_CLIP = 512.f;
 114const F32 MIN_USER_FAR_CLIP = 64.f;
 115const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
 116
 117//control value for middle mouse as talk2push button
 118const static std::string MIDDLE_MOUSE_CV = "MiddleMouse";
 119
 120class LLVoiceSetKeyDialog : public LLModalDialog
 121{
 122public:
 123	LLVoiceSetKeyDialog(const LLSD& key);
 124	~LLVoiceSetKeyDialog();
 125	
 126	/*virtual*/ BOOL postBuild();
 127	
 128	void setParent(LLFloaterPreference* parent) { mParent = parent; }
 129	
 130	BOOL handleKeyHere(KEY key, MASK mask);
 131	static void onCancel(void* user_data);
 132		
 133private:
 134	LLFloaterPreference* mParent;
 135};
 136
 137LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(const LLSD& key)
 138  : LLModalDialog(key),
 139	mParent(NULL)
 140{
 141}
 142
 143//virtual
 144BOOL LLVoiceSetKeyDialog::postBuild()
 145{
 146	childSetAction("Cancel", onCancel, this);
 147	getChild<LLUICtrl>("Cancel")->setFocus(TRUE);
 148	
 149	gFocusMgr.setKeystrokesOnly(TRUE);
 150	
 151	return TRUE;
 152}
 153
 154LLVoiceSetKeyDialog::~LLVoiceSetKeyDialog()
 155{
 156}
 157
 158BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask)
 159{
 160	BOOL result = TRUE;
 161	
 162	if (key == 'Q' && mask == MASK_CONTROL)
 163	{
 164		result = FALSE;
 165	}
 166	else if (mParent)
 167	{
 168		mParent->setKey(key);
 169	}
 170	closeFloater();
 171	return result;
 172}
 173
 174//static
 175void LLVoiceSetKeyDialog::onCancel(void* user_data)
 176{
 177	LLVoiceSetKeyDialog* self = (LLVoiceSetKeyDialog*)user_data;
 178	self->closeFloater();
 179}
 180
 181
 182// global functions 
 183
 184// helper functions for getting/freeing the web browser media
 185// if creating/destroying these is too slow, we'll need to create
 186// a static member and update all our static callbacks
 187
 188void handleNameTagOptionChanged(const LLSD& newvalue);	
 189void handleDisplayNamesOptionChanged(const LLSD& newvalue);	
 190bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response);
 191bool callback_clear_cache(const LLSD& notification, const LLSD& response);
 192
 193//bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
 194//bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
 195
 196void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
 197
 198bool callback_clear_cache(const LLSD& notification, const LLSD& response)
 199{
 200	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 201	if ( option == 0 ) // YES
 202	{
 203		// flag client texture cache for clearing next time the client runs
 204		gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
 205		LLNotificationsUtil::add("CacheWillClear");
 206	}
 207
 208	return false;
 209}
 210
 211bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response)
 212{
 213	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 214	if ( option == 0 ) // YES
 215	{
 216		// clean web
 217		LLViewerMedia::clearAllCaches();
 218		LLViewerMedia::clearAllCookies();
 219		
 220		// clean nav bar history
 221		LLNavigationBar::getInstance()->clearHistoryCache();
 222		
 223		// flag client texture cache for clearing next time the client runs
 224		gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
 225		LLNotificationsUtil::add("CacheWillClear");
 226
 227		LLSearchHistory::getInstance()->clearHistory();
 228		LLSearchHistory::getInstance()->save();
 229		LLSearchComboBox* search_ctrl = LLNavigationBar::getInstance()->getChild<LLSearchComboBox>("search_combo_box");
 230		search_ctrl->clearHistory();
 231
 232		LLTeleportHistoryStorage::getInstance()->purgeItems();
 233		LLTeleportHistoryStorage::getInstance()->save();
 234	}
 235	
 236	return false;
 237}
 238
 239void handleNameTagOptionChanged(const LLSD& newvalue)
 240{
 241	LLVOAvatar::invalidateNameTags();
 242}
 243
 244void handleDisplayNamesOptionChanged(const LLSD& newvalue)
 245{
 246	LLAvatarNameCache::setUseDisplayNames(newvalue.asBoolean());
 247	LLVOAvatar::invalidateNameTags();
 248}
 249
 250
 251/*bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
 252{
 253	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 254	if (0 == option && floater )
 255	{
 256		if ( floater )
 257		{
 258			floater->setAllIgnored();
 259		//	LLFirstUse::disableFirstUse();
 260			floater->buildPopupLists();
 261		}
 262	}
 263	return false;
 264}
 265
 266bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
 267{
 268	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 269	if ( 0 == option && floater )
 270	{
 271		if ( floater )
 272		{
 273			floater->resetAllIgnored();
 274			//LLFirstUse::resetFirstUse();
 275			floater->buildPopupLists();
 276		}
 277	}
 278	return false;
 279}
 280*/
 281
 282void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
 283{
 284	numerator = 0;
 285	denominator = 0;
 286	for (F32 test_denominator = 1.f; test_denominator < 30.f; test_denominator += 1.f)
 287	{
 288		if (fmodf((decimal_val * test_denominator) + 0.01f, 1.f) < 0.02f)
 289		{
 290			numerator = llround(decimal_val * test_denominator);
 291			denominator = llround(test_denominator);
 292			break;
 293		}
 294	}
 295}
 296// static
 297std::string LLFloaterPreference::sSkin = "";
 298//////////////////////////////////////////////
 299// LLFloaterPreference
 300
 301LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 302	: LLFloater(key),
 303	mGotPersonalInfo(false),
 304	mOriginalIMViaEmail(false),
 305	mLanguageChanged(false),
 306	mAvatarDataInitialized(false),
 307	mClickActionDirty(false)
 308{
 309	
 310	//Build Floater is now Called from 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
 311	
 312	static bool registered_dialog = false;
 313	if (!registered_dialog)
 314	{
 315		LLFloaterReg::add("voice_set_key", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLVoiceSetKeyDialog>);
 316		registered_dialog = true;
 317	}
 318	
 319	mCommitCallbackRegistrar.add("Pref.Apply",				boost::bind(&LLFloaterPreference::onBtnApply, this));
 320	mCommitCallbackRegistrar.add("Pref.Cancel",				boost::bind(&LLFloaterPreference::onBtnCancel, this));
 321	mCommitCallbackRegistrar.add("Pref.OK",					boost::bind(&LLFloaterPreference::onBtnOK, this));
 322	
 323	mCommitCallbackRegistrar.add("Pref.ClearCache",				boost::bind(&LLFloaterPreference::onClickClearCache, this));
 324	mCommitCallbackRegistrar.add("Pref.WebClearCache",			boost::bind(&LLFloaterPreference::onClickBrowserClearCache, this));
 325	mCommitCallbackRegistrar.add("Pref.SetCache",				boost::bind(&LLFloaterPreference::onClickSetCache, this));
 326	mCommitCallbackRegistrar.add("Pref.ResetCache",				boost::bind(&LLFloaterPreference::onClickResetCache, this));
 327	mCommitCallbackRegistrar.add("Pref.ClickSkin",				boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2));
 328	mCommitCallbackRegistrar.add("Pref.SelectSkin",				boost::bind(&LLFloaterPreference::onSelectSkin, this));
 329	mCommitCallbackRegistrar.add("Pref.VoiceSetKey",			boost::bind(&LLFloaterPreference::onClickSetKey, this));
 330	mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse",	boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
 331	mCommitCallbackRegistrar.add("Pref.SetSounds",				boost::bind(&LLFloaterPreference::onClickSetSounds, this));
 332//	mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs",		boost::bind(&LLFloaterPreference::onClickSkipDialogs, this));
 333//	mCommitCallbackRegistrar.add("Pref.ClickResetDialogs",		boost::bind(&LLFloaterPreference::onClickResetDialogs, this));
 334	mCommitCallbackRegistrar.add("Pref.ClickEnablePopup",		boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
 335	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
 336	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));
 337	mCommitCallbackRegistrar.add("Pref.HardwareSettings",		boost::bind(&LLFloaterPreference::onOpenHardwareSettings, this));
 338	mCommitCallbackRegistrar.add("Pref.HardwareDefaults",		boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
 339	mCommitCallbackRegistrar.add("Pref.VertexShaderEnable",		boost::bind(&LLFloaterPreference::onVertexShaderEnable, this));
 340	mCommitCallbackRegistrar.add("Pref.WindowedMod",			boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
 341	mCommitCallbackRegistrar.add("Pref.UpdateSliderText",		boost::bind(&LLFloaterPreference::onUpdateSliderText,this, _1,_2));
 342	mCommitCallbackRegistrar.add("Pref.QualityPerformance",		boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
 343	mCommitCallbackRegistrar.add("Pref.applyUIColor",			boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
 344	mCommitCallbackRegistrar.add("Pref.getUIColor",				boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
 345	mCommitCallbackRegistrar.add("Pref.MaturitySettings",		boost::bind(&LLFloaterPreference::onChangeMaturity, this));
 346	mCommitCallbackRegistrar.add("Pref.BlockList",				boost::bind(&LLFloaterPreference::onClickBlockList, this));
 347	mCommitCallbackRegistrar.add("Pref.Proxy",					boost::bind(&LLFloaterPreference::onClickProxySettings, this));
 348	mCommitCallbackRegistrar.add("Pref.TranslationSettings",	boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
 349	
 350	sSkin = gSavedSettings.getString("SkinCurrent");
 351
 352	mCommitCallbackRegistrar.add("Pref.ClickActionChange",				boost::bind(&LLFloaterPreference::onClickActionChange, this));
 353
 354	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 355	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 356	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
 357
 358	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
 359}
 360
 361void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
 362{
 363	if ( APT_PROPERTIES == type )
 364	{
 365		const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
 366		if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
 367		{
 368			storeAvatarProperties( pAvatarData );
 369			processProfileProperties( pAvatarData );
 370		}
 371	}	
 372}
 373
 374void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
 375{
 376	if (LLStartUp::getStartupState() == STATE_STARTED)
 377	{
 378		mAvatarProperties.avatar_id		= pAvatarData->avatar_id;
 379		mAvatarProperties.image_id		= pAvatarData->image_id;
 380		mAvatarProperties.fl_image_id   = pAvatarData->fl_image_id;
 381		mAvatarProperties.about_text	= pAvatarData->about_text;
 382		mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
 383		mAvatarProperties.profile_url   = pAvatarData->profile_url;
 384		mAvatarProperties.flags		    = pAvatarData->flags;
 385		mAvatarProperties.allow_publish	= pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
 386
 387		mAvatarDataInitialized = true;
 388	}
 389}
 390
 391void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
 392{
 393	getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );	
 394}
 395
 396void LLFloaterPreference::saveAvatarProperties( void )
 397{
 398	const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
 399
 400	if (allowPublish)
 401	{
 402		mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
 403	}
 404
 405	//
 406	// NOTE: We really don't want to send the avatar properties unless we absolutely
 407	//       need to so we can avoid the accidental profile reset bug, so, if we're
 408	//       logged in, the avatar data has been initialized and we have a state change
 409	//       for the "allow publish" flag, then set the flag to its new value and send
 410	//       the properties update.
 411	//
 412	// NOTE: The only reason we can not remove this update altogether is because of the
 413	//       "allow publish" flag, the last remaining profile setting in the viewer
 414	//       that doesn't exist in the web profile.
 415	//
 416	if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
 417	{
 418		mAvatarProperties.allow_publish = allowPublish;
 419
 420		LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
 421	}
 422}
 423
 424BOOL LLFloaterPreference::postBuild()
 425{
 426	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
 427
 428	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
 429
 430	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
 431
 432	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
 433
 434	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 435
 436	gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));
 437
 438	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
 439	if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
 440		tabcontainer->selectFirstTab();
 441
 442	getChild<LLUICtrl>("cache_location")->setEnabled(FALSE); // make it read-only but selectable (STORM-227)
 443	std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
 444	setCacheLocation(cache_location);
 445
 446	getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
 447
 448	// if floater is opened before login set default localized busy message
 449	if (LLStartUp::getStartupState() < STATE_STARTED)
 450	{
 451		gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
 452	}
 453
 454	return TRUE;
 455}
 456
 457void LLFloaterPreference::onBusyResponseChanged()
 458{
 459	// set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
 460	if (LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString())
 461	{
 462		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE );
 463	}
 464	else
 465	{
 466		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE );
 467	}
 468}
 469
 470LLFloaterPreference::~LLFloaterPreference()
 471{
 472	// clean up user data
 473	LLComboBox* ctrl_window_size = getChild<LLComboBox>("windowsize combo");
 474	for (S32 i = 0; i < ctrl_window_size->getItemCount(); i++)
 475	{
 476		ctrl_window_size->setCurrentByIndex(i);
 477	}
 478}
 479
 480void LLFloaterPreference::draw()
 481{
 482	BOOL has_first_selected = (getChildRef<LLScrollListCtrl>("disabled_popups").getFirstSelected()!=NULL);
 483	gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected);
 484	
 485	has_first_selected = (getChildRef<LLScrollListCtrl>("enabled_popups").getFirstSelected()!=NULL);
 486	gSavedSettings.setBOOL("FirstSelectedEnabledPopups", has_first_selected);
 487	
 488	LLFloater::draw();
 489}
 490
 491void LLFloaterPreference::saveSettings()
 492{
 493	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
 494	child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
 495	child_list_t::const_iterator end = tabcontainer->getChildList()->end();
 496	for ( ; iter != end; ++iter)
 497	{
 498		LLView* view = *iter;
 499		LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
 500		if (panel)
 501			panel->saveSettings();
 502	}
 503}	
 504
 505void LLFloaterPreference::apply()
 506{
 507	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
 508	
 509	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
 510	if (sSkin != gSavedSettings.getString("SkinCurrent"))
 511	{
 512		LLNotificationsUtil::add("ChangeSkin");
 513		refreshSkin(this);
 514	}
 515	// Call apply() on all panels that derive from LLPanelPreference
 516	for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
 517		 iter != tabcontainer->getChildList()->end(); ++iter)
 518	{
 519		LLView* view = *iter;
 520		LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
 521		if (panel)
 522			panel->apply();
 523	}
 524	// hardware menu apply
 525	LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
 526	if (hardware_settings)
 527	{
 528		hardware_settings->apply();
 529	}
 530	
 531	gViewerWindow->requestResolutionUpdate(); // for UIScaleFactor
 532
 533	LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
 534	fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
 535	fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
 536	
 537	std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
 538	setCacheLocation(cache_location);
 539	
 540	LLViewerMedia::setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue());
 541	
 542	if (hasChild("web_proxy_enabled") &&hasChild("web_proxy_editor") && hasChild("web_proxy_port"))
 543	{
 544		bool proxy_enable = getChild<LLUICtrl>("web_proxy_enabled")->getValue();
 545		std::string proxy_address = getChild<LLUICtrl>("web_proxy_editor")->getValue();
 546		int proxy_port = getChild<LLUICtrl>("web_proxy_port")->getValue();
 547		LLViewerMedia::setProxyConfig(proxy_enable, proxy_address, proxy_port);
 548	}
 549	
 550//	LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString());
 551//	LLWStringUtil::replaceTabsWithSpaces(busy_response, 4);
 552
 553	gSavedSettings.setBOOL("PlainTextChatHistory", getChild<LLUICtrl>("plain_text_chat_history")->getValue().asBoolean());
 554	
 555	if (mGotPersonalInfo)
 556	{ 
 557//		gSavedSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response)));
 558		bool new_im_via_email = getChild<LLUICtrl>("send_im_to_email")->getValue().asBoolean();
 559		bool new_hide_online = getChild<LLUICtrl>("online_visibility")->getValue().asBoolean();		
 560	
 561		if ((new_im_via_email != mOriginalIMViaEmail)
 562			||(new_hide_online != mOriginalHideOnlineStatus))
 563		{
 564			// This hack is because we are representing several different 	 
 565			// possible strings with a single checkbox. Since most users 	 
 566			// can only select between 2 values, we represent it as a 	 
 567			// checkbox. This breaks down a little bit for liaisons, but 	 
 568			// works out in the end. 	 
 569			if (new_hide_online != mOriginalHideOnlineStatus)
 570			{
 571				if (new_hide_online) mDirectoryVisibility = VISIBILITY_HIDDEN;
 572				else mDirectoryVisibility = VISIBILITY_DEFAULT;
 573			 //Update showonline value, otherwise multiple applys won't work
 574				mOriginalHideOnlineStatus = new_hide_online;
 575			}
 576			gAgent.sendAgentUpdateUserInfo(new_im_via_email,mDirectoryVisibility);
 577		}
 578	}
 579
 580	saveAvatarProperties();
 581
 582	if (mClickActionDirty)
 583	{
 584		updateClickActionSettings();
 585		mClickActionDirty = false;
 586	}
 587}
 588
 589void LLFloaterPreference::cancel()
 590{
 591	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
 592	// Call cancel() on all panels that derive from LLPanelPreference
 593	for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
 594		iter != tabcontainer->getChildList()->end(); ++iter)
 595	{
 596		LLView* view = *iter;
 597		LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
 598		if (panel)
 599			panel->cancel();
 600	}
 601	// hide joystick pref floater
 602	LLFloaterReg::hideInstance("pref_joystick");
 603
 604	// hide translation settings floater
 605	LLFloaterReg::hideInstance("prefs_translation");
 606	
 607	// cancel hardware menu
 608	LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
 609	if (hardware_settings)
 610	{
 611		hardware_settings->cancel();
 612	}
 613	
 614	// reverts any changes to current skin
 615	gSavedSettings.setString("SkinCurrent", sSkin);
 616
 617	if (mClickActionDirty)
 618	{
 619		updateClickActionControls();
 620		mClickActionDirty = false;
 621	}
 622
 623	LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy");
 624	if (advanced_proxy_settings)
 625	{
 626		advanced_proxy_settings->cancel();
 627	}
 628}
 629
 630void LLFloaterPreference::onOpen(const LLSD& key)
 631{
 632	
 633	// this variable and if that follows it are used to properly handle busy mode response message
 634	static bool initialized = FALSE;
 635	// if user is logged in and we haven't initialized busy_response yet, do it
 636	if (!initialized && LLStartUp::getStartupState() == STATE_STARTED)
 637	{
 638		// Special approach is used for busy response localization, because "BusyModeResponse" is
 639		// in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized.
 640		// To keep track of whether busy response is default or changed by user additional setting BusyResponseChanged
 641		// was added into per account settings.
 642
 643		// initialization should happen once,so setting variable to TRUE
 644		initialized = TRUE;
 645		// this connection is needed to properly set "BusyResponseChanged" setting when user makes changes in
 646		// busy response message.
 647		gSavedPerAccountSettings.getControl("BusyModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onBusyResponseChanged, this));
 648	}
 649	gAgent.sendAgentUserInfoRequest();
 650
 651	/////////////////////////// From LLPanelGeneral //////////////////////////
 652	// if we have no agent, we can't let them choose anything
 653	// if we have an agent, then we only let them choose if they have a choice
 654	bool can_choose_maturity =
 655		gAgent.getID().notNull() &&
 656		(gAgent.isMature() || gAgent.isGodlike());
 657	
 658	LLComboBox* maturity_combo = getChild<LLComboBox>("maturity_desired_combobox");
 659	LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest( gAgent.getID() );
 660	if (can_choose_maturity)
 661	{		
 662		// if they're not adult or a god, they shouldn't see the adult selection, so delete it
 663		if (!gAgent.isAdult() && !gAgent.isGodlikeWithoutAdminMenuFakery())
 664		{
 665			// we're going to remove the adult entry from the combo
 666			LLScrollListCtrl* maturity_list = maturity_combo->findChild<LLScrollListCtrl>("ComboBox");
 667			if (maturity_list)
 668			{
 669				maturity_list->deleteItems(LLSD(SIM_ACCESS_ADULT));
 670			}
 671		}
 672		getChildView("maturity_desired_combobox")->setVisible( true);
 673		getChildView("maturity_desired_textbox")->setVisible( false);
 674	}
 675	else
 676	{
 677		getChild<LLUICtrl>("maturity_desired_textbox")->setValue(maturity_combo->getSelectedItemLabel());
 678		getChildView("maturity_desired_combobox")->setVisible( false);
 679	}
 680
 681	// Forget previous language changes.
 682	mLanguageChanged = false;
 683
 684	// Display selected maturity icons.
 685	onChangeMaturity();
 686	
 687	// Load (double-)click to walk/teleport settings.
 688	updateClickActionControls();
 689	
 690	// Enabled/disabled popups, might have been changed by user actions
 691	// while preferences floater was closed.
 692	buildPopupLists();
 693
 694	LLPanelLogin::setAlwaysRefresh(true);
 695	refresh();
 696	
 697	// Make sure the current state of prefs are saved away when
 698	// when the floater is opened.  That will make cancel do its
 699	// job
 700	saveSettings();
 701}
 702
 703void LLFloaterPreference::onVertexShaderEnable()
 704{
 705	refreshEnabledGraphics();
 706}
 707
 708//static
 709void LLFloaterPreference::initBusyResponse()
 710	{
 711		if (!gSavedPerAccountSettings.getBOOL("BusyResponseChanged"))
 712		{
 713			//LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885)
 714			gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
 715		}
 716	}
 717
 718void LLFloaterPreference::setHardwareDefaults()
 719{
 720	LLFeatureManager::getInstance()->applyRecommendedSettings();
 721	refreshEnabledGraphics();
 722	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
 723	child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
 724	child_list_t::const_iterator end = tabcontainer->getChildList()->end();
 725	for ( ; iter != end; ++iter)
 726	{
 727		LLView* view = *iter;
 728		LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
 729		if (panel)
 730			panel->setHardwareDefaults();
 731	}
 732}
 733
 734//virtual
 735void LLFloaterPreference::onClose(bool app_quitting)
 736{
 737	gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());
 738	LLPanelLogin::setAlwaysRefresh(false);
 739	cancel();
 740}
 741
 742void LLFloaterPreference::onOpenHardwareSettings()
 743{
 744	LLFloaterReg::showInstance("prefs_hardware_settings");
 745}
 746// static 
 747void LLFloaterPreference::onBtnOK()
 748{
 749	// commit any outstanding text entry
 750	if (hasFocus())
 751	{
 752		LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
 753		if (cur_focus && cur_focus->acceptsTextInput())
 754		{
 755			cur_focus->onCommit();
 756		}
 757	}
 758
 759	if (canClose())
 760	{
 761		saveSettings();
 762		apply();
 763		closeFloater(false);
 764
 765		LLUIColorTable::instance().saveUserSettings();
 766		gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
 767	}
 768	else
 769	{
 770		// Show beep, pop up dialog, etc.
 771		llinfos << "Can't close preferences!" << llendl;
 772	}
 773
 774	LLPanelLogin::updateLocationCombo( false );
 775}
 776
 777// static 
 778void LLFloaterPreference::onBtnApply( )
 779{
 780	if (hasFocus())
 781	{
 782		LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
 783		if (cur_focus && cur_focus->acceptsTextInput())
 784		{
 785			cur_focus->onCommit();
 786		}
 787	}
 788	apply();
 789	saveSettings();
 790
 791	LLPanelLogin::updateLocationCombo( false );
 792}
 793
 794// static 
 795void LLFloaterPreference::onBtnCancel()
 796{
 797	if (hasFocus())
 798	{
 799		LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
 800		if (cur_focus && cur_focus->acceptsTextInput())
 801		{
 802			cur_focus->onCommit();
 803		}
 804		refresh();
 805	}
 806	cancel();
 807	closeFloater();
 808}
 809
 810// static 
 811void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
 812{
 813	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
 814	if (instance)
 815	{
 816		instance->setPersonalInfo(visibility, im_via_email, email);	
 817	}
 818}
 819
 820
 821void LLFloaterPreference::refreshEnabledGraphics()
 822{
 823	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
 824	if (instance)
 825	{
 826		instance->refresh();
 827		//instance->refreshEnabledState();
 828	}
 829	LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
 830	if (hardware_settings)
 831	{
 832		hardware_settings->refreshEnabledState();
 833	}
 834}
 835
 836void LLFloaterPreference::onClickClearCache()
 837{
 838	LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache);
 839}
 840
 841void LLFloaterPreference::onClickBrowserClearCache()
 842{
 843	LLNotificationsUtil::add("ConfirmClearBrowserCache", LLSD(), LLSD(), callback_clear_browser_cache);
 844}
 845
 846// Called when user changes language via the combobox.
 847void LLFloaterPreference::onLanguageChange()
 848{
 849	// Let the user know that the change will only take effect after restart.
 850	// Do it only once so that we're not too irritating.
 851	if (!mLanguageChanged)
 852	{
 853		LLNotificationsUtil::add("ChangeLanguage");
 854		mLanguageChanged = true;
 855	}
 856}
 857
 858void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
 859{
 860	LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background");
 861	if (color_swatch)
 862	{
 863		LLColor4 new_color = color_swatch->get();
 864		color_swatch->set( new_color.setAlpha(newvalue.asReal()) );
 865	}
 866}
 867
 868void LLFloaterPreference::onClickSetCache()
 869{
 870	std::string cur_name(gSavedSettings.getString("CacheLocation"));
 871//	std::string cur_top_folder(gDirUtilp->getBaseFileName(cur_name));
 872	
 873	std::string proposed_name(cur_name);
 874
 875	LLDirPicker& picker = LLDirPicker::instance();
 876	if (! picker.getDir(&proposed_name ) )
 877	{
 878		return; //Canceled!
 879	}
 880
 881	std::string dir_name = picker.getDirName();
 882	if (!dir_name.empty() && dir_name != cur_name)
 883	{
 884		std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));	
 885		LLNotificationsUtil::add("CacheWillBeMoved");
 886		gSavedSettings.setString("NewCacheLocation", dir_name);
 887		gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder);
 888	}
 889	else
 890	{
 891		std::string cache_location = gDirUtilp->getCacheDir();
 892		gSavedSettings.setString("CacheLocation", cache_location);
 893		std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
 894		gSavedSettings.setString("CacheLocationTopFolder", top_folder);
 895	}
 896}
 897
 898void LLFloaterPreference::onClickResetCache()
 899{
 900	if (gDirUtilp->getCacheDir(false) == gDirUtilp->getCacheDir(true))
 901	{
 902		// The cache location was already the default.
 903		return;
 904	}
 905	gSavedSettings.setString("NewCacheLocation", "");
 906	gSavedSettings.setString("NewCacheLocationTopFolder", "");
 907	LLNotificationsUtil::add("CacheWillBeMoved");
 908	std::string cache_location = gDirUtilp->getCacheDir(false);
 909	gSavedSettings.setString("CacheLocation", cache_location);
 910	std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
 911	gSavedSettings.setString("CacheLocationTopFolder", top_folder);
 912}
 913
 914void LLFloaterPreference::onClickSkin(LLUICtrl* ctrl, const LLSD& userdata)
 915{
 916	gSavedSettings.setString("SkinCurrent", userdata.asString());
 917	ctrl->setValue(userdata.asString());
 918}
 919
 920void LLFloaterPreference::onSelectSkin()
 921{
 922	std::string skin_selection = getChild<LLRadioGroup>("skin_selection")->getValue().asString();
 923	gSavedSettings.setString("SkinCurrent", skin_selection);
 924}
 925
 926void LLFloaterPreference::refreshSkin(void* data)
 927{
 928	LLPanel*self = (LLPanel*)data;
 929	sSkin = gSavedSettings.getString("SkinCurrent");
 930	self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
 931}
 932
 933
 934void LLFloaterPreference::buildPopupLists()
 935{
 936	LLScrollListCtrl& disabled_popups =
 937		getChildRef<LLScrollListCtrl>("disabled_popups");
 938	LLScrollListCtrl& enabled_popups =
 939		getChildRef<LLScrollListCtrl>("enabled_popups");
 940	
 941	disabled_popups.deleteAllItems();
 942	enabled_popups.deleteAllItems();
 943	
 944	for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
 945		 iter != LLNotifications::instance().templatesEnd();
 946		 ++iter)
 947	{
 948		LLNotificationTemplatePtr templatep = iter->second;
 949		LLNotificationFormPtr formp = templatep->mForm;
 950		
 951		LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
 952		if (ignore == LLNotificationForm::IGNORE_NO)
 953			continue;
 954		
 955		LLSD row;
 956		row["columns"][0]["value"] = formp->getIgnoreMessage();
 957		row["columns"][0]["font"] = "SANSSERIF_SMALL";
 958		row["columns"][0]["width"] = 400;
 959		
 960		LLScrollListItem* item = NULL;
 961		
 962		bool show_popup = !formp->getIgnored();
 963		if (!show_popup)
 964		{
 965			if (ignore == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
 966			{
 967				LLSD last_response = LLUI::sSettingGroups["config"]->getLLSD("Default" + templatep->mName);
 968				if (!last_response.isUndefined())
 969				{
 970					for (LLSD::map_const_iterator it = last_response.beginMap();
 971						 it != last_response.endMap();
 972						 ++it)
 973					{
 974						if (it->second.asBoolean())
 975						{
 976							row["columns"][1]["value"] = formp->getElement(it->first)["ignore"].asString();
 977							break;
 978						}
 979					}
 980				}
 981				row["columns"][1]["font"] = "SANSSERIF_SMALL";
 982				row["columns"][1]["width"] = 360;
 983			}
 984			item = disabled_popups.addElement(row);
 985		}
 986		else
 987		{
 988			item = enabled_popups.addElement(row);
 989		}
 990		
 991		if (item)
 992		{
 993			item->setUserdata((void*)&iter->first);
 994		}
 995	}
 996}
 997
 998void LLFloaterPreference::refreshEnabledState()
 999{	
1000	LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
1001	LLRadioGroup* radio_reflection_detail = getChild<LLRadioGroup>("ReflectionDetailRadio");
1002	
1003	// Reflections
1004	BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable") 
1005		&& gGLManager.mHasCubeMap
1006		&& LLCubeMap::sUseCubeMaps;
1007	ctrl_reflections->setEnabled(reflections);
1008	
1009	// Bump & Shiny	
1010	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
1011	getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE);
1012	
1013	radio_reflection_detail->setEnabled(reflections);
1014	
1015	// Avatar Mode
1016	// Enable Avatar Shaders
1017	LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
1018	// Avatar Render Mode
1019	LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
1020	
1021	bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP");
1022	if (LLViewerShaderMgr::sInitialized)
1023	{
1024		S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel;
1025		avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE;
1026	}
1027
1028	ctrl_avatar_vp->setEnabled(avatar_vp_enabled);
1029	
1030	if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE || 
1031		gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
1032	{
1033		ctrl_avatar_cloth->setEnabled(false);
1034	} 
1035	else
1036	{
1037		ctrl_avatar_cloth->setEnabled(true);
1038	}
1039	
1040	// Vertex Shaders
1041	// Global Shader Enable
1042	LLCheckBoxCtrl* ctrl_shader_enable   = getChild<LLCheckBoxCtrl>("BasicShaders");
1043	// radio set for terrain detail mode
1044	LLRadioGroup*   mRadioTerrainDetail = getChild<LLRadioGroup>("TerrainDetailRadio");   // can be linked with control var
1045	
1046	ctrl_shader_enable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"));
1047	
1048	BOOL shaders = ctrl_shader_enable->get();
1049	if (shaders)
1050	{
1051		mRadioTerrainDetail->setValue(1);
1052		mRadioTerrainDetail->setEnabled(FALSE);
1053	}
1054	else
1055	{
1056		mRadioTerrainDetail->setEnabled(TRUE);		
1057	}
1058	
1059	// WindLight
1060	LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
1061	
1062	// *HACK just checks to see if we can use shaders... 
1063	// maybe some cards that use shaders, but don't support windlight
1064	ctrl_wind_light->setEnabled(ctrl_shader_enable->getEnabled() && shaders);
1065
1066	//Deferred/SSAO/Shadows
1067	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
1068	
1069	BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && 
1070						shaders && 
1071						gGLManager.mHasFramebufferObject &&
1072						gSavedSettings.getBOOL("RenderAvatarVP") &&
1073						(ctrl_wind_light->get()) ? TRUE : FALSE;
1074
1075	ctrl_deferred->setEnabled(enabled);
1076	
1077	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
1078	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
1079	LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
1080
1081	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
1082		
1083	ctrl_ssao->setEnabled(enabled);
1084	ctrl_dof->setEnabled(enabled);
1085
1086	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail");
1087
1088	ctrl_shadow->setEnabled(enabled);
1089	
1090
1091	// now turn off any features that are unavailable
1092	disableUnavailableSettings();
1093
1094	getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
1095}
1096
1097void LLFloaterPreference::disableUnavailableSettings()
1098{	
1099	LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections");
1100	LLCheckBoxCtrl* ctrl_avatar_vp     = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
1101	LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth");
1102	LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");
1103	LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
1104	LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
1105	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
1106	LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
1107	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
1108	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
1109
1110	// if vertex shaders off, disable all shader related products
1111	if (!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"))
1112	{
1113		ctrl_shader_enable->setEnabled(FALSE);
1114		ctrl_shader_enable->setValue(FALSE);
1115		
1116		ctrl_wind_light->setEnabled(FALSE);
1117		ctrl_wind_light->setValue(FALSE);
1118		
1119		ctrl_reflections->setEnabled(FALSE);
1120		ctrl_reflections->setValue(0);
1121		
1122		ctrl_avatar_vp->setEnabled(FALSE);
1123		ctrl_avatar_vp->setValue(FALSE);
1124		
1125		ctrl_avatar_cloth->setEnabled(FALSE);
1126		ctrl_avatar_cloth->setValue(FALSE);
1127
1128		ctrl_shadows->setEnabled(FALSE);
1129		ctrl_shadows->setValue(0);
1130		
1131		ctrl_ssao->setEnabled(FALSE);
1132		ctrl_ssao->setValue(FALSE);
1133
1134		ctrl_dof->setEnabled(FALSE);
1135		ctrl_dof->setValue(FALSE);
1136
1137		ctrl_deferred->setEnabled(FALSE);
1138		ctrl_deferred->setValue(FALSE);
1139	}
1140	
1141	// disabled windlight
1142	if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
1143	{
1144		ctrl_wind_light->setEnabled(FALSE);
1145		ctrl_wind_light->setValue(FALSE);
1146
1147		//deferred needs windlight, disable deferred
1148		ctrl_shadows->setEnabled(FALSE);
1149		ctrl_shadows->setValue(0);
1150		
1151		ctrl_ssao->setEnabled(FALSE);
1152		ctrl_ssao->setValue(FALSE);
1153
1154		ctrl_dof->setEnabled(FALSE);
1155		ctrl_dof->setValue(FALSE);
1156
1157		ctrl_deferred->setEnabled(FALSE);
1158		ctrl_deferred->setValue(FALSE);
1159	}
1160
1161	// disabled deferred
1162	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
1163		!gGLManager.mHasFramebufferObject)
1164	{
1165		ctrl_shadows->setEnabled(FALSE);
1166		ctrl_shadows->setValue(0);
1167		
1168		ctrl_ssao->setEnabled(FALSE);
1169		ctrl_ssao->setValue(FALSE);
1170
1171		ctrl_dof->setEnabled(FALSE);
1172		ctrl_dof->setValue(FALSE);
1173
1174		ctrl_deferred->setEnabled(FALSE);
1175		ctrl_deferred->setValue(FALSE);
1176	}
1177	
1178	// disabled deferred SSAO
1179	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
1180	{
1181		ctrl_ssao->setEnabled(FALSE);
1182		ctrl_ssao->setValue(FALSE);
1183	}
1184	
1185	// disabled deferred shadows
1186	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
1187	{
1188		ctrl_shadows->setEnabled(FALSE);
1189		ctrl_shadows->setValue(0);
1190	}
1191
1192	// disabled reflections
1193	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
1194	{
1195		ctrl_reflections->setEnabled(FALSE);
1196		ctrl_reflections->setValue(FALSE);
1197	}
1198	
1199	// disabled av
1200	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
1201	{
1202		ctrl_avatar_vp->setEnabled(FALSE);
1203		ctrl_avatar_vp->setValue(FALSE);
1204		
1205		ctrl_avatar_cloth->setEnabled(FALSE);
1206		ctrl_avatar_cloth->setValue(FALSE);
1207
1208		//deferred needs AvatarVP, disable deferred
1209		ctrl_shadows->setEnabled(FALSE);
1210		ctrl_shadows->setValue(0);
1211		
1212		ctrl_ssao->setEnabled(FALSE);
1213		ctrl_ssao->setValue(FALSE);
1214
1215		ctrl_dof->setEnabled(FALSE);
1216		ctrl_dof->setValue(FALSE);
1217
1218		ctrl_deferred->setEnabled(FALSE);
1219		ctrl_deferred->setValue(FALSE);
1220	}
1221
1222	// disabled cloth
1223	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
1224	{
1225		ctrl_avatar_cloth->setEnabled(FALSE);
1226		ctrl_avatar_cloth->setValue(FALSE);
1227	}
1228
1229	// disabled impostors
1230	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors"))
1231	{
1232		ctrl_avatar_impostors->setEnabled(FALSE);
1233		ctrl_avatar_impostors->setValue(FALSE);
1234	}
1235}
1236
1237void LLFloaterPreference::refresh()
1238{
1239	LLPanel::refresh();
1240
1241	// sliders and their text boxes
1242	//	mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
1243	// slider text boxes
1244	updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail",		true), getChild<LLTextBox>("ObjectMeshDetailText",		true));
1245	updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail",	true), getChild<LLTextBox>("FlexibleMeshDetailText",	true));
1246	updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail",		true), getChild<LLTextBox>("TreeMeshDetailText",		true));
1247	updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail",		true), getChild<LLTextBox>("AvatarMeshDetailText",		true));
1248	updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail",	true), getChild<LLTextBox>("AvatarPhysicsDetailText",		true));
1249	updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail",	true), getChild<LLTextBox>("TerrainMeshDetailText",		true));
1250	updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess",	true), getChild<LLTextBox>("PostProcessText",			true));
1251	updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail",		true), getChild<LLTextBox>("SkyMeshDetailText",			true));
1252	
1253	refreshEnabledState();
1254}
1255
1256void LLFloaterPreference::onCommitWindowedMode()
1257{
1258	refresh();
1259}
1260
1261void LLFloaterPreference::onChangeQuality(const LLSD& data)
1262{
1263	U32 level = (U32)(data.asReal());
1264	LLFeatureManager::getInstance()->setGraphicsLevel(level, true);
1265	refreshEnabledGraphics();
1266	refresh();
1267}
1268
1269void LLFloaterPreference::onClickSetKey()
1270{
1271	LLVoiceSetKeyDialog* dialog = LLFloaterReg::showTypedInstance<LLVoiceSetKeyDialog>("voice_set_key", LLSD(), TRUE);
1272	if (dialog)
1273	{
1274		dialog->setParent(this);
1275	}
1276}
1277
1278void LLFloaterPreference::setKey(KEY key)
1279{
1280	getChild<LLUICtrl>("modifier_combo")->setValue(LLKeyboard::stringFromKey(key));
1281	// update the control right away since we no longer wait for apply
1282	getChild<LLUICtrl>("modifier_combo")->onCommit();
1283}
1284
1285void LLFloaterPreference::onClickSetMiddleMouse()
1286{
1287	LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
1288
1289	// update the control right away since we no longer wait for apply
1290	p2t_line_editor->setControlValue(MIDDLE_MOUSE_CV);
1291
1292	//push2talk button "middle mouse" control value is in English, need to localize it for presentation
1293	LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
1294	if (advanced_preferences)
1295	{
1296		p2t_line_editor->setValue(advanced_preferences->getString("middle_mouse"));
1297	}
1298}
1299
1300void LLFloaterPreference::onClickSetSounds()
1301{
1302	// Disable Enable gesture sounds checkbox if the master sound is disabled 
1303	// or if sound effects are disabled.
1304	getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
1305}
1306
1307/*
1308void LLFloaterPreference::onClickSkipDialogs()
1309{
1310	LLNotificationsUtil::add("SkipShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_skip_dialogs, _1, _2, this));
1311}
1312
1313void LLFloaterPreference::onClickResetDialogs()
1314{
1315	LLNotificationsUtil::add("ResetShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_reset_dialogs, _1, _2, this));
1316}
1317 */
1318
1319void LLFloaterPreference::onClickEnablePopup()
1320{	
1321	LLScrollListCtrl& disabled_popups = getChildRef<LLScrollListCtrl>("disabled_popups");
1322	
1323	std::vector<LLScrollListItem*> items = disabled_popups.getAllSelected();
1324	std::vector<LLScrollListItem*>::iterator itor;
1325	for (itor = items.begin(); itor != items.end(); ++itor)
1326	{
1327		LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
1328		//gSavedSettings.setWarning(templatep->mName, TRUE);
1329		std::string notification_name = templatep->mName;
1330		LLUI::sSettingGroups["ignores"]->setBOOL(notification_name, TRUE);
1331	}
1332	
1333	buildPopupLists();
1334}
1335
1336void LLFloaterPreference::onClickDisablePopup()
1337{	
1338	LLScrollListCtrl& enabled_popups = getChildRef<LLScrollListCtrl>("enabled_popups");
1339	
1340	std::vector<LLScrollListItem*> items = enabled_popups.getAllSelected();
1341	std::vector<LLScrollListItem*>::iterator itor;
1342	for (itor = items.begin(); itor != items.end(); ++itor)
1343	{
1344		LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
1345		templatep->mForm->setIgnored(true);
1346	}
1347	
1348	buildPopupLists();
1349}
1350
1351void LLFloaterPreference::resetAllIgnored()
1352{
1353	for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
1354		 iter != LLNotifications::instance().templatesEnd();
1355		 ++iter)
1356	{
1357		if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
1358		{
1359			iter->second->mForm->setIgnored(false);
1360		}
1361	}
1362}
1363
1364void LLFloaterPreference::setAllIgnored()
1365{
1366	for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
1367		 iter != LLNotifications::instance().templatesEnd();
1368		 ++iter)
1369	{
1370		if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
1371		{
1372			iter->second->mForm->setIgnored(true);
1373		}
1374	}
1375}
1376
1377void LLFloaterPreference::onClickLogPath()
1378{
1379	std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));	 
1380	
1381	LLDirPicker& picker = LLDirPicker::instance();
1382	if (!picker.getDir(&proposed_name ) )
1383	{
1384		return; //Canceled!
1385	}
1386
1387	gSavedPerAccountSettings.setString("InstantMessageLogPath", picker.getDirName());
1388}
1389
1390void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
1391{
1392	mGotPersonalInfo = true;
1393	mOriginalIMViaEmail = im_via_email;
1394	mDirectoryVisibility = visibility;
1395	
1396	if (visibility == VISIBILITY_DEFAULT)
1397	{
1398		mOriginalHideOnlineStatus = false;
1399		getChildView("online_visibility")->setEnabled(TRUE); 	 
1400	}
1401	else if (visibility == VISIBILITY_HIDDEN)
1402	{
1403		mOriginalHideOnlineStatus = true;
1404		getChildView("online_visibility")->setEnabled(TRUE); 	 
1405	}
1406	else
1407	{
1408		mOriginalHideOnlineStatus = true;
1409	}
1410	
1411	getChild<LLUICtrl>("online_searchresults")->setEnabled(TRUE);
1412
1413	getChildView("include_im_in_chat_history")->setEnabled(TRUE);
1414	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
1415	getChildView("friends_online_notify_checkbox")->setEnabled(TRUE);
1416	
1417	getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus); 	 
1418	getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
1419	getChildView("send_im_to_email")->setEnabled(TRUE);
1420	getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
1421	getChildView("plain_text_chat_history")->setEnabled(TRUE);
1422	getChild<LLUICtrl>("plain_text_chat_history")->setValue(gSavedSettings.getBOOL("PlainTextChatHistory"));
1423	getChildView("log_instant_messages")->setEnabled(TRUE);
1424//	getChildView("log_chat")->setEnabled(TRUE);
1425//	getChildView("busy_response")->setEnabled(TRUE);
1426//	getChildView("log_instant_messages_timestamp")->setEnabled(TRUE);
1427//	getChildView("log_chat_timestamp")->setEnabled(TRUE);
1428	getChildView("log_chat_IM")->setEnabled(TRUE);
1429	getChildView("log_date_timestamp")->setEnabled(TRUE);
1430	
1431//	getChild<LLUICtrl>("busy_response")->setValue(gSavedSettings.getString("BusyModeResponse2"));
1432	
1433	getChildView("favorites_on_login_check")->setEnabled(TRUE);
1434	getChildView("log_nearby_chat")->setEnabled(TRUE);
1435	getChildView("log_instant_messages")->setEnabled(TRUE);
1436	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
1437	getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
1438	getChildView("log_path_button")->setEnabled(TRUE);
1439	childEnable("logfile_name_datestamp");	
1440	std::string display_email(email);
1441	getChild<LLUICtrl>("email_address")->setValue(display_email);
1442
1443}
1444
1445void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
1446{
1447	std::string ctrl_name = name.asString();
1448	
1449	if ((ctrl_name =="" )|| !hasChild(ctrl_name, true))
1450		return;
1451	
1452	LLTextBox* text_box = getChild<LLTextBox>(name.asString());
1453	LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl);
1454	updateSliderText(slider, text_box);
1455}
1456
1457void LLFloaterPreference::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
1458{
1459	if (text_box == NULL || ctrl== NULL)
1460		return;
1461	
1462	// get range and points when text should change
1463	F32 value = (F32)ctrl->getValue().asReal();
1464	F32 min = ctrl->getMinValue();
1465	F32 max = ctrl->getMaxValue();
1466	F32 range = max - min;
1467	llassert(range > 0);
1468	F32 midPoint = min + range / 3.0f;
1469	F32 highPoint = min + (2.0f * range / 3.0f);
1470	
1471	// choose the right text
1472	if (value < midPoint)
1473	{
1474		text_box->setText(LLTrans::getString("GraphicsQualityLow"));
1475	} 
1476	else if (value < highPoint)
1477	{
1478		text_box->setText(LLTrans::getString("GraphicsQualityMid"));
1479	}
1480	else
1481	{
1482		text_box->setText(LLTrans::getString("GraphicsQualityHigh"));
1483	}
1484}
1485
1486void LLFloaterPreference::onChangeMaturity()
1487{
1488	U8 sim_access = gSavedSettings.getU32("PreferredMaturity");
1489
1490	getChild<LLIconCtrl>("rating_icon_general")->setVisible(sim_access == SIM_ACCESS_PG
1491															|| sim_access == SIM_ACCESS_MATURE
1492															|| sim_access == SIM_ACCESS_ADULT)

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