From 469f2621f170484943093a830ec385f1b8d20934 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Wed, 17 Jan 2024 00:30:37 +0200 Subject: SL-20708 don't reset "Quality & speed" slider when canceling Advanced Settings --- indra/newview/llfloaterpreference.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index aa723eb3a8..d15c52cc24 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -620,7 +620,7 @@ void LLFloaterPreference::apply() saveAvatarProperties(); } -void LLFloaterPreference::cancel() +void LLFloaterPreference::cancel(const std::vector settings_to_skip) { LLTabContainer* tabcontainer = getChild("pref core"); // Call cancel() on all panels that derive from LLPanelPreference @@ -630,7 +630,7 @@ void LLFloaterPreference::cancel() LLView* view = *iter; LLPanelPreference* panel = dynamic_cast(view); if (panel) - panel->cancel(); + panel->cancel(settings_to_skip); } // hide joystick pref floater LLFloaterReg::hideInstance("pref_joystick"); @@ -1011,15 +1011,16 @@ void LLFloaterPreference::onBtnCancel(const LLSD& userdata) } refresh(); } - cancel(); - + if (userdata.asString() == "closeadvanced") { + cancel({"RenderQualityPerformance"}); LLFloaterReg::hideInstance("prefs_graphics_advanced"); updateMaxComplexity(); } else { + cancel(); closeFloater(); } } @@ -2206,7 +2207,7 @@ void LLPanelPreference::toggleMuteWhenMinimized() } } -void LLPanelPreference::cancel() +void LLPanelPreference::cancel(const std::vector settings_to_skip) { for (control_values_map_t::iterator iter = mSavedValues.begin(); iter != mSavedValues.end(); ++iter) @@ -2219,6 +2220,12 @@ void LLPanelPreference::cancel() 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); } @@ -2461,9 +2468,9 @@ void LLPanelPreferenceGraphics::resetDirtyChilds() } } -void LLPanelPreferenceGraphics::cancel() +void LLPanelPreferenceGraphics::cancel(const std::vector settings_to_skip) { - LLPanelPreference::cancel(); + LLPanelPreference::cancel(settings_to_skip); } void LLPanelPreferenceGraphics::saveSettings() { @@ -2751,7 +2758,7 @@ void LLPanelPreferenceControls::apply() } } -void LLPanelPreferenceControls::cancel() +void LLPanelPreferenceControls::cancel(const std::vector settings_to_skip) { for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) { -- cgit v1.2.3 From 4419bb870986c6900fc096338622d27b999cd771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Sun, 11 Feb 2024 01:23:28 +0100 Subject: more misc: BOOL (int) to real bool --- indra/newview/llfloaterpreference.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index d15c52cc24..ab9714b89f 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1980,12 +1980,12 @@ public: protected: - BOOL tick() + bool tick() { mCallback(mNewValue); mEventTimer.stop(); - return FALSE; + return false; } private: -- cgit v1.2.3 From 8c16ec2b53153a10f40181e0e8108d24331451d4 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 20 Feb 2024 13:57:07 +0100 Subject: Convert BOOL to bool in LLControlGroup and related classes --- indra/newview/llfloaterpreference.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index ab9714b89f..19a4081eba 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -180,7 +180,7 @@ bool callback_clear_cache(const LLSD& notification, const LLSD& response) if ( option == 0 ) // YES { // flag client texture cache for clearing next time the client runs - gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE); + gSavedSettings.setBOOL("PurgeCacheOnNextStartup", true); LLNotificationsUtil::add("CacheWillClear"); } @@ -200,7 +200,7 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response LLNavigationBar::getInstance()->clearHistoryCache(); // flag client texture cache for clearing next time the client runs - gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE); + gSavedSettings.setBOOL("PurgeCacheOnNextStartup", true); LLNotificationsUtil::add("CacheWillClear"); LLSearchHistory::getInstance()->clearHistory(); @@ -861,7 +861,7 @@ void LLFloaterPreference::setRecommendedSettings() void LLFloaterPreference::resetAutotuneSettings() { - gSavedSettings.setBOOL("AutoTuneFPS", FALSE); + gSavedSettings.setBOOL("AutoTuneFPS", false); const std::string autotune_settings[] = { "AutoTuneLock", @@ -1327,7 +1327,7 @@ void LLFloaterPreference::onClickEnablePopup() 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); + LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(notification_name, true); } buildPopupLists(); -- cgit v1.2.3 From a5261a5fa8fad810ecb5c260d92c3e771822bf58 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 20 Feb 2024 23:46:23 +0100 Subject: Convert BOOL to bool in llui --- indra/newview/llfloaterpreference.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 19a4081eba..d925ab5ece 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -427,7 +427,7 @@ void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bo LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL; } -BOOL LLFloaterPreference::postBuild() +bool LLFloaterPreference::postBuild() { gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false)); @@ -504,7 +504,7 @@ BOOL LLFloaterPreference::postBuild() getChild("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true); } - return TRUE; + return true; } void LLFloaterPreference::updateDeleteTranscriptsButton() @@ -2007,7 +2007,7 @@ LLPanelPreference::LLPanelPreference() } //virtual -BOOL LLPanelPreference::postBuild() +bool LLPanelPreference::postBuild() { ////////////////////// PanelGeneral /////////////////// if (hasChild("display_names_check", TRUE)) @@ -2324,7 +2324,7 @@ private: static LLPanelInjector t_pref_graph("panel_preference_graphics"); static LLPanelInjector t_pref_privacy("panel_preference_privacy"); -BOOL LLPanelPreferenceGraphics::postBuild() +bool LLPanelPreferenceGraphics::postBuild() { LLFloaterReg::showInstance("prefs_graphics_advanced"); LLFloaterReg::hideInstance("prefs_graphics_advanced"); @@ -2511,7 +2511,7 @@ LLPanelPreferenceControls::~LLPanelPreferenceControls() { } -BOOL LLPanelPreferenceControls::postBuild() +bool LLPanelPreferenceControls::postBuild() { // populate list of controls pControlsTable = getChild("controls_list"); @@ -2521,7 +2521,7 @@ BOOL LLPanelPreferenceControls::postBuild() pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this)); getChild("restore_defaults")->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsBtn, this)); - return TRUE; + return true; } void LLPanelPreferenceControls::regenerateControls() @@ -3113,12 +3113,12 @@ LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy() { } -BOOL LLFloaterPreferenceProxy::postBuild() +bool LLFloaterPreferenceProxy::postBuild() { LLRadioGroup* socksAuth = getChild("socks5_auth_type"); if (!socksAuth) { - return FALSE; + return false; } if (socksAuth->getSelectedValue().asString() == "None") { @@ -3133,7 +3133,7 @@ BOOL LLFloaterPreferenceProxy::postBuild() getChild("socks5_password")->setValue(socks_cred->getAuthenticator()["creds"].asString()); } - return TRUE; + return true; } void LLFloaterPreferenceProxy::onOpen(const LLSD& key) -- cgit v1.2.3 From 60d3dd98a44230c21803c1606552ee098ed9fa7c Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 21 Feb 2024 21:05:14 +0100 Subject: Convert remaining BOOL to bool --- indra/newview/llfloaterpreference.cpp | 82 +++++++++++++++++------------------ 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index d925ab5ece..5b4138e2e9 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -447,11 +447,11 @@ bool LLFloaterPreference::postBuild() if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) tabcontainer->selectFirstTab(); - getChild("cache_location")->setEnabled(FALSE); // make it read-only but selectable (STORM-227) + getChild("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("log_path_string")->setEnabled(FALSE); // make it read-only but selectable + getChild("log_path_string")->setEnabled(false); // make it read-only but selectable getChild("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this)); @@ -516,7 +516,7 @@ void LLFloaterPreference::updateDeleteTranscriptsButton() void LLFloaterPreference::onDoNotDisturbResponseChanged() { - // set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise + // set "DoNotDisturbResponseChanged" true if user edited message differs from default, false otherwise bool response_changed_flag = LLTrans::getString("DoNotDisturbModeResponseDefault") != getChild("do_not_disturb_response")->getValue().asString(); @@ -532,7 +532,7 @@ LLFloaterPreference::~LLFloaterPreference() void LLFloaterPreference::draw() { - BOOL has_first_selected = (getChildRef("disabled_popups").getFirstSelected()!=NULL); + bool has_first_selected = (getChildRef("disabled_popups").getFirstSelected()!=NULL); gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected); has_first_selected = (getChildRef("enabled_popups").getFirstSelected()!=NULL); @@ -587,7 +587,7 @@ void LLFloaterPreference::apply() LLViewerMedia::getInstance()->setCookiesEnabled(getChild("cookies_enabled")->getValue()); - if (hasChild("web_proxy_enabled", TRUE) &&hasChild("web_proxy_editor", TRUE) && hasChild("web_proxy_port", TRUE)) + if (hasChild("web_proxy_enabled", true) &&hasChild("web_proxy_editor", true) && hasChild("web_proxy_port", true)) { bool proxy_enable = getChild("web_proxy_enabled")->getValue(); std::string proxy_address = getChild("web_proxy_editor")->getValue(); @@ -678,7 +678,7 @@ 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; + 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) { @@ -687,8 +687,8 @@ void LLFloaterPreference::onOpen(const LLSD& key) // 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; + // 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)); @@ -975,12 +975,12 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata) } LLUIColorTable::instance().saveUserSettings(); - gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); + gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), true); //Only save once logged in and loaded per account settings if(mGotPersonalInfo) { - gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); + gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), true); } } else @@ -1232,7 +1232,7 @@ void LLFloaterPreference::refreshEnabledState() LLCheckBoxCtrl* ctrl_pbr = getChild("UsePBRShaders"); //PBR - ctrl_pbr->setEnabled(TRUE); + ctrl_pbr->setEnabled(true); // Cannot have floater active until caps have been received getChild("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true); @@ -1325,7 +1325,7 @@ void LLFloaterPreference::onClickEnablePopup() for (itor = items.begin(); itor != items.end(); ++itor) { LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata())); - //gSavedSettings.setWarning(templatep->mName, TRUE); + //gSavedSettings.setWarning(templatep->mName, true); std::string notification_name = templatep->mName; LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(notification_name, true); } @@ -1476,28 +1476,28 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility) if (visibility == VISIBILITY_DEFAULT) { mOriginalHideOnlineStatus = false; - getChildView("online_visibility")->setEnabled(TRUE); + getChildView("online_visibility")->setEnabled(true); } else if (visibility == VISIBILITY_HIDDEN) { mOriginalHideOnlineStatus = true; - getChildView("online_visibility")->setEnabled(TRUE); + getChildView("online_visibility")->setEnabled(true); } else { mOriginalHideOnlineStatus = true; } - getChild("online_searchresults")->setEnabled(TRUE); - getChildView("friends_online_notify_checkbox")->setEnabled(TRUE); + getChild("online_searchresults")->setEnabled(true); + getChildView("friends_online_notify_checkbox")->setEnabled(true); getChild("online_visibility")->setValue(mOriginalHideOnlineStatus); getChild("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("voice_call_friends_only_check")->setEnabled(TRUE); + 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("voice_call_friends_only_check")->setEnabled(true); getChild("voice_call_friends_only_check")->setValue(gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly")); } @@ -1764,9 +1764,9 @@ void LLFloaterPreference::onAtmosShaderChange() 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") && + bool bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump"); + bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); + bool enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && bumpshiny && shaders; @@ -2010,28 +2010,28 @@ LLPanelPreference::LLPanelPreference() bool LLPanelPreference::postBuild() { ////////////////////// PanelGeneral /////////////////// - if (hasChild("display_names_check", TRUE)) + if (hasChild("display_names_check", true)) { - BOOL use_people_api = gSavedSettings.getBOOL("UsePeopleAPI"); + bool use_people_api = gSavedSettings.getBOOL("UsePeopleAPI"); LLCheckBoxCtrl* ctrl_display_name = getChild("display_names_check"); ctrl_display_name->setEnabled(use_people_api); if (!use_people_api) { - ctrl_display_name->setValue(FALSE); + ctrl_display_name->setValue(false); } } ////////////////////// PanelVoice /////////////////// - if (hasChild("voice_unavailable", TRUE)) + if (hasChild("voice_unavailable", true)) { - BOOL voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice"); + 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)) + if (hasChild("skin_selection", true)) { LLFloaterPreference::refreshSkin(this); @@ -2045,32 +2045,32 @@ bool LLPanelPreference::postBuild() } //////////////////////PanelPrivacy /////////////////// - if (hasChild("media_enabled", TRUE)) + if (hasChild("media_enabled", true)) { bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia"); getChild("media_enabled")->set(media_enabled); getChild("autoplay_enabled")->setEnabled(media_enabled); } - if (hasChild("music_enabled", TRUE)) + if (hasChild("music_enabled", true)) { getChild("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic")); } - if (hasChild("voice_call_friends_only_check", TRUE)) + if (hasChild("voice_call_friends_only_check", true)) { getChild("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2)); } - if (hasChild("allow_multiple_viewer_check", TRUE)) + if (hasChild("allow_multiple_viewer_check", true)) { getChild("allow_multiple_viewer_check")->setCommitCallback(boost::bind(&showMultipleViewersWarning, _1, _2)); } - if (hasChild("favorites_on_login_check", TRUE)) + if (hasChild("favorites_on_login_check", true)) { getChild("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2)); bool show_favorites_at_login = LLPanelLogin::getShowFavorites(); getChild("favorites_on_login_check")->setValue(show_favorites_at_login); } - if (hasChild("mute_chb_label", TRUE)) + if (hasChild("mute_chb_label", true)) { getChild("mute_chb_label")->setShowCursorHand(false); getChild("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP); @@ -2078,7 +2078,7 @@ bool LLPanelPreference::postBuild() } //////////////////////PanelSetup /////////////////// - if (hasChild("max_bandwidth", TRUE)) + 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)); @@ -2247,7 +2247,7 @@ void LLPanelPreference::setControlFalse(const LLSD& user_data) LLControlVariable* control = findControl(control_name); if (control) - control->set(LLSD(FALSE)); + control->set(LLSD(false)); } void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl) @@ -2847,7 +2847,7 @@ void LLPanelPreferenceControls::onListCommit() if (root_floater) root_floater->addDependentFloater(dialog); dialog->openFloater(); - dialog->setFocus(TRUE); + dialog->setFocus(true); } } else @@ -3285,9 +3285,9 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings() // Check for invalid states for the other HTTP proxy radio LLRadioGroup* otherHttpProxy = getChild("other_http_proxy_type"); if ((otherHttpProxy->getSelectedValue().asString() == "Socks" && - getChild("socks_proxy_enabled")->get() == FALSE )||( + getChild("socks_proxy_enabled")->get() == false )||( otherHttpProxy->getSelectedValue().asString() == "Web" && - getChild("web_proxy_enabled")->get() == FALSE ) ) + getChild("web_proxy_enabled")->get() == false ) ) { otherHttpProxy->selectFirstItem(); } -- cgit v1.2.3 From 609831b5d244c52a21aef438785cd7c090d4b242 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 13 Feb 2024 01:37:46 +0200 Subject: secondlife/triage#59 Show 'Friends Only' rendering mode --- indra/newview/llfloaterpreference.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5b4138e2e9..93292926b6 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -437,6 +437,12 @@ bool LLFloaterPreference::postBuild() 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)); @@ -476,6 +482,9 @@ bool LLFloaterPreference::postBuild() LLSliderCtrl* fov_slider = getChild("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("IndirectMaxComplexity")->setEnabled(enable_complexity); // Hook up and init for filtering mFilterEdit = getChild("search_prefs_edit"); @@ -1629,6 +1638,12 @@ void LLFloaterPreference::onChangeMaturity() getChild("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("IndirectMaxComplexity")->setEnabled(enable_complexity); +} + std::string get_category_path(LLUUID cat_id) { LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); -- cgit v1.2.3 From f9473e8afcb624cc1b101195bf15943ec372b56f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 6 May 2024 16:52:34 +0200 Subject: secondlife/viewer#1333 BOOL to bool conversion leftovers: ternaries --- indra/newview/llfloaterpreference.cpp | 86 +++++++++++++++++------------------ 1 file changed, 41 insertions(+), 45 deletions(-) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index b1db7bc4f4..b503fc3630 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1244,7 +1244,7 @@ void LLFloaterPreference::refreshEnabledState() ctrl_pbr->setEnabled(true); // Cannot have floater active until caps have been received - getChild("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true); + getChild("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() >= STATE_STARTED); getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess()); } @@ -3281,9 +3281,9 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings() // Check for invalid states for the other HTTP proxy radio LLRadioGroup* otherHttpProxy = getChild("other_http_proxy_type"); if ((otherHttpProxy->getSelectedValue().asString() == "Socks" && - getChild("socks_proxy_enabled")->get() == false )||( + !getChild("socks_proxy_enabled")->get())||( otherHttpProxy->getSelectedValue().asString() == "Web" && - getChild("web_proxy_enabled")->get() == false ) ) + !getChild("web_proxy_enabled")->get())) { otherHttpProxy->selectFirstItem(); } @@ -3292,10 +3292,10 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings() void LLFloaterPreference::onUpdateFilterTerm(bool force) { - LLWString seachValue = utf8str_to_wstring( mFilterEdit->getValue() ); - LLWStringUtil::toLower( seachValue ); + LLWString seachValue = utf8str_to_wstring(mFilterEdit->getValue()); + LLWStringUtil::toLower(seachValue); - if( !mSearchData || (mSearchData->mLastFilter == seachValue && !force)) + if (!mSearchData || (mSearchData->mLastFilter == seachValue && !force)) return; if (mSearchDataDirty) @@ -3306,14 +3306,13 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force) mSearchData->mLastFilter = seachValue; - if( !mSearchData->mRootTab ) + if (!mSearchData->mRootTab) return; mSearchData->mRootTab->hightlightAndHide( seachValue ); filterIgnorableNotifications(); - LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); - if( pRoot ) + if (LLTabContainer* pRoot = getChild("pref core")) pRoot->selectFirstTab(); } @@ -3330,72 +3329,69 @@ void LLFloaterPreference::filterIgnorableNotifications() void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer ) { - if( !aView ) + if (!aView) return; - llassert_always( aParentPanel || aParentTabContainer ); - - LLView::child_list_const_iter_t itr = aView->beginChild(); - LLView::child_list_const_iter_t itrEnd = aView->endChild(); + llassert_always(aParentPanel || aParentTabContainer); - while( itr != itrEnd ) + for (LLView* pView : *aView->getChildList()) { - LLView *pView = *itr; + if (!pView) + continue; + ll::prefs::PanelDataPtr pCurPanelData = aParentPanel; ll::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer; - if( !pView ) - continue; - 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 ) + LLPanel const *pPanel = dynamic_cast(pView); + LLTabContainer const *pTabContainer = dynamic_cast(pView); + ll::ui::SearchableControl const *pSCtrl = dynamic_cast( pView ); + + if (pTabContainer) { pCurPanelData.reset(); - pCurTabContainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData ); - pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>( pTabContainer ); + 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 ); + if (aParentPanel) + aParentPanel->mChildPanel.push_back(pCurTabContainer); + if (aParentTabContainer) + aParentTabContainer->mChildPanel.push_back(pCurTabContainer); } - else if( pPanel ) + else if (pPanel) { pCurTabContainer.reset(); - pCurPanelData = ll::prefs::PanelDataPtr( new ll::prefs::PanelData ); + 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 ); + if (aParentTabContainer) + aParentTabContainer->mChildPanel.push_back(pCurPanelData); + else if (aParentPanel) + aParentPanel->mChildPanel.push_back(pCurPanelData); } - else if( pSCtrl && pSCtrl->getSearchText().size() ) + else if (pSCtrl && pSCtrl->getSearchText().size()) { - ll::prefs::SearchableItemPtr item = ll::prefs::SearchableItemPtr( new ll::prefs::SearchableItem() ); + 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 ); + item->mLabel = utf8str_to_wstring(pSCtrl->getSearchText()); + LLWStringUtil::toLower(item->mLabel); - llassert_always( aParentPanel || aParentTabContainer ); + llassert_always(aParentPanel || aParentTabContainer); - if( aParentPanel ) - aParentPanel->mChildren.push_back( item ); - if( aParentTabContainer ) - aParentTabContainer->mChildren.push_back( item ); + if (aParentPanel) + aParentPanel->mChildren.push_back(item); + if (aParentTabContainer) + aParentTabContainer->mChildren.push_back(item); } - collectChildren( pView, pCurPanelData, pCurTabContainer ); - ++itr; + collectChildren(pView, pCurPanelData, pCurTabContainer); } } -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/newview/llfloaterpreference.cpp | 6872 ++++++++++++++++----------------- 1 file changed, 3436 insertions(+), 3436 deletions(-) (limited to 'indra/newview/llfloaterpreference.cpp') diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 3ed3abce58..85a07f23a4 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1,3436 +1,3436 @@ -/** - * @file llfloaterpreference.cpp - * @brief Global preferences with and without persistence. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -/* - * App-wide preferences. Note that these are not per-user, - * because we need to load many preferences before we have - * a login name. - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterpreference.h" - -#include "message.h" -#include "llfloaterautoreplacesettings.h" -#include "llagent.h" -#include "llagentcamera.h" -#include "llcheckboxctrl.h" -#include "llcolorswatch.h" -#include "llcombobox.h" -#include "llcommandhandler.h" -#include "lldirpicker.h" -#include "lleventtimer.h" -#include "llfeaturemanager.h" -#include "llfocusmgr.h" -//#include "llfirstuse.h" -#include "llfloaterreg.h" -#include "llfloaterabout.h" -#include "llfavoritesbar.h" -#include "llfloaterpreferencesgraphicsadvanced.h" -#include "llfloaterperformance.h" -#include "llfloatersidepanelcontainer.h" -#include "llfloaterimsession.h" -#include "llkeyboard.h" -#include "llmodaldialog.h" -#include "llnavigationbar.h" -#include "llfloaterimnearbychat.h" -#include "llnotifications.h" -#include "llnotificationsutil.h" -#include "llnotificationtemplate.h" -#include "llpanellogin.h" -#include "llpanelvoicedevicesettings.h" -#include "llradiogroup.h" -#include "llsearchcombobox.h" -#include "llsky.h" -#include "llscrolllistctrl.h" -#include "llscrolllistitem.h" -#include "llsliderctrl.h" -#include "lltabcontainer.h" -#include "lltrans.h" -#include "llviewercontrol.h" -#include "llviewercamera.h" -#include "llviewereventrecorder.h" -#include "llviewermessage.h" -#include "llviewerwindow.h" -#include "llviewerthrottle.h" -#include "llvoavatarself.h" -#include "llvotree.h" -#include "llfloaterpathfindingconsole.h" -// linden library includes -#include "llavatarnamecache.h" -#include "llerror.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llstring.h" - -// project includes - -#include "llbutton.h" -#include "llflexibleobject.h" -#include "lllineeditor.h" -#include "llresmgr.h" -#include "llspinctrl.h" -#include "llstartup.h" -#include "lltextbox.h" -#include "llui.h" -#include "llviewerobjectlist.h" -#include "llvovolume.h" -#include "llwindow.h" -#include "llworld.h" -#include "lluictrlfactory.h" -#include "llviewermedia.h" -#include "llpluginclassmedia.h" -#include "llteleporthistorystorage.h" -#include "llproxy.h" -#include "llweb.h" - -#include "lllogininstance.h" // to check if logged in yet -#include "llsdserialize.h" -#include "llpresetsmanager.h" -#include "llviewercontrol.h" -#include "llpresetsmanager.h" -#include "llinventoryfunctions.h" - -#include "llsearchableui.h" -#include "llperfstats.h" - -const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f; -char const* const VISIBILITY_DEFAULT = "default"; -char const* const VISIBILITY_HIDDEN = "hidden"; - -//control value for middle mouse as talk2push button -const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; // for voice client and redability -const static std::string MOUSE_BUTTON_4_CV = "MouseButton4"; -const static std::string MOUSE_BUTTON_5_CV = "MouseButton5"; - -/// This must equal the maximum value set for the IndirectMaxComplexity slider in panel_preferences_graphics1.xml -static const U32 INDIRECT_MAX_ARC_OFF = 101; // all the way to the right == disabled -static const U32 MIN_INDIRECT_ARC_LIMIT = 1; // must match minimum of IndirectMaxComplexity in panel_preferences_graphics1.xml -static const U32 MAX_INDIRECT_ARC_LIMIT = INDIRECT_MAX_ARC_OFF-1; // one short of all the way to the right... - -/// These are the effective range of values for RenderAvatarMaxComplexity -static const F32 MIN_ARC_LIMIT = 20000.0f; -static const F32 MAX_ARC_LIMIT = 350000.0f; -static const F32 MIN_ARC_LOG = log(MIN_ARC_LIMIT); -static const F32 MAX_ARC_LOG = log(MAX_ARC_LIMIT); -static const F32 ARC_LIMIT_MAP_SCALE = (MAX_ARC_LOG - MIN_ARC_LOG) / (MAX_INDIRECT_ARC_LIMIT - MIN_INDIRECT_ARC_LIMIT); - -struct LabelDef : public LLInitParam::Block -{ - Mandatory name; - Mandatory value; - - LabelDef() - : name("name"), - value("value") - {} -}; - -struct LabelTable : public LLInitParam::Block -{ - Multiple 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("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 - (LLFloaterReg::showInstance("preferences")); - - if (prefsfloater) - { - // find 'controls' panel and bring it the front - LLTabContainer* tabcontainer = prefsfloater->getChild("pref core"); - LLPanel* panel = prefsfloater->getChild("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); - - static bool registered_dialog = false; - if (!registered_dialog) - { - LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - 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)); // Hook up for filtering -} - -void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type ) -{ - if ( APT_PROPERTIES_LEGACY == type ) - { - const LLAvatarLegacyData* pAvatarData = static_cast( pData ); - if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null)) - { - mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH); - mAvatarDataInitialized = true; - getChild("online_searchresults")->setValue(mAllowPublish); - } - } -} - -void LLFloaterPreference::saveAvatarProperties( void ) -{ - const bool allowPublish = getChild("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("pref core"); - if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) - tabcontainer->selectFirstTab(); - - getChild("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("log_path_string")->setEnabled(false); // make it read-only but selectable - - getChild("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this)); - - getChild("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions")); - getChild("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions")); - getChild("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions")); - getChild("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions")); - getChild("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions")); - getChild("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("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("IndirectMaxComplexity")->setEnabled(enable_complexity); - - // Hook up and init for filtering - mFilterEdit = getChild("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 labels; - if (loadFromFilename(user_filename, labels)) - { - std::string system_lang = gSavedSettings.getString("SystemLanguage"); - std::map::iterator iter = labels.find(system_lang); - if (iter != labels.end()) - { - getChild("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("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("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true); - } - - return true; -} - -void LLFloaterPreference::updateDeleteTranscriptsButton() -{ - getChild("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("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("disabled_popups").getFirstSelected()!=NULL); - gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected); - - has_first_selected = (getChildRef("enabled_popups").getFirstSelected()!=NULL); - gSavedSettings.setBOOL("FirstSelectedEnabledPopups", has_first_selected); - - LLFloater::draw(); -} - -void LLFloaterPreference::saveSettings() -{ - LLTabContainer* tabcontainer = getChild("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(view); - if (panel) - panel->saveSettings(); - } - saveIgnoredNotifications(); -} - -void LLFloaterPreference::apply() -{ - LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this ); - - LLTabContainer* tabcontainer = getChild("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(view); - if (panel) - panel->apply(); - } - - gViewerWindow->requestResolutionUpdate(); // for UIScaleFactor - - LLSliderCtrl* fov_slider = getChild("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("cookies_enabled")->getValue()); - - if (hasChild("web_proxy_enabled", true) &&hasChild("web_proxy_editor", true) && hasChild("web_proxy_port", true)) - { - bool proxy_enable = getChild("web_proxy_enabled")->getValue(); - std::string proxy_address = getChild("web_proxy_editor")->getValue(); - int proxy_port = getChild("web_proxy_port")->getValue(); - LLViewerMedia::getInstance()->setProxyConfig(proxy_enable, proxy_address, proxy_port); - } - - if (mGotPersonalInfo) - { - bool new_hide_online = getChild("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 settings_to_skip) -{ - LLTabContainer* tabcontainer = getChild("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(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("prefs_proxy"); - if (advanced_proxy_settings) - { - advanced_proxy_settings->cancel(); - } - //Need to reload the navmesh if the pathing console is up - LLHandle 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("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("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("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("PrefLoadButton"); - LLButton* save_btn = findChild("PrefSaveButton"); - LLButton* delete_btn = findChild("PrefDeleteButton"); - LLButton* exceptions_btn = findChild("RenderExceptionsButton"); - LLButton* auto_adjustments_btn = findChild("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("preferences"); - if (instance) - { - instance->getChild("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("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(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& names) -{ - LLView* view = findChild("display"); - LLFloater* advanced = LLFloaterReg::findTypedInstance("prefs_graphics_advanced"); - if (view && advanced) - { - std::list 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(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("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(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 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(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("preferences"); - if (instance) - { - instance->setPersonalInfo(visibility); - } -} - -void LLFloaterPreference::refreshEnabledGraphics() -{ - LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); - if (instance) - { - instance->refresh(); - } - - LLFloater* advanced = LLFloaterReg::findTypedInstance("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(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("notifications_alert")->setVisible(show_notifications_alert); -} - -void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue) -{ - LLColorSwatchCtrl* color_swatch = findChild("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& 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("skin_selection")->getValue().asString(); - gSavedSettings.setString("SkinCurrent", skin_selection); -} - -void LLFloaterPreference::refreshSkin(void* data) -{ - LLPanel*self = (LLPanel*)data; - sSkin = gSavedSettings.getString("SkinCurrent"); - self->getChild("skin_selection", true)->setValue(sSkin); -} - -void LLFloaterPreference::buildPopupLists() -{ - LLScrollListCtrl& disabled_popups = - getChildRef("disabled_popups"); - LLScrollListCtrl& enabled_popups = - getChildRef("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("UsePBRShaders"); - - //PBR - ctrl_pbr->setEnabled(true); - - // Cannot have floater active until caps have been received - getChild("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 - * 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("IndirectMaxComplexityText", true)); - refreshEnabledState(); - LLFloater* advanced = LLFloaterReg::findTypedInstance("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("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds")); -} - -void LLFloaterPreference::onClickEnablePopup() -{ - LLScrollListCtrl& disabled_popups = getChildRef("disabled_popups"); - - std::vector items = disabled_popups.getAllSelected(); - std::vector::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("enabled_popups"); - - std::vector items = enabled_popups.getAllSelected(); - std::vector::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& 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 listOfTranscripts; - std::vector 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("online_searchresults")->setEnabled(true); - getChildView("friends_online_notify_checkbox")->setEnabled(true); - getChild("online_visibility")->setValue(mOriginalHideOnlineStatus); - getChild("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("voice_call_friends_only_check")->setEnabled(true); - getChild("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("IndirectMaxComplexity"), - getChild("IndirectMaxComplexityText")); -} - -void LLFloaterPreference::updateComplexityText() -{ - LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), - getChild("IndirectMaxComplexityText", true)); -} - -bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map &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::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("rating_icon_general")->setVisible(sim_access == SIM_ACCESS_PG - || sim_access == SIM_ACCESS_MATURE - || sim_access == SIM_ACCESS_ADULT); - - getChild("rating_icon_moderate")->setVisible(sim_access == SIM_ACCESS_MATURE - || sim_access == SIM_ACCESS_ADULT); - - getChild("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("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("upload_models")->setText(get_category_path(LLFolderType::FT_OBJECT)); - } -} - -void LLFloaterPreference::onChangePBRFolder() -{ - if (gInventory.isInventoryUsable()) - { - getChild("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL)); - } -} - -void LLFloaterPreference::onChangeTextureFolder() -{ - if (gInventory.isInventoryUsable()) - { - getChild("upload_textures")->setText(get_category_path(LLFolderType::FT_TEXTURE)); - } -} - -void LLFloaterPreference::onChangeSoundFolder() -{ - if (gInventory.isInventoryUsable()) - { - getChild("upload_sounds")->setText(get_category_path(LLFolderType::FT_SOUND)); - } -} - -void LLFloaterPreference::onChangeAnimationFolder() -{ - if (gInventory.isInventoryUsable()) - { - getChild("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("performance"); - if (performance_floater) - { - performance_floater->showAutoadjustmentsPanel(); - } -} - -void LLFloaterPreference::onClickAdvanced() -{ - LLFloaterReg::showInstance("prefs_graphics_advanced"); - - LLTabContainer* tabcontainer = getChild("pref core"); - for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin(); - iter != tabcontainer->getChildList()->end(); ++iter) - { - LLView* view = *iter; - LLPanelPreferenceGraphics* panel = dynamic_cast(view); - if (panel) - { - panel->resetDirtyChilds(); - } - } -} - -void LLFloaterPreference::onClickActionChange() -{ - updateClickActionControls(); -} - -void LLFloaterPreference::onAtmosShaderChange() -{ - LLCheckBoxCtrl* ctrl_alm = getChild("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("delete_transcripts"); - - if (!delete_transcripts_buttonp->getEnabled()) - { - delete_transcripts_buttonp->setEnabled(true); - } -} - -void LLFloaterPreference::updateClickActionControls() -{ - const int single_clk_action = getChild("single_click_action_combo")->getValue().asInteger(); - const int double_clk_action = getChild("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("pref core"); - for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin(); - iter != tabcontainer->getChildList()->end(); ++iter) - { - LLView* view = *iter; - LLPanelPreferenceControls* panel = dynamic_cast(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("pref core"); - for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin(); - iter != tabcontainer->getChildList()->end(); ++iter) - { - LLView* view = *iter; - LLPanelPreferenceControls* panel = dynamic_cast(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("single_click_action_combo")->setValue((int)click_to_walk); - getChild("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("cache_location"); - cache_location_editor->setValue(location); - cache_location_editor->setToolTip(location); -} - -void LLFloaterPreference::selectPanel(const LLSD& name) -{ - LLTabContainer * tab_containerp = getChild("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("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 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 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("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("skin_selection")->getSelectedIndex() < 0) - { - gSavedSettings.setString("SkinCurrent", "default"); - LLFloaterPreference::refreshSkin(this); - } - - } - - //////////////////////PanelPrivacy /////////////////// - if (hasChild("media_enabled", true)) - { - bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia"); - - getChild("media_enabled")->set(media_enabled); - getChild("autoplay_enabled")->setEnabled(media_enabled); - } - if (hasChild("music_enabled", true)) - { - getChild("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic")); - } - if (hasChild("voice_call_friends_only_check", true)) - { - getChild("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2)); - } - if (hasChild("allow_multiple_viewer_check", true)) - { - getChild("allow_multiple_viewer_check")->setCommitCallback(boost::bind(&showMultipleViewersWarning, _1, _2)); - } - if (hasChild("favorites_on_login_check", true)) - { - getChild("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2)); - bool show_favorites_at_login = LLPanelLogin::getShowFavorites(); - getChild("favorites_on_login_check")->setValue(show_favorites_at_login); - } - if (hasChild("mute_chb_label", true)) - { - getChild("mute_chb_label")->setShowCursorHand(false); - getChild("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP); - getChild("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("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("prefs_graphics_advanced"); - - // Save the value of all controls in the hierarchy - mSavedValues.clear(); - std::list 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(curview); - if (color_swatch) - { - mSavedColors[color_swatch->getName()] = color_swatch->get(); - } - else - { - LLUICtrl* ctrl = dynamic_cast(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("preferences"); - if (instance) - { - instance->getChild("mute_when_minimized")->setBtnFocus(); - } -} - -void LLPanelPreference::cancel(const std::vector 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(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("enable_music")->get(); - bool media_enabled = getChild("enable_media")->get(); - - getChild("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 mAccountIndependentSettings; -}; - -static LLPanelInjector t_pref_graph("panel_preference_graphics"); -static LLPanelInjector 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("preferences"); - if (instance && !gSavedSettings.getString("PresetGraphicActive").empty()) - { - instance->saveSettings(); //make cancel work correctly after changing the preset - } -} - -void LLPanelPreferenceGraphics::setPresetText() -{ - LLTextBox* preset_text = getChild("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("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("prefs_graphics_advanced"); - std::list 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(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("prefs_graphics_advanced"); - std::list 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(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 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("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 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("controls_list"); - pKeyModeBox = getChild("key_mode"); - - pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this)); - pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this)); - getChild("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::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::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: - // - // - // - 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("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("preferences"); - if (instance) - { - instance->updateSearchableItems(); - } -} - -void LLPanelPreferenceControls::updateTable() -{ - mEditingControl.clear(); - std::vector 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 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("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("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("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("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("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("socks5_auth_type"); - if (!socksAuth) - { - return false; - } - if (socksAuth->getSelectedValue().asString() == "None") - { - getChild("socks5_username")->setEnabled(false); - getChild("socks5_password")->setEnabled(false); - } - else - { - // Populate the SOCKS 5 credential fields with protected values. - LLPointer socks_cred = gSecAPIHandler->loadCredential("SOCKS5"); - getChild("socks5_username")->setValue(socks_cred->getIdentifier()["username"].asString()); - getChild("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 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(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(gFocusMgr.getKeyboardFocus()); - if (cur_focus && cur_focus->acceptsTextInput()) - { - cur_focus->onCommit(); - } - } - - // Save SOCKS proxy credentials securely if password auth is enabled - LLRadioGroup* socksAuth = getChild("socks5_auth_type"); - if (socksAuth->getSelectedValue().asString() == "UserPass") - { - LLSD socks_id = LLSD::emptyMap(); - socks_id["type"] = "SOCKS5"; - socks_id["username"] = getChild("socks5_username")->getValue().asString(); - - LLSD socks_authenticator = LLSD::emptyMap(); - socks_authenticator["type"] = "SOCKS5"; - socks_authenticator["creds"] = getChild("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 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 socks_cred = new LLCredential("SOCKS5"); - gSecAPIHandler->deleteCredential(socks_cred); - } - - closeFloater(false); -} - -void LLFloaterPreferenceProxy::onBtnCancel() -{ - if (hasFocus()) - { - LLUICtrl* cur_focus = dynamic_cast(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("socks5_auth_type"); - if (socksAuth->getSelectedValue().asString() == "None") - { - getChild("socks5_username")->setEnabled(false); - getChild("socks5_password")->setEnabled(false); - } - else - { - getChild("socks5_username")->setEnabled(true); - getChild("socks5_password")->setEnabled(true); - } - - // Check for invalid states for the other HTTP proxy radio - LLRadioGroup* otherHttpProxy = getChild("other_http_proxy_type"); - if ((otherHttpProxy->getSelectedValue().asString() == "Socks" && - !getChild("socks_proxy_enabled")->get())||( - otherHttpProxy->getSelectedValue().asString() == "Web" && - !getChild("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("pref core")) - pRoot->selectFirstTab(); -} - -void LLFloaterPreference::filterIgnorableNotifications() -{ - bool visible = getChildRef("enabled_popups").highlightMatchingItems(mFilterEdit->getValue()); - visible |= getChildRef("disabled_popups").highlightMatchingItems(mFilterEdit->getValue()); - - if (visible) - { - getChildRef("pref core").setTabVisibility( getChild("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(pView); - LLTabContainer const *pTabContainer = dynamic_cast(pView); - ll::ui::SearchableControl const *pSCtrl = dynamic_cast( 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::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 +{ + Mandatory name; + Mandatory value; + + LabelDef() + : name("name"), + value("value") + {} +}; + +struct LabelTable : public LLInitParam::Block +{ + Multiple 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("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 + (LLFloaterReg::showInstance("preferences")); + + if (prefsfloater) + { + // find 'controls' panel and bring it the front + LLTabContainer* tabcontainer = prefsfloater->getChild("pref core"); + LLPanel* panel = prefsfloater->getChild("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); + + static bool registered_dialog = false; + if (!registered_dialog) + { + LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + 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)); // Hook up for filtering +} + +void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type ) +{ + if ( APT_PROPERTIES_LEGACY == type ) + { + const LLAvatarLegacyData* pAvatarData = static_cast( pData ); + if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null)) + { + mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH); + mAvatarDataInitialized = true; + getChild("online_searchresults")->setValue(mAllowPublish); + } + } +} + +void LLFloaterPreference::saveAvatarProperties( void ) +{ + const bool allowPublish = getChild("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("pref core"); + if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) + tabcontainer->selectFirstTab(); + + getChild("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("log_path_string")->setEnabled(false); // make it read-only but selectable + + getChild("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this)); + + getChild("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions")); + getChild("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions")); + getChild("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions")); + getChild("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions")); + getChild("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions")); + getChild("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("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("IndirectMaxComplexity")->setEnabled(enable_complexity); + + // Hook up and init for filtering + mFilterEdit = getChild("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 labels; + if (loadFromFilename(user_filename, labels)) + { + std::string system_lang = gSavedSettings.getString("SystemLanguage"); + std::map::iterator iter = labels.find(system_lang); + if (iter != labels.end()) + { + getChild("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("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("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true); + } + + return true; +} + +void LLFloaterPreference::updateDeleteTranscriptsButton() +{ + getChild("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("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("disabled_popups").getFirstSelected()!=NULL); + gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected); + + has_first_selected = (getChildRef("enabled_popups").getFirstSelected()!=NULL); + gSavedSettings.setBOOL("FirstSelectedEnabledPopups", has_first_selected); + + LLFloater::draw(); +} + +void LLFloaterPreference::saveSettings() +{ + LLTabContainer* tabcontainer = getChild("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(view); + if (panel) + panel->saveSettings(); + } + saveIgnoredNotifications(); +} + +void LLFloaterPreference::apply() +{ + LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this ); + + LLTabContainer* tabcontainer = getChild("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(view); + if (panel) + panel->apply(); + } + + gViewerWindow->requestResolutionUpdate(); // for UIScaleFactor + + LLSliderCtrl* fov_slider = getChild("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("cookies_enabled")->getValue()); + + if (hasChild("web_proxy_enabled", true) &&hasChild("web_proxy_editor", true) && hasChild("web_proxy_port", true)) + { + bool proxy_enable = getChild("web_proxy_enabled")->getValue(); + std::string proxy_address = getChild("web_proxy_editor")->getValue(); + int proxy_port = getChild("web_proxy_port")->getValue(); + LLViewerMedia::getInstance()->setProxyConfig(proxy_enable, proxy_address, proxy_port); + } + + if (mGotPersonalInfo) + { + bool new_hide_online = getChild("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 settings_to_skip) +{ + LLTabContainer* tabcontainer = getChild("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(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("prefs_proxy"); + if (advanced_proxy_settings) + { + advanced_proxy_settings->cancel(); + } + //Need to reload the navmesh if the pathing console is up + LLHandle 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("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("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("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("PrefLoadButton"); + LLButton* save_btn = findChild("PrefSaveButton"); + LLButton* delete_btn = findChild("PrefDeleteButton"); + LLButton* exceptions_btn = findChild("RenderExceptionsButton"); + LLButton* auto_adjustments_btn = findChild("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("preferences"); + if (instance) + { + instance->getChild("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("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(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& names) +{ + LLView* view = findChild("display"); + LLFloater* advanced = LLFloaterReg::findTypedInstance("prefs_graphics_advanced"); + if (view && advanced) + { + std::list 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(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("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(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 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(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("preferences"); + if (instance) + { + instance->setPersonalInfo(visibility); + } +} + +void LLFloaterPreference::refreshEnabledGraphics() +{ + LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); + if (instance) + { + instance->refresh(); + } + + LLFloater* advanced = LLFloaterReg::findTypedInstance("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(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("notifications_alert")->setVisible(show_notifications_alert); +} + +void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue) +{ + LLColorSwatchCtrl* color_swatch = findChild("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& 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("skin_selection")->getValue().asString(); + gSavedSettings.setString("SkinCurrent", skin_selection); +} + +void LLFloaterPreference::refreshSkin(void* data) +{ + LLPanel*self = (LLPanel*)data; + sSkin = gSavedSettings.getString("SkinCurrent"); + self->getChild("skin_selection", true)->setValue(sSkin); +} + +void LLFloaterPreference::buildPopupLists() +{ + LLScrollListCtrl& disabled_popups = + getChildRef("disabled_popups"); + LLScrollListCtrl& enabled_popups = + getChildRef("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("UsePBRShaders"); + + //PBR + ctrl_pbr->setEnabled(true); + + // Cannot have floater active until caps have been received + getChild("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 + * 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("IndirectMaxComplexityText", true)); + refreshEnabledState(); + LLFloater* advanced = LLFloaterReg::findTypedInstance("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("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds")); +} + +void LLFloaterPreference::onClickEnablePopup() +{ + LLScrollListCtrl& disabled_popups = getChildRef("disabled_popups"); + + std::vector items = disabled_popups.getAllSelected(); + std::vector::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("enabled_popups"); + + std::vector items = enabled_popups.getAllSelected(); + std::vector::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& 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 listOfTranscripts; + std::vector 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("online_searchresults")->setEnabled(true); + getChildView("friends_online_notify_checkbox")->setEnabled(true); + getChild("online_visibility")->setValue(mOriginalHideOnlineStatus); + getChild("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("voice_call_friends_only_check")->setEnabled(true); + getChild("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("IndirectMaxComplexity"), + getChild("IndirectMaxComplexityText")); +} + +void LLFloaterPreference::updateComplexityText() +{ + LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), + getChild("IndirectMaxComplexityText", true)); +} + +bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map &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::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("rating_icon_general")->setVisible(sim_access == SIM_ACCESS_PG + || sim_access == SIM_ACCESS_MATURE + || sim_access == SIM_ACCESS_ADULT); + + getChild("rating_icon_moderate")->setVisible(sim_access == SIM_ACCESS_MATURE + || sim_access == SIM_ACCESS_ADULT); + + getChild("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("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("upload_models")->setText(get_category_path(LLFolderType::FT_OBJECT)); + } +} + +void LLFloaterPreference::onChangePBRFolder() +{ + if (gInventory.isInventoryUsable()) + { + getChild("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL)); + } +} + +void LLFloaterPreference::onChangeTextureFolder() +{ + if (gInventory.isInventoryUsable()) + { + getChild("upload_textures")->setText(get_category_path(LLFolderType::FT_TEXTURE)); + } +} + +void LLFloaterPreference::onChangeSoundFolder() +{ + if (gInventory.isInventoryUsable()) + { + getChild("upload_sounds")->setText(get_category_path(LLFolderType::FT_SOUND)); + } +} + +void LLFloaterPreference::onChangeAnimationFolder() +{ + if (gInventory.isInventoryUsable()) + { + getChild("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("performance"); + if (performance_floater) + { + performance_floater->showAutoadjustmentsPanel(); + } +} + +void LLFloaterPreference::onClickAdvanced() +{ + LLFloaterReg::showInstance("prefs_graphics_advanced"); + + LLTabContainer* tabcontainer = getChild("pref core"); + for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin(); + iter != tabcontainer->getChildList()->end(); ++iter) + { + LLView* view = *iter; + LLPanelPreferenceGraphics* panel = dynamic_cast(view); + if (panel) + { + panel->resetDirtyChilds(); + } + } +} + +void LLFloaterPreference::onClickActionChange() +{ + updateClickActionControls(); +} + +void LLFloaterPreference::onAtmosShaderChange() +{ + LLCheckBoxCtrl* ctrl_alm = getChild("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("delete_transcripts"); + + if (!delete_transcripts_buttonp->getEnabled()) + { + delete_transcripts_buttonp->setEnabled(true); + } +} + +void LLFloaterPreference::updateClickActionControls() +{ + const int single_clk_action = getChild("single_click_action_combo")->getValue().asInteger(); + const int double_clk_action = getChild("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("pref core"); + for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin(); + iter != tabcontainer->getChildList()->end(); ++iter) + { + LLView* view = *iter; + LLPanelPreferenceControls* panel = dynamic_cast(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("pref core"); + for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin(); + iter != tabcontainer->getChildList()->end(); ++iter) + { + LLView* view = *iter; + LLPanelPreferenceControls* panel = dynamic_cast(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("single_click_action_combo")->setValue((int)click_to_walk); + getChild("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("cache_location"); + cache_location_editor->setValue(location); + cache_location_editor->setToolTip(location); +} + +void LLFloaterPreference::selectPanel(const LLSD& name) +{ + LLTabContainer * tab_containerp = getChild("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("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 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 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("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("skin_selection")->getSelectedIndex() < 0) + { + gSavedSettings.setString("SkinCurrent", "default"); + LLFloaterPreference::refreshSkin(this); + } + + } + + //////////////////////PanelPrivacy /////////////////// + if (hasChild("media_enabled", true)) + { + bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia"); + + getChild("media_enabled")->set(media_enabled); + getChild("autoplay_enabled")->setEnabled(media_enabled); + } + if (hasChild("music_enabled", true)) + { + getChild("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic")); + } + if (hasChild("voice_call_friends_only_check", true)) + { + getChild("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2)); + } + if (hasChild("allow_multiple_viewer_check", true)) + { + getChild("allow_multiple_viewer_check")->setCommitCallback(boost::bind(&showMultipleViewersWarning, _1, _2)); + } + if (hasChild("favorites_on_login_check", true)) + { + getChild("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2)); + bool show_favorites_at_login = LLPanelLogin::getShowFavorites(); + getChild("favorites_on_login_check")->setValue(show_favorites_at_login); + } + if (hasChild("mute_chb_label", true)) + { + getChild("mute_chb_label")->setShowCursorHand(false); + getChild("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP); + getChild("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("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("prefs_graphics_advanced"); + + // Save the value of all controls in the hierarchy + mSavedValues.clear(); + std::list 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(curview); + if (color_swatch) + { + mSavedColors[color_swatch->getName()] = color_swatch->get(); + } + else + { + LLUICtrl* ctrl = dynamic_cast(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("preferences"); + if (instance) + { + instance->getChild("mute_when_minimized")->setBtnFocus(); + } +} + +void LLPanelPreference::cancel(const std::vector 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(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("enable_music")->get(); + bool media_enabled = getChild("enable_media")->get(); + + getChild("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 mAccountIndependentSettings; +}; + +static LLPanelInjector t_pref_graph("panel_preference_graphics"); +static LLPanelInjector 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("preferences"); + if (instance && !gSavedSettings.getString("PresetGraphicActive").empty()) + { + instance->saveSettings(); //make cancel work correctly after changing the preset + } +} + +void LLPanelPreferenceGraphics::setPresetText() +{ + LLTextBox* preset_text = getChild("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("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("prefs_graphics_advanced"); + std::list 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(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("prefs_graphics_advanced"); + std::list 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(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 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("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 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("controls_list"); + pKeyModeBox = getChild("key_mode"); + + pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this)); + pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this)); + getChild("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::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::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: + // + // + // + 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("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("preferences"); + if (instance) + { + instance->updateSearchableItems(); + } +} + +void LLPanelPreferenceControls::updateTable() +{ + mEditingControl.clear(); + std::vector 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 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("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("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("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("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("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("socks5_auth_type"); + if (!socksAuth) + { + return false; + } + if (socksAuth->getSelectedValue().asString() == "None") + { + getChild("socks5_username")->setEnabled(false); + getChild("socks5_password")->setEnabled(false); + } + else + { + // Populate the SOCKS 5 credential fields with protected values. + LLPointer socks_cred = gSecAPIHandler->loadCredential("SOCKS5"); + getChild("socks5_username")->setValue(socks_cred->getIdentifier()["username"].asString()); + getChild("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 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(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(gFocusMgr.getKeyboardFocus()); + if (cur_focus && cur_focus->acceptsTextInput()) + { + cur_focus->onCommit(); + } + } + + // Save SOCKS proxy credentials securely if password auth is enabled + LLRadioGroup* socksAuth = getChild("socks5_auth_type"); + if (socksAuth->getSelectedValue().asString() == "UserPass") + { + LLSD socks_id = LLSD::emptyMap(); + socks_id["type"] = "SOCKS5"; + socks_id["username"] = getChild("socks5_username")->getValue().asString(); + + LLSD socks_authenticator = LLSD::emptyMap(); + socks_authenticator["type"] = "SOCKS5"; + socks_authenticator["creds"] = getChild("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 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 socks_cred = new LLCredential("SOCKS5"); + gSecAPIHandler->deleteCredential(socks_cred); + } + + closeFloater(false); +} + +void LLFloaterPreferenceProxy::onBtnCancel() +{ + if (hasFocus()) + { + LLUICtrl* cur_focus = dynamic_cast(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("socks5_auth_type"); + if (socksAuth->getSelectedValue().asString() == "None") + { + getChild("socks5_username")->setEnabled(false); + getChild("socks5_password")->setEnabled(false); + } + else + { + getChild("socks5_username")->setEnabled(true); + getChild("socks5_password")->setEnabled(true); + } + + // Check for invalid states for the other HTTP proxy radio + LLRadioGroup* otherHttpProxy = getChild("other_http_proxy_type"); + if ((otherHttpProxy->getSelectedValue().asString() == "Socks" && + !getChild("socks_proxy_enabled")->get())||( + otherHttpProxy->getSelectedValue().asString() == "Web" && + !getChild("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("pref core")) + pRoot->selectFirstTab(); +} + +void LLFloaterPreference::filterIgnorableNotifications() +{ + bool visible = getChildRef("enabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + visible |= getChildRef("disabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + + if (visible) + { + getChildRef("pref core").setTabVisibility( getChild("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(pView); + LLTabContainer const *pTabContainer = dynamic_cast(pView); + ll::ui::SearchableControl const *pSCtrl = dynamic_cast( 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::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it) + { + LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second); + } +} -- cgit v1.2.3