From c4c465b6c7d6ca4149d9ffabea326ce00e6df45b Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 7 Nov 2015 14:52:46 +0100 Subject: [PATCH 1/4] 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(); From 2de3fc3384f9d6605c1d31e7b1407bab5db1af5a Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 7 Nov 2015 14:53:07 +0100 Subject: [PATCH 2/4] Changed: Add support for Spanish --- code/nel/src/misc/i18n.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/src/misc/i18n.cpp b/code/nel/src/misc/i18n.cpp index 0badbdb62..99e9c68a0 100644 --- a/code/nel/src/misc/i18n.cpp +++ b/code/nel/src/misc/i18n.cpp @@ -58,11 +58,13 @@ void CI18N::initLanguages() _LanguageCodes.push_back("fr"); _LanguageCodes.push_back("de"); _LanguageCodes.push_back("ru"); + _LanguageCodes.push_back("es"); _LanguageNames.push_back(ucstring("English")); _LanguageNames.push_back(ucstring("French")); _LanguageNames.push_back(ucstring("German")); _LanguageNames.push_back(ucstring("Russian")); + _LanguageNames.push_back(ucstring("Spanish")); _LanguagesNamesLoaded = true; } From 4426a9165708f1790f8487a32e02bec7c142c146 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 7 Nov 2015 14:53:49 +0100 Subject: [PATCH 3/4] Changed: Minor changes --- code/ryzom/client/src/app_bundle_utils.cpp | 30 ++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/code/ryzom/client/src/app_bundle_utils.cpp b/code/ryzom/client/src/app_bundle_utils.cpp index b42b00b98..42d1b61bc 100644 --- a/code/ryzom/client/src/app_bundle_utils.cpp +++ b/code/ryzom/client/src/app_bundle_utils.cpp @@ -17,53 +17,57 @@ #include "stdpch.h" #include "app_bundle_utils.h" -#if defined(NL_OS_MAC) +#ifdef NL_OS_MAC #include #endif std::string getAppBundlePath() { - static std::string cachedPathToBundle; + static std::string s_cachedPathToBundle; - if(cachedPathToBundle.size()) - return cachedPathToBundle; + if (!s_cachedPathToBundle.empty()) + return s_cachedPathToBundle; #if defined(NL_OS_MAC) // get the bundle CFBundleRef bundle = CFBundleGetMainBundle(); - if(bundle) + if (bundle) { // get the url to the bundles root CFURLRef url = CFBundleCopyBundleURL(bundle); - if(url) + if (url) { // get the file system path CFStringRef str; - str = CFURLCopyFileSystemPath( - CFURLCopyAbsoluteURL(url), kCFURLPOSIXPathStyle); + str = CFURLCopyFileSystemPath(CFURLCopyAbsoluteURL(url), kCFURLPOSIXPathStyle); CFRelease(url); - if(str) + if (str) { - cachedPathToBundle = CFStringGetCStringPtr( - str, CFStringGetSmallestEncoding(str)); + s_cachedPathToBundle = CFStringGetCStringPtr(str, CFStringGetSmallestEncoding(str)); CFRelease(str); } else + { nlerror("CFStringGetCStringPtr"); + } } else + { nlerror("CFBundleCopyBundleURL"); + } } else + { nlerror("CFBundleGetMainBundle"); + } #elif defined(NL_OS_WINDOWS) char buffer[MAX_PATH+1]; if (GetModuleFileNameA(NULL, buffer, MAX_PATH)) - cachedPathToBundle = NLMISC::CPath::standardizePath(NLMISC::CFile::getPath(buffer), false); + s_cachedPathToBundle = NLMISC::CPath::standardizePath(NLMISC::CFile::getPath(buffer), false); #endif // defined(NL_OS_MAC) - return cachedPathToBundle; + return s_cachedPathToBundle; } From 75aeb2ecf653935e32c1abc10750e72f68b66ed5 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 7 Nov 2015 14:54:24 +0100 Subject: [PATCH 4/4] Fixed: Clang warning, ContinentMngr.cur() is checked later --- code/ryzom/client/src/main_loop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 8a900f381..c0beba4c1 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -2015,7 +2015,7 @@ bool mainLoop() } // Temp for weather test - if (ClientCfg.ManualWeatherSetup && ContinentMngr.cur() && ContinentMngr.cur()->WeatherFunction) + if (ClientCfg.ManualWeatherSetup) { H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) static float displayHourDelta = 0.04f; // static for edition during debug..