diff --git a/src/GUI/DefaultAircraftLocator.cxx b/src/GUI/DefaultAircraftLocator.cxx index bc6b952a9..043a82d05 100644 --- a/src/GUI/DefaultAircraftLocator.cxx +++ b/src/GUI/DefaultAircraftLocator.cxx @@ -4,6 +4,7 @@ #include <simgear/debug/logstream.hxx> #include <Main/globals.hxx> +#include <Main/locale.hxx> static SGPropertyNode_ptr loadXMLDefaults() { @@ -100,8 +101,17 @@ WeatherScenariosModel::WeatherScenariosModel(QObject *pr) : } WeatherScenario ws; - ws.name = QString::fromStdString(scenario->getStringValue("name")); - ws.description = QString::fromStdString(scenario->getStringValue("description")).simplified(); + const string wsId = scenario->getStringValue("id"); + if (!wsId.empty()) { + // translated + auto locale = globals->get_locale(); + ws.name = QString::fromStdString(locale->getLocalizedString(wsId + "-name", "weather-scenarios")); + ws.description = QString::fromStdString(locale->getLocalizedString(wsId + "-desc", "weather-scenarios")); + } else { + ws.name = QString::fromStdString(scenario->getStringValue("name")); + ws.description = QString::fromStdString(scenario->getStringValue("description")).simplified(); + } + ws.metar = QString::fromStdString(scenario->getStringValue("metar")); if (scenario->hasChild("local-weather")) { ws.localWeatherTileManagement = QString::fromStdString(scenario->getStringValue("local-weather/tile-management")); diff --git a/src/GUI/QtLauncher.cxx b/src/GUI/QtLauncher.cxx index c8271868d..4000ce7a5 100644 --- a/src/GUI/QtLauncher.cxx +++ b/src/GUI/QtLauncher.cxx @@ -61,10 +61,11 @@ #include <Add-ons/AddonManager.hxx> -#include <Main/options.hxx> #include <Main/fg_init.hxx> -#include <Viewer/WindowBuilder.hxx> +#include <Main/locale.hxx> +#include <Main/options.hxx> #include <Network/HTTPClient.hxx> +#include <Viewer/WindowBuilder.hxx> #include "LauncherMainWindow.hxx" #include "LaunchConfig.hxx" @@ -457,13 +458,16 @@ bool runLauncherDialog() // setup package language auto lang = options->valueForOption("language"); - if (!lang.empty()) { - globals->packageRoot()->setLocale(lang); - } else { + if (lang.empty()) { const auto langName = QLocale::languageToString(QLocale{}.language()); - globals->packageRoot()->setLocale(langName.toStdString()); + lang = langName.toStdString(); } + // we will re-do this later, but we want to access translated strings + // from within the launcher + globals->get_locale()->selectLanguage(lang); + globals->packageRoot()->setLocale(lang); + // startup the HTTP system now since packages needs it FGHTTPClient* http = globals->add_new_subsystem<FGHTTPClient>(); @@ -492,6 +496,7 @@ bool runLauncherDialog() // don't set scenery paths twice globals->clear_fg_scenery(); + globals->get_locale()->clear(); return true; } diff --git a/src/Main/locale.cxx b/src/Main/locale.cxx index 7626a8010..f7466f822 100644 --- a/src/Main/locale.cxx +++ b/src/Main/locale.cxx @@ -183,8 +183,7 @@ FGLocale::findLocaleNode(const string& localeSpec) // Select the language. When no language is given (nullptr), // a default is determined matching the system locale. -bool -FGLocale::selectLanguage(const char *language) +bool FGLocale::selectLanguage(const std::string& language) { string_list languages = getUserLanguage(); if (languages.empty()) { @@ -194,8 +193,8 @@ FGLocale::selectLanguage(const char *language) } // if we were passed a language option, try it first - if ((language != nullptr) && (std::strlen(language) > 0)) { - languages.insert(languages.begin(), string(language)); + if (!language.empty()) { + languages.insert(languages.begin(), language); } _currentLocaleString = removeEncodingPart(languages[0]); @@ -225,11 +224,9 @@ FGLocale::selectLanguage(const char *language) // load resource for system messages (translations for fgfs internal messages) loadResource("sys"); - - // load resource for atc messages loadResource("atc"); - loadResource("tips"); + loadResource("weather-scenarios"); _inited = true; if (!_currentLocale && !_currentLocaleString.empty()) { @@ -241,6 +238,19 @@ FGLocale::selectLanguage(const char *language) return true; } +void FGLocale::clear() +{ + _inited = false; + _currentLocaleString.clear(); + + if (_currentLocale) { + // remove loaded strings, so we don't duplicate + _currentLocale->removeChild("strings"); + } + + _currentLocale.clear(); +} + // Return the preferred language according to user choice and/or settings // (e.g., 'fr_FR', or the empty string if nothing could be found). std::string @@ -329,7 +339,7 @@ FGLocale::loadResource(const char* resource) } std::string -FGLocale::getLocalizedString(SGPropertyNode *localeNode, const char* id, const char* context, int index) const +FGLocale::innerGetLocalizedString(SGPropertyNode* localeNode, const char* id, const char* context, int index) const { SGPropertyNode *n = localeNode->getNode("strings",0, true)->getNode(context); if (!n) { @@ -344,6 +354,12 @@ FGLocale::getLocalizedString(SGPropertyNode *localeNode, const char* id, const c return std::string(); } +std::string +FGLocale::getLocalizedString(const std::string& id, const char* resource, const std::string& defaultValue) +{ + return getLocalizedString(id.c_str(), resource, defaultValue.c_str()); +} + std::string FGLocale::getLocalizedString(const char* id, const char* resource, const char* Default) { @@ -352,14 +368,14 @@ FGLocale::getLocalizedString(const char* id, const char* resource, const char* D { std::string s; if (_currentLocale) { - s = getLocalizedString(_currentLocale, id, resource, 0); + s = innerGetLocalizedString(_currentLocale, id, resource, 0); if (!s.empty()) { return s; } } if (_defaultLocale) { - s = getLocalizedString(_defaultLocale, id, resource, 0); + s = innerGetLocalizedString(_defaultLocale, id, resource, 0); if (!s.empty()) { return s; } @@ -376,14 +392,14 @@ FGLocale::getLocalizedStringWithIndex(const char* id, const char* resource, unsi if (id && resource) { std::string s; if (_currentLocale) { - s = getLocalizedString(_currentLocale, id, resource, index); + s = innerGetLocalizedString(_currentLocale, id, resource, index); if (!s.empty()) { return s; } } if (_defaultLocale) { - s = getLocalizedString(_defaultLocale, id, resource, index); + s = innerGetLocalizedString(_defaultLocale, id, resource, index); if (!s.empty()) { return s; } diff --git a/src/Main/locale.hxx b/src/Main/locale.hxx index 3bc25d70a..5490e5c46 100644 --- a/src/Main/locale.hxx +++ b/src/Main/locale.hxx @@ -44,7 +44,7 @@ public: * Select the locale's primary language. When no language is given * (nullptr), a default is determined matching the system locale. */ - bool selectLanguage(const char* language = nullptr); + bool selectLanguage(const std::string& language = {}); /** Return the preferred language according to user choice and/or settings. * @@ -73,6 +73,8 @@ public: std::string getLocalizedString(const char* id, const char* resource, const char* Default = nullptr); + std::string getLocalizedString(const std::string& id, const char* resource, const std::string& defaultValue = {}); + /** * Obtain a list of strings from the localized resource matching the given identifier. * Selected context refers to "menu", "options", "dialog" etc. @@ -109,7 +111,12 @@ public: */ static void utf8toLatin1 (std::string& s); - + /** + * reset all data in the locale. This is needed to allow the launcher to use the code, + without disturbing the main behaviour. Afteer calling this you can do + selectLangauge again without problems. + */ + void clear(); protected: /** @@ -125,7 +132,7 @@ protected: /** * Obtain a single string from locale node matching the given identifier and context. */ - std::string getLocalizedString (SGPropertyNode *localeNode, const char* id, const char* context, int index) const; + std::string innerGetLocalizedString(SGPropertyNode* localeNode, const char* id, const char* context, int index) const; /** * Obtain a list of strings from locale node matching the given identifier and context.