From bb3380b2207ea1413536320782d07cb27bc3a47c Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 10 May 2017 15:41:16 +0300
Subject: [PATCH] MAINT-7359 improve new Avatar Render Settings window

---
 .../newview/llfloateravatarrendersettings.cpp | 49 ++++++++++++++-----
 indra/newview/llfloateravatarrendersettings.h |  4 ++
 indra/newview/llmutelist.cpp                  | 23 ++++++++-
 indra/newview/llmutelist.h                    |  3 ++
 .../xui/en/floater_avatar_render_settings.xml |  8 ++-
 .../default/xui/en/menu_attachment_other.xml  |  8 +++
 .../default/xui/en/menu_avatar_other.xml      |  8 +++
 7 files changed, 87 insertions(+), 16 deletions(-)

diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp
index e7ac3f27376..2bae7d63aaa 100644
--- a/indra/newview/llfloateravatarrendersettings.cpp
+++ b/indra/newview/llfloateravatarrendersettings.cpp
@@ -33,6 +33,7 @@
 #include "llfloaterreg.h"
 #include "llnamelistctrl.h"
 #include "llmenugl.h"
+#include "lltrans.h"
 #include "llviewerobjectlist.h"
 #include "llvoavatar.h"
 
@@ -144,6 +145,8 @@ void LLFloaterAvatarRenderSettings::updateList()
             item_params.columns.add().value(av_name.getCompleteName()).column("name");
             std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
             item_params.columns.add().value(setting).column("setting");
+            std::string timestamp = createTimestamp(LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first));
+            item_params.columns.add().value(timestamp).column("timestamp");
             mAvatarSettingsList->addNameItemRow(item_params);
         }
     }
@@ -205,15 +208,7 @@ void LLFloaterAvatarRenderSettings::onCustomAction (const LLSD& userdata, const
         new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
     }
 
-    LLVOAvatar *avatarp = find_avatar(av_id);
-    if (avatarp)
-    {
-        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
-    }
-    else
-    {
-        LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
-    }
+    setAvatarRenderSetting(av_id, new_setting);
 }
 
 
@@ -273,14 +268,44 @@ void LLFloaterAvatarRenderSettings::onClickAdd(const LLSD& userdata)
 void LLFloaterAvatarRenderSettings::callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting)
 {
     if (ids.empty()) return;
+    setAvatarRenderSetting(ids[0], visual_setting);
+}
 
-    LLVOAvatar *avatarp = find_avatar(ids[0]);
+void LLFloaterAvatarRenderSettings::setAvatarRenderSetting(const LLUUID& av_id, S32 new_setting)
+{
+    LLVOAvatar *avatarp = find_avatar(av_id);
     if (avatarp)
     {
-        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(visual_setting));
+        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
     }
     else
     {
-        LLRenderMuteList::getInstance()->saveVisualMuteSetting(ids[0], visual_setting);
+        LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
+    }
+}
+
+BOOL LLFloaterAvatarRenderSettings::handleKeyHere(KEY key, MASK mask )
+{
+    BOOL handled = FALSE;
+
+    if (KEY_DELETE == key)
+    {
+        setAvatarRenderSetting(mAvatarSettingsList->getCurrentID(), (S32)LLVOAvatar::AV_RENDER_NORMALLY);
+        handled = TRUE;
     }
+    return handled;
+}
+
+std::string LLFloaterAvatarRenderSettings::createTimestamp(S32 datetime)
+{
+    std::string timeStr;
+    LLSD substitution;
+    substitution["datetime"] = datetime;
+
+    timeStr = "["+LLTrans::getString ("TimeMonth")+"]/["
+                 +LLTrans::getString ("TimeDay")+"]/["
+                 +LLTrans::getString ("TimeYear")+"]";
+
+    LLStringUtil::format (timeStr, substitution);
+    return timeStr;
 }
diff --git a/indra/newview/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h
index fe727bcf327..6790b24b90b 100644
--- a/indra/newview/llfloateravatarrendersettings.h
+++ b/indra/newview/llfloateravatarrendersettings.h
@@ -43,6 +43,7 @@ class LLFloaterAvatarRenderSettings : public LLFloater
     /*virtual*/ BOOL postBuild();
     /*virtual*/ void onOpen(const LLSD& key);
     /*virtual*/ void draw();
+    /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
 
     void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
 
@@ -51,6 +52,9 @@ class LLFloaterAvatarRenderSettings : public LLFloater
     void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
     bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
     void onClickAdd(const LLSD& userdata);
+    void setAvatarRenderSetting(const LLUUID& av_id, S32 new_setting);
+
+    std::string createTimestamp(S32 datetime);
 
     static void setNeedsUpdate();
 
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 02b28a2bf8e..5b53a052742 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -825,13 +825,14 @@ bool LLRenderMuteList::saveToFile()
         LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
         return false;
     }
+
     for (std::map<LLUUID, S32>::iterator it = sVisuallyMuteSettingsMap.begin(); it != sVisuallyMuteSettingsMap.end(); ++it)
     {
         if (it->second != 0)
         {
             std::string id_string;
             it->first.toString(id_string);
-            fprintf(fp, "%d %s\n", (S32)it->second, id_string.c_str());
+            fprintf(fp, "%d %s [%d]\n", (S32)it->second, id_string.c_str(), (S32)sVisuallyMuteDateMap[it->first]);
         }
     }
     fclose(fp);
@@ -854,8 +855,10 @@ bool LLRenderMuteList::loadFromFile()
 	{
 		id_buffer[0] = '\0';
 		S32 setting = 0;
-		sscanf(buffer, " %d %254s\n", &setting, id_buffer);
+		S32 time = 0;
+		sscanf(buffer, " %d %254s [%d]\n", &setting, id_buffer, &time);
 		sVisuallyMuteSettingsMap[LLUUID(id_buffer)] = setting;
+		sVisuallyMuteDateMap[LLUUID(id_buffer)] = (time == 0) ? (S32)time_corrected() : time;
 	}
 	fclose(fp);
     return true;
@@ -866,10 +869,15 @@ void LLRenderMuteList::saveVisualMuteSetting(const LLUUID& agent_id, S32 setting
     if(setting == 0)
     {
         sVisuallyMuteSettingsMap.erase(agent_id);
+        sVisuallyMuteDateMap.erase(agent_id);
     }
     else
     {
         sVisuallyMuteSettingsMap[agent_id] = setting;
+        if (sVisuallyMuteDateMap.find(agent_id) == sVisuallyMuteDateMap.end())
+        {
+            sVisuallyMuteDateMap[agent_id] =  (S32)time_corrected();
+        }
     }
     saveToFile();
     notifyObservers();
@@ -886,6 +894,17 @@ S32 LLRenderMuteList::getSavedVisualMuteSetting(const LLUUID& agent_id)
     return 0;
 }
 
+S32 LLRenderMuteList::getVisualMuteDate(const LLUUID& agent_id)
+{
+    std::map<LLUUID, S32>::iterator iter = sVisuallyMuteDateMap.find(agent_id);
+    if (iter != sVisuallyMuteDateMap.end())
+    {
+        return iter->second;
+    }
+
+    return 0;
+}
+
 void LLRenderMuteList::addObserver(LLMuteListObserver* observer)
 {
     mObservers.insert(observer);
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 9ab978353bb..f2fcf3dbb33 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -184,10 +184,13 @@ class LLRenderMuteList : public LLSingleton<LLRenderMuteList>
 	S32 getSavedVisualMuteSetting(const LLUUID& agent_id);
 	void saveVisualMuteSetting(const LLUUID& agent_id, S32 setting);
 
+	S32 getVisualMuteDate(const LLUUID& agent_id);
+
 	void addObserver(LLMuteListObserver* observer);
 	void removeObserver(LLMuteListObserver* observer);
 
 	std::map<LLUUID, S32> sVisuallyMuteSettingsMap;
+	std::map<LLUUID, S32> sVisuallyMuteDateMap;
 
 private:
 	void notifyObservers();
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
index 03e812d36d0..e088d4d2a16 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
@@ -57,10 +57,14 @@
         <name_list.columns
          label="Name"
          name="name"
-         relative_width="0.65" />
+         relative_width="0.5" />
         <name_list.columns
          label="Render setting"
          name="setting"
-         relative_width="0.35" />
+         relative_width="0.25" />
+        <name_list.columns
+         label="Date added"
+         name="timestamp"
+         relative_width="0.25" />
      </name_list>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 49b9ac273d9..38f4b7715f6 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -164,6 +164,14 @@
 	      function="Avatar.SetImpostorMode"
 	      parameter="1" />
       </menu_item_check>
+      <menu_item_separator />
+      <menu_item_call
+        label="Exceptions..."
+        name="RenderExceptions">
+        <menu_item_call.on_click
+          function="Floater.ToggleOrBringToFront"
+          parameter="avatar_render_settings" />
+      </menu_item_call>
       </context_menu>
   <menu_item_separator
        layout="topleft" name="Impostor seperator"/>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index c5426cb232d..f9fb8479107 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -155,6 +155,14 @@
 	      function="Avatar.SetImpostorMode"
 	      parameter="1" />
       </menu_item_check>
+      <menu_item_separator />
+      <menu_item_call
+        label="Exceptions..."
+        name="RenderExceptions">
+        <menu_item_call.on_click
+          function="Floater.ToggleOrBringToFront"
+          parameter="avatar_render_settings" />
+      </menu_item_call>
       </context_menu>
 
   <menu_item_separator 
-- 
GitLab