From c4c465b6c7d6ca4149d9ffabea326ce00e6df45b Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 7 Nov 2015 14:52:46 +0100 Subject: [PATCH] Fixed: Get system language code under OS X too and added method in NLMISC::CI18N --- code/nel/include/nel/misc/i18n.h | 8 ++ code/nel/src/misc/i18n.cpp | 108 +++++++++++++++++++++++++++ code/ryzom/client/src/client_cfg.cpp | 5 +- 3 files changed, 117 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/misc/i18n.h b/code/nel/include/nel/misc/i18n.h index 5f98c5f34..1102a8907 100644 --- a/code/nel/include/nel/misc/i18n.h +++ b/code/nel/include/nel/misc/i18n.h @@ -104,6 +104,11 @@ public: */ static const std::vector &getLanguageCodes(); + /** Check if a language code is supported. + * Code are ISO 639-2 compliant. + */ + static bool isLanguageCodeSupported(const std::string &lang); + /// Load a language file depending of the language code("en", "fr", ...). Code are ISO 639-2 compliant. static void load (const std::string &languageCode, const std::string &fallbackLanguageCode=""); @@ -119,6 +124,9 @@ public: /// Returns the code of the language ("fr", "en", ...) static std::string getCurrentLanguageCode (); + /// Returns the code of the language ("fr", "en", ...) defined on system + static std::string getSystemLanguageCode (); + /// Find a string in the selected language and return his association. static const ucstring &get (const std::string &label); diff --git a/code/nel/src/misc/i18n.cpp b/code/nel/src/misc/i18n.cpp index e53750af7..0badbdb62 100644 --- a/code/nel/src/misc/i18n.cpp +++ b/code/nel/src/misc/i18n.cpp @@ -20,6 +20,12 @@ #include "nel/misc/path.h" #include "nel/misc/i18n.h" +#include + +#ifdef NL_OS_MAC +#include +#endif + using namespace std; #ifdef DEBUG_NEW @@ -226,6 +232,108 @@ string CI18N::getCurrentLanguageCode () return _SelectedLanguageCode; } +bool CI18N::isLanguageCodeSupported(const std::string &lang) +{ + initLanguages(); + + for (sint i = 0, ilen = _LanguageCodes.size(); i < ilen; ++i) + { + if (lang == _LanguageCodes[i]) return true; + } + + return false; +} + +std::string CI18N::getSystemLanguageCode () +{ + static std::string s_cachedSystemLanguage; + + if (!s_cachedSystemLanguage.empty()) + return s_cachedSystemLanguage; + +#ifdef NL_OS_MAC + // under OS X, locale is only defined in console, not in UI + // so we need to use CoreFoundation API to retrieve it + + // get an array with all preferred languages + CFArrayRef langs = CFLocaleCopyPreferredLanguages(); + + if (langs) + { + // get languages count + sint languagesCount = CFArrayGetCount(langs); + + // process each language + for (sint i = 0; i < languagesCount; ++i) + { + std::string lang; + + // get language CFString + CFStringRef langCF = (CFStringRef)CFArrayGetValueAtIndex(langs, i); + + if (langCF) + { + // get a C string from CFString + const char *langStr = CFStringGetCStringPtr(langCF, kCFStringEncodingASCII); + + if (!langStr) + { + // get length of the CFString + CFIndex length = CFStringGetLength(langCF); + + // allocate a temporary buffer to hold converted string + char *tmp = new char[length+1]; + + // use alternative function to get a C string from CFString + if (CFStringGetCString(langCF, tmp, length+1, kCFStringEncodingASCII)) + { + lang = std::string(tmp, length); + } + else + { + nlerror("Unable to convert CFStringRef to string"); + } + + delete [] tmp; + } + else + { + lang = std::string(langStr); + } + + CFRelease(langCF); + } + + // only keep language code if supported by NeL + if (!lang.empty() && isLanguageCodeSupported(lang)) + { + s_cachedSystemLanguage = lang; + break; + } + } + + // don't need languages array anymore + CFRelease(langs); + } +#endif + + // use system locale (works under Linux and Windows) + if (s_cachedSystemLanguage.empty()) + { + std::string lang = NLMISC::toLower(std::string(setlocale(LC_CTYPE, ""))); + + // only keep 2 first characters + if (lang.size() > 1) + s_cachedSystemLanguage = lang.substr(0, 2); + } + + // english is default language + if (s_cachedSystemLanguage.empty()) + s_cachedSystemLanguage = "en"; + + return s_cachedSystemLanguage; +} + void CI18N::removeCComment(ucstring &commentedString) { ucstring temp; diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index ff86b5091..7c964904b 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -49,8 +49,6 @@ #include "app_bundle_utils.h" #endif // NL_OS_MAC -#include - /////////// // MACRO // /////////// @@ -1934,8 +1932,7 @@ void CClientConfig::init(const string &configFileName) nlwarning("CFG::init: creating '%s' with default values", configFileName.c_str ()); // get current locale - std::string lang = toLower(std::string(setlocale(LC_CTYPE, ""))); - lang = lang.substr(0, 2); + std::string lang = CI18N::getSystemLanguageCode(); const std::vector &languages = CI18N::getLanguageCodes();