summaryrefslogtreecommitdiff
path: root/indra/newview/llfloaterpreference.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfloaterpreference.cpp')
-rw-r--r--indra/newview/llfloaterpreference.cpp6872
1 files changed, 3436 insertions, 3436 deletions
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3ed3abce58..85a07f23a4 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1,3436 +1,3436 @@
-/**
- * @file llfloaterpreference.cpp
- * @brief Global preferences with and without persistence.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*
- * App-wide preferences. Note that these are not per-user,
- * because we need to load many preferences before we have
- * a login name.
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterpreference.h"
-
-#include "message.h"
-#include "llfloaterautoreplacesettings.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llcheckboxctrl.h"
-#include "llcolorswatch.h"
-#include "llcombobox.h"
-#include "llcommandhandler.h"
-#include "lldirpicker.h"
-#include "lleventtimer.h"
-#include "llfeaturemanager.h"
-#include "llfocusmgr.h"
-//#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llfloaterabout.h"
-#include "llfavoritesbar.h"
-#include "llfloaterpreferencesgraphicsadvanced.h"
-#include "llfloaterperformance.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfloaterimsession.h"
-#include "llkeyboard.h"
-#include "llmodaldialog.h"
-#include "llnavigationbar.h"
-#include "llfloaterimnearbychat.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "llnotificationtemplate.h"
-#include "llpanellogin.h"
-#include "llpanelvoicedevicesettings.h"
-#include "llradiogroup.h"
-#include "llsearchcombobox.h"
-#include "llsky.h"
-#include "llscrolllistctrl.h"
-#include "llscrolllistitem.h"
-#include "llsliderctrl.h"
-#include "lltabcontainer.h"
-#include "lltrans.h"
-#include "llviewercontrol.h"
-#include "llviewercamera.h"
-#include "llviewereventrecorder.h"
-#include "llviewermessage.h"
-#include "llviewerwindow.h"
-#include "llviewerthrottle.h"
-#include "llvoavatarself.h"
-#include "llvotree.h"
-#include "llfloaterpathfindingconsole.h"
-// linden library includes
-#include "llavatarnamecache.h"
-#include "llerror.h"
-#include "llfontgl.h"
-#include "llrect.h"
-#include "llstring.h"
-
-// project includes
-
-#include "llbutton.h"
-#include "llflexibleobject.h"
-#include "lllineeditor.h"
-#include "llresmgr.h"
-#include "llspinctrl.h"
-#include "llstartup.h"
-#include "lltextbox.h"
-#include "llui.h"
-#include "llviewerobjectlist.h"
-#include "llvovolume.h"
-#include "llwindow.h"
-#include "llworld.h"
-#include "lluictrlfactory.h"
-#include "llviewermedia.h"
-#include "llpluginclassmedia.h"
-#include "llteleporthistorystorage.h"
-#include "llproxy.h"
-#include "llweb.h"
-
-#include "lllogininstance.h" // to check if logged in yet
-#include "llsdserialize.h"
-#include "llpresetsmanager.h"
-#include "llviewercontrol.h"
-#include "llpresetsmanager.h"
-#include "llinventoryfunctions.h"
-
-#include "llsearchableui.h"
-#include "llperfstats.h"
-
-const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
-char const* const VISIBILITY_DEFAULT = "default";
-char const* const VISIBILITY_HIDDEN = "hidden";
-
-//control value for middle mouse as talk2push button
-const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; // for voice client and redability
-const static std::string MOUSE_BUTTON_4_CV = "MouseButton4";
-const static std::string MOUSE_BUTTON_5_CV = "MouseButton5";
-
-/// This must equal the maximum value set for the IndirectMaxComplexity slider in panel_preferences_graphics1.xml
-static const U32 INDIRECT_MAX_ARC_OFF = 101; // all the way to the right == disabled
-static const U32 MIN_INDIRECT_ARC_LIMIT = 1; // must match minimum of IndirectMaxComplexity in panel_preferences_graphics1.xml
-static const U32 MAX_INDIRECT_ARC_LIMIT = INDIRECT_MAX_ARC_OFF-1; // one short of all the way to the right...
-
-/// These are the effective range of values for RenderAvatarMaxComplexity
-static const F32 MIN_ARC_LIMIT = 20000.0f;
-static const F32 MAX_ARC_LIMIT = 350000.0f;
-static const F32 MIN_ARC_LOG = log(MIN_ARC_LIMIT);
-static const F32 MAX_ARC_LOG = log(MAX_ARC_LIMIT);
-static const F32 ARC_LIMIT_MAP_SCALE = (MAX_ARC_LOG - MIN_ARC_LOG) / (MAX_INDIRECT_ARC_LIMIT - MIN_INDIRECT_ARC_LIMIT);
-
-struct LabelDef : public LLInitParam::Block<LabelDef>
-{
- Mandatory<std::string> name;
- Mandatory<std::string> value;
-
- LabelDef()
- : name("name"),
- value("value")
- {}
-};
-
-struct LabelTable : public LLInitParam::Block<LabelTable>
-{
- Multiple<LabelDef> labels;
- LabelTable()
- : labels("label")
- {}
-};
-
-
-// global functions
-
-// helper functions for getting/freeing the web browser media
-// if creating/destroying these is too slow, we'll need to create
-// a static member and update all our static callbacks
-
-void handleNameTagOptionChanged(const LLSD& newvalue);
-void handleDisplayNamesOptionChanged(const LLSD& newvalue);
-bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response);
-bool callback_clear_cache(const LLSD& notification, const LLSD& response);
-
-//bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
-//bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
-
-void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
-
-bool callback_clear_cache(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if ( option == 0 ) // YES
- {
- // flag client texture cache for clearing next time the client runs
- gSavedSettings.setBOOL("PurgeCacheOnNextStartup", true);
- LLNotificationsUtil::add("CacheWillClear");
- }
-
- return false;
-}
-
-bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if ( option == 0 ) // YES
- {
- // clean web
- LLViewerMedia::getInstance()->clearAllCaches();
- LLViewerMedia::getInstance()->clearAllCookies();
-
- // clean nav bar history
- LLNavigationBar::getInstance()->clearHistoryCache();
-
- // flag client texture cache for clearing next time the client runs
- gSavedSettings.setBOOL("PurgeCacheOnNextStartup", true);
- LLNotificationsUtil::add("CacheWillClear");
-
- LLSearchHistory::getInstance()->clearHistory();
- LLSearchHistory::getInstance()->save();
- LLSearchComboBox* search_ctrl = LLNavigationBar::getInstance()->getChild<LLSearchComboBox>("search_combo_box");
- search_ctrl->clearHistory();
-
- LLTeleportHistoryStorage::getInstance()->purgeItems();
- LLTeleportHistoryStorage::getInstance()->save();
- }
-
- return false;
-}
-
-void handleNameTagOptionChanged(const LLSD& newvalue)
-{
- LLAvatarNameCache::getInstance()->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
- LLVOAvatar::invalidateNameTags();
-}
-
-void handleDisplayNamesOptionChanged(const LLSD& newvalue)
-{
- LLAvatarNameCache::getInstance()->setUseDisplayNames(newvalue.asBoolean());
- LLVOAvatar::invalidateNameTags();
-}
-
-void handleAppearanceCameraMovementChanged(const LLSD& newvalue)
-{
- if(!newvalue.asBoolean() && gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
- {
- gAgentCamera.changeCameraToDefault();
- gAgentCamera.resetView();
- }
-}
-
-void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
-{
- numerator = 0;
- denominator = 0;
- for (F32 test_denominator = 1.f; test_denominator < 30.f; test_denominator += 1.f)
- {
- if (fmodf((decimal_val * test_denominator) + 0.01f, 1.f) < 0.02f)
- {
- numerator = ll_round(decimal_val * test_denominator);
- denominator = ll_round(test_denominator);
- break;
- }
- }
-}
-
-// handle secondlife:///app/worldmap/{NAME}/{COORDS} URLs
-// Also see LLUrlEntryKeybinding, the value of this command type
-// is ability to show up to date value in chat
-class LLKeybindingHandler: public LLCommandHandler
-{
-public:
- // requires trusted browser to trigger
- LLKeybindingHandler(): LLCommandHandler("keybinding", UNTRUSTED_CLICK_ONLY)
- {
- }
-
- bool handle(const LLSD& params, const LLSD& query_map,
- const std::string& grid, LLMediaCtrl* web)
- {
- if (params.size() < 1) return false;
-
- LLFloaterPreference* prefsfloater = dynamic_cast<LLFloaterPreference*>
- (LLFloaterReg::showInstance("preferences"));
-
- if (prefsfloater)
- {
- // find 'controls' panel and bring it the front
- LLTabContainer* tabcontainer = prefsfloater->getChild<LLTabContainer>("pref core");
- LLPanel* panel = prefsfloater->getChild<LLPanel>("controls");
- if (tabcontainer && panel)
- {
- tabcontainer->selectTabPanel(panel);
- }
- }
-
- return true;
- }
-};
-LLKeybindingHandler gKeybindHandler;
-
-
-//////////////////////////////////////////////
-// LLFloaterPreference
-
-// static
-std::string LLFloaterPreference::sSkin = "";
-
-LLFloaterPreference::LLFloaterPreference(const LLSD& key)
- : LLFloater(key),
- mGotPersonalInfo(false),
- mLanguageChanged(false),
- mAvatarDataInitialized(false),
- mSearchDataDirty(true)
-{
- LLConversationLog::instance().addObserver(this);
-
- //Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
-
- static bool registered_dialog = false;
- if (!registered_dialog)
- {
- LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSetKeyBindDialog>);
- registered_dialog = true;
- }
-
- mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreference::onBtnCancel, this, _2));
- mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreference::onBtnOK, this, _2));
-
- mCommitCallbackRegistrar.add("Pref.ClearCache", boost::bind(&LLFloaterPreference::onClickClearCache, this));
- mCommitCallbackRegistrar.add("Pref.WebClearCache", boost::bind(&LLFloaterPreference::onClickBrowserClearCache, this));
- mCommitCallbackRegistrar.add("Pref.SetCache", boost::bind(&LLFloaterPreference::onClickSetCache, this));
- mCommitCallbackRegistrar.add("Pref.ResetCache", boost::bind(&LLFloaterPreference::onClickResetCache, this));
- mCommitCallbackRegistrar.add("Pref.ClickSkin", boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2));
- mCommitCallbackRegistrar.add("Pref.SelectSkin", boost::bind(&LLFloaterPreference::onSelectSkin, this));
- mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this));
- mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
- mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this));
- mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
- mCommitCallbackRegistrar.add("Pref.RenderExceptions", boost::bind(&LLFloaterPreference::onClickRenderExceptions, this));
- mCommitCallbackRegistrar.add("Pref.AutoAdjustments", boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this));
- mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
- mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
- mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
- mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreference::onRenderOptionEnable, this));
- mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
- mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::refreshUI,this));
- mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
- mCommitCallbackRegistrar.add("Pref.applyUIColor", boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
- mCommitCallbackRegistrar.add("Pref.getUIColor", boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
- mCommitCallbackRegistrar.add("Pref.MaturitySettings", boost::bind(&LLFloaterPreference::onChangeMaturity, this));
- mCommitCallbackRegistrar.add("Pref.BlockList", boost::bind(&LLFloaterPreference::onClickBlockList, this));
- mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this));
- mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
- mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
- mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
- mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
- mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
- mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
-
- sSkin = gSavedSettings.getString("SkinCurrent");
-
- mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
-
- gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
- gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
- gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2));
-
- gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged, _2));
- gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAtmosShaderChange, this));
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
-
- mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this));
-
- mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
- mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
- mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering
-}
-
-void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
-{
- if ( APT_PROPERTIES_LEGACY == type )
- {
- const LLAvatarLegacyData* pAvatarData = static_cast<const LLAvatarLegacyData*>( pData );
- if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
- {
- mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
- mAvatarDataInitialized = true;
- getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
- }
- }
-}
-
-void LLFloaterPreference::saveAvatarProperties( void )
-{
- const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
-
- if ((LLStartUp::getStartupState() == STATE_STARTED)
- && mAvatarDataInitialized
- && (allowPublish != mAllowPublish))
- {
- std::string cap_url = gAgent.getRegionCapability("AgentProfile");
- if (!cap_url.empty())
- {
- mAllowPublish = allowPublish;
-
- LLCoros::instance().launch("requestAgentUserInfoCoro",
- boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
- }
- }
-}
-
-void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders;
-
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- httpOpts->setFollowRedirects(true);
-
- std::string finalUrl = cap_url + "/" + gAgentID.asString();
- LLSD data;
- data["allow_publish"] = allow_publish;
-
- LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
- return;
- }
-
- LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
-}
-
-bool LLFloaterPreference::postBuild()
-{
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
-
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
-
- gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));
-
- gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this));
-
- gSavedSettings.getControl("RenderAvatarComplexityMode")->getSignal()->connect(
- [this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
- {
- onChangeComplexityMode(new_val);
- });
-
- gSavedPerAccountSettings.getControl("ModelUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeModelFolder, this));
- gSavedPerAccountSettings.getControl("PBRUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangePBRFolder, this));
- gSavedPerAccountSettings.getControl("TextureUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeTextureFolder, this));
- gSavedPerAccountSettings.getControl("SoundUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeSoundFolder, this));
- gSavedPerAccountSettings.getControl("AnimationUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeAnimationFolder, this));
-
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
- tabcontainer->selectFirstTab();
-
- getChild<LLUICtrl>("cache_location")->setEnabled(false); // make it read-only but selectable (STORM-227)
- std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
- setCacheLocation(cache_location);
-
- getChild<LLUICtrl>("log_path_string")->setEnabled(false); // make it read-only but selectable
-
- getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
-
- getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions"));
- getChild<LLComboBox>("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions"));
- getChild<LLComboBox>("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions"));
- getChild<LLComboBox>("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions"));
- getChild<LLComboBox>("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions"));
- getChild<LLComboBox>("ObjectIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ObjectIMOptions"));
-
- // if floater is opened before login set default localized do not disturb message
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
- }
-
- // set 'enable' property for 'Clear log...' button
- changed();
-
- LLLogChat::getInstance()->setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
-
- LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
- fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
- fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
-
- bool enable_complexity = gSavedSettings.getS32("RenderAvatarComplexityMode") != LLVOAvatar::AV_RENDER_ONLY_SHOW_FRIENDS;
- getChild<LLSliderCtrl>("IndirectMaxComplexity")->setEnabled(enable_complexity);
-
- // Hook up and init for filtering
- mFilterEdit = getChild<LLSearchEditor>("search_prefs_edit");
- mFilterEdit->setKeystrokeCallback(boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false));
-
- // Load and assign label for 'default language'
- std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "default_languages.xml");
- std::map<std::string, std::string> labels;
- if (loadFromFilename(user_filename, labels))
- {
- std::string system_lang = gSavedSettings.getString("SystemLanguage");
- std::map<std::string, std::string>::iterator iter = labels.find(system_lang);
- if (iter != labels.end())
- {
- getChild<LLComboBox>("language_combobox")->add(iter->second, LLSD("default"), ADD_TOP, true);
- }
- else
- {
- LL_WARNS() << "Language \"" << system_lang << "\" is not in default_languages.xml" << LL_ENDL;
- getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
- }
- }
- else
- {
- LL_WARNS() << "Failed to load labels from " << user_filename << ". Using default." << LL_ENDL;
- getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
- }
-
- return true;
-}
-
-void LLFloaterPreference::updateDeleteTranscriptsButton()
-{
- getChild<LLButton>("delete_transcripts")->setEnabled(LLLogChat::transcriptFilesExist());
-}
-
-void LLFloaterPreference::onDoNotDisturbResponseChanged()
-{
- // set "DoNotDisturbResponseChanged" true if user edited message differs from default, false otherwise
- bool response_changed_flag =
- LLTrans::getString("DoNotDisturbModeResponseDefault")
- != getChild<LLUICtrl>("do_not_disturb_response")->getValue().asString();
-
- gSavedPerAccountSettings.setBOOL("DoNotDisturbResponseChanged", response_changed_flag );
-}
-
-LLFloaterPreference::~LLFloaterPreference()
-{
- LLConversationLog::instance().removeObserver(this);
- mComplexityChangedSignal.disconnect();
-}
-
-void LLFloaterPreference::draw()
-{
- bool has_first_selected = (getChildRef<LLScrollListCtrl>("disabled_popups").getFirstSelected()!=NULL);
- gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected);
-
- has_first_selected = (getChildRef<LLScrollListCtrl>("enabled_popups").getFirstSelected()!=NULL);
- gSavedSettings.setBOOL("FirstSelectedEnabledPopups", has_first_selected);
-
- LLFloater::draw();
-}
-
-void LLFloaterPreference::saveSettings()
-{
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
- child_list_t::const_iterator end = tabcontainer->getChildList()->end();
- for ( ; iter != end; ++iter)
- {
- LLView* view = *iter;
- LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
- if (panel)
- panel->saveSettings();
- }
- saveIgnoredNotifications();
-}
-
-void LLFloaterPreference::apply()
-{
- LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
-
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- if (sSkin != gSavedSettings.getString("SkinCurrent"))
- {
- LLNotificationsUtil::add("ChangeSkin");
- refreshSkin(this);
- }
- // Call apply() on all panels that derive from LLPanelPreference
- for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
- iter != tabcontainer->getChildList()->end(); ++iter)
- {
- LLView* view = *iter;
- LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
- if (panel)
- panel->apply();
- }
-
- gViewerWindow->requestResolutionUpdate(); // for UIScaleFactor
-
- LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
- fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
- fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
-
- std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
- setCacheLocation(cache_location);
-
- LLViewerMedia::getInstance()->setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue());
-
- if (hasChild("web_proxy_enabled", true) &&hasChild("web_proxy_editor", true) && hasChild("web_proxy_port", true))
- {
- bool proxy_enable = getChild<LLUICtrl>("web_proxy_enabled")->getValue();
- std::string proxy_address = getChild<LLUICtrl>("web_proxy_editor")->getValue();
- int proxy_port = getChild<LLUICtrl>("web_proxy_port")->getValue();
- LLViewerMedia::getInstance()->setProxyConfig(proxy_enable, proxy_address, proxy_port);
- }
-
- if (mGotPersonalInfo)
- {
- bool new_hide_online = getChild<LLUICtrl>("online_visibility")->getValue().asBoolean();
-
- if (new_hide_online != mOriginalHideOnlineStatus)
- {
- // This hack is because we are representing several different
- // possible strings with a single checkbox. Since most users
- // can only select between 2 values, we represent it as a
- // checkbox. This breaks down a little bit for liaisons, but
- // works out in the end.
- if (new_hide_online != mOriginalHideOnlineStatus)
- {
- if (new_hide_online) mDirectoryVisibility = VISIBILITY_HIDDEN;
- else mDirectoryVisibility = VISIBILITY_DEFAULT;
- //Update showonline value, otherwise multiple applys won't work
- mOriginalHideOnlineStatus = new_hide_online;
- }
- gAgent.sendAgentUpdateUserInfo(mDirectoryVisibility);
- }
- }
-
- saveAvatarProperties();
-}
-
-void LLFloaterPreference::cancel(const std::vector<std::string> settings_to_skip)
-{
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- // Call cancel() on all panels that derive from LLPanelPreference
- for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
- iter != tabcontainer->getChildList()->end(); ++iter)
- {
- LLView* view = *iter;
- LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
- if (panel)
- panel->cancel(settings_to_skip);
- }
- // hide joystick pref floater
- LLFloaterReg::hideInstance("pref_joystick");
-
- // hide translation settings floater
- LLFloaterReg::hideInstance("prefs_translation");
-
- // hide autoreplace settings floater
- LLFloaterReg::hideInstance("prefs_autoreplace");
-
- // hide spellchecker settings folder
- LLFloaterReg::hideInstance("prefs_spellchecker");
-
- // hide advanced graphics floater
- LLFloaterReg::hideInstance("prefs_graphics_advanced");
-
- // reverts any changes to current skin
- gSavedSettings.setString("SkinCurrent", sSkin);
-
- updateClickActionViews();
-
- LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy");
- if (advanced_proxy_settings)
- {
- advanced_proxy_settings->cancel();
- }
- //Need to reload the navmesh if the pathing console is up
- LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
- if ( !pathfindingConsoleHandle.isDead() )
- {
- LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
- pPathfindingConsole->onRegionBoundaryCross();
- }
-
- if (!mSavedGraphicsPreset.empty())
- {
- gSavedSettings.setString("PresetGraphicActive", mSavedGraphicsPreset);
- LLPresetsManager::getInstance()->triggerChangeSignal();
- }
-
- restoreIgnoredNotifications();
-}
-
-void LLFloaterPreference::onOpen(const LLSD& key)
-{
- // this variable and if that follows it are used to properly handle do not disturb mode response message
- static bool initialized = false;
- // if user is logged in and we haven't initialized do not disturb mode response yet, do it
- if (!initialized && LLStartUp::getStartupState() == STATE_STARTED)
- {
- // Special approach is used for do not disturb response localization, because "DoNotDisturbModeResponse" is
- // in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized.
- // To keep track of whether do not disturb response is default or changed by user additional setting DoNotDisturbResponseChanged
- // was added into per account settings.
-
- // initialization should happen once,so setting variable to true
- initialized = true;
- // this connection is needed to properly set "DoNotDisturbResponseChanged" setting when user makes changes in
- // do not disturb response message.
- gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onDoNotDisturbResponseChanged, this));
- }
- gAgent.sendAgentUserInfoRequest();
-
- /////////////////////////// From LLPanelGeneral //////////////////////////
- // if we have no agent, we can't let them choose anything
- // if we have an agent, then we only let them choose if they have a choice
- bool can_choose_maturity =
- gAgent.getID().notNull() &&
- (gAgent.isMature() || gAgent.isGodlike());
-
- LLComboBox* maturity_combo = getChild<LLComboBox>("maturity_desired_combobox");
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarLegacyPropertiesRequest( gAgent.getID() );
- if (can_choose_maturity)
- {
- // if they're not adult or a god, they shouldn't see the adult selection, so delete it
- if (!gAgent.isAdult() && !gAgent.isGodlikeWithoutAdminMenuFakery())
- {
- // we're going to remove the adult entry from the combo
- LLScrollListCtrl* maturity_list = maturity_combo->findChild<LLScrollListCtrl>("ComboBox");
- if (maturity_list)
- {
- maturity_list->deleteItems(LLSD(SIM_ACCESS_ADULT));
- }
- }
- getChildView("maturity_desired_combobox")->setEnabled( true);
- getChildView("maturity_desired_textbox")->setVisible( false);
- }
- else
- {
- getChild<LLUICtrl>("maturity_desired_textbox")->setValue(maturity_combo->getSelectedItemLabel());
- getChildView("maturity_desired_combobox")->setEnabled( false);
- }
-
- // Forget previous language changes.
- mLanguageChanged = false;
-
- // Display selected maturity icons.
- onChangeMaturity();
-
- onChangeModelFolder();
- onChangePBRFolder();
- onChangeTextureFolder();
- onChangeSoundFolder();
- onChangeAnimationFolder();
-
- // Load (double-)click to walk/teleport settings.
- updateClickActionViews();
-
- // Enabled/disabled popups, might have been changed by user actions
- // while preferences floater was closed.
- buildPopupLists();
-
-
- //get the options that were checked
- onNotificationsChange("FriendIMOptions");
- onNotificationsChange("NonFriendIMOptions");
- onNotificationsChange("ConferenceIMOptions");
- onNotificationsChange("GroupChatOptions");
- onNotificationsChange("NearbyChatOptions");
- onNotificationsChange("ObjectIMOptions");
-
- LLPanelLogin::setAlwaysRefresh(true);
- refresh();
-
- // Make sure the current state of prefs are saved away when
- // when the floater is opened. That will make cancel do its
- // job
- saveSettings();
-
- // Make sure there is a default preference file
- LLPresetsManager::getInstance()->createMissingDefault(PRESETS_CAMERA);
- LLPresetsManager::getInstance()->createMissingDefault(PRESETS_GRAPHIC);
-
- bool started = (LLStartUp::getStartupState() == STATE_STARTED);
-
- LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
- LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
- LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
- LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
- LLButton* auto_adjustments_btn = findChild<LLButton>("AutoAdjustmentsButton");
-
- if (load_btn && save_btn && delete_btn && exceptions_btn && auto_adjustments_btn)
- {
- load_btn->setEnabled(started);
- save_btn->setEnabled(started);
- delete_btn->setEnabled(started);
- exceptions_btn->setEnabled(started);
- auto_adjustments_btn->setEnabled(started);
- }
-
- collectSearchableItems();
- if (!mFilterEdit->getText().empty())
- {
- mFilterEdit->setText(LLStringExplicit(""));
- onUpdateFilterTerm(true);
- }
-}
-
-void LLFloaterPreference::onRenderOptionEnable()
-{
- refreshEnabledGraphics();
-}
-
-void LLFloaterPreference::onAvatarImpostorsEnable()
-{
- refreshEnabledGraphics();
-}
-
-//static
-void LLFloaterPreference::initDoNotDisturbResponse()
- {
- if (!gSavedPerAccountSettings.getBOOL("DoNotDisturbResponseChanged"))
- {
- //LLTrans::getString("DoNotDisturbModeResponseDefault") is used here for localization (EXT-5885)
- gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
- }
- }
-
-//static
-void LLFloaterPreference::updateShowFavoritesCheckbox(bool val)
-{
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->getChild<LLUICtrl>("favorites_on_login_check")->setValue(val);
- }
-}
-
-void LLFloaterPreference::setHardwareDefaults()
-{
- std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
- if (!preset_graphic_active.empty())
- {
- saveGraphicsPreset(preset_graphic_active);
- saveSettings(); // save here to be able to return to the previous preset by Cancel
- }
- setRecommendedSettings();
-}
-
-void LLFloaterPreference::setRecommendedSettings()
-{
- resetAutotuneSettings();
- gSavedSettings.getControl("RenderVSyncEnable")->resetToDefault(true);
-
- LLFeatureManager::getInstance()->applyRecommendedSettings();
-
- // reset indirects before refresh because we may have changed what they control
- LLAvatarComplexityControls::setIndirectControls();
-
- refreshEnabledGraphics();
- gSavedSettings.setString("PresetGraphicActive", "");
- LLPresetsManager::getInstance()->triggerChangeSignal();
-
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
- child_list_t::const_iterator end = tabcontainer->getChildList()->end();
- for ( ; iter != end; ++iter)
- {
- LLView* view = *iter;
- LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
- if (panel)
- {
- panel->setHardwareDefaults();
- }
- }
-}
-
-void LLFloaterPreference::resetAutotuneSettings()
-{
- gSavedSettings.setBOOL("AutoTuneFPS", false);
-
- const std::string autotune_settings[] = {
- "AutoTuneLock",
- "KeepAutoTuneLock",
- "TargetFPS",
- "TuningFPSStrategy",
- "AutoTuneImpostorByDistEnabled",
- "AutoTuneImpostorFarAwayDistance" ,
- "AutoTuneRenderFarClipMin",
- "AutoTuneRenderFarClipTarget",
- "RenderAvatarMaxART"
- };
-
- for (auto it : autotune_settings)
- {
- gSavedSettings.getControl(it)->resetToDefault(true);
- }
-}
-
-void LLFloaterPreference::getControlNames(std::vector<std::string>& names)
-{
- LLView* view = findChild<LLView>("display");
- LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
- if (view && advanced)
- {
- std::list<LLView*> stack;
- stack.push_back(view);
- stack.push_back(advanced);
- while(!stack.empty())
- {
- // Process view on top of the stack
- LLView* curview = stack.front();
- stack.pop_front();
-
- LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
- if (ctrl)
- {
- LLControlVariable* control = ctrl->getControlVariable();
- if (control)
- {
- std::string control_name = control->getName();
- if (std::find(names.begin(), names.end(), control_name) == names.end())
- {
- names.push_back(control_name);
- }
- }
- }
-
- for (child_list_t::const_iterator iter = curview->getChildList()->begin();
- iter != curview->getChildList()->end(); ++iter)
- {
- stack.push_back(*iter);
- }
- }
- }
-}
-
-//virtual
-void LLFloaterPreference::onClose(bool app_quitting)
-{
- gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());
- LLPanelLogin::setAlwaysRefresh(false);
- if (!app_quitting)
- {
- cancel();
- }
-}
-
-// static
-void LLFloaterPreference::onBtnOK(const LLSD& userdata)
-{
- // commit any outstanding text entry
- if (hasFocus())
- {
- LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
- if (cur_focus && cur_focus->acceptsTextInput())
- {
- cur_focus->onCommit();
- }
- }
-
- if (canClose())
- {
- saveSettings();
- apply();
-
- if (userdata.asString() == "closeadvanced")
- {
- LLFloaterReg::hideInstance("prefs_graphics_advanced");
- }
- else
- {
- closeFloater(false);
- }
-
- //Conversation transcript and log path changed so reload conversations based on new location
- if(mPriorInstantMessageLogPath.length())
- {
- if(moveTranscriptsAndLog())
- {
- //When floaters are empty but have a chat history files, reload chat history into them
- LLFloaterIMSessionTab::reloadEmptyFloaters();
- }
- //Couldn't move files so restore the old path and show a notification
- else
- {
- gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath);
- LLNotificationsUtil::add("PreferenceChatPathChanged");
- }
- mPriorInstantMessageLogPath.clear();
- }
-
- LLUIColorTable::instance().saveUserSettings();
- gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), true);
-
- //Only save once logged in and loaded per account settings
- if(mGotPersonalInfo)
- {
- gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), true);
- }
- }
- else
- {
- // Show beep, pop up dialog, etc.
- LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
- }
-
- LLPanelLogin::updateLocationSelectorsVisibility();
- //Need to reload the navmesh if the pathing console is up
- LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
- if ( !pathfindingConsoleHandle.isDead() )
- {
- LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
- pPathfindingConsole->onRegionBoundaryCross();
- }
-}
-
-// static
-void LLFloaterPreference::onBtnCancel(const LLSD& userdata)
-{
- if (hasFocus())
- {
- LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
- if (cur_focus && cur_focus->acceptsTextInput())
- {
- cur_focus->onCommit();
- }
- refresh();
- }
-
- if (userdata.asString() == "closeadvanced")
- {
- cancel({"RenderQualityPerformance"});
- LLFloaterReg::hideInstance("prefs_graphics_advanced");
- }
- else
- {
- cancel();
- closeFloater();
- }
-}
-
-// static
-void LLFloaterPreference::updateUserInfo(const std::string& visibility)
-{
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->setPersonalInfo(visibility);
- }
-}
-
-void LLFloaterPreference::refreshEnabledGraphics()
-{
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->refresh();
- }
-
- LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
- if (advanced)
- {
- advanced->refresh();
- }
-}
-
-void LLFloaterPreference::onClickClearCache()
-{
- LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache);
-}
-
-void LLFloaterPreference::onClickBrowserClearCache()
-{
- LLNotificationsUtil::add("ConfirmClearBrowserCache", LLSD(), LLSD(), callback_clear_browser_cache);
-}
-
-// Called when user changes language via the combobox.
-void LLFloaterPreference::onLanguageChange()
-{
- // Let the user know that the change will only take effect after restart.
- // Do it only once so that we're not too irritating.
- if (!mLanguageChanged)
- {
- LLNotificationsUtil::add("ChangeLanguage");
- mLanguageChanged = true;
- }
-}
-
-void LLFloaterPreference::onNotificationsChange(const std::string& OptionName)
-{
- mNotificationOptions[OptionName] = getChild<LLComboBox>(OptionName)->getSelectedItemLabel();
-
- bool show_notifications_alert = true;
- for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++)
- {
- if(it_notification->second != "No action")
- {
- show_notifications_alert = false;
- break;
- }
- }
-
- getChild<LLTextBox>("notifications_alert")->setVisible(show_notifications_alert);
-}
-
-void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
-{
- LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background");
- if (color_swatch)
- {
- LLColor4 new_color = color_swatch->get();
- color_swatch->set( new_color.setAlpha(newvalue.asReal()) );
- }
-}
-
-void LLFloaterPreference::onClickSetCache()
-{
- std::string cur_name(gSavedSettings.getString("CacheLocation"));
-// std::string cur_top_folder(gDirUtilp->getBaseFileName(cur_name));
-
- std::string proposed_name(cur_name);
-
- (new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeCachePath, this, _1, _2), proposed_name))->getFile();
-}
-
-void LLFloaterPreference::changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name)
-{
- std::string dir_name = filenames[0];
- if (!dir_name.empty() && dir_name != proposed_name)
- {
- std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));
- LLNotificationsUtil::add("CacheWillBeMoved");
- gSavedSettings.setString("NewCacheLocation", dir_name);
- gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder);
- }
- else
- {
- std::string cache_location = gDirUtilp->getCacheDir();
- gSavedSettings.setString("CacheLocation", cache_location);
- std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
- gSavedSettings.setString("CacheLocationTopFolder", top_folder);
- }
-}
-
-void LLFloaterPreference::onClickResetCache()
-{
- if (gDirUtilp->getCacheDir(false) == gDirUtilp->getCacheDir(true))
- {
- // The cache location was already the default.
- return;
- }
- gSavedSettings.setString("NewCacheLocation", "");
- gSavedSettings.setString("NewCacheLocationTopFolder", "");
- LLNotificationsUtil::add("CacheWillBeMoved");
- std::string cache_location = gDirUtilp->getCacheDir(false);
- gSavedSettings.setString("CacheLocation", cache_location);
- std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
- gSavedSettings.setString("CacheLocationTopFolder", top_folder);
-}
-
-void LLFloaterPreference::onClickSkin(LLUICtrl* ctrl, const LLSD& userdata)
-{
- gSavedSettings.setString("SkinCurrent", userdata.asString());
- ctrl->setValue(userdata.asString());
-}
-
-void LLFloaterPreference::onSelectSkin()
-{
- std::string skin_selection = getChild<LLRadioGroup>("skin_selection")->getValue().asString();
- gSavedSettings.setString("SkinCurrent", skin_selection);
-}
-
-void LLFloaterPreference::refreshSkin(void* data)
-{
- LLPanel*self = (LLPanel*)data;
- sSkin = gSavedSettings.getString("SkinCurrent");
- self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
-}
-
-void LLFloaterPreference::buildPopupLists()
-{
- LLScrollListCtrl& disabled_popups =
- getChildRef<LLScrollListCtrl>("disabled_popups");
- LLScrollListCtrl& enabled_popups =
- getChildRef<LLScrollListCtrl>("enabled_popups");
-
- disabled_popups.deleteAllItems();
- enabled_popups.deleteAllItems();
-
- for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
- iter != LLNotifications::instance().templatesEnd();
- ++iter)
- {
- LLNotificationTemplatePtr templatep = iter->second;
- LLNotificationFormPtr formp = templatep->mForm;
-
- LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
- if (ignore <= LLNotificationForm::IGNORE_NO)
- continue;
-
- LLSD row;
- row["columns"][0]["value"] = formp->getIgnoreMessage();
- row["columns"][0]["font"] = "SANSSERIF_SMALL";
- row["columns"][0]["width"] = 400;
-
- LLScrollListItem* item = NULL;
-
- bool show_popup = !formp->getIgnored();
- if (!show_popup)
- {
- if (ignore == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
- {
- LLSD last_response = LLUI::getInstance()->mSettingGroups["config"]->getLLSD("Default" + templatep->mName);
- if (!last_response.isUndefined())
- {
- for (LLSD::map_const_iterator it = last_response.beginMap();
- it != last_response.endMap();
- ++it)
- {
- if (it->second.asBoolean())
- {
- row["columns"][1]["value"] = formp->getElement(it->first)["ignore"].asString();
- row["columns"][1]["font"] = "SANSSERIF_SMALL";
- row["columns"][1]["width"] = 360;
- break;
- }
- }
- }
- }
- item = disabled_popups.addElement(row);
- }
- else
- {
- item = enabled_popups.addElement(row);
- }
-
- if (item)
- {
- item->setUserdata((void*)&iter->first);
- }
- }
-}
-
-void LLFloaterPreference::refreshEnabledState()
-{
- LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");
-
- //PBR
- ctrl_pbr->setEnabled(true);
-
- // Cannot have floater active until caps have been received
- getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() >= STATE_STARTED);
-
- getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
-}
-
-void LLAvatarComplexityControls::setIndirectControls()
-{
- /*
- * We have controls that have an indirect relationship between the control
- * values and adjacent text and the underlying setting they influence.
- * In each case, the control and its associated setting are named Indirect<something>
- * This method interrogates the controlled setting and establishes the
- * appropriate value for the indirect control. It must be called whenever the
- * underlying setting may have changed other than through the indirect control,
- * such as when the 'Reset all to recommended settings' button is used...
- */
- setIndirectMaxNonImpostors();
- setIndirectMaxArc();
-}
-
-// static
-void LLAvatarComplexityControls::setIndirectMaxNonImpostors()
-{
- U32 max_non_impostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
- // for this one, we just need to make zero, which means off, the max value of the slider
- U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER : max_non_impostors;
- gSavedSettings.setU32("IndirectMaxNonImpostors", indirect_max_non_impostors);
-}
-
-void LLAvatarComplexityControls::setIndirectMaxArc()
-{
- U32 max_arc = gSavedSettings.getU32("RenderAvatarMaxComplexity");
- U32 indirect_max_arc;
- if (0 == max_arc)
- {
- // the off position is all the way to the right, so set to control max
- indirect_max_arc = INDIRECT_MAX_ARC_OFF;
- }
- else
- {
- // This is the inverse of the calculation in updateMaxComplexity
- indirect_max_arc = (U32)ll_round(((log(F32(max_arc)) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE)) + MIN_INDIRECT_ARC_LIMIT;
- }
- gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);
-}
-
-void LLFloaterPreference::refresh()
-{
- LLPanel::refresh();
- LLAvatarComplexityControls::setText(
- gSavedSettings.getU32("RenderAvatarMaxComplexity"),
- getChild<LLTextBox>("IndirectMaxComplexityText", true));
- refreshEnabledState();
- LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
- if (advanced)
- {
- advanced->refresh();
- }
- updateClickActionViews();
-}
-
-void LLFloaterPreference::onCommitWindowedMode()
-{
- refresh();
-}
-
-void LLFloaterPreference::onChangeQuality(const LLSD& data)
-{
- U32 level = (U32)(data.asReal());
- LLFeatureManager::getInstance()->setGraphicsLevel(level, true);
- refreshEnabledGraphics();
- refresh();
-}
-
-void LLFloaterPreference::onClickSetSounds()
-{
- // Disable Enable gesture sounds checkbox if the master sound is disabled
- // or if sound effects are disabled.
- getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
-}
-
-void LLFloaterPreference::onClickEnablePopup()
-{
- LLScrollListCtrl& disabled_popups = getChildRef<LLScrollListCtrl>("disabled_popups");
-
- std::vector<LLScrollListItem*> items = disabled_popups.getAllSelected();
- std::vector<LLScrollListItem*>::iterator itor;
- for (itor = items.begin(); itor != items.end(); ++itor)
- {
- LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
- //gSavedSettings.setWarning(templatep->mName, true);
- std::string notification_name = templatep->mName;
- LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(notification_name, true);
- }
-
- buildPopupLists();
- if (!mFilterEdit->getText().empty())
- {
- filterIgnorableNotifications();
- }
-}
-
-void LLFloaterPreference::onClickDisablePopup()
-{
- LLScrollListCtrl& enabled_popups = getChildRef<LLScrollListCtrl>("enabled_popups");
-
- std::vector<LLScrollListItem*> items = enabled_popups.getAllSelected();
- std::vector<LLScrollListItem*>::iterator itor;
- for (itor = items.begin(); itor != items.end(); ++itor)
- {
- LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
- templatep->mForm->setIgnored(true);
- }
-
- buildPopupLists();
- if (!mFilterEdit->getText().empty())
- {
- filterIgnorableNotifications();
- }
-}
-
-void LLFloaterPreference::resetAllIgnored()
-{
- for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
- iter != LLNotifications::instance().templatesEnd();
- ++iter)
- {
- if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
- {
- iter->second->mForm->setIgnored(false);
- }
- }
-}
-
-void LLFloaterPreference::setAllIgnored()
-{
- for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
- iter != LLNotifications::instance().templatesEnd();
- ++iter)
- {
- if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
- {
- iter->second->mForm->setIgnored(true);
- }
- }
-}
-
-void LLFloaterPreference::onClickLogPath()
-{
- std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
- mPriorInstantMessageLogPath.clear();
-
-
- (new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeLogPath, this, _1, _2), proposed_name))->getFile();
-}
-
-void LLFloaterPreference::changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name)
-{
- //Path changed
- if (proposed_name != filenames[0])
- {
- gSavedPerAccountSettings.setString("InstantMessageLogPath", filenames[0]);
- mPriorInstantMessageLogPath = proposed_name;
-
- // enable/disable 'Delete transcripts button
- updateDeleteTranscriptsButton();
- }
-}
-
-bool LLFloaterPreference::moveTranscriptsAndLog()
-{
- std::string instantMessageLogPath(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
- std::string chatLogPath = gDirUtilp->add(instantMessageLogPath, gDirUtilp->getUserName());
-
- bool madeDirectory = false;
-
- //Does the directory really exist, if not then make it
- if(!LLFile::isdir(chatLogPath))
- {
- //mkdir success is defined as zero
- if(LLFile::mkdir(chatLogPath) != 0)
- {
- return false;
- }
- madeDirectory = true;
- }
-
- std::string originalConversationLogDir = LLConversationLog::instance().getFileName();
- std::string targetConversationLogDir = gDirUtilp->add(chatLogPath, "conversation.log");
- //Try to move the conversation log
- if(!LLConversationLog::instance().moveLog(originalConversationLogDir, targetConversationLogDir))
- {
- //Couldn't move the log and created a new directory so remove the new directory
- if(madeDirectory)
- {
- LLFile::rmdir(chatLogPath);
- }
- return false;
- }
-
- //Attempt to move transcripts
- std::vector<std::string> listOfTranscripts;
- std::vector<std::string> listOfFilesMoved;
-
- LLLogChat::getListOfTranscriptFiles(listOfTranscripts);
-
- if(!LLLogChat::moveTranscripts(gDirUtilp->getChatLogsDir(),
- instantMessageLogPath,
- listOfTranscripts,
- listOfFilesMoved))
- {
- //Couldn't move all the transcripts so restore those that moved back to their old location
- LLLogChat::moveTranscripts(instantMessageLogPath,
- gDirUtilp->getChatLogsDir(),
- listOfFilesMoved);
-
- //Move the conversation log back
- LLConversationLog::instance().moveLog(targetConversationLogDir, originalConversationLogDir);
-
- if(madeDirectory)
- {
- LLFile::rmdir(chatLogPath);
- }
-
- return false;
- }
-
- gDirUtilp->setChatLogsDir(instantMessageLogPath);
- gDirUtilp->updatePerAccountChatLogsDir();
-
- return true;
-}
-
-void LLFloaterPreference::setPersonalInfo(const std::string& visibility)
-{
- mGotPersonalInfo = true;
- mDirectoryVisibility = visibility;
-
- if (visibility == VISIBILITY_DEFAULT)
- {
- mOriginalHideOnlineStatus = false;
- getChildView("online_visibility")->setEnabled(true);
- }
- else if (visibility == VISIBILITY_HIDDEN)
- {
- mOriginalHideOnlineStatus = true;
- getChildView("online_visibility")->setEnabled(true);
- }
- else
- {
- mOriginalHideOnlineStatus = true;
- }
-
- getChild<LLUICtrl>("online_searchresults")->setEnabled(true);
- getChildView("friends_online_notify_checkbox")->setEnabled(true);
- getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus);
- getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
-
- getChildView("favorites_on_login_check")->setEnabled(true);
- getChildView("log_path_button")->setEnabled(true);
- getChildView("chat_font_size")->setEnabled(true);
- getChildView("conversation_log_combo")->setEnabled(true);
- getChild<LLUICtrl>("voice_call_friends_only_check")->setEnabled(true);
- getChild<LLUICtrl>("voice_call_friends_only_check")->setValue(gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly"));
-}
-
-
-void LLFloaterPreference::refreshUI()
-{
- refresh();
-}
-
-void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
-{
- // Called when the IndirectMaxComplexity control changes
- // Responsible for fixing the slider label (IndirectMaxComplexityText) and setting RenderAvatarMaxComplexity
- U32 indirect_value = slider->getValue().asInteger();
- U32 max_arc;
-
- if (INDIRECT_MAX_ARC_OFF == indirect_value)
- {
- // The 'off' position is when the slider is all the way to the right,
- // which is a value of INDIRECT_MAX_ARC_OFF,
- // so it is necessary to set max_arc to 0 disable muted avatars.
- max_arc = 0;
- }
- else
- {
- // if this is changed, the inverse calculation in setIndirectMaxArc
- // must be changed to match
- max_arc = (U32)ll_round(exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT))));
- }
-
- gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc);
- setText(max_arc, value_label, short_val);
-}
-
-void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool short_val)
-{
- if (0 == value)
- {
- text_box->setText(LLTrans::getString("no_limit"));
- }
- else
- {
- std::string text_value = short_val ? llformat("%d", value / 1000) : llformat("%d", value);
- text_box->setText(text_value);
- }
-}
-
-void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
-{
- setRenderTimeText((F32)(LLPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val);
-}
-
-void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val)
-{
- if (0 == value)
- {
- text_box->setText(LLTrans::getString("no_limit"));
- }
- else
- {
- text_box->setText(llformat("%.0f", value));
- }
-}
-
-void LLFloaterPreference::updateMaxComplexity()
-{
- // Called when the IndirectMaxComplexity control changes
- LLAvatarComplexityControls::updateMax(
- getChild<LLSliderCtrl>("IndirectMaxComplexity"),
- getChild<LLTextBox>("IndirectMaxComplexityText"));
-}
-
-void LLFloaterPreference::updateComplexityText()
-{
- LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
- getChild<LLTextBox>("IndirectMaxComplexityText", true));
-}
-
-bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map)
-{
- LLXMLNodePtr root;
-
- if (!LLXMLNode::parseFile(filename, root, NULL))
- {
- LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
- return false;
- }
-
- if (!root->hasName("labels"))
- {
- LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
- return false;
- }
-
- LabelTable params;
- LLXUIParser parser;
- parser.readXUI(root, params, filename);
-
- if (params.validateBlock())
- {
- for (LLInitParam::ParamIterator<LabelDef>::const_iterator it = params.labels.begin();
- it != params.labels.end();
- ++it)
- {
- LabelDef label_entry = *it;
- label_map[label_entry.name] = label_entry.value;
- }
- }
- else
- {
- LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
- return false;
- }
-
- return true;
-}
-
-void LLFloaterPreference::onChangeMaturity()
-{
- U8 sim_access = gSavedSettings.getU32("PreferredMaturity");
-
- getChild<LLIconCtrl>("rating_icon_general")->setVisible(sim_access == SIM_ACCESS_PG
- || sim_access == SIM_ACCESS_MATURE
- || sim_access == SIM_ACCESS_ADULT);
-
- getChild<LLIconCtrl>("rating_icon_moderate")->setVisible(sim_access == SIM_ACCESS_MATURE
- || sim_access == SIM_ACCESS_ADULT);
-
- getChild<LLIconCtrl>("rating_icon_adult")->setVisible(sim_access == SIM_ACCESS_ADULT);
-}
-
-void LLFloaterPreference::onChangeComplexityMode(const LLSD& newvalue)
-{
- bool enable_complexity = newvalue.asInteger() != LLVOAvatar::AV_RENDER_ONLY_SHOW_FRIENDS;
- getChild<LLSliderCtrl>("IndirectMaxComplexity")->setEnabled(enable_complexity);
-}
-
-std::string get_category_path(LLFolderType::EType cat_type)
-{
- LLUUID cat_id = gInventory.findUserDefinedCategoryUUIDForType(cat_type);
- return get_category_path(cat_id);
-}
-
-void LLFloaterPreference::onChangeModelFolder()
-{
- if (gInventory.isInventoryUsable())
- {
- getChild<LLTextBox>("upload_models")->setText(get_category_path(LLFolderType::FT_OBJECT));
- }
-}
-
-void LLFloaterPreference::onChangePBRFolder()
-{
- if (gInventory.isInventoryUsable())
- {
- getChild<LLTextBox>("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL));
- }
-}
-
-void LLFloaterPreference::onChangeTextureFolder()
-{
- if (gInventory.isInventoryUsable())
- {
- getChild<LLTextBox>("upload_textures")->setText(get_category_path(LLFolderType::FT_TEXTURE));
- }
-}
-
-void LLFloaterPreference::onChangeSoundFolder()
-{
- if (gInventory.isInventoryUsable())
- {
- getChild<LLTextBox>("upload_sounds")->setText(get_category_path(LLFolderType::FT_SOUND));
- }
-}
-
-void LLFloaterPreference::onChangeAnimationFolder()
-{
- if (gInventory.isInventoryUsable())
- {
- getChild<LLTextBox>("upload_animation")->setText(get_category_path(LLFolderType::FT_ANIMATION));
- }
-}
-
-// FIXME: this will stop you from spawning the sidetray from preferences dialog on login screen
-// but the UI for this will still be enabled
-void LLFloaterPreference::onClickBlockList()
-{
- LLFloaterSidePanelContainer::showPanel("people", "panel_people",
- LLSD().with("people_panel_tab_name", "blocked_panel"));
-}
-
-void LLFloaterPreference::onClickProxySettings()
-{
- LLFloaterReg::showInstance("prefs_proxy");
-}
-
-void LLFloaterPreference::onClickTranslationSettings()
-{
- LLFloaterReg::showInstance("prefs_translation");
-}
-
-void LLFloaterPreference::onClickAutoReplace()
-{
- LLFloaterReg::showInstance("prefs_autoreplace");
-}
-
-void LLFloaterPreference::onClickSpellChecker()
-{
- LLFloaterReg::showInstance("prefs_spellchecker");
-}
-
-void LLFloaterPreference::onClickRenderExceptions()
-{
- LLFloaterReg::showInstance("avatar_render_settings");
-}
-
-void LLFloaterPreference::onClickAutoAdjustments()
-{
- LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance");
- if (performance_floater)
- {
- performance_floater->showAutoadjustmentsPanel();
- }
-}
-
-void LLFloaterPreference::onClickAdvanced()
-{
- LLFloaterReg::showInstance("prefs_graphics_advanced");
-
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
- iter != tabcontainer->getChildList()->end(); ++iter)
- {
- LLView* view = *iter;
- LLPanelPreferenceGraphics* panel = dynamic_cast<LLPanelPreferenceGraphics*>(view);
- if (panel)
- {
- panel->resetDirtyChilds();
- }
- }
-}
-
-void LLFloaterPreference::onClickActionChange()
-{
- updateClickActionControls();
-}
-
-void LLFloaterPreference::onAtmosShaderChange()
-{
- LLCheckBoxCtrl* ctrl_alm = getChild<LLCheckBoxCtrl>("UseLightShaders");
- if(ctrl_alm)
- {
- //Deferred/SSAO/Shadows
- bool bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
- bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- bool enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- bumpshiny &&
- shaders;
-
- ctrl_alm->setEnabled(enabled);
- }
-}
-
-void LLFloaterPreference::onClickPermsDefault()
-{
- LLFloaterReg::showInstance("perms_default");
-}
-
-void LLFloaterPreference::onClickRememberedUsernames()
-{
- LLFloaterReg::showInstance("forget_username");
-}
-
-void LLFloaterPreference::onDeleteTranscripts()
-{
- LLSD args;
- args["FOLDER"] = gDirUtilp->getUserName();
-
- LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", args, LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
-}
-
-void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
-{
- if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
- {
- LLLogChat::deleteTranscripts();
- updateDeleteTranscriptsButton();
- }
-}
-
-void LLFloaterPreference::onLogChatHistorySaved()
-{
- LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts");
-
- if (!delete_transcripts_buttonp->getEnabled())
- {
- delete_transcripts_buttonp->setEnabled(true);
- }
-}
-
-void LLFloaterPreference::updateClickActionControls()
-{
- const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
- const int double_clk_action = getChild<LLComboBox>("double_click_action_combo")->getValue().asInteger();
-
- // Todo: This is a very ugly way to get access to keybindings.
- // Reconsider possible options.
- // Potential option: make constructor of LLKeyConflictHandler private
- // but add a getter that will return shared pointer for specific
- // mode, pointer should only exist so long as there are external users.
- // In such case we won't need to do this 'dynamic_cast' nightmare.
- // updateTable() can also be avoided
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
- iter != tabcontainer->getChildList()->end(); ++iter)
- {
- LLView* view = *iter;
- LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
- if (panel)
- {
- panel->setKeyBind("walk_to",
- EMouseClickType::CLICK_LEFT,
- KEY_NONE,
- MASK_NONE,
- single_clk_action == 1);
-
- panel->setKeyBind("walk_to",
- EMouseClickType::CLICK_DOUBLELEFT,
- KEY_NONE,
- MASK_NONE,
- double_clk_action == 1);
-
- panel->setKeyBind("teleport_to",
- EMouseClickType::CLICK_DOUBLELEFT,
- KEY_NONE,
- MASK_NONE,
- double_clk_action == 2);
-
- panel->updateAndApply();
- }
- }
-}
-
-void LLFloaterPreference::updateClickActionViews()
-{
- bool click_to_walk = false;
- bool dbl_click_to_walk = false;
- bool dbl_click_to_teleport = false;
-
- // Todo: This is a very ugly way to get access to keybindings.
- // Reconsider possible options.
- LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
- for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
- iter != tabcontainer->getChildList()->end(); ++iter)
- {
- LLView* view = *iter;
- LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
- if (panel)
- {
- click_to_walk = panel->canKeyBindHandle("walk_to",
- EMouseClickType::CLICK_LEFT,
- KEY_NONE,
- MASK_NONE);
-
- dbl_click_to_walk = panel->canKeyBindHandle("walk_to",
- EMouseClickType::CLICK_DOUBLELEFT,
- KEY_NONE,
- MASK_NONE);
-
- dbl_click_to_teleport = panel->canKeyBindHandle("teleport_to",
- EMouseClickType::CLICK_DOUBLELEFT,
- KEY_NONE,
- MASK_NONE);
- }
- }
-
- getChild<LLComboBox>("single_click_action_combo")->setValue((int)click_to_walk);
- getChild<LLComboBox>("double_click_action_combo")->setValue(dbl_click_to_teleport ? 2 : (int)dbl_click_to_walk);
-}
-
-void LLFloaterPreference::updateSearchableItems()
-{
- mSearchDataDirty = true;
-}
-
-void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
-{
- LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
-}
-
-void LLFloaterPreference::getUIColor(LLUICtrl* ctrl, const LLSD& param)
-{
- LLColorSwatchCtrl* color_swatch = (LLColorSwatchCtrl*) ctrl;
- color_swatch->setOriginal(LLUIColorTable::instance().getColor(param.asString()));
-}
-
-void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location)
-{
- LLUICtrl* cache_location_editor = getChild<LLUICtrl>("cache_location");
- cache_location_editor->setValue(location);
- cache_location_editor->setToolTip(location);
-}
-
-void LLFloaterPreference::selectPanel(const LLSD& name)
-{
- LLTabContainer * tab_containerp = getChild<LLTabContainer>("pref core");
- LLPanel * panel = tab_containerp->getPanelByName(name);
- if (NULL != panel)
- {
- tab_containerp->selectTabPanel(panel);
- }
-}
-
-void LLFloaterPreference::selectPrivacyPanel()
-{
- selectPanel("im");
-}
-
-void LLFloaterPreference::selectChatPanel()
-{
- selectPanel("chat");
-}
-
-void LLFloaterPreference::changed()
-{
- getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
-
- // set 'enable' property for 'Delete transcripts...' button
- updateDeleteTranscriptsButton();
-
-}
-
-void LLFloaterPreference::saveGraphicsPreset(std::string& preset)
-{
- mSavedGraphicsPreset = preset;
-}
-
-//------------------------------Updater---------------------------------------
-
-static bool handleBandwidthChanged(const LLSD& newvalue)
-{
- gViewerThrottle.setMaxBandwidth((F32) newvalue.asReal());
- return true;
-}
-
-class LLPanelPreference::Updater : public LLEventTimer
-{
-
-public:
-
- typedef boost::function<bool(const LLSD&)> callback_t;
-
- Updater(callback_t cb, F32 period)
- :LLEventTimer(period),
- mCallback(cb)
- {
- mEventTimer.stop();
- }
-
- virtual ~Updater(){}
-
- void update(const LLSD& new_value)
- {
- mNewValue = new_value;
- mEventTimer.start();
- }
-
-protected:
-
- bool tick()
- {
- mCallback(mNewValue);
- mEventTimer.stop();
-
- return false;
- }
-
-private:
-
- LLSD mNewValue;
- callback_t mCallback;
-};
-//----------------------------------------------------------------------------
-static LLPanelInjector<LLPanelPreference> t_places("panel_preference");
-LLPanelPreference::LLPanelPreference()
-: LLPanel(),
- mBandWidthUpdater(NULL)
-{
- mCommitCallbackRegistrar.add("Pref.setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2));
- mCommitCallbackRegistrar.add("Pref.updateMediaAutoPlayCheckbox", boost::bind(&LLPanelPreference::updateMediaAutoPlayCheckbox, this, _1));
- mCommitCallbackRegistrar.add("Pref.PrefDelete", boost::bind(&LLPanelPreference::deletePreset, this, _2));
- mCommitCallbackRegistrar.add("Pref.PrefSave", boost::bind(&LLPanelPreference::savePreset, this, _2));
- mCommitCallbackRegistrar.add("Pref.PrefLoad", boost::bind(&LLPanelPreference::loadPreset, this, _2));
-}
-
-//virtual
-bool LLPanelPreference::postBuild()
-{
- ////////////////////// PanelGeneral ///////////////////
- if (hasChild("display_names_check", true))
- {
- bool use_people_api = gSavedSettings.getBOOL("UsePeopleAPI");
- LLCheckBoxCtrl* ctrl_display_name = getChild<LLCheckBoxCtrl>("display_names_check");
- ctrl_display_name->setEnabled(use_people_api);
- if (!use_people_api)
- {
- ctrl_display_name->setValue(false);
- }
- }
-
- ////////////////////// PanelVoice ///////////////////
- if (hasChild("voice_unavailable", true))
- {
- bool voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice");
- getChildView("voice_unavailable")->setVisible( voice_disabled);
- getChildView("enable_voice_check")->setVisible( !voice_disabled);
- }
-
- //////////////////////PanelSkins ///////////////////
-
- if (hasChild("skin_selection", true))
- {
- LLFloaterPreference::refreshSkin(this);
-
- // if skin is set to a skin that no longer exists (silver) set back to default
- if (getChild<LLRadioGroup>("skin_selection")->getSelectedIndex() < 0)
- {
- gSavedSettings.setString("SkinCurrent", "default");
- LLFloaterPreference::refreshSkin(this);
- }
-
- }
-
- //////////////////////PanelPrivacy ///////////////////
- if (hasChild("media_enabled", true))
- {
- bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
-
- getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);
- getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);
- }
- if (hasChild("music_enabled", true))
- {
- getChild<LLCheckBoxCtrl>("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic"));
- }
- if (hasChild("voice_call_friends_only_check", true))
- {
- getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));
- }
- if (hasChild("allow_multiple_viewer_check", true))
- {
- getChild<LLCheckBoxCtrl>("allow_multiple_viewer_check")->setCommitCallback(boost::bind(&showMultipleViewersWarning, _1, _2));
- }
- if (hasChild("favorites_on_login_check", true))
- {
- getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2));
- bool show_favorites_at_login = LLPanelLogin::getShowFavorites();
- getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setValue(show_favorites_at_login);
- }
- if (hasChild("mute_chb_label", true))
- {
- getChild<LLTextBox>("mute_chb_label")->setShowCursorHand(false);
- getChild<LLTextBox>("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP);
- getChild<LLTextBox>("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized));
- }
-
- //////////////////////PanelSetup ///////////////////
- if (hasChild("max_bandwidth", true))
- {
- mBandWidthUpdater = new LLPanelPreference::Updater(boost::bind(&handleBandwidthChanged, _1), BANDWIDTH_UPDATER_TIMEOUT);
- gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2));
- }
-
-#ifdef EXTERNAL_TOS
- LLRadioGroup* ext_browser_settings = getChild<LLRadioGroup>("preferred_browser_behavior");
- if (ext_browser_settings)
- {
- // turn off ability to set external/internal browser
- ext_browser_settings->setSelectedByValue(LLWeb::BROWSER_EXTERNAL_ONLY, true);
- ext_browser_settings->setEnabled(false);
- }
-#endif
-
- apply();
- return true;
-}
-
-LLPanelPreference::~LLPanelPreference()
-{
- if (mBandWidthUpdater)
- {
- delete mBandWidthUpdater;
- }
-}
-void LLPanelPreference::apply()
-{
- // no-op
-}
-
-void LLPanelPreference::saveSettings()
-{
- LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
-
- // Save the value of all controls in the hierarchy
- mSavedValues.clear();
- std::list<LLView*> view_stack;
- view_stack.push_back(this);
- if (advanced)
- {
- view_stack.push_back(advanced);
- }
- while(!view_stack.empty())
- {
- // Process view on top of the stack
- LLView* curview = view_stack.front();
- view_stack.pop_front();
-
- LLColorSwatchCtrl* color_swatch = dynamic_cast<LLColorSwatchCtrl *>(curview);
- if (color_swatch)
- {
- mSavedColors[color_swatch->getName()] = color_swatch->get();
- }
- else
- {
- LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
- if (ctrl)
- {
- LLControlVariable* control = ctrl->getControlVariable();
- if (control)
- {
- mSavedValues[control] = control->getValue();
- }
- }
- }
-
- // Push children onto the end of the work stack
- for (child_list_t::const_iterator iter = curview->getChildList()->begin();
- iter != curview->getChildList()->end(); ++iter)
- {
- view_stack.push_back(*iter);
- }
- }
-
- if (LLStartUp::getStartupState() == STATE_STARTED)
- {
- LLControlVariable* control = gSavedPerAccountSettings.getControl("VoiceCallsFriendsOnly");
- if (control)
- {
- mSavedValues[control] = control->getValue();
- }
- }
-}
-
-void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLSD& value)
-{
- if (checkbox && checkbox->getValue())
- {
- LLNotificationsUtil::add("AllowMultipleViewers");
- }
-}
-
-void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value)
-{
- if (checkbox)
- {
- gSavedPerAccountSettings.setBOOL("VoiceCallsFriendsOnly", checkbox->getValue().asBoolean());
- if (checkbox->getValue())
- {
- LLNotificationsUtil::add("FriendsAndGroupsOnly");
- }
- }
-}
-
-void LLPanelPreference::handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const LLSD& value)
-{
- if (checkbox)
- {
- LLFavoritesOrderStorage::instance().showFavoritesOnLoginChanged(checkbox->getValue().asBoolean());
- if(checkbox->getValue())
- {
- LLNotificationsUtil::add("FavoritesOnLogin");
- }
- }
-}
-
-void LLPanelPreference::toggleMuteWhenMinimized()
-{
- std::string mute("MuteWhenMinimized");
- gSavedSettings.setBOOL(mute, !gSavedSettings.getBOOL(mute));
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->getChild<LLCheckBoxCtrl>("mute_when_minimized")->setBtnFocus();
- }
-}
-
-void LLPanelPreference::cancel(const std::vector<std::string> settings_to_skip)
-{
- for (control_values_map_t::iterator iter = mSavedValues.begin();
- iter != mSavedValues.end(); ++iter)
- {
- LLControlVariable* control = iter->first;
- LLSD ctrl_value = iter->second;
-
- if((control->getName() == "InstantMessageLogPath") && (ctrl_value.asString() == ""))
- {
- continue;
- }
-
- auto found = std::find(settings_to_skip.begin(), settings_to_skip.end(), control->getName());
- if (found != settings_to_skip.end())
- {
- continue;
- }
-
- control->set(ctrl_value);
- }
-
- for (string_color_map_t::iterator iter = mSavedColors.begin();
- iter != mSavedColors.end(); ++iter)
- {
- LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>(iter->first);
- if (color_swatch)
- {
- color_swatch->set(iter->second);
- color_swatch->onCommit();
- }
- }
-}
-
-void LLPanelPreference::setControlFalse(const LLSD& user_data)
-{
- std::string control_name = user_data.asString();
- LLControlVariable* control = findControl(control_name);
-
- if (control)
- control->set(LLSD(false));
-}
-
-void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
-{
- std::string name = ctrl->getName();
-
- // Disable "Allow Media to auto play" only when both
- // "Streaming Music" and "Media" are unchecked. STORM-513.
- if ((name == "enable_music") || (name == "enable_media"))
- {
- bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
- bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
-
- getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
- }
-}
-
-void LLPanelPreference::deletePreset(const LLSD& user_data)
-{
- LLFloaterReg::showInstance("delete_pref_preset", user_data.asString());
-}
-
-void LLPanelPreference::savePreset(const LLSD& user_data)
-{
- LLFloaterReg::showInstance("save_pref_preset", user_data.asString());
-}
-
-void LLPanelPreference::loadPreset(const LLSD& user_data)
-{
- LLFloaterReg::showInstance("load_pref_preset", user_data.asString());
-}
-
-void LLPanelPreference::setHardwareDefaults()
-{
-}
-
-class LLPanelPreferencePrivacy : public LLPanelPreference
-{
-public:
- LLPanelPreferencePrivacy()
- {
- mAccountIndependentSettings.push_back("AutoDisengageMic");
- }
-
- /*virtual*/ void saveSettings()
- {
- LLPanelPreference::saveSettings();
-
- // Don't save (=erase from the saved values map) per-account privacy settings
- // if we're not logged in, otherwise they will be reset to defaults on log off.
- if (LLStartUp::getStartupState() != STATE_STARTED)
- {
- // Erase only common settings, assuming there are no color settings on Privacy page.
- for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); )
- {
- const std::string setting = it->first->getName();
- if (find(mAccountIndependentSettings.begin(),
- mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end())
- {
- mSavedValues.erase(it++);
- }
- else
- {
- ++it;
- }
- }
- }
- }
-
-private:
- std::list<std::string> mAccountIndependentSettings;
-};
-
-static LLPanelInjector<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics");
-static LLPanelInjector<LLPanelPreferencePrivacy> t_pref_privacy("panel_preference_privacy");
-
-bool LLPanelPreferenceGraphics::postBuild()
-{
- LLFloaterReg::showInstance("prefs_graphics_advanced");
- LLFloaterReg::hideInstance("prefs_graphics_advanced");
-
- resetDirtyChilds();
- setPresetText();
-
- LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
- presetsMgr->setPresetListChangeCallback(boost::bind(&LLPanelPreferenceGraphics::onPresetsListChange, this));
- presetsMgr->createMissingDefault(PRESETS_GRAPHIC); // a no-op after the first time, but that's ok
-
- return LLPanelPreference::postBuild();
-}
-
-void LLPanelPreferenceGraphics::draw()
-{
- setPresetText();
- LLPanelPreference::draw();
-}
-
-void LLPanelPreferenceGraphics::onPresetsListChange()
-{
- resetDirtyChilds();
- setPresetText();
-
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance && !gSavedSettings.getString("PresetGraphicActive").empty())
- {
- instance->saveSettings(); //make cancel work correctly after changing the preset
- }
-}
-
-void LLPanelPreferenceGraphics::setPresetText()
-{
- LLTextBox* preset_text = getChild<LLTextBox>("preset_text");
-
- std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
-
- if (!preset_graphic_active.empty() && preset_graphic_active != preset_text->getText())
- {
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->saveGraphicsPreset(preset_graphic_active);
- }
- }
-
- if (hasDirtyChilds() && !preset_graphic_active.empty())
- {
- gSavedSettings.setString("PresetGraphicActive", "");
- preset_graphic_active.clear();
- // This doesn't seem to cause an infinite recursion. This trigger is needed to cause the pulldown
- // panel to update.
- LLPresetsManager::getInstance()->triggerChangeSignal();
- }
-
- if (!preset_graphic_active.empty())
- {
- if (preset_graphic_active == PRESETS_DEFAULT)
- {
- preset_graphic_active = LLTrans::getString(PRESETS_DEFAULT);
- }
- preset_text->setText(preset_graphic_active);
- }
- else
- {
- preset_text->setText(LLTrans::getString("none_paren_cap"));
- }
-
- preset_text->resetDirty();
-}
-
-bool LLPanelPreferenceGraphics::hasDirtyChilds()
-{
- LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
- std::list<LLView*> view_stack;
- view_stack.push_back(this);
- if (advanced)
- {
- view_stack.push_back(advanced);
- }
- while(!view_stack.empty())
- {
- // Process view on top of the stack
- LLView* curview = view_stack.front();
- view_stack.pop_front();
-
- LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
- if (ctrl)
- {
- if (ctrl->isDirty())
- {
- LLControlVariable* control = ctrl->getControlVariable();
- if (control)
- {
- std::string control_name = control->getName();
- if (!control_name.empty())
- {
- return true;
- }
- }
- }
- }
- // Push children onto the end of the work stack
- for (child_list_t::const_iterator iter = curview->getChildList()->begin();
- iter != curview->getChildList()->end(); ++iter)
- {
- view_stack.push_back(*iter);
- }
- }
-
- return false;
-}
-
-void LLPanelPreferenceGraphics::resetDirtyChilds()
-{
- LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
- std::list<LLView*> view_stack;
- view_stack.push_back(this);
- if (advanced)
- {
- view_stack.push_back(advanced);
- }
- while(!view_stack.empty())
- {
- // Process view on top of the stack
- LLView* curview = view_stack.front();
- view_stack.pop_front();
-
- LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
- if (ctrl)
- {
- ctrl->resetDirty();
- }
- // Push children onto the end of the work stack
- for (child_list_t::const_iterator iter = curview->getChildList()->begin();
- iter != curview->getChildList()->end(); ++iter)
- {
- view_stack.push_back(*iter);
- }
- }
-}
-
-void LLPanelPreferenceGraphics::cancel(const std::vector<std::string> settings_to_skip)
-{
- LLPanelPreference::cancel(settings_to_skip);
-}
-void LLPanelPreferenceGraphics::saveSettings()
-{
- resetDirtyChilds();
- std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
- if (preset_graphic_active.empty())
- {
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- //don't restore previous preset after closing Preferences
- instance->saveGraphicsPreset(preset_graphic_active);
- }
- }
- LLPanelPreference::saveSettings();
-}
-void LLPanelPreferenceGraphics::setHardwareDefaults()
-{
- resetDirtyChilds();
-}
-
-//------------------------LLPanelPreferenceControls--------------------------------
-static LLPanelInjector<LLPanelPreferenceControls> t_pref_contrls("panel_preference_controls");
-
-LLPanelPreferenceControls::LLPanelPreferenceControls()
- :LLPanelPreference(),
- mEditingColumn(-1),
- mEditingMode(0)
-{
- // MODE_COUNT - 1 because there are currently no settings assigned to 'saved settings'.
- for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
- {
- mConflictHandler[i].setLoadMode((LLKeyConflictHandler::ESourceMode)i);
- }
-}
-
-LLPanelPreferenceControls::~LLPanelPreferenceControls()
-{
-}
-
-bool LLPanelPreferenceControls::postBuild()
-{
- // populate list of controls
- pControlsTable = getChild<LLScrollListCtrl>("controls_list");
- pKeyModeBox = getChild<LLComboBox>("key_mode");
-
- pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this));
- pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this));
- getChild<LLButton>("restore_defaults")->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsBtn, this));
-
- return true;
-}
-
-void LLPanelPreferenceControls::regenerateControls()
-{
- mEditingMode = pKeyModeBox->getValue().asInteger();
- mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
- populateControlTable();
-}
-
-bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filename)
-{
- LLXMLNodePtr xmlNode;
- LLScrollListCtrl::Contents contents;
- if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
- {
- LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
- return false;
- }
- LLXUIParser parser;
- parser.readXUI(xmlNode, contents, filename);
-
- if (!contents.validateBlock())
- {
- return false;
- }
-
- for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator col_it = contents.columns.begin();
- col_it != contents.columns.end();
- ++col_it)
- {
- pControlsTable->addColumn(*col_it);
- }
-
- return true;
-}
-
-bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
-{
- LLXMLNodePtr xmlNode;
- LLScrollListCtrl::Contents contents;
- if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
- {
- LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
- return false;
- }
- LLXUIParser parser;
- parser.readXUI(xmlNode, contents, filename);
-
- if (!contents.validateBlock())
- {
- return false;
- }
-
- LLScrollListCell::Params cell_params;
- // init basic cell params
- cell_params.font = LLFontGL::getFontSansSerif();
- cell_params.font_halign = LLFontGL::LEFT;
- cell_params.column = "";
- cell_params.value = "";
-
-
- for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = contents.rows.begin();
- row_it != contents.rows.end();
- ++row_it)
- {
- std::string control = row_it->value.getValue().asString();
- if (!control.empty() && control != "menu_separator")
- {
- bool show = true;
- bool enabled = mConflictHandler[mEditingMode].canAssignControl(control);
- if (!enabled)
- {
- // If empty: this is a placeholder to make sure user won't assign
- // value by accident, don't show it
- // If not empty: predefined control combination user should see
- // to know that combination is reserved
- show = !mConflictHandler[mEditingMode].isControlEmpty(control);
- // example: teleport_to and walk_to in first person view, and
- // sitting related functions, see generatePlaceholders()
- }
-
- if (show)
- {
- // At the moment viewer is hardcoded to assume that columns are named as lst_ctrl%d
- LLScrollListItem::Params item_params(*row_it);
- item_params.enabled.setValue(enabled);
-
- S32 num_columns = pControlsTable->getNumColumns();
- for (S32 col = 1; col < num_columns; col++)
- {
- cell_params.column = llformat("lst_ctrl%d", col);
- cell_params.value = mConflictHandler[mEditingMode].getControlString(control, col - 1);
- item_params.columns.add(cell_params);
- }
- pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM);
- }
- }
- else
- {
- // Separator example:
- // <rows
- // enabled = "false">
- // <columns
- // type = "icon"
- // color = "0 0 0 0.7"
- // halign = "center"
- // value = "menu_separator"
- // column = "lst_action" / >
- //</rows>
- pControlsTable->addRow(*row_it, EAddPosition::ADD_BOTTOM);
- }
- }
- return true;
-}
-
-void LLPanelPreferenceControls::addControlTableSeparator()
-{
- LLScrollListItem::Params separator_params;
- separator_params.enabled(false);
- LLScrollListCell::Params column_params;
- column_params.type = "icon";
- column_params.value = "menu_separator";
- column_params.column = "lst_action";
- column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f);
- column_params.font_halign = LLFontGL::HCENTER;
- separator_params.columns.add(column_params);
- pControlsTable->addRow(separator_params, EAddPosition::ADD_BOTTOM);
-}
-
-void LLPanelPreferenceControls::populateControlTable()
-{
- pControlsTable->clearRows();
- pControlsTable->clearColumns();
-
- // Add columns
- std::string filename;
- switch ((LLKeyConflictHandler::ESourceMode)mEditingMode)
- {
- case LLKeyConflictHandler::MODE_THIRD_PERSON:
- case LLKeyConflictHandler::MODE_FIRST_PERSON:
- case LLKeyConflictHandler::MODE_EDIT_AVATAR:
- case LLKeyConflictHandler::MODE_SITTING:
- filename = "control_table_contents_columns_basic.xml";
- break;
- default:
- {
- // Either unknown mode or MODE_SAVED_SETTINGS
- // It doesn't have UI or actual settings yet
- LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
-
- // Searchable columns were removed, mark searchables for an update
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->updateSearchableItems();
- }
- return;
- }
- }
- addControlTableColumns(filename);
-
- // Add rows.
- // Each file represents individual visual group (movement/camera/media...)
- if (mEditingMode == LLKeyConflictHandler::MODE_FIRST_PERSON)
- {
- // Don't display whole camera and editing groups
- addControlTableRows("control_table_contents_movement.xml");
- addControlTableSeparator();
- addControlTableRows("control_table_contents_media.xml");
- }
- // MODE_THIRD_PERSON; MODE_EDIT_AVATAR; MODE_SITTING
- else if (mEditingMode < LLKeyConflictHandler::MODE_SAVED_SETTINGS)
- {
- // In case of 'sitting' mode, movements still apply due to vehicles
- // but walk_to is not supported and will be hidden by addControlTableRows
- addControlTableRows("control_table_contents_movement.xml");
- addControlTableSeparator();
-
- addControlTableRows("control_table_contents_camera.xml");
- addControlTableSeparator();
-
- addControlTableRows("control_table_contents_editing.xml");
- addControlTableSeparator();
-
- addControlTableRows("control_table_contents_media.xml");
- }
- else
- {
- LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
- }
-
- // explicit update to make sure table is ready for llsearchableui
- pControlsTable->updateColumns();
-
- // Searchable columns were removed and readded, mark searchables for an update
- // Note: at the moment tables/lists lack proper llsearchableui support
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->updateSearchableItems();
- }
-}
-
-void LLPanelPreferenceControls::updateTable()
-{
- mEditingControl.clear();
- std::vector<LLScrollListItem*> list = pControlsTable->getAllData();
- for (S32 i = 0; i < list.size(); ++i)
- {
- std::string control = list[i]->getValue();
- if (!control.empty())
- {
- LLScrollListCell* cell = NULL;
-
- S32 num_columns = pControlsTable->getNumColumns();
- for (S32 col = 1; col < num_columns; col++)
- {
- cell = list[i]->getColumn(col);
- cell->setValue(mConflictHandler[mEditingMode].getControlString(control, col - 1));
- }
- }
- }
- pControlsTable->deselectAllItems();
-}
-
-void LLPanelPreferenceControls::apply()
-{
- for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
- {
- if (mConflictHandler[i].hasUnsavedChanges())
- {
- mConflictHandler[i].saveToSettings();
- }
- }
-}
-
-void LLPanelPreferenceControls::cancel(const std::vector<std::string> settings_to_skip)
-{
- for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
- {
- if (mConflictHandler[i].hasUnsavedChanges())
- {
- mConflictHandler[i].clear();
- if (mEditingMode == i)
- {
- // cancel() can be called either when preferences floater closes
- // or when child floater closes (like advanced graphical settings)
- // in which case we need to clear and repopulate table
- regenerateControls();
- }
- }
- }
-}
-
-void LLPanelPreferenceControls::saveSettings()
-{
- for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
- {
- if (mConflictHandler[i].hasUnsavedChanges())
- {
- mConflictHandler[i].saveToSettings();
- mConflictHandler[i].clear();
- }
- }
-
- S32 mode = pKeyModeBox->getValue().asInteger();
- if (mConflictHandler[mode].empty() || pControlsTable->isEmpty())
- {
- regenerateControls();
- }
-}
-
-void LLPanelPreferenceControls::resetDirtyChilds()
-{
- regenerateControls();
-}
-
-void LLPanelPreferenceControls::onListCommit()
-{
- LLScrollListItem* item = pControlsTable->getFirstSelected();
- if (item == NULL)
- {
- return;
- }
-
- std::string control = item->getValue();
-
- if (control.empty())
- {
- pControlsTable->deselectAllItems();
- return;
- }
-
- if (!mConflictHandler[mEditingMode].canAssignControl(control))
- {
- pControlsTable->deselectAllItems();
- return;
- }
-
- S32 cell_ind = item->getSelectedCell();
- if (cell_ind <= 0)
- {
- pControlsTable->deselectAllItems();
- return;
- }
-
- // List does not tell us what cell was clicked, so we have to figure it out manually, but
- // fresh mouse coordinates are not yet accessible during onCommit() and there are other issues,
- // so we cheat: remember item user clicked at, trigger 'key dialog' on hover that comes next,
- // use coordinates from hover to calculate cell
-
- LLScrollListCell* cell = item->getColumn(cell_ind);
- if (cell)
- {
- LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD());
- if (dialog)
- {
- mEditingControl = control;
- mEditingColumn = cell_ind;
- dialog->setParent(this, pControlsTable, DEFAULT_KEY_FILTER);
-
- LLFloater* root_floater = gFloaterView->getParentFloater(this);
- if (root_floater)
- root_floater->addDependentFloater(dialog);
- dialog->openFloater();
- dialog->setFocus(true);
- }
- }
- else
- {
- pControlsTable->deselectAllItems();
- }
-}
-
-void LLPanelPreferenceControls::onModeCommit()
-{
- mEditingMode = pKeyModeBox->getValue().asInteger();
- if (mConflictHandler[mEditingMode].empty())
- {
- // opening for first time
- mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
- }
- populateControlTable();
-}
-
-void LLPanelPreferenceControls::onRestoreDefaultsBtn()
-{
- LLNotificationsUtil::add("PreferenceControlsDefaults", LLSD(), LLSD(), boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsResponse, this, _1, _2));
-}
-
-void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch(option)
- {
- case 0: // All
- for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
- {
- mConflictHandler[i].resetToDefaults();
- // Apply changes to viewer as 'temporary'
- mConflictHandler[i].saveToSettings(true);
-
- // notify comboboxes in move&view about potential change
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->updateClickActionViews();
- }
- }
-
- updateTable();
- break;
- case 1: // Current
- mConflictHandler[mEditingMode].resetToDefaults();
- // Apply changes to viewer as 'temporary'
- mConflictHandler[mEditingMode].saveToSettings(true);
-
- if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON)
- {
- // notify comboboxes in move&view about potential change
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->updateClickActionViews();
- }
- }
-
- updateTable();
- break;
- case 2: // Cancel
- default:
- //exit;
- break;
- }
-}
-
-// Bypass to let Move & view read values without need to create own key binding handler
-// Assumes third person view
-// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
-bool LLPanelPreferenceControls::canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask)
-{
- S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
- if (mConflictHandler[mode].empty())
- {
- // opening for first time
- mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
- }
-
- return mConflictHandler[mode].canHandleControl(control, click, key, mask);
-}
-
-// Bypass to let Move & view modify values without need to create own key binding handler
-// Assumes third person view
-// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
-void LLPanelPreferenceControls::setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set)
-{
- S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
- if (mConflictHandler[mode].empty())
- {
- // opening for first time
- mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
- }
-
- if (!mConflictHandler[mode].canAssignControl(mEditingControl))
- {
- return;
- }
-
- bool already_recorded = mConflictHandler[mode].canHandleControl(control, click, key, mask);
- if (set)
- {
- if (already_recorded)
- {
- // nothing to do
- return;
- }
-
- // find free spot to add data, if no free spot, assign to first
- S32 index = 0;
- for (S32 i = 0; i < 3; i++)
- {
- if (mConflictHandler[mode].getControl(control, i).isEmpty())
- {
- index = i;
- break;
- }
- }
- // At the moment 'ignore_mask' mask is mostly ignored, a placeholder
- // Todo: implement it since it's preferable for things like teleport to match
- // mask exactly but for things like running to ignore additional masks
- // Ideally this needs representation in keybindings UI
- bool ignore_mask = true;
- mConflictHandler[mode].registerControl(control, index, click, key, mask, ignore_mask);
- }
- else if (!set)
- {
- if (!already_recorded)
- {
- // nothing to do
- return;
- }
-
- // find specific control and reset it
- for (S32 i = 0; i < 3; i++)
- {
- LLKeyData data = mConflictHandler[mode].getControl(control, i);
- if (data.mMouse == click && data.mKey == key && data.mMask == mask)
- {
- mConflictHandler[mode].clearControl(control, i);
- }
- }
- }
-}
-
-void LLPanelPreferenceControls::updateAndApply()
-{
- S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
- mConflictHandler[mode].saveToSettings(true);
- updateTable();
-}
-
-// from LLSetKeybindDialog's interface
-bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes)
-{
- if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
- {
- return true;
- }
-
- if ( mEditingColumn > 0)
- {
- if (all_modes)
- {
- for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
- {
- if (mConflictHandler[i].empty())
- {
- mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
- }
- mConflictHandler[i].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
- // Apply changes to viewer as 'temporary'
- mConflictHandler[i].saveToSettings(true);
- }
- }
- else
- {
- mConflictHandler[mEditingMode].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
- // Apply changes to viewer as 'temporary'
- mConflictHandler[mEditingMode].saveToSettings(true);
- }
- }
-
- updateTable();
-
- if ((mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
- && (mEditingControl == "walk_to"
- || mEditingControl == "teleport_to"
- || click == CLICK_LEFT
- || click == CLICK_DOUBLELEFT))
- {
- // notify comboboxes in move&view about potential change
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->updateClickActionViews();
- }
- }
-
- return true;
-}
-
-void LLPanelPreferenceControls::onDefaultKeyBind(bool all_modes)
-{
- if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
- {
- return;
- }
-
- if (mEditingColumn > 0)
- {
- if (all_modes)
- {
- for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
- {
- if (mConflictHandler[i].empty())
- {
- mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
- }
- mConflictHandler[i].resetToDefault(mEditingControl, mEditingColumn - 1);
- // Apply changes to viewer as 'temporary'
- mConflictHandler[i].saveToSettings(true);
- }
- }
- else
- {
- mConflictHandler[mEditingMode].resetToDefault(mEditingControl, mEditingColumn - 1);
- // Apply changes to viewer as 'temporary'
- mConflictHandler[mEditingMode].saveToSettings(true);
- }
- }
- updateTable();
-
- if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
- {
- // notify comboboxes in move&view about potential change
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
- {
- instance->updateClickActionViews();
- }
- }
-}
-
-void LLPanelPreferenceControls::onCancelKeyBind()
-{
- pControlsTable->deselectAllItems();
-}
-
-LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
- : LLFloater(key),
- mSocksSettingsDirty(false)
-{
- mCommitCallbackRegistrar.add("Proxy.OK", boost::bind(&LLFloaterPreferenceProxy::onBtnOk, this));
- mCommitCallbackRegistrar.add("Proxy.Cancel", boost::bind(&LLFloaterPreferenceProxy::onBtnCancel, this));
- mCommitCallbackRegistrar.add("Proxy.Change", boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));
-}
-
-LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
-{
-}
-
-bool LLFloaterPreferenceProxy::postBuild()
-{
- LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
- if (!socksAuth)
- {
- return false;
- }
- if (socksAuth->getSelectedValue().asString() == "None")
- {
- getChild<LLLineEditor>("socks5_username")->setEnabled(false);
- getChild<LLLineEditor>("socks5_password")->setEnabled(false);
- }
- else
- {
- // Populate the SOCKS 5 credential fields with protected values.
- LLPointer<LLCredential> socks_cred = gSecAPIHandler->loadCredential("SOCKS5");
- getChild<LLLineEditor>("socks5_username")->setValue(socks_cred->getIdentifier()["username"].asString());
- getChild<LLLineEditor>("socks5_password")->setValue(socks_cred->getAuthenticator()["creds"].asString());
- }
-
- return true;
-}
-
-void LLFloaterPreferenceProxy::onOpen(const LLSD& key)
-{
- saveSettings();
-}
-
-void LLFloaterPreferenceProxy::onClose(bool app_quitting)
-{
- if(app_quitting)
- {
- cancel();
- }
-
- if (mSocksSettingsDirty)
- {
-
- // If the user plays with the Socks proxy settings after login, it's only fair we let them know
- // it will not be updated until next restart.
- if (LLStartUp::getStartupState()>STATE_LOGIN_WAIT)
- {
- LLNotifications::instance().add("ChangeProxySettings", LLSD(), LLSD());
- mSocksSettingsDirty = false; // we have notified the user now be quiet again
- }
- }
-}
-
-void LLFloaterPreferenceProxy::saveSettings()
-{
- // Save the value of all controls in the hierarchy
- mSavedValues.clear();
- std::list<LLView*> view_stack;
- view_stack.push_back(this);
- while(!view_stack.empty())
- {
- // Process view on top of the stack
- LLView* curview = view_stack.front();
- view_stack.pop_front();
-
- LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
- if (ctrl)
- {
- LLControlVariable* control = ctrl->getControlVariable();
- if (control)
- {
- mSavedValues[control] = control->getValue();
- }
- }
-
- // Push children onto the end of the work stack
- for (child_list_t::const_iterator iter = curview->getChildList()->begin();
- iter != curview->getChildList()->end(); ++iter)
- {
- view_stack.push_back(*iter);
- }
- }
-}
-
-void LLFloaterPreferenceProxy::onBtnOk()
-{
- // commit any outstanding text entry
- if (hasFocus())
- {
- LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
- if (cur_focus && cur_focus->acceptsTextInput())
- {
- cur_focus->onCommit();
- }
- }
-
- // Save SOCKS proxy credentials securely if password auth is enabled
- LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
- if (socksAuth->getSelectedValue().asString() == "UserPass")
- {
- LLSD socks_id = LLSD::emptyMap();
- socks_id["type"] = "SOCKS5";
- socks_id["username"] = getChild<LLLineEditor>("socks5_username")->getValue().asString();
-
- LLSD socks_authenticator = LLSD::emptyMap();
- socks_authenticator["type"] = "SOCKS5";
- socks_authenticator["creds"] = getChild<LLLineEditor>("socks5_password")->getValue().asString();
-
- // Using "SOCKS5" as the "grid" argument since the same proxy
- // settings will be used for all grids and because there is no
- // way to specify the type of credential.
- LLPointer<LLCredential> socks_cred = gSecAPIHandler->createCredential("SOCKS5", socks_id, socks_authenticator);
- gSecAPIHandler->saveCredential(socks_cred, true);
- }
- else
- {
- // Clear SOCKS5 credentials since they are no longer needed.
- LLPointer<LLCredential> socks_cred = new LLCredential("SOCKS5");
- gSecAPIHandler->deleteCredential(socks_cred);
- }
-
- closeFloater(false);
-}
-
-void LLFloaterPreferenceProxy::onBtnCancel()
-{
- if (hasFocus())
- {
- LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
- if (cur_focus && cur_focus->acceptsTextInput())
- {
- cur_focus->onCommit();
- }
- refresh();
- }
-
- cancel();
-}
-
-void LLFloaterPreferenceProxy::onClickCloseBtn(bool app_quitting)
-{
- cancel();
-}
-
-void LLFloaterPreferenceProxy::cancel()
-{
-
- for (control_values_map_t::iterator iter = mSavedValues.begin();
- iter != mSavedValues.end(); ++iter)
- {
- LLControlVariable* control = iter->first;
- LLSD ctrl_value = iter->second;
- control->set(ctrl_value);
- }
- mSocksSettingsDirty = false;
- closeFloater();
-}
-
-void LLFloaterPreferenceProxy::onChangeSocksSettings()
-{
- mSocksSettingsDirty = true;
-
- LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
- if (socksAuth->getSelectedValue().asString() == "None")
- {
- getChild<LLLineEditor>("socks5_username")->setEnabled(false);
- getChild<LLLineEditor>("socks5_password")->setEnabled(false);
- }
- else
- {
- getChild<LLLineEditor>("socks5_username")->setEnabled(true);
- getChild<LLLineEditor>("socks5_password")->setEnabled(true);
- }
-
- // Check for invalid states for the other HTTP proxy radio
- LLRadioGroup* otherHttpProxy = getChild<LLRadioGroup>("other_http_proxy_type");
- if ((otherHttpProxy->getSelectedValue().asString() == "Socks" &&
- !getChild<LLCheckBoxCtrl>("socks_proxy_enabled")->get())||(
- otherHttpProxy->getSelectedValue().asString() == "Web" &&
- !getChild<LLCheckBoxCtrl>("web_proxy_enabled")->get()))
- {
- otherHttpProxy->selectFirstItem();
- }
-
-}
-
-void LLFloaterPreference::onUpdateFilterTerm(bool force)
-{
- LLWString seachValue = utf8str_to_wstring(mFilterEdit->getValue());
- LLWStringUtil::toLower(seachValue);
-
- if (!mSearchData || (mSearchData->mLastFilter == seachValue && !force))
- return;
-
- if (mSearchDataDirty)
- {
- // Data exists, but is obsolete, regenerate
- collectSearchableItems();
- }
-
- mSearchData->mLastFilter = seachValue;
-
- if (!mSearchData->mRootTab)
- return;
-
- mSearchData->mRootTab->hightlightAndHide( seachValue );
- filterIgnorableNotifications();
-
- if (LLTabContainer* pRoot = getChild<LLTabContainer>("pref core"))
- pRoot->selectFirstTab();
-}
-
-void LLFloaterPreference::filterIgnorableNotifications()
-{
- bool visible = getChildRef<LLScrollListCtrl>("enabled_popups").highlightMatchingItems(mFilterEdit->getValue());
- visible |= getChildRef<LLScrollListCtrl>("disabled_popups").highlightMatchingItems(mFilterEdit->getValue());
-
- if (visible)
- {
- getChildRef<LLTabContainer>("pref core").setTabVisibility( getChild<LLPanel>("msgs"), true );
- }
-}
-
-void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
-{
- if (!aView)
- return;
-
- llassert_always(aParentPanel || aParentTabContainer);
-
- for (LLView* pView : *aView->getChildList())
- {
- if (!pView)
- continue;
-
- ll::prefs::PanelDataPtr pCurPanelData = aParentPanel;
- ll::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer;
-
- LLPanel const *pPanel = dynamic_cast<LLPanel const*>(pView);
- LLTabContainer const *pTabContainer = dynamic_cast<LLTabContainer const*>(pView);
- ll::ui::SearchableControl const *pSCtrl = dynamic_cast<ll::ui::SearchableControl const*>( pView );
-
- if (pTabContainer)
- {
- pCurPanelData.reset();
-
- pCurTabContainer = ll::prefs::TabContainerDataPtr(new ll::prefs::TabContainerData);
- pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>(pTabContainer);
- pCurTabContainer->mLabel = pTabContainer->getLabel();
- pCurTabContainer->mPanel = 0;
-
- if (aParentPanel)
- aParentPanel->mChildPanel.push_back(pCurTabContainer);
- if (aParentTabContainer)
- aParentTabContainer->mChildPanel.push_back(pCurTabContainer);
- }
- else if (pPanel)
- {
- pCurTabContainer.reset();
-
- pCurPanelData = ll::prefs::PanelDataPtr(new ll::prefs::PanelData);
- pCurPanelData->mPanel = pPanel;
- pCurPanelData->mLabel = pPanel->getLabel();
-
- llassert_always( aParentPanel || aParentTabContainer );
-
- if (aParentTabContainer)
- aParentTabContainer->mChildPanel.push_back(pCurPanelData);
- else if (aParentPanel)
- aParentPanel->mChildPanel.push_back(pCurPanelData);
- }
- else if (pSCtrl && pSCtrl->getSearchText().size())
- {
- ll::prefs::SearchableItemPtr item = ll::prefs::SearchableItemPtr(new ll::prefs::SearchableItem());
- item->mView = pView;
- item->mCtrl = pSCtrl;
-
- item->mLabel = utf8str_to_wstring(pSCtrl->getSearchText());
- LLWStringUtil::toLower(item->mLabel);
-
- llassert_always(aParentPanel || aParentTabContainer);
-
- if (aParentPanel)
- aParentPanel->mChildren.push_back(item);
- if (aParentTabContainer)
- aParentTabContainer->mChildren.push_back(item);
- }
- collectChildren(pView, pCurPanelData, pCurTabContainer);
- }
-}
-
-void LLFloaterPreference::collectSearchableItems()
-{
- mSearchData.reset( nullptr );
- LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
- if( mFilterEdit && pRoot )
- {
- mSearchData.reset(new ll::prefs::SearchData() );
-
- ll::prefs::TabContainerDataPtr pRootTabcontainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
- pRootTabcontainer->mTabContainer = pRoot;
- pRootTabcontainer->mLabel = pRoot->getLabel();
- mSearchData->mRootTab = pRootTabcontainer;
-
- collectChildren( this, ll::prefs::PanelDataPtr(), pRootTabcontainer );
- }
- mSearchDataDirty = false;
-}
-
-void LLFloaterPreference::saveIgnoredNotifications()
-{
- for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
- iter != LLNotifications::instance().templatesEnd();
- ++iter)
- {
- LLNotificationTemplatePtr templatep = iter->second;
- LLNotificationFormPtr formp = templatep->mForm;
-
- LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
- if (ignore <= LLNotificationForm::IGNORE_NO)
- continue;
-
- mIgnorableNotifs[templatep->mName] = !formp->getIgnored();
- }
-}
-
-void LLFloaterPreference::restoreIgnoredNotifications()
-{
- for (std::map<std::string, bool>::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it)
- {
- LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second);
- }
-}
+/**
+ * @file llfloaterpreference.cpp
+ * @brief Global preferences with and without persistence.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*
+ * App-wide preferences. Note that these are not per-user,
+ * because we need to load many preferences before we have
+ * a login name.
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterpreference.h"
+
+#include "message.h"
+#include "llfloaterautoreplacesettings.h"
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llcheckboxctrl.h"
+#include "llcolorswatch.h"
+#include "llcombobox.h"
+#include "llcommandhandler.h"
+#include "lldirpicker.h"
+#include "lleventtimer.h"
+#include "llfeaturemanager.h"
+#include "llfocusmgr.h"
+//#include "llfirstuse.h"
+#include "llfloaterreg.h"
+#include "llfloaterabout.h"
+#include "llfavoritesbar.h"
+#include "llfloaterpreferencesgraphicsadvanced.h"
+#include "llfloaterperformance.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfloaterimsession.h"
+#include "llkeyboard.h"
+#include "llmodaldialog.h"
+#include "llnavigationbar.h"
+#include "llfloaterimnearbychat.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llnotificationtemplate.h"
+#include "llpanellogin.h"
+#include "llpanelvoicedevicesettings.h"
+#include "llradiogroup.h"
+#include "llsearchcombobox.h"
+#include "llsky.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llsliderctrl.h"
+#include "lltabcontainer.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewercamera.h"
+#include "llviewereventrecorder.h"
+#include "llviewermessage.h"
+#include "llviewerwindow.h"
+#include "llviewerthrottle.h"
+#include "llvoavatarself.h"
+#include "llvotree.h"
+#include "llfloaterpathfindingconsole.h"
+// linden library includes
+#include "llavatarnamecache.h"
+#include "llerror.h"
+#include "llfontgl.h"
+#include "llrect.h"
+#include "llstring.h"
+
+// project includes
+
+#include "llbutton.h"
+#include "llflexibleobject.h"
+#include "lllineeditor.h"
+#include "llresmgr.h"
+#include "llspinctrl.h"
+#include "llstartup.h"
+#include "lltextbox.h"
+#include "llui.h"
+#include "llviewerobjectlist.h"
+#include "llvovolume.h"
+#include "llwindow.h"
+#include "llworld.h"
+#include "lluictrlfactory.h"
+#include "llviewermedia.h"
+#include "llpluginclassmedia.h"
+#include "llteleporthistorystorage.h"
+#include "llproxy.h"
+#include "llweb.h"
+
+#include "lllogininstance.h" // to check if logged in yet
+#include "llsdserialize.h"
+#include "llpresetsmanager.h"
+#include "llviewercontrol.h"
+#include "llpresetsmanager.h"
+#include "llinventoryfunctions.h"
+
+#include "llsearchableui.h"
+#include "llperfstats.h"
+
+const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
+char const* const VISIBILITY_DEFAULT = "default";
+char const* const VISIBILITY_HIDDEN = "hidden";
+
+//control value for middle mouse as talk2push button
+const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; // for voice client and redability
+const static std::string MOUSE_BUTTON_4_CV = "MouseButton4";
+const static std::string MOUSE_BUTTON_5_CV = "MouseButton5";
+
+/// This must equal the maximum value set for the IndirectMaxComplexity slider in panel_preferences_graphics1.xml
+static const U32 INDIRECT_MAX_ARC_OFF = 101; // all the way to the right == disabled
+static const U32 MIN_INDIRECT_ARC_LIMIT = 1; // must match minimum of IndirectMaxComplexity in panel_preferences_graphics1.xml
+static const U32 MAX_INDIRECT_ARC_LIMIT = INDIRECT_MAX_ARC_OFF-1; // one short of all the way to the right...
+
+/// These are the effective range of values for RenderAvatarMaxComplexity
+static const F32 MIN_ARC_LIMIT = 20000.0f;
+static const F32 MAX_ARC_LIMIT = 350000.0f;
+static const F32 MIN_ARC_LOG = log(MIN_ARC_LIMIT);
+static const F32 MAX_ARC_LOG = log(MAX_ARC_LIMIT);
+static const F32 ARC_LIMIT_MAP_SCALE = (MAX_ARC_LOG - MIN_ARC_LOG) / (MAX_INDIRECT_ARC_LIMIT - MIN_INDIRECT_ARC_LIMIT);
+
+struct LabelDef : public LLInitParam::Block<LabelDef>
+{
+ Mandatory<std::string> name;
+ Mandatory<std::string> value;
+
+ LabelDef()
+ : name("name"),
+ value("value")
+ {}
+};
+
+struct LabelTable : public LLInitParam::Block<LabelTable>
+{
+ Multiple<LabelDef> labels;
+ LabelTable()
+ : labels("label")
+ {}
+};
+
+
+// global functions
+
+// helper functions for getting/freeing the web browser media
+// if creating/destroying these is too slow, we'll need to create
+// a static member and update all our static callbacks
+
+void handleNameTagOptionChanged(const LLSD& newvalue);
+void handleDisplayNamesOptionChanged(const LLSD& newvalue);
+bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response);
+bool callback_clear_cache(const LLSD& notification, const LLSD& response);
+
+//bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
+//bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
+
+void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
+
+bool callback_clear_cache(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if ( option == 0 ) // YES
+ {
+ // flag client texture cache for clearing next time the client runs
+ gSavedSettings.setBOOL("PurgeCacheOnNextStartup", true);
+ LLNotificationsUtil::add("CacheWillClear");
+ }
+
+ return false;
+}
+
+bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if ( option == 0 ) // YES
+ {
+ // clean web
+ LLViewerMedia::getInstance()->clearAllCaches();
+ LLViewerMedia::getInstance()->clearAllCookies();
+
+ // clean nav bar history
+ LLNavigationBar::getInstance()->clearHistoryCache();
+
+ // flag client texture cache for clearing next time the client runs
+ gSavedSettings.setBOOL("PurgeCacheOnNextStartup", true);
+ LLNotificationsUtil::add("CacheWillClear");
+
+ LLSearchHistory::getInstance()->clearHistory();
+ LLSearchHistory::getInstance()->save();
+ LLSearchComboBox* search_ctrl = LLNavigationBar::getInstance()->getChild<LLSearchComboBox>("search_combo_box");
+ search_ctrl->clearHistory();
+
+ LLTeleportHistoryStorage::getInstance()->purgeItems();
+ LLTeleportHistoryStorage::getInstance()->save();
+ }
+
+ return false;
+}
+
+void handleNameTagOptionChanged(const LLSD& newvalue)
+{
+ LLAvatarNameCache::getInstance()->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
+ LLVOAvatar::invalidateNameTags();
+}
+
+void handleDisplayNamesOptionChanged(const LLSD& newvalue)
+{
+ LLAvatarNameCache::getInstance()->setUseDisplayNames(newvalue.asBoolean());
+ LLVOAvatar::invalidateNameTags();
+}
+
+void handleAppearanceCameraMovementChanged(const LLSD& newvalue)
+{
+ if(!newvalue.asBoolean() && gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
+ {
+ gAgentCamera.changeCameraToDefault();
+ gAgentCamera.resetView();
+ }
+}
+
+void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
+{
+ numerator = 0;
+ denominator = 0;
+ for (F32 test_denominator = 1.f; test_denominator < 30.f; test_denominator += 1.f)
+ {
+ if (fmodf((decimal_val * test_denominator) + 0.01f, 1.f) < 0.02f)
+ {
+ numerator = ll_round(decimal_val * test_denominator);
+ denominator = ll_round(test_denominator);
+ break;
+ }
+ }
+}
+
+// handle secondlife:///app/worldmap/{NAME}/{COORDS} URLs
+// Also see LLUrlEntryKeybinding, the value of this command type
+// is ability to show up to date value in chat
+class LLKeybindingHandler: public LLCommandHandler
+{
+public:
+ // requires trusted browser to trigger
+ LLKeybindingHandler(): LLCommandHandler("keybinding", UNTRUSTED_CLICK_ONLY)
+ {
+ }
+
+ bool handle(const LLSD& params, const LLSD& query_map,
+ const std::string& grid, LLMediaCtrl* web)
+ {
+ if (params.size() < 1) return false;
+
+ LLFloaterPreference* prefsfloater = dynamic_cast<LLFloaterPreference*>
+ (LLFloaterReg::showInstance("preferences"));
+
+ if (prefsfloater)
+ {
+ // find 'controls' panel and bring it the front
+ LLTabContainer* tabcontainer = prefsfloater->getChild<LLTabContainer>("pref core");
+ LLPanel* panel = prefsfloater->getChild<LLPanel>("controls");
+ if (tabcontainer && panel)
+ {
+ tabcontainer->selectTabPanel(panel);
+ }
+ }
+
+ return true;
+ }
+};
+LLKeybindingHandler gKeybindHandler;
+
+
+//////////////////////////////////////////////
+// LLFloaterPreference
+
+// static
+std::string LLFloaterPreference::sSkin = "";
+
+LLFloaterPreference::LLFloaterPreference(const LLSD& key)
+ : LLFloater(key),
+ mGotPersonalInfo(false),
+ mLanguageChanged(false),
+ mAvatarDataInitialized(false),
+ mSearchDataDirty(true)
+{
+ LLConversationLog::instance().addObserver(this);
+
+ //Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
+
+ static bool registered_dialog = false;
+ if (!registered_dialog)
+ {
+ LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSetKeyBindDialog>);
+ registered_dialog = true;
+ }
+
+ mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreference::onBtnCancel, this, _2));
+ mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreference::onBtnOK, this, _2));
+
+ mCommitCallbackRegistrar.add("Pref.ClearCache", boost::bind(&LLFloaterPreference::onClickClearCache, this));
+ mCommitCallbackRegistrar.add("Pref.WebClearCache", boost::bind(&LLFloaterPreference::onClickBrowserClearCache, this));
+ mCommitCallbackRegistrar.add("Pref.SetCache", boost::bind(&LLFloaterPreference::onClickSetCache, this));
+ mCommitCallbackRegistrar.add("Pref.ResetCache", boost::bind(&LLFloaterPreference::onClickResetCache, this));
+ mCommitCallbackRegistrar.add("Pref.ClickSkin", boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2));
+ mCommitCallbackRegistrar.add("Pref.SelectSkin", boost::bind(&LLFloaterPreference::onSelectSkin, this));
+ mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this));
+ mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
+ mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this));
+ mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
+ mCommitCallbackRegistrar.add("Pref.RenderExceptions", boost::bind(&LLFloaterPreference::onClickRenderExceptions, this));
+ mCommitCallbackRegistrar.add("Pref.AutoAdjustments", boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this));
+ mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
+ mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
+ mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
+ mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreference::onRenderOptionEnable, this));
+ mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
+ mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::refreshUI,this));
+ mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
+ mCommitCallbackRegistrar.add("Pref.applyUIColor", boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
+ mCommitCallbackRegistrar.add("Pref.getUIColor", boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
+ mCommitCallbackRegistrar.add("Pref.MaturitySettings", boost::bind(&LLFloaterPreference::onChangeMaturity, this));
+ mCommitCallbackRegistrar.add("Pref.BlockList", boost::bind(&LLFloaterPreference::onClickBlockList, this));
+ mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this));
+ mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
+ mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
+ mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
+ mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
+ mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
+ mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
+
+ sSkin = gSavedSettings.getString("SkinCurrent");
+
+ mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
+
+ gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
+ gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
+ gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2));
+
+ gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged, _2));
+ gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAtmosShaderChange, this));
+
+ LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
+
+ mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this));
+
+ mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
+ mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
+ mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering
+}
+
+void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
+{
+ if ( APT_PROPERTIES_LEGACY == type )
+ {
+ const LLAvatarLegacyData* pAvatarData = static_cast<const LLAvatarLegacyData*>( pData );
+ if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
+ {
+ mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
+ mAvatarDataInitialized = true;
+ getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
+ }
+ }
+}
+
+void LLFloaterPreference::saveAvatarProperties( void )
+{
+ const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
+
+ if ((LLStartUp::getStartupState() == STATE_STARTED)
+ && mAvatarDataInitialized
+ && (allowPublish != mAllowPublish))
+ {
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (!cap_url.empty())
+ {
+ mAllowPublish = allowPublish;
+
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
+ }
+ }
+}
+
+void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + gAgentID.asString();
+ LLSD data;
+ data["allow_publish"] = allow_publish;
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
+}
+
+bool LLFloaterPreference::postBuild()
+{
+ gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
+
+ gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
+
+ gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));
+
+ gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this));
+
+ gSavedSettings.getControl("RenderAvatarComplexityMode")->getSignal()->connect(
+ [this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ onChangeComplexityMode(new_val);
+ });
+
+ gSavedPerAccountSettings.getControl("ModelUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeModelFolder, this));
+ gSavedPerAccountSettings.getControl("PBRUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangePBRFolder, this));
+ gSavedPerAccountSettings.getControl("TextureUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeTextureFolder, this));
+ gSavedPerAccountSettings.getControl("SoundUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeSoundFolder, this));
+ gSavedPerAccountSettings.getControl("AnimationUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeAnimationFolder, this));
+
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
+ tabcontainer->selectFirstTab();
+
+ getChild<LLUICtrl>("cache_location")->setEnabled(false); // make it read-only but selectable (STORM-227)
+ std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
+ setCacheLocation(cache_location);
+
+ getChild<LLUICtrl>("log_path_string")->setEnabled(false); // make it read-only but selectable
+
+ getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
+
+ getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions"));
+ getChild<LLComboBox>("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions"));
+ getChild<LLComboBox>("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions"));
+ getChild<LLComboBox>("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions"));
+ getChild<LLComboBox>("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions"));
+ getChild<LLComboBox>("ObjectIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ObjectIMOptions"));
+
+ // if floater is opened before login set default localized do not disturb message
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
+ }
+
+ // set 'enable' property for 'Clear log...' button
+ changed();
+
+ LLLogChat::getInstance()->setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
+
+ LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
+ fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
+ fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
+
+ bool enable_complexity = gSavedSettings.getS32("RenderAvatarComplexityMode") != LLVOAvatar::AV_RENDER_ONLY_SHOW_FRIENDS;
+ getChild<LLSliderCtrl>("IndirectMaxComplexity")->setEnabled(enable_complexity);
+
+ // Hook up and init for filtering
+ mFilterEdit = getChild<LLSearchEditor>("search_prefs_edit");
+ mFilterEdit->setKeystrokeCallback(boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false));
+
+ // Load and assign label for 'default language'
+ std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "default_languages.xml");
+ std::map<std::string, std::string> labels;
+ if (loadFromFilename(user_filename, labels))
+ {
+ std::string system_lang = gSavedSettings.getString("SystemLanguage");
+ std::map<std::string, std::string>::iterator iter = labels.find(system_lang);
+ if (iter != labels.end())
+ {
+ getChild<LLComboBox>("language_combobox")->add(iter->second, LLSD("default"), ADD_TOP, true);
+ }
+ else
+ {
+ LL_WARNS() << "Language \"" << system_lang << "\" is not in default_languages.xml" << LL_ENDL;
+ getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load labels from " << user_filename << ". Using default." << LL_ENDL;
+ getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+ }
+
+ return true;
+}
+
+void LLFloaterPreference::updateDeleteTranscriptsButton()
+{
+ getChild<LLButton>("delete_transcripts")->setEnabled(LLLogChat::transcriptFilesExist());
+}
+
+void LLFloaterPreference::onDoNotDisturbResponseChanged()
+{
+ // set "DoNotDisturbResponseChanged" true if user edited message differs from default, false otherwise
+ bool response_changed_flag =
+ LLTrans::getString("DoNotDisturbModeResponseDefault")
+ != getChild<LLUICtrl>("do_not_disturb_response")->getValue().asString();
+
+ gSavedPerAccountSettings.setBOOL("DoNotDisturbResponseChanged", response_changed_flag );
+}
+
+LLFloaterPreference::~LLFloaterPreference()
+{
+ LLConversationLog::instance().removeObserver(this);
+ mComplexityChangedSignal.disconnect();
+}
+
+void LLFloaterPreference::draw()
+{
+ bool has_first_selected = (getChildRef<LLScrollListCtrl>("disabled_popups").getFirstSelected()!=NULL);
+ gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected);
+
+ has_first_selected = (getChildRef<LLScrollListCtrl>("enabled_popups").getFirstSelected()!=NULL);
+ gSavedSettings.setBOOL("FirstSelectedEnabledPopups", has_first_selected);
+
+ LLFloater::draw();
+}
+
+void LLFloaterPreference::saveSettings()
+{
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ child_list_t::const_iterator end = tabcontainer->getChildList()->end();
+ for ( ; iter != end; ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
+ if (panel)
+ panel->saveSettings();
+ }
+ saveIgnoredNotifications();
+}
+
+void LLFloaterPreference::apply()
+{
+ LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
+
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ if (sSkin != gSavedSettings.getString("SkinCurrent"))
+ {
+ LLNotificationsUtil::add("ChangeSkin");
+ refreshSkin(this);
+ }
+ // Call apply() on all panels that derive from LLPanelPreference
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
+ if (panel)
+ panel->apply();
+ }
+
+ gViewerWindow->requestResolutionUpdate(); // for UIScaleFactor
+
+ LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
+ fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
+ fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
+
+ std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
+ setCacheLocation(cache_location);
+
+ LLViewerMedia::getInstance()->setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue());
+
+ if (hasChild("web_proxy_enabled", true) &&hasChild("web_proxy_editor", true) && hasChild("web_proxy_port", true))
+ {
+ bool proxy_enable = getChild<LLUICtrl>("web_proxy_enabled")->getValue();
+ std::string proxy_address = getChild<LLUICtrl>("web_proxy_editor")->getValue();
+ int proxy_port = getChild<LLUICtrl>("web_proxy_port")->getValue();
+ LLViewerMedia::getInstance()->setProxyConfig(proxy_enable, proxy_address, proxy_port);
+ }
+
+ if (mGotPersonalInfo)
+ {
+ bool new_hide_online = getChild<LLUICtrl>("online_visibility")->getValue().asBoolean();
+
+ if (new_hide_online != mOriginalHideOnlineStatus)
+ {
+ // This hack is because we are representing several different
+ // possible strings with a single checkbox. Since most users
+ // can only select between 2 values, we represent it as a
+ // checkbox. This breaks down a little bit for liaisons, but
+ // works out in the end.
+ if (new_hide_online != mOriginalHideOnlineStatus)
+ {
+ if (new_hide_online) mDirectoryVisibility = VISIBILITY_HIDDEN;
+ else mDirectoryVisibility = VISIBILITY_DEFAULT;
+ //Update showonline value, otherwise multiple applys won't work
+ mOriginalHideOnlineStatus = new_hide_online;
+ }
+ gAgent.sendAgentUpdateUserInfo(mDirectoryVisibility);
+ }
+ }
+
+ saveAvatarProperties();
+}
+
+void LLFloaterPreference::cancel(const std::vector<std::string> settings_to_skip)
+{
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ // Call cancel() on all panels that derive from LLPanelPreference
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
+ if (panel)
+ panel->cancel(settings_to_skip);
+ }
+ // hide joystick pref floater
+ LLFloaterReg::hideInstance("pref_joystick");
+
+ // hide translation settings floater
+ LLFloaterReg::hideInstance("prefs_translation");
+
+ // hide autoreplace settings floater
+ LLFloaterReg::hideInstance("prefs_autoreplace");
+
+ // hide spellchecker settings folder
+ LLFloaterReg::hideInstance("prefs_spellchecker");
+
+ // hide advanced graphics floater
+ LLFloaterReg::hideInstance("prefs_graphics_advanced");
+
+ // reverts any changes to current skin
+ gSavedSettings.setString("SkinCurrent", sSkin);
+
+ updateClickActionViews();
+
+ LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy");
+ if (advanced_proxy_settings)
+ {
+ advanced_proxy_settings->cancel();
+ }
+ //Need to reload the navmesh if the pathing console is up
+ LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
+ if ( !pathfindingConsoleHandle.isDead() )
+ {
+ LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
+ pPathfindingConsole->onRegionBoundaryCross();
+ }
+
+ if (!mSavedGraphicsPreset.empty())
+ {
+ gSavedSettings.setString("PresetGraphicActive", mSavedGraphicsPreset);
+ LLPresetsManager::getInstance()->triggerChangeSignal();
+ }
+
+ restoreIgnoredNotifications();
+}
+
+void LLFloaterPreference::onOpen(const LLSD& key)
+{
+ // this variable and if that follows it are used to properly handle do not disturb mode response message
+ static bool initialized = false;
+ // if user is logged in and we haven't initialized do not disturb mode response yet, do it
+ if (!initialized && LLStartUp::getStartupState() == STATE_STARTED)
+ {
+ // Special approach is used for do not disturb response localization, because "DoNotDisturbModeResponse" is
+ // in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized.
+ // To keep track of whether do not disturb response is default or changed by user additional setting DoNotDisturbResponseChanged
+ // was added into per account settings.
+
+ // initialization should happen once,so setting variable to true
+ initialized = true;
+ // this connection is needed to properly set "DoNotDisturbResponseChanged" setting when user makes changes in
+ // do not disturb response message.
+ gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onDoNotDisturbResponseChanged, this));
+ }
+ gAgent.sendAgentUserInfoRequest();
+
+ /////////////////////////// From LLPanelGeneral //////////////////////////
+ // if we have no agent, we can't let them choose anything
+ // if we have an agent, then we only let them choose if they have a choice
+ bool can_choose_maturity =
+ gAgent.getID().notNull() &&
+ (gAgent.isMature() || gAgent.isGodlike());
+
+ LLComboBox* maturity_combo = getChild<LLComboBox>("maturity_desired_combobox");
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarLegacyPropertiesRequest( gAgent.getID() );
+ if (can_choose_maturity)
+ {
+ // if they're not adult or a god, they shouldn't see the adult selection, so delete it
+ if (!gAgent.isAdult() && !gAgent.isGodlikeWithoutAdminMenuFakery())
+ {
+ // we're going to remove the adult entry from the combo
+ LLScrollListCtrl* maturity_list = maturity_combo->findChild<LLScrollListCtrl>("ComboBox");
+ if (maturity_list)
+ {
+ maturity_list->deleteItems(LLSD(SIM_ACCESS_ADULT));
+ }
+ }
+ getChildView("maturity_desired_combobox")->setEnabled( true);
+ getChildView("maturity_desired_textbox")->setVisible( false);
+ }
+ else
+ {
+ getChild<LLUICtrl>("maturity_desired_textbox")->setValue(maturity_combo->getSelectedItemLabel());
+ getChildView("maturity_desired_combobox")->setEnabled( false);
+ }
+
+ // Forget previous language changes.
+ mLanguageChanged = false;
+
+ // Display selected maturity icons.
+ onChangeMaturity();
+
+ onChangeModelFolder();
+ onChangePBRFolder();
+ onChangeTextureFolder();
+ onChangeSoundFolder();
+ onChangeAnimationFolder();
+
+ // Load (double-)click to walk/teleport settings.
+ updateClickActionViews();
+
+ // Enabled/disabled popups, might have been changed by user actions
+ // while preferences floater was closed.
+ buildPopupLists();
+
+
+ //get the options that were checked
+ onNotificationsChange("FriendIMOptions");
+ onNotificationsChange("NonFriendIMOptions");
+ onNotificationsChange("ConferenceIMOptions");
+ onNotificationsChange("GroupChatOptions");
+ onNotificationsChange("NearbyChatOptions");
+ onNotificationsChange("ObjectIMOptions");
+
+ LLPanelLogin::setAlwaysRefresh(true);
+ refresh();
+
+ // Make sure the current state of prefs are saved away when
+ // when the floater is opened. That will make cancel do its
+ // job
+ saveSettings();
+
+ // Make sure there is a default preference file
+ LLPresetsManager::getInstance()->createMissingDefault(PRESETS_CAMERA);
+ LLPresetsManager::getInstance()->createMissingDefault(PRESETS_GRAPHIC);
+
+ bool started = (LLStartUp::getStartupState() == STATE_STARTED);
+
+ LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
+ LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
+ LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
+ LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
+ LLButton* auto_adjustments_btn = findChild<LLButton>("AutoAdjustmentsButton");
+
+ if (load_btn && save_btn && delete_btn && exceptions_btn && auto_adjustments_btn)
+ {
+ load_btn->setEnabled(started);
+ save_btn->setEnabled(started);
+ delete_btn->setEnabled(started);
+ exceptions_btn->setEnabled(started);
+ auto_adjustments_btn->setEnabled(started);
+ }
+
+ collectSearchableItems();
+ if (!mFilterEdit->getText().empty())
+ {
+ mFilterEdit->setText(LLStringExplicit(""));
+ onUpdateFilterTerm(true);
+ }
+}
+
+void LLFloaterPreference::onRenderOptionEnable()
+{
+ refreshEnabledGraphics();
+}
+
+void LLFloaterPreference::onAvatarImpostorsEnable()
+{
+ refreshEnabledGraphics();
+}
+
+//static
+void LLFloaterPreference::initDoNotDisturbResponse()
+ {
+ if (!gSavedPerAccountSettings.getBOOL("DoNotDisturbResponseChanged"))
+ {
+ //LLTrans::getString("DoNotDisturbModeResponseDefault") is used here for localization (EXT-5885)
+ gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
+ }
+ }
+
+//static
+void LLFloaterPreference::updateShowFavoritesCheckbox(bool val)
+{
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->getChild<LLUICtrl>("favorites_on_login_check")->setValue(val);
+ }
+}
+
+void LLFloaterPreference::setHardwareDefaults()
+{
+ std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
+ if (!preset_graphic_active.empty())
+ {
+ saveGraphicsPreset(preset_graphic_active);
+ saveSettings(); // save here to be able to return to the previous preset by Cancel
+ }
+ setRecommendedSettings();
+}
+
+void LLFloaterPreference::setRecommendedSettings()
+{
+ resetAutotuneSettings();
+ gSavedSettings.getControl("RenderVSyncEnable")->resetToDefault(true);
+
+ LLFeatureManager::getInstance()->applyRecommendedSettings();
+
+ // reset indirects before refresh because we may have changed what they control
+ LLAvatarComplexityControls::setIndirectControls();
+
+ refreshEnabledGraphics();
+ gSavedSettings.setString("PresetGraphicActive", "");
+ LLPresetsManager::getInstance()->triggerChangeSignal();
+
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ child_list_t::const_iterator end = tabcontainer->getChildList()->end();
+ for ( ; iter != end; ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
+ if (panel)
+ {
+ panel->setHardwareDefaults();
+ }
+ }
+}
+
+void LLFloaterPreference::resetAutotuneSettings()
+{
+ gSavedSettings.setBOOL("AutoTuneFPS", false);
+
+ const std::string autotune_settings[] = {
+ "AutoTuneLock",
+ "KeepAutoTuneLock",
+ "TargetFPS",
+ "TuningFPSStrategy",
+ "AutoTuneImpostorByDistEnabled",
+ "AutoTuneImpostorFarAwayDistance" ,
+ "AutoTuneRenderFarClipMin",
+ "AutoTuneRenderFarClipTarget",
+ "RenderAvatarMaxART"
+ };
+
+ for (auto it : autotune_settings)
+ {
+ gSavedSettings.getControl(it)->resetToDefault(true);
+ }
+}
+
+void LLFloaterPreference::getControlNames(std::vector<std::string>& names)
+{
+ LLView* view = findChild<LLView>("display");
+ LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
+ if (view && advanced)
+ {
+ std::list<LLView*> stack;
+ stack.push_back(view);
+ stack.push_back(advanced);
+ while(!stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = stack.front();
+ stack.pop_front();
+
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ LLControlVariable* control = ctrl->getControlVariable();
+ if (control)
+ {
+ std::string control_name = control->getName();
+ if (std::find(names.begin(), names.end(), control_name) == names.end())
+ {
+ names.push_back(control_name);
+ }
+ }
+ }
+
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ stack.push_back(*iter);
+ }
+ }
+ }
+}
+
+//virtual
+void LLFloaterPreference::onClose(bool app_quitting)
+{
+ gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());
+ LLPanelLogin::setAlwaysRefresh(false);
+ if (!app_quitting)
+ {
+ cancel();
+ }
+}
+
+// static
+void LLFloaterPreference::onBtnOK(const LLSD& userdata)
+{
+ // commit any outstanding text entry
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus && cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ }
+ }
+
+ if (canClose())
+ {
+ saveSettings();
+ apply();
+
+ if (userdata.asString() == "closeadvanced")
+ {
+ LLFloaterReg::hideInstance("prefs_graphics_advanced");
+ }
+ else
+ {
+ closeFloater(false);
+ }
+
+ //Conversation transcript and log path changed so reload conversations based on new location
+ if(mPriorInstantMessageLogPath.length())
+ {
+ if(moveTranscriptsAndLog())
+ {
+ //When floaters are empty but have a chat history files, reload chat history into them
+ LLFloaterIMSessionTab::reloadEmptyFloaters();
+ }
+ //Couldn't move files so restore the old path and show a notification
+ else
+ {
+ gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath);
+ LLNotificationsUtil::add("PreferenceChatPathChanged");
+ }
+ mPriorInstantMessageLogPath.clear();
+ }
+
+ LLUIColorTable::instance().saveUserSettings();
+ gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), true);
+
+ //Only save once logged in and loaded per account settings
+ if(mGotPersonalInfo)
+ {
+ gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), true);
+ }
+ }
+ else
+ {
+ // Show beep, pop up dialog, etc.
+ LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
+ }
+
+ LLPanelLogin::updateLocationSelectorsVisibility();
+ //Need to reload the navmesh if the pathing console is up
+ LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
+ if ( !pathfindingConsoleHandle.isDead() )
+ {
+ LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
+ pPathfindingConsole->onRegionBoundaryCross();
+ }
+}
+
+// static
+void LLFloaterPreference::onBtnCancel(const LLSD& userdata)
+{
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus && cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ }
+ refresh();
+ }
+
+ if (userdata.asString() == "closeadvanced")
+ {
+ cancel({"RenderQualityPerformance"});
+ LLFloaterReg::hideInstance("prefs_graphics_advanced");
+ }
+ else
+ {
+ cancel();
+ closeFloater();
+ }
+}
+
+// static
+void LLFloaterPreference::updateUserInfo(const std::string& visibility)
+{
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->setPersonalInfo(visibility);
+ }
+}
+
+void LLFloaterPreference::refreshEnabledGraphics()
+{
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->refresh();
+ }
+
+ LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
+ if (advanced)
+ {
+ advanced->refresh();
+ }
+}
+
+void LLFloaterPreference::onClickClearCache()
+{
+ LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache);
+}
+
+void LLFloaterPreference::onClickBrowserClearCache()
+{
+ LLNotificationsUtil::add("ConfirmClearBrowserCache", LLSD(), LLSD(), callback_clear_browser_cache);
+}
+
+// Called when user changes language via the combobox.
+void LLFloaterPreference::onLanguageChange()
+{
+ // Let the user know that the change will only take effect after restart.
+ // Do it only once so that we're not too irritating.
+ if (!mLanguageChanged)
+ {
+ LLNotificationsUtil::add("ChangeLanguage");
+ mLanguageChanged = true;
+ }
+}
+
+void LLFloaterPreference::onNotificationsChange(const std::string& OptionName)
+{
+ mNotificationOptions[OptionName] = getChild<LLComboBox>(OptionName)->getSelectedItemLabel();
+
+ bool show_notifications_alert = true;
+ for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++)
+ {
+ if(it_notification->second != "No action")
+ {
+ show_notifications_alert = false;
+ break;
+ }
+ }
+
+ getChild<LLTextBox>("notifications_alert")->setVisible(show_notifications_alert);
+}
+
+void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
+{
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background");
+ if (color_swatch)
+ {
+ LLColor4 new_color = color_swatch->get();
+ color_swatch->set( new_color.setAlpha(newvalue.asReal()) );
+ }
+}
+
+void LLFloaterPreference::onClickSetCache()
+{
+ std::string cur_name(gSavedSettings.getString("CacheLocation"));
+// std::string cur_top_folder(gDirUtilp->getBaseFileName(cur_name));
+
+ std::string proposed_name(cur_name);
+
+ (new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeCachePath, this, _1, _2), proposed_name))->getFile();
+}
+
+void LLFloaterPreference::changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name)
+{
+ std::string dir_name = filenames[0];
+ if (!dir_name.empty() && dir_name != proposed_name)
+ {
+ std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));
+ LLNotificationsUtil::add("CacheWillBeMoved");
+ gSavedSettings.setString("NewCacheLocation", dir_name);
+ gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder);
+ }
+ else
+ {
+ std::string cache_location = gDirUtilp->getCacheDir();
+ gSavedSettings.setString("CacheLocation", cache_location);
+ std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
+ gSavedSettings.setString("CacheLocationTopFolder", top_folder);
+ }
+}
+
+void LLFloaterPreference::onClickResetCache()
+{
+ if (gDirUtilp->getCacheDir(false) == gDirUtilp->getCacheDir(true))
+ {
+ // The cache location was already the default.
+ return;
+ }
+ gSavedSettings.setString("NewCacheLocation", "");
+ gSavedSettings.setString("NewCacheLocationTopFolder", "");
+ LLNotificationsUtil::add("CacheWillBeMoved");
+ std::string cache_location = gDirUtilp->getCacheDir(false);
+ gSavedSettings.setString("CacheLocation", cache_location);
+ std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
+ gSavedSettings.setString("CacheLocationTopFolder", top_folder);
+}
+
+void LLFloaterPreference::onClickSkin(LLUICtrl* ctrl, const LLSD& userdata)
+{
+ gSavedSettings.setString("SkinCurrent", userdata.asString());
+ ctrl->setValue(userdata.asString());
+}
+
+void LLFloaterPreference::onSelectSkin()
+{
+ std::string skin_selection = getChild<LLRadioGroup>("skin_selection")->getValue().asString();
+ gSavedSettings.setString("SkinCurrent", skin_selection);
+}
+
+void LLFloaterPreference::refreshSkin(void* data)
+{
+ LLPanel*self = (LLPanel*)data;
+ sSkin = gSavedSettings.getString("SkinCurrent");
+ self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
+}
+
+void LLFloaterPreference::buildPopupLists()
+{
+ LLScrollListCtrl& disabled_popups =
+ getChildRef<LLScrollListCtrl>("disabled_popups");
+ LLScrollListCtrl& enabled_popups =
+ getChildRef<LLScrollListCtrl>("enabled_popups");
+
+ disabled_popups.deleteAllItems();
+ enabled_popups.deleteAllItems();
+
+ for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+ iter != LLNotifications::instance().templatesEnd();
+ ++iter)
+ {
+ LLNotificationTemplatePtr templatep = iter->second;
+ LLNotificationFormPtr formp = templatep->mForm;
+
+ LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
+ if (ignore <= LLNotificationForm::IGNORE_NO)
+ continue;
+
+ LLSD row;
+ row["columns"][0]["value"] = formp->getIgnoreMessage();
+ row["columns"][0]["font"] = "SANSSERIF_SMALL";
+ row["columns"][0]["width"] = 400;
+
+ LLScrollListItem* item = NULL;
+
+ bool show_popup = !formp->getIgnored();
+ if (!show_popup)
+ {
+ if (ignore == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
+ {
+ LLSD last_response = LLUI::getInstance()->mSettingGroups["config"]->getLLSD("Default" + templatep->mName);
+ if (!last_response.isUndefined())
+ {
+ for (LLSD::map_const_iterator it = last_response.beginMap();
+ it != last_response.endMap();
+ ++it)
+ {
+ if (it->second.asBoolean())
+ {
+ row["columns"][1]["value"] = formp->getElement(it->first)["ignore"].asString();
+ row["columns"][1]["font"] = "SANSSERIF_SMALL";
+ row["columns"][1]["width"] = 360;
+ break;
+ }
+ }
+ }
+ }
+ item = disabled_popups.addElement(row);
+ }
+ else
+ {
+ item = enabled_popups.addElement(row);
+ }
+
+ if (item)
+ {
+ item->setUserdata((void*)&iter->first);
+ }
+ }
+}
+
+void LLFloaterPreference::refreshEnabledState()
+{
+ LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");
+
+ //PBR
+ ctrl_pbr->setEnabled(true);
+
+ // Cannot have floater active until caps have been received
+ getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() >= STATE_STARTED);
+
+ getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
+}
+
+void LLAvatarComplexityControls::setIndirectControls()
+{
+ /*
+ * We have controls that have an indirect relationship between the control
+ * values and adjacent text and the underlying setting they influence.
+ * In each case, the control and its associated setting are named Indirect<something>
+ * This method interrogates the controlled setting and establishes the
+ * appropriate value for the indirect control. It must be called whenever the
+ * underlying setting may have changed other than through the indirect control,
+ * such as when the 'Reset all to recommended settings' button is used...
+ */
+ setIndirectMaxNonImpostors();
+ setIndirectMaxArc();
+}
+
+// static
+void LLAvatarComplexityControls::setIndirectMaxNonImpostors()
+{
+ U32 max_non_impostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
+ // for this one, we just need to make zero, which means off, the max value of the slider
+ U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER : max_non_impostors;
+ gSavedSettings.setU32("IndirectMaxNonImpostors", indirect_max_non_impostors);
+}
+
+void LLAvatarComplexityControls::setIndirectMaxArc()
+{
+ U32 max_arc = gSavedSettings.getU32("RenderAvatarMaxComplexity");
+ U32 indirect_max_arc;
+ if (0 == max_arc)
+ {
+ // the off position is all the way to the right, so set to control max
+ indirect_max_arc = INDIRECT_MAX_ARC_OFF;
+ }
+ else
+ {
+ // This is the inverse of the calculation in updateMaxComplexity
+ indirect_max_arc = (U32)ll_round(((log(F32(max_arc)) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE)) + MIN_INDIRECT_ARC_LIMIT;
+ }
+ gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);
+}
+
+void LLFloaterPreference::refresh()
+{
+ LLPanel::refresh();
+ LLAvatarComplexityControls::setText(
+ gSavedSettings.getU32("RenderAvatarMaxComplexity"),
+ getChild<LLTextBox>("IndirectMaxComplexityText", true));
+ refreshEnabledState();
+ LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
+ if (advanced)
+ {
+ advanced->refresh();
+ }
+ updateClickActionViews();
+}
+
+void LLFloaterPreference::onCommitWindowedMode()
+{
+ refresh();
+}
+
+void LLFloaterPreference::onChangeQuality(const LLSD& data)
+{
+ U32 level = (U32)(data.asReal());
+ LLFeatureManager::getInstance()->setGraphicsLevel(level, true);
+ refreshEnabledGraphics();
+ refresh();
+}
+
+void LLFloaterPreference::onClickSetSounds()
+{
+ // Disable Enable gesture sounds checkbox if the master sound is disabled
+ // or if sound effects are disabled.
+ getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
+}
+
+void LLFloaterPreference::onClickEnablePopup()
+{
+ LLScrollListCtrl& disabled_popups = getChildRef<LLScrollListCtrl>("disabled_popups");
+
+ std::vector<LLScrollListItem*> items = disabled_popups.getAllSelected();
+ std::vector<LLScrollListItem*>::iterator itor;
+ for (itor = items.begin(); itor != items.end(); ++itor)
+ {
+ LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
+ //gSavedSettings.setWarning(templatep->mName, true);
+ std::string notification_name = templatep->mName;
+ LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(notification_name, true);
+ }
+
+ buildPopupLists();
+ if (!mFilterEdit->getText().empty())
+ {
+ filterIgnorableNotifications();
+ }
+}
+
+void LLFloaterPreference::onClickDisablePopup()
+{
+ LLScrollListCtrl& enabled_popups = getChildRef<LLScrollListCtrl>("enabled_popups");
+
+ std::vector<LLScrollListItem*> items = enabled_popups.getAllSelected();
+ std::vector<LLScrollListItem*>::iterator itor;
+ for (itor = items.begin(); itor != items.end(); ++itor)
+ {
+ LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
+ templatep->mForm->setIgnored(true);
+ }
+
+ buildPopupLists();
+ if (!mFilterEdit->getText().empty())
+ {
+ filterIgnorableNotifications();
+ }
+}
+
+void LLFloaterPreference::resetAllIgnored()
+{
+ for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+ iter != LLNotifications::instance().templatesEnd();
+ ++iter)
+ {
+ if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
+ {
+ iter->second->mForm->setIgnored(false);
+ }
+ }
+}
+
+void LLFloaterPreference::setAllIgnored()
+{
+ for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+ iter != LLNotifications::instance().templatesEnd();
+ ++iter)
+ {
+ if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
+ {
+ iter->second->mForm->setIgnored(true);
+ }
+ }
+}
+
+void LLFloaterPreference::onClickLogPath()
+{
+ std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+ mPriorInstantMessageLogPath.clear();
+
+
+ (new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeLogPath, this, _1, _2), proposed_name))->getFile();
+}
+
+void LLFloaterPreference::changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name)
+{
+ //Path changed
+ if (proposed_name != filenames[0])
+ {
+ gSavedPerAccountSettings.setString("InstantMessageLogPath", filenames[0]);
+ mPriorInstantMessageLogPath = proposed_name;
+
+ // enable/disable 'Delete transcripts button
+ updateDeleteTranscriptsButton();
+ }
+}
+
+bool LLFloaterPreference::moveTranscriptsAndLog()
+{
+ std::string instantMessageLogPath(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+ std::string chatLogPath = gDirUtilp->add(instantMessageLogPath, gDirUtilp->getUserName());
+
+ bool madeDirectory = false;
+
+ //Does the directory really exist, if not then make it
+ if(!LLFile::isdir(chatLogPath))
+ {
+ //mkdir success is defined as zero
+ if(LLFile::mkdir(chatLogPath) != 0)
+ {
+ return false;
+ }
+ madeDirectory = true;
+ }
+
+ std::string originalConversationLogDir = LLConversationLog::instance().getFileName();
+ std::string targetConversationLogDir = gDirUtilp->add(chatLogPath, "conversation.log");
+ //Try to move the conversation log
+ if(!LLConversationLog::instance().moveLog(originalConversationLogDir, targetConversationLogDir))
+ {
+ //Couldn't move the log and created a new directory so remove the new directory
+ if(madeDirectory)
+ {
+ LLFile::rmdir(chatLogPath);
+ }
+ return false;
+ }
+
+ //Attempt to move transcripts
+ std::vector<std::string> listOfTranscripts;
+ std::vector<std::string> listOfFilesMoved;
+
+ LLLogChat::getListOfTranscriptFiles(listOfTranscripts);
+
+ if(!LLLogChat::moveTranscripts(gDirUtilp->getChatLogsDir(),
+ instantMessageLogPath,
+ listOfTranscripts,
+ listOfFilesMoved))
+ {
+ //Couldn't move all the transcripts so restore those that moved back to their old location
+ LLLogChat::moveTranscripts(instantMessageLogPath,
+ gDirUtilp->getChatLogsDir(),
+ listOfFilesMoved);
+
+ //Move the conversation log back
+ LLConversationLog::instance().moveLog(targetConversationLogDir, originalConversationLogDir);
+
+ if(madeDirectory)
+ {
+ LLFile::rmdir(chatLogPath);
+ }
+
+ return false;
+ }
+
+ gDirUtilp->setChatLogsDir(instantMessageLogPath);
+ gDirUtilp->updatePerAccountChatLogsDir();
+
+ return true;
+}
+
+void LLFloaterPreference::setPersonalInfo(const std::string& visibility)
+{
+ mGotPersonalInfo = true;
+ mDirectoryVisibility = visibility;
+
+ if (visibility == VISIBILITY_DEFAULT)
+ {
+ mOriginalHideOnlineStatus = false;
+ getChildView("online_visibility")->setEnabled(true);
+ }
+ else if (visibility == VISIBILITY_HIDDEN)
+ {
+ mOriginalHideOnlineStatus = true;
+ getChildView("online_visibility")->setEnabled(true);
+ }
+ else
+ {
+ mOriginalHideOnlineStatus = true;
+ }
+
+ getChild<LLUICtrl>("online_searchresults")->setEnabled(true);
+ getChildView("friends_online_notify_checkbox")->setEnabled(true);
+ getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus);
+ getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
+
+ getChildView("favorites_on_login_check")->setEnabled(true);
+ getChildView("log_path_button")->setEnabled(true);
+ getChildView("chat_font_size")->setEnabled(true);
+ getChildView("conversation_log_combo")->setEnabled(true);
+ getChild<LLUICtrl>("voice_call_friends_only_check")->setEnabled(true);
+ getChild<LLUICtrl>("voice_call_friends_only_check")->setValue(gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly"));
+}
+
+
+void LLFloaterPreference::refreshUI()
+{
+ refresh();
+}
+
+void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
+{
+ // Called when the IndirectMaxComplexity control changes
+ // Responsible for fixing the slider label (IndirectMaxComplexityText) and setting RenderAvatarMaxComplexity
+ U32 indirect_value = slider->getValue().asInteger();
+ U32 max_arc;
+
+ if (INDIRECT_MAX_ARC_OFF == indirect_value)
+ {
+ // The 'off' position is when the slider is all the way to the right,
+ // which is a value of INDIRECT_MAX_ARC_OFF,
+ // so it is necessary to set max_arc to 0 disable muted avatars.
+ max_arc = 0;
+ }
+ else
+ {
+ // if this is changed, the inverse calculation in setIndirectMaxArc
+ // must be changed to match
+ max_arc = (U32)ll_round(exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT))));
+ }
+
+ gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc);
+ setText(max_arc, value_label, short_val);
+}
+
+void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool short_val)
+{
+ if (0 == value)
+ {
+ text_box->setText(LLTrans::getString("no_limit"));
+ }
+ else
+ {
+ std::string text_value = short_val ? llformat("%d", value / 1000) : llformat("%d", value);
+ text_box->setText(text_value);
+ }
+}
+
+void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
+{
+ setRenderTimeText((F32)(LLPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val);
+}
+
+void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val)
+{
+ if (0 == value)
+ {
+ text_box->setText(LLTrans::getString("no_limit"));
+ }
+ else
+ {
+ text_box->setText(llformat("%.0f", value));
+ }
+}
+
+void LLFloaterPreference::updateMaxComplexity()
+{
+ // Called when the IndirectMaxComplexity control changes
+ LLAvatarComplexityControls::updateMax(
+ getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+ getChild<LLTextBox>("IndirectMaxComplexityText"));
+}
+
+void LLFloaterPreference::updateComplexityText()
+{
+ LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
+ getChild<LLTextBox>("IndirectMaxComplexityText", true));
+}
+
+bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map)
+{
+ LLXMLNodePtr root;
+
+ if (!LLXMLNode::parseFile(filename, root, NULL))
+ {
+ LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
+ return false;
+ }
+
+ if (!root->hasName("labels"))
+ {
+ LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
+ return false;
+ }
+
+ LabelTable params;
+ LLXUIParser parser;
+ parser.readXUI(root, params, filename);
+
+ if (params.validateBlock())
+ {
+ for (LLInitParam::ParamIterator<LabelDef>::const_iterator it = params.labels.begin();
+ it != params.labels.end();
+ ++it)
+ {
+ LabelDef label_entry = *it;
+ label_map[label_entry.name] = label_entry.value;
+ }
+ }
+ else
+ {
+ LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
+ return false;
+ }
+
+ return true;
+}
+
+void LLFloaterPreference::onChangeMaturity()
+{
+ U8 sim_access = gSavedSettings.getU32("PreferredMaturity");
+
+ getChild<LLIconCtrl>("rating_icon_general")->setVisible(sim_access == SIM_ACCESS_PG
+ || sim_access == SIM_ACCESS_MATURE
+ || sim_access == SIM_ACCESS_ADULT);
+
+ getChild<LLIconCtrl>("rating_icon_moderate")->setVisible(sim_access == SIM_ACCESS_MATURE
+ || sim_access == SIM_ACCESS_ADULT);
+
+ getChild<LLIconCtrl>("rating_icon_adult")->setVisible(sim_access == SIM_ACCESS_ADULT);
+}
+
+void LLFloaterPreference::onChangeComplexityMode(const LLSD& newvalue)
+{
+ bool enable_complexity = newvalue.asInteger() != LLVOAvatar::AV_RENDER_ONLY_SHOW_FRIENDS;
+ getChild<LLSliderCtrl>("IndirectMaxComplexity")->setEnabled(enable_complexity);
+}
+
+std::string get_category_path(LLFolderType::EType cat_type)
+{
+ LLUUID cat_id = gInventory.findUserDefinedCategoryUUIDForType(cat_type);
+ return get_category_path(cat_id);
+}
+
+void LLFloaterPreference::onChangeModelFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_models")->setText(get_category_path(LLFolderType::FT_OBJECT));
+ }
+}
+
+void LLFloaterPreference::onChangePBRFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL));
+ }
+}
+
+void LLFloaterPreference::onChangeTextureFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_textures")->setText(get_category_path(LLFolderType::FT_TEXTURE));
+ }
+}
+
+void LLFloaterPreference::onChangeSoundFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_sounds")->setText(get_category_path(LLFolderType::FT_SOUND));
+ }
+}
+
+void LLFloaterPreference::onChangeAnimationFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_animation")->setText(get_category_path(LLFolderType::FT_ANIMATION));
+ }
+}
+
+// FIXME: this will stop you from spawning the sidetray from preferences dialog on login screen
+// but the UI for this will still be enabled
+void LLFloaterPreference::onClickBlockList()
+{
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+ LLSD().with("people_panel_tab_name", "blocked_panel"));
+}
+
+void LLFloaterPreference::onClickProxySettings()
+{
+ LLFloaterReg::showInstance("prefs_proxy");
+}
+
+void LLFloaterPreference::onClickTranslationSettings()
+{
+ LLFloaterReg::showInstance("prefs_translation");
+}
+
+void LLFloaterPreference::onClickAutoReplace()
+{
+ LLFloaterReg::showInstance("prefs_autoreplace");
+}
+
+void LLFloaterPreference::onClickSpellChecker()
+{
+ LLFloaterReg::showInstance("prefs_spellchecker");
+}
+
+void LLFloaterPreference::onClickRenderExceptions()
+{
+ LLFloaterReg::showInstance("avatar_render_settings");
+}
+
+void LLFloaterPreference::onClickAutoAdjustments()
+{
+ LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance");
+ if (performance_floater)
+ {
+ performance_floater->showAutoadjustmentsPanel();
+ }
+}
+
+void LLFloaterPreference::onClickAdvanced()
+{
+ LLFloaterReg::showInstance("prefs_graphics_advanced");
+
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreferenceGraphics* panel = dynamic_cast<LLPanelPreferenceGraphics*>(view);
+ if (panel)
+ {
+ panel->resetDirtyChilds();
+ }
+ }
+}
+
+void LLFloaterPreference::onClickActionChange()
+{
+ updateClickActionControls();
+}
+
+void LLFloaterPreference::onAtmosShaderChange()
+{
+ LLCheckBoxCtrl* ctrl_alm = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ if(ctrl_alm)
+ {
+ //Deferred/SSAO/Shadows
+ bool bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+ bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+ bool enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ bumpshiny &&
+ shaders;
+
+ ctrl_alm->setEnabled(enabled);
+ }
+}
+
+void LLFloaterPreference::onClickPermsDefault()
+{
+ LLFloaterReg::showInstance("perms_default");
+}
+
+void LLFloaterPreference::onClickRememberedUsernames()
+{
+ LLFloaterReg::showInstance("forget_username");
+}
+
+void LLFloaterPreference::onDeleteTranscripts()
+{
+ LLSD args;
+ args["FOLDER"] = gDirUtilp->getUserName();
+
+ LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", args, LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
+}
+
+void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
+{
+ if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+ {
+ LLLogChat::deleteTranscripts();
+ updateDeleteTranscriptsButton();
+ }
+}
+
+void LLFloaterPreference::onLogChatHistorySaved()
+{
+ LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts");
+
+ if (!delete_transcripts_buttonp->getEnabled())
+ {
+ delete_transcripts_buttonp->setEnabled(true);
+ }
+}
+
+void LLFloaterPreference::updateClickActionControls()
+{
+ const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
+ const int double_clk_action = getChild<LLComboBox>("double_click_action_combo")->getValue().asInteger();
+
+ // Todo: This is a very ugly way to get access to keybindings.
+ // Reconsider possible options.
+ // Potential option: make constructor of LLKeyConflictHandler private
+ // but add a getter that will return shared pointer for specific
+ // mode, pointer should only exist so long as there are external users.
+ // In such case we won't need to do this 'dynamic_cast' nightmare.
+ // updateTable() can also be avoided
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+ if (panel)
+ {
+ panel->setKeyBind("walk_to",
+ EMouseClickType::CLICK_LEFT,
+ KEY_NONE,
+ MASK_NONE,
+ single_clk_action == 1);
+
+ panel->setKeyBind("walk_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE,
+ double_clk_action == 1);
+
+ panel->setKeyBind("teleport_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE,
+ double_clk_action == 2);
+
+ panel->updateAndApply();
+ }
+ }
+}
+
+void LLFloaterPreference::updateClickActionViews()
+{
+ bool click_to_walk = false;
+ bool dbl_click_to_walk = false;
+ bool dbl_click_to_teleport = false;
+
+ // Todo: This is a very ugly way to get access to keybindings.
+ // Reconsider possible options.
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+ if (panel)
+ {
+ click_to_walk = panel->canKeyBindHandle("walk_to",
+ EMouseClickType::CLICK_LEFT,
+ KEY_NONE,
+ MASK_NONE);
+
+ dbl_click_to_walk = panel->canKeyBindHandle("walk_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE);
+
+ dbl_click_to_teleport = panel->canKeyBindHandle("teleport_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE);
+ }
+ }
+
+ getChild<LLComboBox>("single_click_action_combo")->setValue((int)click_to_walk);
+ getChild<LLComboBox>("double_click_action_combo")->setValue(dbl_click_to_teleport ? 2 : (int)dbl_click_to_walk);
+}
+
+void LLFloaterPreference::updateSearchableItems()
+{
+ mSearchDataDirty = true;
+}
+
+void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
+{
+ LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
+}
+
+void LLFloaterPreference::getUIColor(LLUICtrl* ctrl, const LLSD& param)
+{
+ LLColorSwatchCtrl* color_swatch = (LLColorSwatchCtrl*) ctrl;
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor(param.asString()));
+}
+
+void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location)
+{
+ LLUICtrl* cache_location_editor = getChild<LLUICtrl>("cache_location");
+ cache_location_editor->setValue(location);
+ cache_location_editor->setToolTip(location);
+}
+
+void LLFloaterPreference::selectPanel(const LLSD& name)
+{
+ LLTabContainer * tab_containerp = getChild<LLTabContainer>("pref core");
+ LLPanel * panel = tab_containerp->getPanelByName(name);
+ if (NULL != panel)
+ {
+ tab_containerp->selectTabPanel(panel);
+ }
+}
+
+void LLFloaterPreference::selectPrivacyPanel()
+{
+ selectPanel("im");
+}
+
+void LLFloaterPreference::selectChatPanel()
+{
+ selectPanel("chat");
+}
+
+void LLFloaterPreference::changed()
+{
+ getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+
+ // set 'enable' property for 'Delete transcripts...' button
+ updateDeleteTranscriptsButton();
+
+}
+
+void LLFloaterPreference::saveGraphicsPreset(std::string& preset)
+{
+ mSavedGraphicsPreset = preset;
+}
+
+//------------------------------Updater---------------------------------------
+
+static bool handleBandwidthChanged(const LLSD& newvalue)
+{
+ gViewerThrottle.setMaxBandwidth((F32) newvalue.asReal());
+ return true;
+}
+
+class LLPanelPreference::Updater : public LLEventTimer
+{
+
+public:
+
+ typedef boost::function<bool(const LLSD&)> callback_t;
+
+ Updater(callback_t cb, F32 period)
+ :LLEventTimer(period),
+ mCallback(cb)
+ {
+ mEventTimer.stop();
+ }
+
+ virtual ~Updater(){}
+
+ void update(const LLSD& new_value)
+ {
+ mNewValue = new_value;
+ mEventTimer.start();
+ }
+
+protected:
+
+ bool tick()
+ {
+ mCallback(mNewValue);
+ mEventTimer.stop();
+
+ return false;
+ }
+
+private:
+
+ LLSD mNewValue;
+ callback_t mCallback;
+};
+//----------------------------------------------------------------------------
+static LLPanelInjector<LLPanelPreference> t_places("panel_preference");
+LLPanelPreference::LLPanelPreference()
+: LLPanel(),
+ mBandWidthUpdater(NULL)
+{
+ mCommitCallbackRegistrar.add("Pref.setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2));
+ mCommitCallbackRegistrar.add("Pref.updateMediaAutoPlayCheckbox", boost::bind(&LLPanelPreference::updateMediaAutoPlayCheckbox, this, _1));
+ mCommitCallbackRegistrar.add("Pref.PrefDelete", boost::bind(&LLPanelPreference::deletePreset, this, _2));
+ mCommitCallbackRegistrar.add("Pref.PrefSave", boost::bind(&LLPanelPreference::savePreset, this, _2));
+ mCommitCallbackRegistrar.add("Pref.PrefLoad", boost::bind(&LLPanelPreference::loadPreset, this, _2));
+}
+
+//virtual
+bool LLPanelPreference::postBuild()
+{
+ ////////////////////// PanelGeneral ///////////////////
+ if (hasChild("display_names_check", true))
+ {
+ bool use_people_api = gSavedSettings.getBOOL("UsePeopleAPI");
+ LLCheckBoxCtrl* ctrl_display_name = getChild<LLCheckBoxCtrl>("display_names_check");
+ ctrl_display_name->setEnabled(use_people_api);
+ if (!use_people_api)
+ {
+ ctrl_display_name->setValue(false);
+ }
+ }
+
+ ////////////////////// PanelVoice ///////////////////
+ if (hasChild("voice_unavailable", true))
+ {
+ bool voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice");
+ getChildView("voice_unavailable")->setVisible( voice_disabled);
+ getChildView("enable_voice_check")->setVisible( !voice_disabled);
+ }
+
+ //////////////////////PanelSkins ///////////////////
+
+ if (hasChild("skin_selection", true))
+ {
+ LLFloaterPreference::refreshSkin(this);
+
+ // if skin is set to a skin that no longer exists (silver) set back to default
+ if (getChild<LLRadioGroup>("skin_selection")->getSelectedIndex() < 0)
+ {
+ gSavedSettings.setString("SkinCurrent", "default");
+ LLFloaterPreference::refreshSkin(this);
+ }
+
+ }
+
+ //////////////////////PanelPrivacy ///////////////////
+ if (hasChild("media_enabled", true))
+ {
+ bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
+
+ getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);
+ getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);
+ }
+ if (hasChild("music_enabled", true))
+ {
+ getChild<LLCheckBoxCtrl>("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic"));
+ }
+ if (hasChild("voice_call_friends_only_check", true))
+ {
+ getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));
+ }
+ if (hasChild("allow_multiple_viewer_check", true))
+ {
+ getChild<LLCheckBoxCtrl>("allow_multiple_viewer_check")->setCommitCallback(boost::bind(&showMultipleViewersWarning, _1, _2));
+ }
+ if (hasChild("favorites_on_login_check", true))
+ {
+ getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2));
+ bool show_favorites_at_login = LLPanelLogin::getShowFavorites();
+ getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setValue(show_favorites_at_login);
+ }
+ if (hasChild("mute_chb_label", true))
+ {
+ getChild<LLTextBox>("mute_chb_label")->setShowCursorHand(false);
+ getChild<LLTextBox>("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP);
+ getChild<LLTextBox>("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized));
+ }
+
+ //////////////////////PanelSetup ///////////////////
+ if (hasChild("max_bandwidth", true))
+ {
+ mBandWidthUpdater = new LLPanelPreference::Updater(boost::bind(&handleBandwidthChanged, _1), BANDWIDTH_UPDATER_TIMEOUT);
+ gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2));
+ }
+
+#ifdef EXTERNAL_TOS
+ LLRadioGroup* ext_browser_settings = getChild<LLRadioGroup>("preferred_browser_behavior");
+ if (ext_browser_settings)
+ {
+ // turn off ability to set external/internal browser
+ ext_browser_settings->setSelectedByValue(LLWeb::BROWSER_EXTERNAL_ONLY, true);
+ ext_browser_settings->setEnabled(false);
+ }
+#endif
+
+ apply();
+ return true;
+}
+
+LLPanelPreference::~LLPanelPreference()
+{
+ if (mBandWidthUpdater)
+ {
+ delete mBandWidthUpdater;
+ }
+}
+void LLPanelPreference::apply()
+{
+ // no-op
+}
+
+void LLPanelPreference::saveSettings()
+{
+ LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
+
+ // Save the value of all controls in the hierarchy
+ mSavedValues.clear();
+ std::list<LLView*> view_stack;
+ view_stack.push_back(this);
+ if (advanced)
+ {
+ view_stack.push_back(advanced);
+ }
+ while(!view_stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = view_stack.front();
+ view_stack.pop_front();
+
+ LLColorSwatchCtrl* color_swatch = dynamic_cast<LLColorSwatchCtrl *>(curview);
+ if (color_swatch)
+ {
+ mSavedColors[color_swatch->getName()] = color_swatch->get();
+ }
+ else
+ {
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ LLControlVariable* control = ctrl->getControlVariable();
+ if (control)
+ {
+ mSavedValues[control] = control->getValue();
+ }
+ }
+ }
+
+ // Push children onto the end of the work stack
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ view_stack.push_back(*iter);
+ }
+ }
+
+ if (LLStartUp::getStartupState() == STATE_STARTED)
+ {
+ LLControlVariable* control = gSavedPerAccountSettings.getControl("VoiceCallsFriendsOnly");
+ if (control)
+ {
+ mSavedValues[control] = control->getValue();
+ }
+ }
+}
+
+void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLSD& value)
+{
+ if (checkbox && checkbox->getValue())
+ {
+ LLNotificationsUtil::add("AllowMultipleViewers");
+ }
+}
+
+void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value)
+{
+ if (checkbox)
+ {
+ gSavedPerAccountSettings.setBOOL("VoiceCallsFriendsOnly", checkbox->getValue().asBoolean());
+ if (checkbox->getValue())
+ {
+ LLNotificationsUtil::add("FriendsAndGroupsOnly");
+ }
+ }
+}
+
+void LLPanelPreference::handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const LLSD& value)
+{
+ if (checkbox)
+ {
+ LLFavoritesOrderStorage::instance().showFavoritesOnLoginChanged(checkbox->getValue().asBoolean());
+ if(checkbox->getValue())
+ {
+ LLNotificationsUtil::add("FavoritesOnLogin");
+ }
+ }
+}
+
+void LLPanelPreference::toggleMuteWhenMinimized()
+{
+ std::string mute("MuteWhenMinimized");
+ gSavedSettings.setBOOL(mute, !gSavedSettings.getBOOL(mute));
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->getChild<LLCheckBoxCtrl>("mute_when_minimized")->setBtnFocus();
+ }
+}
+
+void LLPanelPreference::cancel(const std::vector<std::string> settings_to_skip)
+{
+ for (control_values_map_t::iterator iter = mSavedValues.begin();
+ iter != mSavedValues.end(); ++iter)
+ {
+ LLControlVariable* control = iter->first;
+ LLSD ctrl_value = iter->second;
+
+ if((control->getName() == "InstantMessageLogPath") && (ctrl_value.asString() == ""))
+ {
+ continue;
+ }
+
+ auto found = std::find(settings_to_skip.begin(), settings_to_skip.end(), control->getName());
+ if (found != settings_to_skip.end())
+ {
+ continue;
+ }
+
+ control->set(ctrl_value);
+ }
+
+ for (string_color_map_t::iterator iter = mSavedColors.begin();
+ iter != mSavedColors.end(); ++iter)
+ {
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>(iter->first);
+ if (color_swatch)
+ {
+ color_swatch->set(iter->second);
+ color_swatch->onCommit();
+ }
+ }
+}
+
+void LLPanelPreference::setControlFalse(const LLSD& user_data)
+{
+ std::string control_name = user_data.asString();
+ LLControlVariable* control = findControl(control_name);
+
+ if (control)
+ control->set(LLSD(false));
+}
+
+void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
+{
+ std::string name = ctrl->getName();
+
+ // Disable "Allow Media to auto play" only when both
+ // "Streaming Music" and "Media" are unchecked. STORM-513.
+ if ((name == "enable_music") || (name == "enable_media"))
+ {
+ bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
+ bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
+
+ getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
+ }
+}
+
+void LLPanelPreference::deletePreset(const LLSD& user_data)
+{
+ LLFloaterReg::showInstance("delete_pref_preset", user_data.asString());
+}
+
+void LLPanelPreference::savePreset(const LLSD& user_data)
+{
+ LLFloaterReg::showInstance("save_pref_preset", user_data.asString());
+}
+
+void LLPanelPreference::loadPreset(const LLSD& user_data)
+{
+ LLFloaterReg::showInstance("load_pref_preset", user_data.asString());
+}
+
+void LLPanelPreference::setHardwareDefaults()
+{
+}
+
+class LLPanelPreferencePrivacy : public LLPanelPreference
+{
+public:
+ LLPanelPreferencePrivacy()
+ {
+ mAccountIndependentSettings.push_back("AutoDisengageMic");
+ }
+
+ /*virtual*/ void saveSettings()
+ {
+ LLPanelPreference::saveSettings();
+
+ // Don't save (=erase from the saved values map) per-account privacy settings
+ // if we're not logged in, otherwise they will be reset to defaults on log off.
+ if (LLStartUp::getStartupState() != STATE_STARTED)
+ {
+ // Erase only common settings, assuming there are no color settings on Privacy page.
+ for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); )
+ {
+ const std::string setting = it->first->getName();
+ if (find(mAccountIndependentSettings.begin(),
+ mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end())
+ {
+ mSavedValues.erase(it++);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ }
+ }
+
+private:
+ std::list<std::string> mAccountIndependentSettings;
+};
+
+static LLPanelInjector<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics");
+static LLPanelInjector<LLPanelPreferencePrivacy> t_pref_privacy("panel_preference_privacy");
+
+bool LLPanelPreferenceGraphics::postBuild()
+{
+ LLFloaterReg::showInstance("prefs_graphics_advanced");
+ LLFloaterReg::hideInstance("prefs_graphics_advanced");
+
+ resetDirtyChilds();
+ setPresetText();
+
+ LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
+ presetsMgr->setPresetListChangeCallback(boost::bind(&LLPanelPreferenceGraphics::onPresetsListChange, this));
+ presetsMgr->createMissingDefault(PRESETS_GRAPHIC); // a no-op after the first time, but that's ok
+
+ return LLPanelPreference::postBuild();
+}
+
+void LLPanelPreferenceGraphics::draw()
+{
+ setPresetText();
+ LLPanelPreference::draw();
+}
+
+void LLPanelPreferenceGraphics::onPresetsListChange()
+{
+ resetDirtyChilds();
+ setPresetText();
+
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance && !gSavedSettings.getString("PresetGraphicActive").empty())
+ {
+ instance->saveSettings(); //make cancel work correctly after changing the preset
+ }
+}
+
+void LLPanelPreferenceGraphics::setPresetText()
+{
+ LLTextBox* preset_text = getChild<LLTextBox>("preset_text");
+
+ std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
+
+ if (!preset_graphic_active.empty() && preset_graphic_active != preset_text->getText())
+ {
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->saveGraphicsPreset(preset_graphic_active);
+ }
+ }
+
+ if (hasDirtyChilds() && !preset_graphic_active.empty())
+ {
+ gSavedSettings.setString("PresetGraphicActive", "");
+ preset_graphic_active.clear();
+ // This doesn't seem to cause an infinite recursion. This trigger is needed to cause the pulldown
+ // panel to update.
+ LLPresetsManager::getInstance()->triggerChangeSignal();
+ }
+
+ if (!preset_graphic_active.empty())
+ {
+ if (preset_graphic_active == PRESETS_DEFAULT)
+ {
+ preset_graphic_active = LLTrans::getString(PRESETS_DEFAULT);
+ }
+ preset_text->setText(preset_graphic_active);
+ }
+ else
+ {
+ preset_text->setText(LLTrans::getString("none_paren_cap"));
+ }
+
+ preset_text->resetDirty();
+}
+
+bool LLPanelPreferenceGraphics::hasDirtyChilds()
+{
+ LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
+ std::list<LLView*> view_stack;
+ view_stack.push_back(this);
+ if (advanced)
+ {
+ view_stack.push_back(advanced);
+ }
+ while(!view_stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = view_stack.front();
+ view_stack.pop_front();
+
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ if (ctrl->isDirty())
+ {
+ LLControlVariable* control = ctrl->getControlVariable();
+ if (control)
+ {
+ std::string control_name = control->getName();
+ if (!control_name.empty())
+ {
+ return true;
+ }
+ }
+ }
+ }
+ // Push children onto the end of the work stack
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ view_stack.push_back(*iter);
+ }
+ }
+
+ return false;
+}
+
+void LLPanelPreferenceGraphics::resetDirtyChilds()
+{
+ LLFloater* advanced = LLFloaterReg::findTypedInstance<LLFloater>("prefs_graphics_advanced");
+ std::list<LLView*> view_stack;
+ view_stack.push_back(this);
+ if (advanced)
+ {
+ view_stack.push_back(advanced);
+ }
+ while(!view_stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = view_stack.front();
+ view_stack.pop_front();
+
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ ctrl->resetDirty();
+ }
+ // Push children onto the end of the work stack
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ view_stack.push_back(*iter);
+ }
+ }
+}
+
+void LLPanelPreferenceGraphics::cancel(const std::vector<std::string> settings_to_skip)
+{
+ LLPanelPreference::cancel(settings_to_skip);
+}
+void LLPanelPreferenceGraphics::saveSettings()
+{
+ resetDirtyChilds();
+ std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
+ if (preset_graphic_active.empty())
+ {
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ //don't restore previous preset after closing Preferences
+ instance->saveGraphicsPreset(preset_graphic_active);
+ }
+ }
+ LLPanelPreference::saveSettings();
+}
+void LLPanelPreferenceGraphics::setHardwareDefaults()
+{
+ resetDirtyChilds();
+}
+
+//------------------------LLPanelPreferenceControls--------------------------------
+static LLPanelInjector<LLPanelPreferenceControls> t_pref_contrls("panel_preference_controls");
+
+LLPanelPreferenceControls::LLPanelPreferenceControls()
+ :LLPanelPreference(),
+ mEditingColumn(-1),
+ mEditingMode(0)
+{
+ // MODE_COUNT - 1 because there are currently no settings assigned to 'saved settings'.
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ mConflictHandler[i].setLoadMode((LLKeyConflictHandler::ESourceMode)i);
+ }
+}
+
+LLPanelPreferenceControls::~LLPanelPreferenceControls()
+{
+}
+
+bool LLPanelPreferenceControls::postBuild()
+{
+ // populate list of controls
+ pControlsTable = getChild<LLScrollListCtrl>("controls_list");
+ pKeyModeBox = getChild<LLComboBox>("key_mode");
+
+ pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this));
+ pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this));
+ getChild<LLButton>("restore_defaults")->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsBtn, this));
+
+ return true;
+}
+
+void LLPanelPreferenceControls::regenerateControls()
+{
+ mEditingMode = pKeyModeBox->getValue().asInteger();
+ mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
+ populateControlTable();
+}
+
+bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filename)
+{
+ LLXMLNodePtr xmlNode;
+ LLScrollListCtrl::Contents contents;
+ if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
+ {
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
+ return false;
+ }
+ LLXUIParser parser;
+ parser.readXUI(xmlNode, contents, filename);
+
+ if (!contents.validateBlock())
+ {
+ return false;
+ }
+
+ for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator col_it = contents.columns.begin();
+ col_it != contents.columns.end();
+ ++col_it)
+ {
+ pControlsTable->addColumn(*col_it);
+ }
+
+ return true;
+}
+
+bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
+{
+ LLXMLNodePtr xmlNode;
+ LLScrollListCtrl::Contents contents;
+ if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
+ {
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
+ return false;
+ }
+ LLXUIParser parser;
+ parser.readXUI(xmlNode, contents, filename);
+
+ if (!contents.validateBlock())
+ {
+ return false;
+ }
+
+ LLScrollListCell::Params cell_params;
+ // init basic cell params
+ cell_params.font = LLFontGL::getFontSansSerif();
+ cell_params.font_halign = LLFontGL::LEFT;
+ cell_params.column = "";
+ cell_params.value = "";
+
+
+ for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = contents.rows.begin();
+ row_it != contents.rows.end();
+ ++row_it)
+ {
+ std::string control = row_it->value.getValue().asString();
+ if (!control.empty() && control != "menu_separator")
+ {
+ bool show = true;
+ bool enabled = mConflictHandler[mEditingMode].canAssignControl(control);
+ if (!enabled)
+ {
+ // If empty: this is a placeholder to make sure user won't assign
+ // value by accident, don't show it
+ // If not empty: predefined control combination user should see
+ // to know that combination is reserved
+ show = !mConflictHandler[mEditingMode].isControlEmpty(control);
+ // example: teleport_to and walk_to in first person view, and
+ // sitting related functions, see generatePlaceholders()
+ }
+
+ if (show)
+ {
+ // At the moment viewer is hardcoded to assume that columns are named as lst_ctrl%d
+ LLScrollListItem::Params item_params(*row_it);
+ item_params.enabled.setValue(enabled);
+
+ S32 num_columns = pControlsTable->getNumColumns();
+ for (S32 col = 1; col < num_columns; col++)
+ {
+ cell_params.column = llformat("lst_ctrl%d", col);
+ cell_params.value = mConflictHandler[mEditingMode].getControlString(control, col - 1);
+ item_params.columns.add(cell_params);
+ }
+ pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM);
+ }
+ }
+ else
+ {
+ // Separator example:
+ // <rows
+ // enabled = "false">
+ // <columns
+ // type = "icon"
+ // color = "0 0 0 0.7"
+ // halign = "center"
+ // value = "menu_separator"
+ // column = "lst_action" / >
+ //</rows>
+ pControlsTable->addRow(*row_it, EAddPosition::ADD_BOTTOM);
+ }
+ }
+ return true;
+}
+
+void LLPanelPreferenceControls::addControlTableSeparator()
+{
+ LLScrollListItem::Params separator_params;
+ separator_params.enabled(false);
+ LLScrollListCell::Params column_params;
+ column_params.type = "icon";
+ column_params.value = "menu_separator";
+ column_params.column = "lst_action";
+ column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f);
+ column_params.font_halign = LLFontGL::HCENTER;
+ separator_params.columns.add(column_params);
+ pControlsTable->addRow(separator_params, EAddPosition::ADD_BOTTOM);
+}
+
+void LLPanelPreferenceControls::populateControlTable()
+{
+ pControlsTable->clearRows();
+ pControlsTable->clearColumns();
+
+ // Add columns
+ std::string filename;
+ switch ((LLKeyConflictHandler::ESourceMode)mEditingMode)
+ {
+ case LLKeyConflictHandler::MODE_THIRD_PERSON:
+ case LLKeyConflictHandler::MODE_FIRST_PERSON:
+ case LLKeyConflictHandler::MODE_EDIT_AVATAR:
+ case LLKeyConflictHandler::MODE_SITTING:
+ filename = "control_table_contents_columns_basic.xml";
+ break;
+ default:
+ {
+ // Either unknown mode or MODE_SAVED_SETTINGS
+ // It doesn't have UI or actual settings yet
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
+
+ // Searchable columns were removed, mark searchables for an update
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateSearchableItems();
+ }
+ return;
+ }
+ }
+ addControlTableColumns(filename);
+
+ // Add rows.
+ // Each file represents individual visual group (movement/camera/media...)
+ if (mEditingMode == LLKeyConflictHandler::MODE_FIRST_PERSON)
+ {
+ // Don't display whole camera and editing groups
+ addControlTableRows("control_table_contents_movement.xml");
+ addControlTableSeparator();
+ addControlTableRows("control_table_contents_media.xml");
+ }
+ // MODE_THIRD_PERSON; MODE_EDIT_AVATAR; MODE_SITTING
+ else if (mEditingMode < LLKeyConflictHandler::MODE_SAVED_SETTINGS)
+ {
+ // In case of 'sitting' mode, movements still apply due to vehicles
+ // but walk_to is not supported and will be hidden by addControlTableRows
+ addControlTableRows("control_table_contents_movement.xml");
+ addControlTableSeparator();
+
+ addControlTableRows("control_table_contents_camera.xml");
+ addControlTableSeparator();
+
+ addControlTableRows("control_table_contents_editing.xml");
+ addControlTableSeparator();
+
+ addControlTableRows("control_table_contents_media.xml");
+ }
+ else
+ {
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
+ }
+
+ // explicit update to make sure table is ready for llsearchableui
+ pControlsTable->updateColumns();
+
+ // Searchable columns were removed and readded, mark searchables for an update
+ // Note: at the moment tables/lists lack proper llsearchableui support
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateSearchableItems();
+ }
+}
+
+void LLPanelPreferenceControls::updateTable()
+{
+ mEditingControl.clear();
+ std::vector<LLScrollListItem*> list = pControlsTable->getAllData();
+ for (S32 i = 0; i < list.size(); ++i)
+ {
+ std::string control = list[i]->getValue();
+ if (!control.empty())
+ {
+ LLScrollListCell* cell = NULL;
+
+ S32 num_columns = pControlsTable->getNumColumns();
+ for (S32 col = 1; col < num_columns; col++)
+ {
+ cell = list[i]->getColumn(col);
+ cell->setValue(mConflictHandler[mEditingMode].getControlString(control, col - 1));
+ }
+ }
+ }
+ pControlsTable->deselectAllItems();
+}
+
+void LLPanelPreferenceControls::apply()
+{
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].hasUnsavedChanges())
+ {
+ mConflictHandler[i].saveToSettings();
+ }
+ }
+}
+
+void LLPanelPreferenceControls::cancel(const std::vector<std::string> settings_to_skip)
+{
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].hasUnsavedChanges())
+ {
+ mConflictHandler[i].clear();
+ if (mEditingMode == i)
+ {
+ // cancel() can be called either when preferences floater closes
+ // or when child floater closes (like advanced graphical settings)
+ // in which case we need to clear and repopulate table
+ regenerateControls();
+ }
+ }
+ }
+}
+
+void LLPanelPreferenceControls::saveSettings()
+{
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].hasUnsavedChanges())
+ {
+ mConflictHandler[i].saveToSettings();
+ mConflictHandler[i].clear();
+ }
+ }
+
+ S32 mode = pKeyModeBox->getValue().asInteger();
+ if (mConflictHandler[mode].empty() || pControlsTable->isEmpty())
+ {
+ regenerateControls();
+ }
+}
+
+void LLPanelPreferenceControls::resetDirtyChilds()
+{
+ regenerateControls();
+}
+
+void LLPanelPreferenceControls::onListCommit()
+{
+ LLScrollListItem* item = pControlsTable->getFirstSelected();
+ if (item == NULL)
+ {
+ return;
+ }
+
+ std::string control = item->getValue();
+
+ if (control.empty())
+ {
+ pControlsTable->deselectAllItems();
+ return;
+ }
+
+ if (!mConflictHandler[mEditingMode].canAssignControl(control))
+ {
+ pControlsTable->deselectAllItems();
+ return;
+ }
+
+ S32 cell_ind = item->getSelectedCell();
+ if (cell_ind <= 0)
+ {
+ pControlsTable->deselectAllItems();
+ return;
+ }
+
+ // List does not tell us what cell was clicked, so we have to figure it out manually, but
+ // fresh mouse coordinates are not yet accessible during onCommit() and there are other issues,
+ // so we cheat: remember item user clicked at, trigger 'key dialog' on hover that comes next,
+ // use coordinates from hover to calculate cell
+
+ LLScrollListCell* cell = item->getColumn(cell_ind);
+ if (cell)
+ {
+ LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD());
+ if (dialog)
+ {
+ mEditingControl = control;
+ mEditingColumn = cell_ind;
+ dialog->setParent(this, pControlsTable, DEFAULT_KEY_FILTER);
+
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ root_floater->addDependentFloater(dialog);
+ dialog->openFloater();
+ dialog->setFocus(true);
+ }
+ }
+ else
+ {
+ pControlsTable->deselectAllItems();
+ }
+}
+
+void LLPanelPreferenceControls::onModeCommit()
+{
+ mEditingMode = pKeyModeBox->getValue().asInteger();
+ if (mConflictHandler[mEditingMode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
+ }
+ populateControlTable();
+}
+
+void LLPanelPreferenceControls::onRestoreDefaultsBtn()
+{
+ LLNotificationsUtil::add("PreferenceControlsDefaults", LLSD(), LLSD(), boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsResponse, this, _1, _2));
+}
+
+void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case 0: // All
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ mConflictHandler[i].resetToDefaults();
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[i].saveToSettings(true);
+
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
+ updateTable();
+ break;
+ case 1: // Current
+ mConflictHandler[mEditingMode].resetToDefaults();
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[mEditingMode].saveToSettings(true);
+
+ if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON)
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
+ updateTable();
+ break;
+ case 2: // Cancel
+ default:
+ //exit;
+ break;
+ }
+}
+
+// Bypass to let Move & view read values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+bool LLPanelPreferenceControls::canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask)
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ if (mConflictHandler[mode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+ }
+
+ return mConflictHandler[mode].canHandleControl(control, click, key, mask);
+}
+
+// Bypass to let Move & view modify values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+void LLPanelPreferenceControls::setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set)
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ if (mConflictHandler[mode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+ }
+
+ if (!mConflictHandler[mode].canAssignControl(mEditingControl))
+ {
+ return;
+ }
+
+ bool already_recorded = mConflictHandler[mode].canHandleControl(control, click, key, mask);
+ if (set)
+ {
+ if (already_recorded)
+ {
+ // nothing to do
+ return;
+ }
+
+ // find free spot to add data, if no free spot, assign to first
+ S32 index = 0;
+ for (S32 i = 0; i < 3; i++)
+ {
+ if (mConflictHandler[mode].getControl(control, i).isEmpty())
+ {
+ index = i;
+ break;
+ }
+ }
+ // At the moment 'ignore_mask' mask is mostly ignored, a placeholder
+ // Todo: implement it since it's preferable for things like teleport to match
+ // mask exactly but for things like running to ignore additional masks
+ // Ideally this needs representation in keybindings UI
+ bool ignore_mask = true;
+ mConflictHandler[mode].registerControl(control, index, click, key, mask, ignore_mask);
+ }
+ else if (!set)
+ {
+ if (!already_recorded)
+ {
+ // nothing to do
+ return;
+ }
+
+ // find specific control and reset it
+ for (S32 i = 0; i < 3; i++)
+ {
+ LLKeyData data = mConflictHandler[mode].getControl(control, i);
+ if (data.mMouse == click && data.mKey == key && data.mMask == mask)
+ {
+ mConflictHandler[mode].clearControl(control, i);
+ }
+ }
+ }
+}
+
+void LLPanelPreferenceControls::updateAndApply()
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ mConflictHandler[mode].saveToSettings(true);
+ updateTable();
+}
+
+// from LLSetKeybindDialog's interface
+bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes)
+{
+ if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
+ {
+ return true;
+ }
+
+ if ( mEditingColumn > 0)
+ {
+ if (all_modes)
+ {
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].empty())
+ {
+ mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
+ }
+ mConflictHandler[i].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[i].saveToSettings(true);
+ }
+ }
+ else
+ {
+ mConflictHandler[mEditingMode].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[mEditingMode].saveToSettings(true);
+ }
+ }
+
+ updateTable();
+
+ if ((mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+ && (mEditingControl == "walk_to"
+ || mEditingControl == "teleport_to"
+ || click == CLICK_LEFT
+ || click == CLICK_DOUBLELEFT))
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
+ return true;
+}
+
+void LLPanelPreferenceControls::onDefaultKeyBind(bool all_modes)
+{
+ if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
+ {
+ return;
+ }
+
+ if (mEditingColumn > 0)
+ {
+ if (all_modes)
+ {
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].empty())
+ {
+ mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
+ }
+ mConflictHandler[i].resetToDefault(mEditingControl, mEditingColumn - 1);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[i].saveToSettings(true);
+ }
+ }
+ else
+ {
+ mConflictHandler[mEditingMode].resetToDefault(mEditingControl, mEditingColumn - 1);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[mEditingMode].saveToSettings(true);
+ }
+ }
+ updateTable();
+
+ if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+}
+
+void LLPanelPreferenceControls::onCancelKeyBind()
+{
+ pControlsTable->deselectAllItems();
+}
+
+LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
+ : LLFloater(key),
+ mSocksSettingsDirty(false)
+{
+ mCommitCallbackRegistrar.add("Proxy.OK", boost::bind(&LLFloaterPreferenceProxy::onBtnOk, this));
+ mCommitCallbackRegistrar.add("Proxy.Cancel", boost::bind(&LLFloaterPreferenceProxy::onBtnCancel, this));
+ mCommitCallbackRegistrar.add("Proxy.Change", boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));
+}
+
+LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
+{
+}
+
+bool LLFloaterPreferenceProxy::postBuild()
+{
+ LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
+ if (!socksAuth)
+ {
+ return false;
+ }
+ if (socksAuth->getSelectedValue().asString() == "None")
+ {
+ getChild<LLLineEditor>("socks5_username")->setEnabled(false);
+ getChild<LLLineEditor>("socks5_password")->setEnabled(false);
+ }
+ else
+ {
+ // Populate the SOCKS 5 credential fields with protected values.
+ LLPointer<LLCredential> socks_cred = gSecAPIHandler->loadCredential("SOCKS5");
+ getChild<LLLineEditor>("socks5_username")->setValue(socks_cred->getIdentifier()["username"].asString());
+ getChild<LLLineEditor>("socks5_password")->setValue(socks_cred->getAuthenticator()["creds"].asString());
+ }
+
+ return true;
+}
+
+void LLFloaterPreferenceProxy::onOpen(const LLSD& key)
+{
+ saveSettings();
+}
+
+void LLFloaterPreferenceProxy::onClose(bool app_quitting)
+{
+ if(app_quitting)
+ {
+ cancel();
+ }
+
+ if (mSocksSettingsDirty)
+ {
+
+ // If the user plays with the Socks proxy settings after login, it's only fair we let them know
+ // it will not be updated until next restart.
+ if (LLStartUp::getStartupState()>STATE_LOGIN_WAIT)
+ {
+ LLNotifications::instance().add("ChangeProxySettings", LLSD(), LLSD());
+ mSocksSettingsDirty = false; // we have notified the user now be quiet again
+ }
+ }
+}
+
+void LLFloaterPreferenceProxy::saveSettings()
+{
+ // Save the value of all controls in the hierarchy
+ mSavedValues.clear();
+ std::list<LLView*> view_stack;
+ view_stack.push_back(this);
+ while(!view_stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = view_stack.front();
+ view_stack.pop_front();
+
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ LLControlVariable* control = ctrl->getControlVariable();
+ if (control)
+ {
+ mSavedValues[control] = control->getValue();
+ }
+ }
+
+ // Push children onto the end of the work stack
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ view_stack.push_back(*iter);
+ }
+ }
+}
+
+void LLFloaterPreferenceProxy::onBtnOk()
+{
+ // commit any outstanding text entry
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus && cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ }
+ }
+
+ // Save SOCKS proxy credentials securely if password auth is enabled
+ LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
+ if (socksAuth->getSelectedValue().asString() == "UserPass")
+ {
+ LLSD socks_id = LLSD::emptyMap();
+ socks_id["type"] = "SOCKS5";
+ socks_id["username"] = getChild<LLLineEditor>("socks5_username")->getValue().asString();
+
+ LLSD socks_authenticator = LLSD::emptyMap();
+ socks_authenticator["type"] = "SOCKS5";
+ socks_authenticator["creds"] = getChild<LLLineEditor>("socks5_password")->getValue().asString();
+
+ // Using "SOCKS5" as the "grid" argument since the same proxy
+ // settings will be used for all grids and because there is no
+ // way to specify the type of credential.
+ LLPointer<LLCredential> socks_cred = gSecAPIHandler->createCredential("SOCKS5", socks_id, socks_authenticator);
+ gSecAPIHandler->saveCredential(socks_cred, true);
+ }
+ else
+ {
+ // Clear SOCKS5 credentials since they are no longer needed.
+ LLPointer<LLCredential> socks_cred = new LLCredential("SOCKS5");
+ gSecAPIHandler->deleteCredential(socks_cred);
+ }
+
+ closeFloater(false);
+}
+
+void LLFloaterPreferenceProxy::onBtnCancel()
+{
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus && cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ }
+ refresh();
+ }
+
+ cancel();
+}
+
+void LLFloaterPreferenceProxy::onClickCloseBtn(bool app_quitting)
+{
+ cancel();
+}
+
+void LLFloaterPreferenceProxy::cancel()
+{
+
+ for (control_values_map_t::iterator iter = mSavedValues.begin();
+ iter != mSavedValues.end(); ++iter)
+ {
+ LLControlVariable* control = iter->first;
+ LLSD ctrl_value = iter->second;
+ control->set(ctrl_value);
+ }
+ mSocksSettingsDirty = false;
+ closeFloater();
+}
+
+void LLFloaterPreferenceProxy::onChangeSocksSettings()
+{
+ mSocksSettingsDirty = true;
+
+ LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
+ if (socksAuth->getSelectedValue().asString() == "None")
+ {
+ getChild<LLLineEditor>("socks5_username")->setEnabled(false);
+ getChild<LLLineEditor>("socks5_password")->setEnabled(false);
+ }
+ else
+ {
+ getChild<LLLineEditor>("socks5_username")->setEnabled(true);
+ getChild<LLLineEditor>("socks5_password")->setEnabled(true);
+ }
+
+ // Check for invalid states for the other HTTP proxy radio
+ LLRadioGroup* otherHttpProxy = getChild<LLRadioGroup>("other_http_proxy_type");
+ if ((otherHttpProxy->getSelectedValue().asString() == "Socks" &&
+ !getChild<LLCheckBoxCtrl>("socks_proxy_enabled")->get())||(
+ otherHttpProxy->getSelectedValue().asString() == "Web" &&
+ !getChild<LLCheckBoxCtrl>("web_proxy_enabled")->get()))
+ {
+ otherHttpProxy->selectFirstItem();
+ }
+
+}
+
+void LLFloaterPreference::onUpdateFilterTerm(bool force)
+{
+ LLWString seachValue = utf8str_to_wstring(mFilterEdit->getValue());
+ LLWStringUtil::toLower(seachValue);
+
+ if (!mSearchData || (mSearchData->mLastFilter == seachValue && !force))
+ return;
+
+ if (mSearchDataDirty)
+ {
+ // Data exists, but is obsolete, regenerate
+ collectSearchableItems();
+ }
+
+ mSearchData->mLastFilter = seachValue;
+
+ if (!mSearchData->mRootTab)
+ return;
+
+ mSearchData->mRootTab->hightlightAndHide( seachValue );
+ filterIgnorableNotifications();
+
+ if (LLTabContainer* pRoot = getChild<LLTabContainer>("pref core"))
+ pRoot->selectFirstTab();
+}
+
+void LLFloaterPreference::filterIgnorableNotifications()
+{
+ bool visible = getChildRef<LLScrollListCtrl>("enabled_popups").highlightMatchingItems(mFilterEdit->getValue());
+ visible |= getChildRef<LLScrollListCtrl>("disabled_popups").highlightMatchingItems(mFilterEdit->getValue());
+
+ if (visible)
+ {
+ getChildRef<LLTabContainer>("pref core").setTabVisibility( getChild<LLPanel>("msgs"), true );
+ }
+}
+
+void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
+{
+ if (!aView)
+ return;
+
+ llassert_always(aParentPanel || aParentTabContainer);
+
+ for (LLView* pView : *aView->getChildList())
+ {
+ if (!pView)
+ continue;
+
+ ll::prefs::PanelDataPtr pCurPanelData = aParentPanel;
+ ll::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer;
+
+ LLPanel const *pPanel = dynamic_cast<LLPanel const*>(pView);
+ LLTabContainer const *pTabContainer = dynamic_cast<LLTabContainer const*>(pView);
+ ll::ui::SearchableControl const *pSCtrl = dynamic_cast<ll::ui::SearchableControl const*>( pView );
+
+ if (pTabContainer)
+ {
+ pCurPanelData.reset();
+
+ pCurTabContainer = ll::prefs::TabContainerDataPtr(new ll::prefs::TabContainerData);
+ pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>(pTabContainer);
+ pCurTabContainer->mLabel = pTabContainer->getLabel();
+ pCurTabContainer->mPanel = 0;
+
+ if (aParentPanel)
+ aParentPanel->mChildPanel.push_back(pCurTabContainer);
+ if (aParentTabContainer)
+ aParentTabContainer->mChildPanel.push_back(pCurTabContainer);
+ }
+ else if (pPanel)
+ {
+ pCurTabContainer.reset();
+
+ pCurPanelData = ll::prefs::PanelDataPtr(new ll::prefs::PanelData);
+ pCurPanelData->mPanel = pPanel;
+ pCurPanelData->mLabel = pPanel->getLabel();
+
+ llassert_always( aParentPanel || aParentTabContainer );
+
+ if (aParentTabContainer)
+ aParentTabContainer->mChildPanel.push_back(pCurPanelData);
+ else if (aParentPanel)
+ aParentPanel->mChildPanel.push_back(pCurPanelData);
+ }
+ else if (pSCtrl && pSCtrl->getSearchText().size())
+ {
+ ll::prefs::SearchableItemPtr item = ll::prefs::SearchableItemPtr(new ll::prefs::SearchableItem());
+ item->mView = pView;
+ item->mCtrl = pSCtrl;
+
+ item->mLabel = utf8str_to_wstring(pSCtrl->getSearchText());
+ LLWStringUtil::toLower(item->mLabel);
+
+ llassert_always(aParentPanel || aParentTabContainer);
+
+ if (aParentPanel)
+ aParentPanel->mChildren.push_back(item);
+ if (aParentTabContainer)
+ aParentTabContainer->mChildren.push_back(item);
+ }
+ collectChildren(pView, pCurPanelData, pCurTabContainer);
+ }
+}
+
+void LLFloaterPreference::collectSearchableItems()
+{
+ mSearchData.reset( nullptr );
+ LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
+ if( mFilterEdit && pRoot )
+ {
+ mSearchData.reset(new ll::prefs::SearchData() );
+
+ ll::prefs::TabContainerDataPtr pRootTabcontainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
+ pRootTabcontainer->mTabContainer = pRoot;
+ pRootTabcontainer->mLabel = pRoot->getLabel();
+ mSearchData->mRootTab = pRootTabcontainer;
+
+ collectChildren( this, ll::prefs::PanelDataPtr(), pRootTabcontainer );
+ }
+ mSearchDataDirty = false;
+}
+
+void LLFloaterPreference::saveIgnoredNotifications()
+{
+ for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+ iter != LLNotifications::instance().templatesEnd();
+ ++iter)
+ {
+ LLNotificationTemplatePtr templatep = iter->second;
+ LLNotificationFormPtr formp = templatep->mForm;
+
+ LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
+ if (ignore <= LLNotificationForm::IGNORE_NO)
+ continue;
+
+ mIgnorableNotifs[templatep->mName] = !formp->getIgnored();
+ }
+}
+
+void LLFloaterPreference::restoreIgnoredNotifications()
+{
+ for (std::map<std::string, bool>::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it)
+ {
+ LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second);
+ }
+}