nat_linden avatar nat_linden committed 47c84c1

Make LLTransUtil::parseStrings() merge all relevant strings.xml files.
Until now, adding a xui/en/strings.xml file in any non-default skin meant you
had to clone the entire file, editing only the particular entries you wanted
to override. With this change, we load strings.xml file(s) from the default
skin before loading the specified skin -- so a non-default skin can now
provide a strings.xml file containing only the specific entries it wants to
override.

Comments (0)

Files changed (2)

indra/llui/lltransutil.cpp

 #include "lltrans.h"
 #include "lluictrlfactory.h"
 #include "llxmlnode.h"
-
+#include "lldir.h"
 
 bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args)
 {
+	// LLUICtrlFactory::getLayeredXMLNode() just calls
+	// gDirUtilp->findSkinnedFilenames(merge=false) and then passes the
+	// resulting paths to LLXMLNode::getLayeredXMLNode(). Bypass that and call
+	// LLXMLNode::getLayeredXMLNode() directly: we want merge=true.
+	std::vector<std::string> paths =
+		gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename, true);
+	if (paths.empty())
+	{
+		// xml_filename not found at all in any skin -- check whether entire
+		// path was passed (but I hope we no longer have callers who do that)
+		paths.push_back(xml_filename);
+	}
 	LLXMLNodePtr root;
-	BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+	bool success = LLXMLNode::getLayeredXMLNode(root, paths);
 	if (!success)
 	{
-		llerrs << "Couldn't load string table" << llendl;
+		llerrs << "Couldn't load string table " << xml_filename << llendl;
 		return false;
 	}
 
 	
 	if (!success)
 	{
-		llerrs << "Couldn't load string table " << xml_filename << llendl;
+		llerrs << "Couldn't load localization table " << xml_filename << llendl;
 		return false;
 	}
 	

indra/llxml/llxmlnode.cpp

 
 	std::vector<std::string>::const_iterator itor;
 
-	for (itor = paths.begin(), ++itor; itor != paths.end(); ++itor)
+	// We've already dealt with the first item, skip that one
+	for (itor = paths.begin() + 1; itor != paths.end(); ++itor)
 	{
 		std::string layer_filename = *itor;
 		if(layer_filename.empty() || layer_filename == filename)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.