diff options
| author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
|---|---|---|
| committer | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
| commit | 1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch) | |
| tree | ab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llfloaterpreference.cpp | |
| parent | 6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff) | |
| parent | e1623bb276f83a43ce7a197e388720c05bdefe61 (diff) | |
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts:
# autobuild.xml
# indra/cmake/CMakeLists.txt
# indra/cmake/GoogleMock.cmake
# indra/llaudio/llaudioengine_fmodstudio.cpp
# indra/llaudio/llaudioengine_fmodstudio.h
# indra/llaudio/lllistener_fmodstudio.cpp
# indra/llaudio/lllistener_fmodstudio.h
# indra/llaudio/llstreamingaudio_fmodstudio.cpp
# indra/llaudio/llstreamingaudio_fmodstudio.h
# indra/llcharacter/llmultigesture.cpp
# indra/llcharacter/llmultigesture.h
# indra/llimage/llimage.cpp
# indra/llimage/llimagepng.cpp
# indra/llimage/llimageworker.cpp
# indra/llimage/tests/llimageworker_test.cpp
# indra/llmessage/tests/llmockhttpclient.h
# indra/llprimitive/llgltfmaterial.h
# indra/llrender/llfontfreetype.cpp
# indra/llui/llcombobox.cpp
# indra/llui/llfolderview.cpp
# indra/llui/llfolderviewmodel.h
# indra/llui/lllineeditor.cpp
# indra/llui/lllineeditor.h
# indra/llui/lltextbase.cpp
# indra/llui/lltextbase.h
# indra/llui/lltexteditor.cpp
# indra/llui/lltextvalidate.cpp
# indra/llui/lltextvalidate.h
# indra/llui/lluictrl.h
# indra/llui/llview.cpp
# indra/llwindow/llwindowmacosx.cpp
# indra/newview/app_settings/settings.xml
# indra/newview/llappearancemgr.cpp
# indra/newview/llappearancemgr.h
# indra/newview/llavatarpropertiesprocessor.cpp
# indra/newview/llavatarpropertiesprocessor.h
# indra/newview/llbreadcrumbview.cpp
# indra/newview/llbreadcrumbview.h
# indra/newview/llbreastmotion.cpp
# indra/newview/llbreastmotion.h
# indra/newview/llconversationmodel.h
# indra/newview/lldensityctrl.cpp
# indra/newview/lldensityctrl.h
# indra/newview/llface.inl
# indra/newview/llfloatereditsky.cpp
# indra/newview/llfloatereditwater.cpp
# indra/newview/llfloateremojipicker.h
# indra/newview/llfloaterimsessiontab.cpp
# indra/newview/llfloaterprofiletexture.cpp
# indra/newview/llfloaterprofiletexture.h
# indra/newview/llgesturemgr.cpp
# indra/newview/llgesturemgr.h
# indra/newview/llimpanel.cpp
# indra/newview/llimpanel.h
# indra/newview/llinventorybridge.cpp
# indra/newview/llinventorybridge.h
# indra/newview/llinventoryclipboard.cpp
# indra/newview/llinventoryclipboard.h
# indra/newview/llinventoryfunctions.cpp
# indra/newview/llinventoryfunctions.h
# indra/newview/llinventorygallery.cpp
# indra/newview/lllistbrowser.cpp
# indra/newview/lllistbrowser.h
# indra/newview/llpanelobjectinventory.cpp
# indra/newview/llpanelprofile.cpp
# indra/newview/llpanelprofile.h
# indra/newview/llpreviewgesture.cpp
# indra/newview/llsavedsettingsglue.cpp
# indra/newview/llsavedsettingsglue.h
# indra/newview/lltooldraganddrop.cpp
# indra/newview/llurllineeditorctrl.cpp
# indra/newview/llvectorperfoptions.cpp
# indra/newview/llvectorperfoptions.h
# indra/newview/llviewerparceloverlay.cpp
# indra/newview/llviewertexlayer.cpp
# indra/newview/llviewertexturelist.cpp
# indra/newview/macmain.h
# indra/test/test.cpp
Diffstat (limited to 'indra/newview/llfloaterpreference.cpp')
| -rw-r--r-- | indra/newview/llfloaterpreference.cpp | 6875 |
1 files changed, 3436 insertions, 3439 deletions
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index b503fc3630..3ed3abce58 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1,3439 +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 == type ) - { - const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( 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() -{ - std::vector<std::string> list_of_transcriptions_file_names; - LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names); - getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0); -} - -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()->sendAvatarPropertiesRequest( 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);
+ }
+}
|
