From ff071bbdce6478f8cd666ecf75658ca6e24f1140 Mon Sep 17 00:00:00 2001
From: Monroe Linden <monroe@lindenlab.com>
Date: Tue, 28 Sep 2010 16:49:22 -0700
Subject: Added a mechanism for preventing classes of notifications from being
 displayed, controlled by the notification_visibility.xml file in the viewer
 skin.

Reviewed by Richard.
---
 indra/llui/CMakeLists.txt                          |  1 +
 indra/llui/llnotifications.cpp                     | 75 ++++++++++++++++++++-
 indra/llui/llnotifications.h                       | 17 ++++-
 indra/llui/llnotificationvisibilityrule.h          | 76 ++++++++++++++++++++++
 indra/newview/llfloaternotificationsconsole.cpp    |  1 +
 .../default/xui/en/notification_visibility.xml     |  5 ++
 6 files changed, 173 insertions(+), 2 deletions(-)
 create mode 100644 indra/llui/llnotificationvisibilityrule.h
 create mode 100644 indra/newview/skins/default/xui/en/notification_visibility.xml

(limited to 'indra')

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index e98201ea63..864f3f699e 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -159,6 +159,7 @@ set(llui_HEADER_FILES
     llnotificationslistener.h
     llnotificationsutil.h
     llnotificationtemplate.h
+	llnotificationvisibilityrule.h
     llpanel.h
     llprogressbar.h
     llradiogroup.h
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 9a3933093c..46af9323e1 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -28,6 +28,7 @@
 
 #include "llnotifications.h"
 #include "llnotificationtemplate.h"
+#include "llnotificationvisibilityrule.h"
 
 #include "llinstantmessage.h"
 #include "llxmlnode.h"
@@ -414,6 +415,13 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 	mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
 }
 
+LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationVisibilityRule::Params &p)
+:	mVisible(p.visible),
+	mType(p.type),
+	mTag(p.tag)
+{
+}
+
 LLNotification::LLNotification(const LLNotification::Params& p) : 
 	mTimestamp(p.time_stamp), 
 	mSubstitutions(p.substitutions),
@@ -1188,6 +1196,7 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN
 void LLNotifications::initSingleton()
 {
 	loadTemplates();
+	loadVisibilityRules();
 	createDefaultChannels();
 }
 
@@ -1205,7 +1214,9 @@ void LLNotifications::createDefaultChannels()
 		boost::bind(&LLNotifications::uniqueFilter, this, _1));
 	LLNotificationChannel::buildChannel("Ignore", "Unique",
 		filterIgnoredNotifications);
-	LLNotificationChannel::buildChannel("Visible", "Ignore",
+	LLNotificationChannel::buildChannel("VisibilityRules", "Ignore",
+		boost::bind(&LLNotifications::isVisibleByRules, this, _1));
+	LLNotificationChannel::buildChannel("Visible", "VisibilityRules",
 		&LLNotificationFilters::includeEverything);
 
 	// create special persistent notification channel
@@ -1226,6 +1237,8 @@ void LLNotifications::createDefaultChannels()
 //        connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
 	LLNotifications::instance().getChannel("Ignore")->
 		connectFailedFilter(&handleIgnoredNotification);
+	LLNotifications::instance().getChannel("VisibilityRules")->
+		connectFailedFilter(&handleIgnoredNotification);
 }
 
 bool LLNotifications::addTemplate(const std::string &name, 
@@ -1404,6 +1417,36 @@ bool LLNotifications::loadTemplates()
 	return true;
 }
 
+bool LLNotifications::loadVisibilityRules()
+{
+	const std::string xml_filename = "notification_visibility.xml";
+	std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename);
+
+	LLXMLNodePtr root;
+	BOOL success  = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+	
+	if (!success || root.isNull() || !root->hasName( "notification_visibility" ))
+	{
+		llerrs << "Problem reading UI Notification Visibility Rules file: " << full_filename << llendl;
+		return false;
+	}
+
+	LLNotificationVisibilityRule::Rules params;
+	LLXUIParser parser;
+	parser.readXUI(root, params, full_filename);
+
+	mVisibilityRules.clear();
+
+	for(LLInitParam::ParamIterator<LLNotificationVisibilityRule::Params>::iterator it = params.rules.begin(), end_it = params.rules.end();
+		it != end_it;
+		++it)
+	{
+		mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(*it)));
+	}
+
+	return true;
+}
+
 // Add a simple notification (from XUI)
 void LLNotifications::addFromCallback(const LLSD& name)
 {
@@ -1553,6 +1596,36 @@ bool LLNotifications::getIgnoreAllNotifications()
 {
 	return mIgnoreAllNotifications; 
 }
+
+bool LLNotifications::isVisibleByRules(LLNotificationPtr n)
+{
+	VisibilityRuleList::iterator it;
+	
+	for(it = mVisibilityRules.begin(); it != mVisibilityRules.end(); it++)
+	{
+		// An empty type or tag string will match any notification, so only do the comparison when the string is non-empty in the rule.
+
+		if(!(*it)->mType.empty())
+		{
+			if((*it)->mType != n->getType())
+			{
+				// Type doesn't match, so skip this rule.
+				continue;
+			}
+		}
+		
+		if(!(*it)->mTag.empty())
+		{
+			// TODO: check this notification's tag(s) against it->mTag and continue if no match is found.
+		}
+		
+		// If we got here, the rule matches.  Don't evaluate subsequent rules.
+		return (*it)->mVisible;
+	}
+	
+	// Default for cases with no rules or incomplete rules is to show all notifications.
+	return true;
+}
 													
 // ---
 // END OF LLNotifications implementation
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 4fe1687f0e..75c67151ca 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -268,6 +268,11 @@ struct LLNotificationTemplate;
 // with smart pointers
 typedef boost::shared_ptr<LLNotificationTemplate> LLNotificationTemplatePtr;
 
+
+struct LLNotificationVisibilityRule;
+
+typedef boost::shared_ptr<LLNotificationVisibilityRule> LLNotificationVisibilityRulePtr;
+
 /**
  * @class LLNotification
  * @brief The object that expresses the details of a notification
@@ -856,6 +861,10 @@ public:
 	// load notification descriptions from file; 
 	// OK to call more than once because it will reload
 	bool loadTemplates();  
+
+	// load visibility rules from file; 
+	// OK to call more than once because it will reload
+	bool loadVisibilityRules();  
 	
 	// Add a simple notification (from XUI)
 	void addFromCallback(const LLSD& name);
@@ -902,6 +911,8 @@ public:
 	// test for existence
 	bool templateExists(const std::string& name);
 
+	typedef std::list<LLNotificationVisibilityRulePtr> VisibilityRuleList;
+	
 	void forceResponse(const LLNotification::Params& params, S32 option);
 
 	void createDefaultChannels();
@@ -916,7 +927,9 @@ public:
 
 	void setIgnoreAllNotifications(bool ignore);
 	bool getIgnoreAllNotifications();
-
+	
+	bool isVisibleByRules(LLNotificationPtr pNotification);
+	
 private:
 	// we're a singleton, so we don't have a public constructor
 	LLNotifications();
@@ -935,6 +948,8 @@ private:
 	// put your template in
 	bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate);
 	TemplateMap mTemplates;
+	
+	VisibilityRuleList mVisibilityRules;
 
 	std::string mFileName;
 	
diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h
new file mode 100644
index 0000000000..a98591c9d6
--- /dev/null
+++ b/indra/llui/llnotificationvisibilityrule.h
@@ -0,0 +1,76 @@
+/**
+* @file llnotificationvisibility.h
+* @brief Rules for 
+* @author Monroe
+*
+* $LicenseInfo:firstyear=2010&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$
+*/
+
+#ifndef LL_LLNOTIFICATION_VISIBILITY_RULE_H
+#define LL_LLNOTIFICATION_VISIBILITY_RULE_H
+
+#include "llinitparam.h"
+//#include "llnotifications.h"
+
+
+
+// This is the class of object read from the XML file (notification_visibility.xml, 
+// from the appropriate local language directory).
+struct LLNotificationVisibilityRule
+{
+	struct Params : public LLInitParam::Block<Params>
+	{
+		Mandatory<bool>	visible;
+		Optional<std::string> type;
+		Optional<std::string> tag;
+
+		Params()
+		:	visible("visible"),
+			type("type"),
+			tag("tag")
+		{}
+	};
+
+
+	struct Rules : public LLInitParam::Block<Rules>
+	{
+		Multiple<Params>	rules;
+
+		Rules()
+		:	rules("rule")
+		{}
+	};
+
+	LLNotificationVisibilityRule(const Params& p);
+	
+    // If true, this rule makes matching notifications visible.  Otherwise, it makes them invisible.
+    bool mVisible;
+
+    // String to match against the notification's "type".  An empty string matches all notifications.
+    std::string mType;
+	
+    // String to match against the notification's tag(s).  An empty string matches all notifications.
+	std::string mTag;
+};
+
+#endif //LL_LLNOTIFICATION_VISIBILITY_RULE_H
+
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 42dc60f9e0..29af81d64c 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -174,6 +174,7 @@ BOOL LLFloaterNotificationConsole::postBuild()
 	// these are in the order of processing
 	addChannel("Unexpired");
 	addChannel("Ignore");
+	addChannel("VisibilityRules");
 	addChannel("Visible", true);
 	// all the ones below attach to the Visible channel
 	addChannel("Persistent");
diff --git a/indra/newview/skins/default/xui/en/notification_visibility.xml b/indra/newview/skins/default/xui/en/notification_visibility.xml
new file mode 100644
index 0000000000..cb36890fe6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/notification_visibility.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<notification_visibility>
+	<rule visible="true"/> 
+</notification_visibility>
+
-- 
cgit v1.2.3