X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Flocale.cxx;h=fd7a5f2b5137aeb8a1f290a69db414f23bde2fb4;hb=0c00cd3c6d34e4e167457897a274864cb7236da6;hp=cd868ca17e3a17ed0830214761b55711bfd08627;hpb=470552fab1c55a6c8168120997bcd54c115e3bb4;p=flightgear.git diff --git a/src/Main/locale.cxx b/src/Main/locale.cxx index cd868ca17..fd7a5f2b5 100644 --- a/src/Main/locale.cxx +++ b/src/Main/locale.cxx @@ -16,7 +16,18 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +#include +#endif + +#include +#include #include #include @@ -37,12 +48,70 @@ FGLocale::~FGLocale() { } +#ifdef _WIN32 +/** + * Determine locale/language settings on Windows. + * + * Copyright (C) 1997, 2002, 2003 Martin von Loewis + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies. + * + * This software comes with no warranty. Use at your own risk. + */ +string_list +FGLocale::getUserLanguage() +{ + string_list result; + static char locale[100] = {0}; + + if (GetLocaleInfo(LOCALE_USER_DEFAULT, + LOCALE_SISO639LANGNAME, + locale, sizeof(locale))) + { + SG_LOG(SG_GENERAL, SG_DEBUG, "Detected locale's language setting: " << locale); + size_t i = strlen(locale); + locale[i++] = '_'; + if (GetLocaleInfo(LOCALE_USER_DEFAULT, + LOCALE_SISO3166CTRYNAME, + locale+i, (int)(sizeof(locale)-i))) + { + result.push_back(locale); + return result; + } + + locale[--i] = 0; + SG_LOG(SG_GENERAL, SG_WARN, "Failed to detected locale's country setting."); + result.push_back(locale); + return result; + } + + return result; +} +#elif __APPLE__ +// implemented in CocoaHelpers.mm +#else +/** + * Determine locale/language settings on Linux/Unix. + */ +string_list +FGLocale::getUserLanguage() +{ + string_list result; + const char* langEnv = ::getenv("LANG"); + if (langEnv) { + result.push_back(langEnv); + } + + return result; +} +#endif + // Search property tree for matching locale description SGPropertyNode* FGLocale::findLocaleNode(const string& language) { - SG_LOG(SG_GENERAL, SG_INFO, "Searching language resource for locale: " << language); - SGPropertyNode* node = NULL; // remove character encoding from the locale spec, i.e. "de_DE.utf8" => "de_DE" @@ -54,15 +123,7 @@ FGLocale::findLocaleNode(const string& language) return node; } - // try country's default resource, i.e. "de_DE" => "de" - pos = language.find("_"); - if ((pos != string::npos)&&(pos>0)) - { - node = findLocaleNode(language.substr(0, pos)); - if (node) - return node; - } - + SG_LOG(SG_GENERAL, SG_DEBUG, "Searching language resource for locale: " << language); // search locale using full string vector localeList = _intl->getChildren("locale"); @@ -72,11 +133,23 @@ FGLocale::findLocaleNode(const string& language) for (size_t j = 0; j < langList.size(); j++) { - if (!language.compare(langList[j]->getStringValue())) - return localeList[i]; + if (!language.compare(langList[j]->getStringValue())) + { + SG_LOG(SG_GENERAL, SG_INFO, "Found language resource for: " << language); + return localeList[i]; + } } } + // try country's default resource, i.e. "de_DE" => "de" + pos = language.find("_"); + if ((pos != string::npos)&&(pos>0)) + { + node = findLocaleNode(language.substr(0, pos)); + if (node) + return node; + } + return NULL; } @@ -85,26 +158,42 @@ FGLocale::findLocaleNode(const string& language) bool FGLocale::selectLanguage(const char *language) { - // Use environment setting when no language is given. - if ((language == NULL)||(language[0]==0)) - language = ::getenv("LANG"); + string_list languages = getUserLanguage(); + if (languages.empty()) { + // Use plain C locale if nothing is available. + SG_LOG(SG_GENERAL, SG_WARN, "Unable to detect system language" ); + languages.push_back("C"); + } + + // if we were passed a language option, try it first + if ((language != NULL) && (strlen(language) > 0)) { + languages.insert(languages.begin(), string(language)); + } - // Use plain C locale if nothing is available. - if (language == NULL) - { - SG_LOG(SG_GENERAL, SG_INFO, "Unable to detect the language" ); - language = "C"; + + _currentLocale = NULL; + BOOST_FOREACH(string lang, languages) { + SG_LOG(SG_GENERAL, SG_DEBUG, "trying to find locale for " << lang ); + _currentLocale = findLocaleNode(lang); + if (_currentLocale) { + SG_LOG(SG_GENERAL, SG_DEBUG, "found locale for " << lang << " at " << _currentLocale->getPath() ); + break; + } } + + // load resource for system messages (translations for fgfs internal messages) + loadResource("sys"); + + // load resource for atc messages + loadResource("atc"); - SGPropertyNode *locale = findLocaleNode(language); - if (!locale) + if (!_currentLocale) { SG_LOG(SG_GENERAL, SG_ALERT, - "No internationalization settings specified in preferences.xml" ); + "System locale not found or no internationalization settings specified in preferences.xml. Using default (en)." ); return false; } - _currentLocale = locale; return true; } @@ -120,22 +209,22 @@ FGLocale::loadResource(SGPropertyNode* localeNode, const char* resource) const char *path_str = stringNode->getStringValue(resource, NULL); if (!path_str) { - SG_LOG(SG_GENERAL, SG_ALERT, "No path in " << stringNode->getPath() << "/" << resource << "."); - return NULL; + SG_LOG(SG_GENERAL, SG_WARN, "No path in " << stringNode->getPath() << "/" << resource << "."); + return false; } path.append(path_str); SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings for '" << localeNode->getStringValue("lang", "") - <<"' from " << path.str()); + <<"' from " << path); // load the actual file try { - readProperties(path.str(), stringNode->getNode(resource, 0, true)); + readProperties(path, stringNode->getNode(resource, 0, true)); } catch (const sg_exception &e) { - SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings from " << path.str() << + SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings from " << path << ". Error: " << e.getFormattedMessage()); return false; } @@ -208,14 +297,14 @@ FGLocale::getLocalizedStrings(const char* id, const char* resource) if (_currentLocale) { simgear::PropertyList s = getLocalizedStrings(_currentLocale, id, resource); - if (s.size()) + if (! s.empty()) return s; } if (_defaultLocale) { simgear::PropertyList s = getLocalizedStrings(_defaultLocale, id, resource); - if (s.size()) + if (! s.empty()) return s; } } @@ -243,6 +332,24 @@ FGLocale::getDefaultFont(const char* fallbackFont) return fallbackFont; } +std::string FGLocale::localizedPrintf(const char* id, const char* resource, ... ) +{ + va_list args; + va_start(args, resource); + string r = vlocalizedPrintf(id, resource, args); + va_end(args); + return r; +} + +std::string FGLocale::vlocalizedPrintf(const char* id, const char* resource, va_list args) +{ + const char* format = getLocalizedString(id, resource); + int len = ::vsprintf(NULL, format, args); + char* buf = (char*) alloca(len); + ::vsprintf(buf, format, args); + return std::string(buf); +} + // Simple UTF8 to Latin1 encoder. void FGLocale::utf8toLatin1(string& s) { @@ -292,3 +399,18 @@ void FGLocale::utf8toLatin1(string& s) pos++; } } + +const char* fgTrMsg(const char* key) +{ + return globals->get_locale()->getLocalizedString(key, "message"); +} + +std::string fgTrPrintfMsg(const char* key, ...) +{ + va_list args; + va_start(args, key); + string r = globals->get_locale()->vlocalizedPrintf(key, "message", args); + va_end(args); + return r; + +}