From 6d1296f71640c9c25affcff4e784ea5798ba2d5c Mon Sep 17 00:00:00 2001
From: Jonathan Yap <jhwelch@gmail.com>
Date: Mon, 1 Dec 2014 08:09:17 -0500
Subject: [PATCH] STORM-2082 Implement save floater and some code cleanup.

---
 indra/newview/CMakeLists.txt                  |  2 +
 indra/newview/llfloaterdeleteprefpreset.cpp   | 12 ++-
 indra/newview/llfloaterdeleteprefpreset.h     |  2 +-
 indra/newview/llfloaterpreference.cpp         | 25 +++--
 indra/newview/llfloaterpreference.h           |  5 +-
 indra/newview/llfloatersaveprefpreset.cpp     | 97 +++++++++++++++++++
 indra/newview/llfloatersaveprefpreset.h       | 57 +++++++++++
 indra/newview/llpresetsmanager.cpp            | 41 +++-----
 indra/newview/llpresetsmanager.h              |  4 +-
 indra/newview/llviewerfloaterreg.cpp          |  2 +
 .../xui/en/floater_save_pref_preset.xml       | 50 ++++++++++
 .../skins/default/xui/en/notifications.xml    | 14 +++
 .../xui/en/panel_preferences_graphics1.xml    |  6 +-
 13 files changed, 274 insertions(+), 43 deletions(-)
 create mode 100644 indra/newview/llfloatersaveprefpreset.cpp
 create mode 100644 indra/newview/llfloatersaveprefpreset.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_save_pref_preset.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 213446ccfb7..57fa11a0bfb 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -279,6 +279,7 @@ set(viewer_SOURCE_FILES
     llfloaterregioninfo.cpp
     llfloaterreporter.cpp
     llfloaterregionrestarting.cpp
+    llfloatersaveprefpreset.cpp
     llfloatersceneloadstats.cpp
     llfloaterscriptdebug.cpp
     llfloaterscriptedprefs.cpp
@@ -890,6 +891,7 @@ set(viewer_HEADER_FILES
     llfloaterregioninfo.h
     llfloaterreporter.h
     llfloaterregionrestarting.h
+    llfloatersaveprefpreset.h
     llfloatersceneloadstats.h
     llfloaterscriptdebug.h
     llfloaterscriptedprefs.h
diff --git a/indra/newview/llfloaterdeleteprefpreset.cpp b/indra/newview/llfloaterdeleteprefpreset.cpp
index bef5b4e3bf5..74f8805d039 100644
--- a/indra/newview/llfloaterdeleteprefpreset.cpp
+++ b/indra/newview/llfloaterdeleteprefpreset.cpp
@@ -28,9 +28,11 @@
 
 #include "llfloaterdeleteprefpreset.h"
 
+#include "llpresetsmanager.h"
+
 #include "llbutton.h"
 #include "llcombobox.h"
-#include "llpresetsmanager.h"
+#include "llnotificationsutil.h"
 
 LLFloaterDeletePrefPreset::LLFloaterDeletePrefPreset(const LLSD &key)
 :	LLFloater(key)
@@ -49,7 +51,7 @@ BOOL LLFloaterDeletePrefPreset::postBuild()
 
 void LLFloaterDeletePrefPreset::onOpen(const LLSD& key)
 {
-	std::string mSubdirectory = key.asString();
+	mSubdirectory = key.asString();
 	std::string floater_title = getString(std::string("title_") + mSubdirectory);
 
 	setTitle(floater_title);
@@ -65,7 +67,11 @@ void LLFloaterDeletePrefPreset::onBtnDelete()
 	std::string name = combo->getSimple();
 
 	// Ignore return status
-	LLPresetsManager::getInstance()->deletePreset(name);
+	LLPresetsManager::getInstance()->deletePreset(mSubdirectory, name);
+
+	LLSD args;
+	args["NAME"] = name;
+	LLNotificationsUtil::add("PresetDeleted", args);
 }
 
 void LLFloaterDeletePrefPreset::onPresetsListChange()
diff --git a/indra/newview/llfloaterdeleteprefpreset.h b/indra/newview/llfloaterdeleteprefpreset.h
index 356bc1a4372..0ab3da71392 100644
--- a/indra/newview/llfloaterdeleteprefpreset.h
+++ b/indra/newview/llfloaterdeleteprefpreset.h
@@ -25,7 +25,7 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLFLOATERDELETPREFPRESET_H
+#ifndef LL_LLFLOATERDELETEPREFPRESET_H
 #define LL_LLFLOATERDELETEPREFPRESET_H
 
 #include "llfloater.h"
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 508d82522e0..2e1e1ba318f 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1883,8 +1883,9 @@ LLPanelPreference::LLPanelPreference()
 {
 	mCommitCallbackRegistrar.add("Pref.setControlFalse",	boost::bind(&LLPanelPreference::setControlFalse,this, _2));
 	mCommitCallbackRegistrar.add("Pref.updateMediaAutoPlayCheckbox",	boost::bind(&LLPanelPreference::updateMediaAutoPlayCheckbox, this, _1));
-	mCommitCallbackRegistrar.add("Pref.Preset",	boost::bind(&LLPanelPreference::onChangePreset, this));
-	mCommitCallbackRegistrar.add("Pref.PrefDelete",	boost::bind(&LLPanelPreference::onDeletePreset, this));
+	mCommitCallbackRegistrar.add("Pref.Preset",	boost::bind(&LLPanelPreference::onChangePreset, this, _2));
+	mCommitCallbackRegistrar.add("Pref.PrefDelete",	boost::bind(&LLPanelPreference::DeletePreset, this, _2));
+	mCommitCallbackRegistrar.add("Pref.PrefSave",	boost::bind(&LLPanelPreference::SavePreset, this, _2));
 }
 
 //virtual
@@ -2082,17 +2083,27 @@ void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
 	}
 }
 
-void LLPanelPreference::onDeletePreset()
+void LLPanelPreference::DeletePreset(const LLSD& user_data)
 {
-	LLFloaterReg::showInstance("delete_pref_preset", PRESETS_GRAPHIC);
+	std::string subdirectory = user_data.asString();
+	LLFloaterReg::showInstance("delete_pref_preset", subdirectory);
 }
 
-void LLPanelPreference::onChangePreset()
+void LLPanelPreference::SavePreset(const LLSD& user_data)
 {
-	LLComboBox* combo = getChild<LLComboBox>("graphic_preset_combo");
+	std::string subdirectory = user_data.asString();
+	LLFloaterReg::showInstance("save_pref_preset", subdirectory);
+}
+
+void LLPanelPreference::onChangePreset(const LLSD& user_data)
+{
+	std::string subdirectory = user_data.asString();
+
+	LLComboBox* combo = getChild<LLComboBox>(subdirectory + "_preset_combo");
 	std::string name = combo->getSimple();
 
-	LLPresetsManager::getInstance()->loadPreset(name);
+
+	LLPresetsManager::getInstance()->loadPreset(subdirectory, name);
 	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
 	if (instance)
 	{
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index be228c86250..5452dc64425 100755
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -221,8 +221,9 @@ class LLPanelPreference : public LLPanel
 	// cancel() can restore them.
 	virtual void saveSettings();
 
-	void onDeletePreset();
-	void onChangePreset();
+	void onChangePreset(const LLSD& user_data);
+	void DeletePreset(const LLSD& user_data);
+	void SavePreset(const LLSD& user_data);
 
 	class Updater;
 
diff --git a/indra/newview/llfloatersaveprefpreset.cpp b/indra/newview/llfloatersaveprefpreset.cpp
new file mode 100644
index 00000000000..16d77c0750f
--- /dev/null
+++ b/indra/newview/llfloatersaveprefpreset.cpp
@@ -0,0 +1,97 @@
+/** 
+ * @file llfloatersaveprefpreset.cpp
+ * @brief Floater to save a graphics / camera preset
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, 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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatersaveprefpreset.h"
+
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llnotificationsutil.h"
+#include "llpresetsmanager.h"
+
+LLFloaterSavePrefPreset::LLFloaterSavePrefPreset(const LLSD &key)
+:	LLFloater(key)
+{
+}
+
+// virtual
+BOOL LLFloaterSavePrefPreset::postBuild()
+{
+	getChild<LLComboBox>("preset_combo")->setTextEntryCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetNameEdited, this));
+	getChild<LLComboBox>("preset_combo")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetNameEdited, this));
+	getChild<LLButton>("save")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onBtnSave, this));
+	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onBtnCancel, this));
+
+	LLPresetsManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetsListChange, this));
+
+	mSaveButton = getChild<LLButton>("save");
+	mPresetCombo = getChild<LLComboBox>("preset_combo");
+
+	return TRUE;
+}
+
+void LLFloaterSavePrefPreset::onPresetNameEdited()
+{
+	// Disable saving a preset having empty name.
+	std::string name = mPresetCombo->getSimple();
+
+	mSaveButton->setEnabled(!name.empty());
+}
+
+void LLFloaterSavePrefPreset::onOpen(const LLSD& key)
+{
+	mSubdirectory = key.asString();
+
+	std::string floater_title = getString(std::string("title_") + mSubdirectory);
+
+	setTitle(floater_title);
+
+	LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, mPresetCombo);
+
+	onPresetNameEdited();
+}
+
+void LLFloaterSavePrefPreset::onBtnSave()
+{
+	std::string name = mPresetCombo->getSimple();
+
+	LLPresetsManager::getInstance()->savePreset(mSubdirectory, name);
+
+	LLSD args;
+	args["NAME"] = name;
+	LLNotificationsUtil::add("PresetSaved", args);
+}
+
+void LLFloaterSavePrefPreset::onPresetsListChange()
+{
+	LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, mPresetCombo);
+}
+
+void LLFloaterSavePrefPreset::onBtnCancel()
+{
+	closeFloater();
+}
diff --git a/indra/newview/llfloatersaveprefpreset.h b/indra/newview/llfloatersaveprefpreset.h
new file mode 100644
index 00000000000..09a87b8c629
--- /dev/null
+++ b/indra/newview/llfloatersaveprefpreset.h
@@ -0,0 +1,57 @@
+/** 
+ * @file llfloatersaveprefpreset.h
+ * @brief Floater to save a graphics / camera preset
+
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, 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$
+ */
+
+#ifndef LL_LLFLOATERSAVEPREFPRESET_H
+#define LL_LLFLOATERSAVEPREFPRESET_H
+
+#include "llfloater.h"
+
+class LLComboBox;
+
+class LLFloaterSavePrefPreset : public LLFloater
+{
+
+public:
+	LLFloaterSavePrefPreset(const LLSD &key);
+
+	/*virtual*/	BOOL	postBuild();
+	/*virtual*/ void	onOpen(const LLSD& key);
+
+	void onBtnSave();
+	void onBtnCancel();
+
+private:
+	LLComboBox*		mPresetCombo;
+	LLButton*		mSaveButton;
+
+	void onPresetsListChange();
+	void onPresetNameEdited();
+
+	std::string mSubdirectory;
+};
+
+#endif // LL_LLFLOATERSAVEPREFPRESET_H
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index 6e00a90ae56..f6f2275da9b 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -165,7 +165,7 @@ void LLPresetsManager::savePreset(const std::string& subdirectory, const std::st
 		paramsData[ctrl_name]["Value"] = value;
 	}
 
-	std::string pathName(getPresetsDir(subdirectory) + "\\" + LLURI::escape(name) + ".xml");
+	std::string pathName(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml");
 
 	// write to file
 	llofstream presetsXML(pathName);
@@ -188,46 +188,35 @@ void LLPresetsManager::setPresetNamesInComboBox(const std::string& subdirectory,
 		std::list<std::string> preset_names;
 		loadPresetNamesFromDir(presets_dir, preset_names);
 
-		combo->setLabel(LLTrans::getString("preset_combo_label"));
-
-		for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
+		if (preset_names.begin() != preset_names.end())
 		{
-			const std::string& name = *it;
-			combo->add(name, LLSD().with(0, name));
+			for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
+			{
+				const std::string& name = *it;
+				combo->add(name, LLSD().with(0, name));
+			}
+		}
+		else
+		{
+			combo->setLabel(LLTrans::getString("preset_combo_label"));
 		}
-	}
-	else
-	{
-		LL_WARNS() << "Could not obtain graphic presets path" << LL_ENDL;
 	}
 }
 
-void LLPresetsManager::loadPreset(const std::string& name)
+void LLPresetsManager::loadPreset(const std::string& subdirectory, const std::string& name)
 {
-	std::string full_path(getPresetsDir(PRESETS_GRAPHIC) + "\\" + LLURI::escape(name) + ".xml");
+	std::string full_path(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml");
 
 	gSavedSettings.loadFromFile(full_path, false, true);
 }
 
-bool LLPresetsManager::deletePreset(const std::string& name)
+bool LLPresetsManager::deletePreset(const std::string& subdirectory, const std::string& name)
 {
-	// remove from param list
-	preset_name_list_t::iterator it = find(mPresetNames.begin(), mPresetNames.end(), name);
-	if (it == mPresetNames.end())
-	{
-		LL_WARNS("Presets") << "No preset named " << name << LL_ENDL;
-		return false;
-	}
-
-	if (gDirUtilp->deleteFilesInDir(getPresetsDir(PRESETS_GRAPHIC), LLURI::escape(name) + ".xml") < 1)
+	if (gDirUtilp->deleteFilesInDir(getPresetsDir(subdirectory), LLURI::escape(name) + ".xml") < 1)
 	{
 		LL_WARNS("Presets") << "Error removing preset " << name << " from disk" << LL_ENDL;
 		return false;
 	}
-	else
-	{
-		mPresetNames.erase(it);
-	}
 
 	// signal interested parties
 	mPresetListChangeSignal();
diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h
index 3a2542bda06..7bbaa778c6f 100644
--- a/indra/newview/llpresetsmanager.h
+++ b/indra/newview/llpresetsmanager.h
@@ -46,8 +46,8 @@ class LLPresetsManager : public LLSingleton<LLPresetsManager>
 	void setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo);
 	void loadPresetNamesFromDir(const std::string& dir, preset_name_list_t& presets);
 	void savePreset(const std::string& subdirectory, const std::string & name);
-	void loadPreset(const std::string & name);
-	bool deletePreset(const std::string& name);
+	void loadPreset(const std::string& subdirectory, const std::string & name);
+	bool deletePreset(const std::string& subdirectory, const std::string& name);
 
 	/// Emitted when a preset gets loaded or deleted.
 	boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 03360deaee9..3ee67d8ac55 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -101,6 +101,7 @@
 #include "llfloaterregioninfo.h"
 #include "llfloaterregionrestarting.h"
 #include "llfloaterreporter.h"
+#include "llfloatersaveprefpreset.h"
 #include "llfloatersceneloadstats.h"
 #include "llfloaterscriptdebug.h"
 #include "llfloaterscriptedprefs.h"
@@ -290,6 +291,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview");
 	LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProperties>);
 	LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>);
+	LLFloaterReg::add("save_pref_preset", "floater_save_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSavePrefPreset>);
 	LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
 
 	LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
diff --git a/indra/newview/skins/default/xui/en/floater_save_pref_preset.xml b/indra/newview/skins/default/xui/en/floater_save_pref_preset.xml
new file mode 100644
index 00000000000..5919d9e3d78
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_save_pref_preset.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<floater
+ legacy_header_height="18"
+ height="130"
+ help_topic=""
+ layout="topleft"
+ name="Save Pref Preset"
+ save_rect="true"
+ title="SAVE PREF PRESET"
+ width="550">
+
+    <string name="title_graphic">Save Graphic Preset</string>
+    <string name="title_camera">Save Camera Preset</string>
+
+    <text
+     follows="top|left|right"
+     font="SansSerif"
+     height="10"
+     layout="topleft"
+     left="50"
+     name="Preset"
+     top="60"
+     width="60">
+     Preset:
+    </text>
+    <combo_box
+     follows="top|left"
+     layout="topleft"
+     left_pad="10"
+     name="preset_combo"
+     top_delta="-5"
+     allow_text_entry="true"
+     width="200"/>
+    <button
+     follows="bottom|right"
+     height="23"
+     label="Save"
+     layout="topleft"
+     left_pad="15"
+     name="save"
+     width="70"/>
+    <button
+     follows="bottom|right"
+     height="23"
+     label="Cancel"
+     layout="topleft"
+     left_pad="5"
+     name="cancel"
+     width="70"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f1d34a14497..e1d2f012d35 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -7657,6 +7657,20 @@ Are you sure you want to close all IMs?
 Attachment has been saved.
   </notification>
 
+  <notification
+    icon="alertmodal.tga"
+	name="PresetSaved"
+    type="alertmodal">
+Preset [NAME] has been saved.
+  </notification>
+
+  <notification
+    icon="alertmodal.tga"
+	name="PresetDeleted"
+    type="alertmodal">
+Preset [NAME] has been deleted.
+  </notification>
+
   <notification
     icon="alertmodal.tga"
     name="UnableToFindHelpTopic"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 3d7fdbb0ab6..2a7560fd2cc 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -31,7 +31,8 @@
    	top_delta="0"
    	width="150">
     <combo_box.commit_callback
-      function="Pref.Preset" />
+      function="Pref.Preset"
+      parameter="graphic" />
   </combo_box>
   <button
     follows="top|left"
@@ -43,7 +44,8 @@
     top_delta="0"
     width="115">
     <button.commit_callback
-      function="Pref.PrefSave" />
+      function="Pref.PrefSave"
+	  parameter="graphic"/>
   </button>
   <button
     follows="top|left"
-- 
GitLab