From 8886460a22a6cc6307dd0909219b4dd442c55f8d Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 9 Mar 2011 00:21:57 -0800
Subject: [PATCH] SOCIAL-654 WIP Items purchased on Marketplace.secondlife.com
 while logged into Minimal skin are declined and not present in inventory made
 notification text skinnable

---
 indra/llui/llnotifications.cpp | 44 +++++++++++++++++++---------------
 indra/llui/llnotifications.h   | 11 ++++-----
 indra/llui/lluictrlfactory.cpp | 22 ++++++++++++++++-
 indra/llvfs/lldir.cpp          |  6 ++++-
 indra/llxml/llxmlnode.cpp      | 24 +++++++++----------
 indra/llxml/llxmlnode.h        |  3 +--
 6 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 89614e6d124..578de4376c3 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1266,7 +1266,6 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN
 void LLNotifications::initSingleton()
 {
 	loadTemplates();
-	loadVisibilityRules();
 	createDefaultChannels();
 }
 
@@ -1310,17 +1309,6 @@ void LLNotifications::createDefaultChannels()
 		connectFailedFilter(&visibilityRuleMached);
 }
 
-bool LLNotifications::addTemplate(const std::string &name, 
-								  LLNotificationTemplatePtr theTemplate)
-{
-	if (mTemplates.count(name))
-	{
-		llwarns << "LLNotifications -- attempted to add template '" << name << "' twice." << llendl;
-		return false;
-	}
-	mTemplates[name] = theTemplate;
-	return true;
-}
 
 LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name)
 {
@@ -1417,27 +1405,45 @@ void replaceFormText(LLNotificationForm::Params& form, const std::string& patter
 	}
 }
 
+void addPathIfExists(std::string& new_path, std::vector<std::string>& paths)
+{
+	if (gDirUtilp->fileExists(new_path))
+	{
+		paths.push_back(new_path);
+	}
+}
+
 bool LLNotifications::loadTemplates()
 {
-	const std::string xml_filename = "notifications.xml";
-	std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename);
+	std::vector<std::string> search_paths;
+	
+	std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
+	std::string localized_skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
+
+	addPathIfExists(gDirUtilp->getDefaultSkinDir() + skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getDefaultSkinDir() + localized_skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getSkinDir() + skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getSkinDir() + localized_skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getUserSkinDir() + skin_relative_path, search_paths);
+	addPathIfExists(gDirUtilp->getUserSkinDir() + localized_skin_relative_path, search_paths);
 
+	std::string base_filename = search_paths.front();
 	LLXMLNodePtr root;
-	BOOL success  = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+	BOOL success  = LLXMLNode::getLayeredXMLNode(root, search_paths);
 	
 	if (!success || root.isNull() || !root->hasName( "notifications" ))
 	{
-		llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
+		llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
 		return false;
 	}
 
 	LLNotificationTemplate::Notifications params;
 	LLXUIParser parser;
-	parser.readXUI(root, params, full_filename);
+	parser.readXUI(root, params, base_filename);
 
 	if(!params.validateBlock())
 	{
-		llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
+		llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
 		return false;
 	}
 
@@ -1484,7 +1490,7 @@ bool LLNotifications::loadTemplates()
 				replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);
 			}
 		}
-		addTemplate(it->name, LLNotificationTemplatePtr(new LLNotificationTemplate(*it)));
+		mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it));
 	}
 
 	return true;
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 34d3537781b..0c4d4fc897a 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -863,10 +863,11 @@ class LLNotifications :
 
 	friend class LLSingleton<LLNotifications>;
 public:
-	// load notification descriptions from file; 
-	// OK to call more than once because it will reload
-	bool loadTemplates();  
-	
+	// load all notification descriptions from file
+	// calling more than once will overwrite existing templates
+	// but never delete a template
+	bool loadTemplates();
+
 	// load visibility rules from file; 
 	// OK to call more than once because it will reload
 	bool loadVisibilityRules();  
@@ -950,8 +951,6 @@ class LLNotifications :
 	LLNotificationChannelPtr pHistoryChannel;
 	LLNotificationChannelPtr pExpirationChannel;
 	
-	// put your template in
-	bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate);
 	TemplateMap mTemplates;
 
 	VisibilityRuleList mVisibilityRules;
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 55b32fc8b1a..25e7a31e907 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -152,7 +152,27 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing");
 bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
 {
 	LLFastTimer timer(FTM_XML_PARSE);
-	return LLXMLNode::getLayeredXMLNode(xui_filename, root, LLUI::getXUIPaths());
+	
+	std::vector<std::string> paths;
+	std::string path = gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), xui_filename);
+	if (!path.empty())
+	{
+		paths.push_back(path);
+	}
+
+	std::string localize_path = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename);
+	if (!localize_path.empty() && localize_path != path)
+	{
+		paths.push_back(localize_path);
+	}
+
+	if (paths.empty())
+	{
+		// sometimes whole path is passed in as filename
+		paths.push_back(xui_filename);
+	}
+
+	return LLXMLNode::getLayeredXMLNode(root, paths);
 }
 
 
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index cb898e385f9..341c96f6ea7 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -149,7 +149,11 @@ const std::string LLDir::findFile(const std::string& filename, const std::vector
 	{
 		if (!search_path_iter->empty())
 		{
-			std::string filename_and_path = (*search_path_iter) + getDirDelimiter() + filename;
+			std::string filename_and_path = (*search_path_iter);
+			if (!filename.empty())
+			{
+				filename_and_path += getDirDelimiter() + filename;
+			}
 			if (fileExists(filename_and_path))
 			{
 				return filename_and_path;
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 8168f968cdc..9f1e249ddda 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -859,23 +859,21 @@ BOOL LLXMLNode::isFullyDefault()
 }
 
 // static
-bool LLXMLNode::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root,
+bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root,
 								  const std::vector<std::string>& paths)
 {
-	std::string full_filename = gDirUtilp->findSkinnedFilename(paths.front(), xui_filename);
-	if (full_filename.empty())
+	if (paths.empty()) return false;
+
+	std::string filename = paths.front();
+	if (filename.empty())
 	{
 		return false;
 	}
-
-	if (!LLXMLNode::parseFile(full_filename, root, NULL))
+	
+	if (!LLXMLNode::parseFile(filename, root, NULL))
 	{
-		// try filename as passed in since sometimes we load an xml file from a user-supplied path
-		if (!LLXMLNode::parseFile(xui_filename, root, NULL))
-		{
-			llwarns << "Problem reading UI description file: " << xui_filename << llendl;
-			return false;
-		}
+		llwarns << "Problem reading UI description file: " << filename << llendl;
+		return false;
 	}
 
 	LLXMLNodePtr updateRoot;
@@ -887,7 +885,7 @@ bool LLXMLNode::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr&
 		std::string nodeName;
 		std::string updateName;
 
-		std::string layer_filename = gDirUtilp->findSkinnedFilename((*itor), xui_filename);
+		std::string layer_filename = *itor;
 		if(layer_filename.empty())
 		{
 			// no localized version of this file, that's ok, keep looking
@@ -896,7 +894,7 @@ bool LLXMLNode::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr&
 
 		if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL))
 		{
-			llwarns << "Problem reading localized UI description file: " << (*itor) + gDirUtilp->getDirDelimiter() + xui_filename << llendl;
+			llwarns << "Problem reading localized UI description file: " << layer_filename << llendl;
 			return false;
 		}
 
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h
index 9df37ccb6f2..e3da7169e7e 100644
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -149,8 +149,7 @@ class LLXMLNode : public LLThreadSafeRefCount
 		LLXMLNodePtr& update_node);
 	static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
 	
-	static bool getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root,
-								  const std::vector<std::string>& paths);
+	static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths);
 	
 	
 	// Write standard XML file header:
-- 
GitLab