Improve locale handling
- fgfs --language=fr-FR now works as expected for the launcher (also with --language=fr_FR as before): the value added by option --language to the _languages member of FGLocale is normalized in "underscore" style (e.g., fr_FR). - Add-on translations must now use a hyphen in their property node names in addon-metadata.xml (talking about children of <localized>): i.e., use for instance <fr-FR> there, not <fr_FR>. An exception (addons::errors::error_loading_metadata_file) is thrown if one of these nodes has a name containing an underscore.
This commit is contained in:
parent
54264e6591
commit
f105e8dfb2
3 changed files with 38 additions and 4 deletions
|
@ -73,6 +73,29 @@ static string getMaybeLocalized(const string& tag, SGPropertyNode* base, SGPrope
|
|||
return {};
|
||||
}
|
||||
|
||||
static SGPropertyNode* getAndCheckLocalizedNode(SGPropertyNode* addonNode,
|
||||
const SGPath& metadataFile)
|
||||
{
|
||||
const auto localizedNode = addonNode->getChild("localized");
|
||||
if (!localizedNode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < localizedNode->nChildren(); ++i) {
|
||||
const auto node = localizedNode->getChild(i);
|
||||
const string& name = node->getNameString();
|
||||
|
||||
if (name.find('_') != string::npos) {
|
||||
throw errors::error_loading_metadata_file(
|
||||
"underscores not allowed in names of children of <localized> "
|
||||
"(in add-on metadata file '" + metadataFile.utf8Str() + "'); "
|
||||
"hyphens should be used, as in 'fr-FR' or 'en-GB'");
|
||||
}
|
||||
}
|
||||
|
||||
return localizedNode;
|
||||
}
|
||||
|
||||
// Static method
|
||||
Addon::Metadata
|
||||
Addon::MetadataParser::parseMetadataFile(const SGPath& addonPath)
|
||||
|
@ -141,7 +164,7 @@ Addon::MetadataParser::parseMetadataFile(const SGPath& addonPath)
|
|||
metadataFile.utf8Str() + "'");
|
||||
}
|
||||
|
||||
SGPropertyNode* localizedNode = addonNode->getChild("localized");
|
||||
const auto localizedNode = getAndCheckLocalizedNode(addonNode, metadataFile);
|
||||
SGPropertyNode* langStringsNode = globals->get_locale()->selectLanguageNode(localizedNode);
|
||||
|
||||
SGPropertyNode *idNode = addonNode->getChild("identifier");
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/package/Root.hxx>
|
||||
#include <simgear/package/Catalog.hxx>
|
||||
#include <simgear/package/Package.hxx>
|
||||
|
@ -292,7 +293,10 @@ void initApp(int& argc, char** argv, bool doInitQSettings)
|
|||
QTranslator* translator = new QTranslator(static_qApp.get());
|
||||
// check for --langauge=xx option and prefer that over QLocale
|
||||
// detection of the locale if it exists
|
||||
auto lang = Options::getArgValue(argc, argv, "--language");
|
||||
auto lang = simgear::strutils::replace(
|
||||
Options::getArgValue(argc, argv, "--language"),
|
||||
"-",
|
||||
"_");
|
||||
if (!lang.empty()) {
|
||||
QString localeFile = "FlightGear_" + QString::fromStdString(lang);
|
||||
if (translator->load(localeFile, QLatin1String(":/"))) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <cstddef> // std::size_t
|
||||
#include <cassert>
|
||||
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
@ -41,6 +42,7 @@
|
|||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
namespace strutils = simgear::strutils;
|
||||
|
||||
FGLocale::FGLocale(SGPropertyNode* root) :
|
||||
_intl(root->getNode("/sim/intl", 0, true)),
|
||||
|
@ -178,6 +180,7 @@ FGLocale::findLocaleNode(const string& localeSpec)
|
|||
}
|
||||
}
|
||||
|
||||
// try country's default resource, i.e. "de_DE" => "de"
|
||||
const auto justTheLanguage = removeLocalePart(language);
|
||||
if (!justTheLanguage.empty()) {
|
||||
node = findLocaleNode(justTheLanguage);
|
||||
|
@ -201,7 +204,8 @@ bool FGLocale::selectLanguage(const std::string& language)
|
|||
|
||||
// if we were passed a language option, try it first
|
||||
if (!language.empty()) {
|
||||
_languages.insert(_languages.begin(), language);
|
||||
const auto normalizedLang = strutils::replace(language, "-", "_");
|
||||
_languages.insert(_languages.begin(), normalizedLang);
|
||||
}
|
||||
|
||||
_currentLocaleString = removeEncodingPart(_languages.front());
|
||||
|
@ -600,7 +604,10 @@ SGPropertyNode_ptr FGLocale::selectLanguageNode(SGPropertyNode* langs) const
|
|||
return {};
|
||||
|
||||
for (auto l : _languages) {
|
||||
const auto langNoEncoding = removeEncodingPart(l);
|
||||
// Only accept the hyphen separator in PropertyList node names between
|
||||
// language and territory
|
||||
const auto langNoEncoding = strutils::replace(removeEncodingPart(l),
|
||||
"_", "-");
|
||||
if (langs->hasChild(langNoEncoding)) {
|
||||
return langs->getChild(langNoEncoding);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue