From 382c1845012cc4e2be78a5a03334b4157a732349 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 12 Nov 2019 16:26:34 +0200
Subject: [PATCH] SL-12186 WIP Added ability to reset default presets and
 updated item list in 'My camera presets' floater

---
 indra/newview/app_settings/settings.xml       |  2 +-
 indra/newview/llfloatercamera.cpp             |  7 +-
 indra/newview/llfloatercamerapresets.cpp      | 32 ++++++++-
 indra/newview/llfloatercamerapresets.h        |  4 ++
 indra/newview/llpresetsmanager.cpp            | 65 +++++++++++++++++--
 indra/newview/llpresetsmanager.h              |  9 +++
 .../xui/en/panel_camera_preset_item.xml       | 20 ++++++
 7 files changed, 126 insertions(+), 13 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f44185340a0..04ab620b3a5 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1565,7 +1565,7 @@
     <key>CameraPreset</key>
     <map>
       <key>Comment</key>
-      <string>Preset camera position - view (0 - rear, 1 - front, 2 - group)</string>
+      <string>Preset camera position - view (0 - rear, 1 - front, 2 - group, 3 - custom)</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index 2f85e7db345..47f05884b3b 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -550,17 +550,17 @@ void LLFloaterCamera::switchToPreset(const std::string& name)
 	if ("rear_view" == name)
 	{
 		gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
-		LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, PRESETS_REAR);
+		LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, PRESETS_REAR_VIEW);
 	}
 	else if ("group_view" == name)
 	{
 		gAgentCamera.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
-		LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, PRESETS_SIDE);
+		LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, PRESETS_SIDE_VIEW);
 	}
 	else if ("front_view" == name)
 	{
 		gAgentCamera.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
-		LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, PRESETS_FRONT);
+		LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, PRESETS_FRONT_VIEW);
 	}
 }
 
@@ -590,6 +590,7 @@ void LLFloaterCamera::populatePresetCombo()
 	{
 		mPresetCombo->setLabel(getString("inactive_combo_text"));
 	}
+	updateItemsSelection();
 }
 
 void LLFloaterCamera::onSavePreset()
diff --git a/indra/newview/llfloatercamerapresets.cpp b/indra/newview/llfloatercamerapresets.cpp
index 6a9df5d067d..75660e590a0 100644
--- a/indra/newview/llfloatercamerapresets.cpp
+++ b/indra/newview/llfloatercamerapresets.cpp
@@ -58,7 +58,10 @@ void LLFloaterCameraPresets::populateList()
     std::string presets_dir = presetsMgr->getPresetsDir(PRESETS_CAMERA);
     std::list<std::string> preset_names;
 
-    presetsMgr->loadPresetNamesFromDir(presets_dir, preset_names, DEFAULT_TOP);
+    presetsMgr->loadPresetNamesFromDir(presets_dir, preset_names, DEFAULT_VIEWS_HIDE);
+    preset_names.push_back(PRESETS_FRONT_VIEW);
+    preset_names.push_back(PRESETS_REAR_VIEW);
+    preset_names.push_back(PRESETS_SIDE_VIEW);
     for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
     {
         const std::string& name = *it;
@@ -86,10 +89,10 @@ LLCameraPresetFlatItem::~LLCameraPresetFlatItem()
 BOOL LLCameraPresetFlatItem::postBuild()
 {
     mDeleteBtn = getChild<LLButton>("delete_btn");
-    mDeleteBtn->setVisible(!mIsDefaultPrest);
+    mDeleteBtn->setVisible(false);
 
     mResetBtn = getChild<LLButton>("reset_btn");
-    mResetBtn->setVisible(mIsDefaultPrest);
+    mResetBtn->setVisible(false);
 
     LLStyle::Params style;
     LLTextBox* name_text = getChild<LLTextBox>("preset_name");
@@ -102,6 +105,29 @@ BOOL LLCameraPresetFlatItem::postBuild()
     return true;
 }
 
+void LLCameraPresetFlatItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+    mDeleteBtn->setVisible(!mIsDefaultPrest);
+    mResetBtn->setVisible(mIsDefaultPrest);
+    getChildView("hovered_icon")->setVisible(true);
+    LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLCameraPresetFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+    mDeleteBtn->setVisible(false);
+    mResetBtn->setVisible(false);
+    getChildView("hovered_icon")->setVisible(false);
+    LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLCameraPresetFlatItem::setValue(const LLSD& value)
+{
+    if (!value.isMap()) return;;
+    if (!value.has("selected")) return;
+    getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
 void LLCameraPresetFlatItem::onDeleteBtnClick()
 {
     if (!LLPresetsManager::getInstance()->deletePreset(PRESETS_CAMERA, mPresetName))
diff --git a/indra/newview/llfloatercamerapresets.h b/indra/newview/llfloatercamerapresets.h
index 8c293c57de5..66430fa3994 100644
--- a/indra/newview/llfloatercamerapresets.h
+++ b/indra/newview/llfloatercamerapresets.h
@@ -52,7 +52,11 @@ class LLCameraPresetFlatItem : public LLPanel
     LLCameraPresetFlatItem(const std::string &preset_name, bool is_default);
     virtual ~LLCameraPresetFlatItem();
 
+    void setValue(const LLSD& value);
+
     virtual BOOL postBuild();
+    virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+    virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 
 private:
     void onDeleteBtnClick();
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index ab4f60d4866..057f60a015f 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -65,7 +65,13 @@ void LLPresetsManager::createMissingDefault(const std::string& subdirectory)
 {
 	if(gDirUtilp->getLindenUserDir().empty())
 	{
-return;
+		return;
+	}
+
+	if (PRESETS_CAMERA == subdirectory)
+	{
+		createCameraDefaultPresets();
+		return;
 	}
 
 	std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR,
@@ -83,6 +89,13 @@ return;
 	}
 }
 
+void LLPresetsManager::createCameraDefaultPresets()
+{
+	createDefaultCameraPreset(PRESETS_REAR_VIEW);
+	createDefaultCameraPreset(PRESETS_FRONT_VIEW);
+	createDefaultCameraPreset(PRESETS_SIDE_VIEW);
+}
+
 void LLPresetsManager::startWatching(const std::string& subdirectory)
 {
 	if (PRESETS_CAMERA == subdirectory)
@@ -163,6 +176,10 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
 			std::string name = LLURI::unescape(gDirUtilp->getBaseFileName(path, /*strip_exten = */ true));
 			LL_DEBUGS() << "  Found preset '" << name << "'" << LL_ENDL;
 
+			if (isTemplateCameraPreset(name))
+			{
+				continue;
+			}
 			if (default_option == DEFAULT_VIEWS_HIDE)
 			{
 				if (isDefaultCameraPreset(name))
@@ -198,6 +215,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
 }
 
 bool LLPresetsManager::mCameraDirty = false;
+bool LLPresetsManager::mIgnoreChangedSignal = false;
 
 void LLPresetsManager::setCameraDirty(bool dirty)
 {
@@ -215,7 +233,7 @@ void LLPresetsManager::settingChanged()
 
 	static LLCachedControl<std::string> preset_camera_active(gSavedSettings, "PresetCameraActive", "");
 	std::string preset_name = preset_camera_active;
-	if (!preset_name.empty())
+	if (!preset_name.empty() && !mIgnoreChangedSignal)
 	{
 		gSavedSettings.setString("PresetCameraActive", "");
 
@@ -267,6 +285,12 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
 		return false;
 	}
 
+	if (isTemplateCameraPreset(name))
+	{
+		LL_WARNS() << "Should not overwrite template presets" << LL_ENDL;
+		return false;
+	}
+
 	bool saved = false;
 	std::vector<std::string> name_list;
 
@@ -434,8 +458,10 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n
 
     LL_DEBUGS() << "attempting to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
 
+	mIgnoreChangedSignal = true;
 	if(gSavedSettings.loadFromFile(full_path, false, true) > 0)
 	{
+		mIgnoreChangedSignal = false;
 		if(PRESETS_GRAPHIC == subdirectory)
 		{
 			gSavedSettings.setString("PresetGraphicActive", name);
@@ -453,10 +479,11 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n
 			triggerChangeCameraSignal();
 		}
 	}
-    else
-    {
-        LL_WARNS("Presets") << "failed to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
-    }
+	else
+	{
+		mIgnoreChangedSignal = false;
+		LL_WARNS("Presets") << "failed to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
+	}
 }
 
 bool LLPresetsManager::deletePreset(const std::string& subdirectory, std::string name)
@@ -506,13 +533,39 @@ bool LLPresetsManager::deletePreset(const std::string& subdirectory, std::string
 }
 
 bool LLPresetsManager::isDefaultCameraPreset(std::string preset_name)
+{
+	return (preset_name == PRESETS_REAR_VIEW || preset_name == PRESETS_SIDE_VIEW || preset_name == PRESETS_FRONT_VIEW);
+}
+
+bool LLPresetsManager::isTemplateCameraPreset(std::string preset_name)
 {
 	return (preset_name == PRESETS_REAR || preset_name == PRESETS_SIDE || preset_name == PRESETS_FRONT);
 }
 
 void LLPresetsManager::resetCameraPreset(std::string preset_name)
 {
+	if (isDefaultCameraPreset(preset_name))
+	{
+		createDefaultCameraPreset(preset_name, true);
+
+		if (gSavedSettings.getString("PresetCameraActive") == preset_name)
+		{
+			loadPreset(PRESETS_CAMERA, preset_name);
+		}
+	}
+}
 
+void LLPresetsManager::createDefaultCameraPreset(std::string preset_name, bool force_reset)
+{
+	std::string preset_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR,
+		PRESETS_CAMERA, LLURI::escape(preset_name) + ".xml");
+	if (!gDirUtilp->fileExists(preset_file) || force_reset)
+	{
+		std::string template_name = preset_name.substr(0, preset_name.size() - PRESETS_VIEW_SUFFIX.size());
+		std::string default_template_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR,
+			PRESETS_CAMERA, template_name + ".xml");
+		LLFile::copy(default_template_file, preset_file);
+	}
 }
 
 boost::signals2::connection LLPresetsManager::setPresetListChangeCameraCallback(const preset_list_signal_t::slot_type& cb)
diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h
index 9964cc0fcf0..d489a0ad5a7 100644
--- a/indra/newview/llpresetsmanager.h
+++ b/indra/newview/llpresetsmanager.h
@@ -39,6 +39,10 @@ static const std::string PRESETS_CAMERA = "camera";
 static const std::string PRESETS_REAR = "Rear";
 static const std::string PRESETS_FRONT = "Front";
 static const std::string PRESETS_SIDE = "Side";
+static const std::string PRESETS_VIEW_SUFFIX = " View";
+static const std::string PRESETS_REAR_VIEW = PRESETS_REAR + PRESETS_VIEW_SUFFIX;
+static const std::string PRESETS_FRONT_VIEW = PRESETS_FRONT + PRESETS_VIEW_SUFFIX;
+static const std::string PRESETS_SIDE_VIEW = PRESETS_SIDE + PRESETS_VIEW_SUFFIX;
 
 enum EDefaultOptions
 {
@@ -71,8 +75,12 @@ class LLPresetsManager : public LLSingleton<LLPresetsManager>
 	bool isCameraDirty();
 	static void setCameraDirty(bool dirty);
 
+	void createCameraDefaultPresets();
+
+	bool isTemplateCameraPreset(std::string preset_name);
 	bool isDefaultCameraPreset(std::string preset_name);
 	void resetCameraPreset(std::string preset_name);
+	void createDefaultCameraPreset(std::string preset_name, bool force_reset = false);
 
 	// Emitted when a preset gets loaded, deleted, or saved.
 	boost::signals2::connection setPresetListChangeCameraCallback(const preset_list_signal_t::slot_type& cb);
@@ -95,6 +103,7 @@ class LLPresetsManager : public LLSingleton<LLPresetsManager>
 	boost::signals2::connection	mCameraChangedSignal;
 
 	static bool	mCameraDirty;
+	static bool mIgnoreChangedSignal;
 };
 
 #endif // LL_PRESETSMANAGER_H
diff --git a/indra/newview/skins/default/xui/en/panel_camera_preset_item.xml b/indra/newview/skins/default/xui/en/panel_camera_preset_item.xml
index 187f5889eb3..9417ab4ac2d 100644
--- a/indra/newview/skins/default/xui/en/panel_camera_preset_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_camera_preset_item.xml
@@ -7,6 +7,26 @@
  name="camera_preset_item"
  top="0"
  width="280">
+    <icon
+     follows="top|right|left"
+     height="20"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     height="20"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="380" />
     <text
      follows="left"
      height="20"
-- 
GitLab