From 307df37ba76b92a118518239924dc139b085b234 Mon Sep 17 00:00:00 2001 From: A-lex-Ra Date: Tue, 26 Dec 2023 19:54:03 +0600 Subject: [PATCH] improve locale detection as much as possible --- src/engine.cpp | 2 +- src/frontend/locale/langs.cpp | 25 ++++++++++++++++++++++++- src/frontend/locale/langs.h | 3 +++ src/util/platform.cpp | 32 ++++++-------------------------- src/util/platform.h | 2 +- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 63762f09..84583d77 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -68,7 +68,7 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths) Audio::initialize(); gui = new gui::GUI(); if (settings.ui.language == "auto") { - settings.ui.language = platform::detect_locale(); + settings.ui.language = langs::locale_by_envlocale(platform::detect_locale(), paths->getResources()); } setLanguage(settings.ui.language); std::cout << "-- initializing finished" << std::endl; diff --git a/src/frontend/locale/langs.cpp b/src/frontend/locale/langs.cpp index 762e2756..af39b069 100644 --- a/src/frontend/locale/langs.cpp +++ b/src/frontend/locale/langs.cpp @@ -77,6 +77,7 @@ void langs::loadLocalesInfo(const path& resdir, string& fallback) { auto langs = root->obj("langs"); if (langs) { + std::cout << "locales "; for (auto& entry : langs->map) { auto langInfo = entry.second; @@ -87,9 +88,31 @@ void langs::loadLocalesInfo(const path& resdir, string& fallback) { continue; } - std::cout << "locale " << entry.first << " (" << name << ") added" << std::endl; + std::cout << "[" << entry.first << " (" << name << ")] "; langs::locales_info[entry.first] = LocaleInfo {entry.first, name}; } + std::cout << "added" << std::endl; + } +} + +std::string langs::locale_by_envlocale(const std::string& envlocale, const path& resdir){ + string fallback = FALLBACK_DEFAULT; + if (locales_info.size() == 0) { + loadLocalesInfo(resdir, fallback); + } + if (locales_info.find(envlocale) != locales_info.end()) { + std::cout << "locale " << envlocale << " is automatically selected" << std::endl; + return envlocale; + } + else { + for (const auto& loc : locales_info) { + if (loc.first.find(envlocale.substr(0, 2)) != std::string::npos) { + std::cout << "locale " << loc.first << " is automatically selected" << std::endl; + return loc.first; + } + } + std::cout << "locale " << fallback << " is automatically selected" << std::endl; + return fallback; } } diff --git a/src/frontend/locale/langs.h b/src/frontend/locale/langs.h index 7f6d916c..5f0e5aab 100644 --- a/src/frontend/locale/langs.h +++ b/src/frontend/locale/langs.h @@ -48,6 +48,9 @@ namespace langs { const std::filesystem::path& resdir, std::string& fallback); + extern std::string locale_by_envlocale(const std::string& envlocale, + const std::filesystem::path& resdir); + extern void load(const std::filesystem::path& resdir, const std::string& locale, const std::vector& packs, diff --git a/src/util/platform.cpp b/src/util/platform.cpp index c4a3500f..0ffc884f 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -7,18 +7,6 @@ #include "../typedefs.h" -namespace platform { - const std::string DEFAULT_LOCALE = "en_EN"; -} - -/*System locale to engine locale mapping*/ -std::string platform::get_locale_by_lang(std::string lang) { - if (lang == "ru") { - return "ru_RU"; - } - return DEFAULT_LOCALE; -} - #ifdef WIN32 #include @@ -32,18 +20,12 @@ void platform::configure_encoding() { std::string platform::detect_locale() { LCID lcid = GetThreadLocale(); - wchar_t preferredLocaleName[LOCALE_NAME_MAX_LENGTH]; + wchar_t preferredLocaleName[LOCALE_NAME_MAX_LENGTH];//locale name format: ll-CC if (LCIDToLocaleName(lcid, preferredLocaleName, LOCALE_NAME_MAX_LENGTH, 0) == 0) { - std::cout << "error in platform::detect_locale! LCIDToLocaleName failed." << std::endl; + std::cerr << "error in platform::detect_locale! LCIDToLocaleName failed." << std::endl; } - wchar_t parentLocaleName[LOCALE_NAME_MAX_LENGTH]; - if (GetLocaleInfoEx(preferredLocaleName, LOCALE_SPARENT, parentLocaleName, LOCALE_NAME_MAX_LENGTH) == 0){ - std::cout << "error in platform::detect_locale! GetLocaleInfoEx failed." << std::endl; - } - std::wcout << "detected environment language locale: " << parentLocaleName << std::endl; - - std::string preferredLang = util::wstr2str_utf8(parentLocaleName); - return get_locale_by_lang(preferredLang); + //ll_CC format + return util::wstr2str_utf8(preferredLocaleName).replace(2, 1, "_").substr(0, 5); } #else @@ -53,12 +35,10 @@ void platform::configure_encoding(){ std::string platform::detect_locale() { std::string programLocaleName = setlocale(LC_ALL, nullptr); - std::string preferredLocaleName = setlocale(LC_ALL, ""); - std::cout << "detected environment locale: " << preferredLocaleName << std::endl; + std::string preferredLocaleName = setlocale(LC_ALL, ""); //locale name format: ll_CC.encoding setlocale(LC_ALL, programLocaleName.c_str()); - std::string preferredLang = preferredLocaleName.substr(0, 2); - return get_locale_by_lang(preferredLang); + return preferredLocaleName.substr(0, 5); } #endif \ No newline at end of file diff --git a/src/util/platform.h b/src/util/platform.h index f955cd55..a53ec40c 100644 --- a/src/util/platform.h +++ b/src/util/platform.h @@ -5,8 +5,8 @@ namespace platform { extern void configure_encoding(); + // @return environment locale in ISO format ll_CC extern std::string detect_locale(); - extern std::string get_locale_by_lang(std::string lang); } #endif // UTIL_PLATFORM_H_ \ No newline at end of file