From e8370769a911c3113af2cb68e28cf726cbb59554 Mon Sep 17 00:00:00 2001 From: y5nw <37980625+y5nw@users.noreply.github.com> Date: Mon, 24 Feb 2025 16:32:09 +0100 Subject: [PATCH] Rework translate_string and related --- src/gui/guiEngine.cpp | 52 +++++++++++++++++-------------- src/gui/guiEngine.h | 2 +- src/script/lua_api/l_env.cpp | 3 +- src/script/lua_api/l_mainmenu.cpp | 4 +-- src/translation.h | 5 ++- src/util/string.cpp | 23 +++++++------- src/util/string.h | 2 +- 7 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index 99a755d41f..fba12cd163 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -229,42 +229,46 @@ std::string findLocaleFileInMods(const std::string &path, const std::string &fil /******************************************************************************/ Translations *GUIEngine::getContentTranslations(const std::string &path, - const std::string &domain, const std::string &lang_code) + const std::string &domain, const std::vector &lang) { - if (domain.empty() || lang_code.empty()) + if (domain.empty() || lang.empty()) return nullptr; - std::string filename_no_ext = domain + "." + lang_code; - std::string key = path + DIR_DELIM "locale" DIR_DELIM + filename_no_ext; + std::string key = path + DIR_DELIM "locale" DIR_DELIM + domain; if (key == m_last_translations_key) return &m_last_translations; - std::string trans_path = key; - - switch (getContentType(path)) { - case ContentType::GAME: - trans_path = findLocaleFileInMods(path + DIR_DELIM "mods" DIR_DELIM, - filename_no_ext); - break; - case ContentType::MODPACK: - trans_path = findLocaleFileInMods(path, filename_no_ext); - break; - default: - trans_path = findLocaleFileWithExtension(trans_path); - break; + Translations translations; + for (const auto &lang_code: lang) { + auto utf8_lang_code = wide_to_utf8(lang_code); + std::string filename_no_ext = domain + "." + utf8_lang_code; + auto trans_path = key + "." + utf8_lang_code; + switch (getContentType(path)) { + case ContentType::GAME: + trans_path = findLocaleFileInMods(path + DIR_DELIM "mods" DIR_DELIM, + filename_no_ext); + break; + case ContentType::MODPACK: + trans_path = findLocaleFileInMods(path, filename_no_ext); + break; + default: + trans_path = findLocaleFileWithExtension(trans_path); + break; + } + if (trans_path.empty()) + continue; + std::string data; + if (fs::ReadFile(trans_path, data)) { + translations.loadTranslation(fs::GetFilenameFromPath(trans_path.c_str()), data); + } } - if (trans_path.empty()) + if (translations.empty()) return nullptr; m_last_translations_key = key; - m_last_translations = {}; - - std::string data; - if (fs::ReadFile(trans_path, data)) { - m_last_translations.loadTranslation(fs::GetFilenameFromPath(trans_path.c_str()), data); - } + m_last_translations = std::move(translations); return &m_last_translations; } diff --git a/src/gui/guiEngine.h b/src/gui/guiEngine.h index da0700319d..e1ae45ed4f 100644 --- a/src/gui/guiEngine.h +++ b/src/gui/guiEngine.h @@ -156,7 +156,7 @@ public: * change with the next call to `getContentTranslations`. * */ Translations *getContentTranslations(const std::string &path, - const std::string &domain, const std::string &lang_code); + const std::string &domain, const std::vector &lang_code); private: std::string m_last_translations_key; diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index eff68ec852..ad3d83b8b7 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -1376,9 +1376,10 @@ int ModApiEnv::l_get_translated_string(lua_State * L) std::string lang_code = luaL_checkstring(L, 1); std::string string = luaL_checkstring(L, 2); + auto lang = str_split(utf8_to_wide(lang_code), L':'); auto *translations = getServer(L)->getTranslationLanguage(lang_code); - string = wide_to_utf8(translate_string(utf8_to_wide(string), translations)); + string = wide_to_utf8(translate_string(utf8_to_wide(string), lang, translations)); lua_pushstring(L, string.c_str()); return 1; } diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 1523a224e4..4326400a6d 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -527,10 +527,10 @@ int ModApiMainMenu::l_get_content_translation(lua_State *L) std::string path = luaL_checkstring(L, 1); std::string domain = luaL_checkstring(L, 2); std::string string = luaL_checkstring(L, 3); - std::string lang = get_client_language_code(); + auto lang = get_effective_locale(); auto *translations = engine->getContentTranslations(path, domain, lang); - string = wide_to_utf8(translate_string(utf8_to_wide(string), translations)); + string = wide_to_utf8(translate_string(utf8_to_wide(string), lang, translations)); lua_pushstring(L, string.c_str()); return 1; } diff --git a/src/translation.h b/src/translation.h index b883a4b239..9f8947165f 100644 --- a/src/translation.h +++ b/src/translation.h @@ -30,11 +30,14 @@ public: { return getFileLanguage(filename) != ""; } - // for testing inline size_t size() { return m_translations.size() + m_plural_translations.size()/2; } + inline bool empty() + { + return size() == 0; + } #ifndef SERVER const std::wstring &getTranslation( diff --git a/src/util/string.cpp b/src/util/string.cpp index aeec51cb80..1c2646ef36 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -7,6 +7,7 @@ #include "numeric.h" #include "log.h" +#include "gettext.h" #include "hex.h" #include "porting.h" #include "translation.h" @@ -654,9 +655,9 @@ std::string wrap_rows(std::string_view from, unsigned row_len, bool has_color_co */ static void translate_all(std::wstring_view s, size_t &i, - Translations *translations, std::wstring &res); + const std::vector &lang, Translations *translations, std::wstring &res); -static void translate_string(std::wstring_view s, Translations *translations, +static void translate_string(std::wstring_view s, const std::vector &lang, Translations *translations, const std::wstring &textdomain, size_t &i, std::wstring &res, bool use_plural, unsigned long int number) { @@ -716,7 +717,7 @@ static void translate_string(std::wstring_view s, Translations *translations, if (arg_number >= 10) { errorstream << "Ignoring too many arguments to translation" << std::endl; std::wstring arg; - translate_all(s, i, translations, arg); + translate_all(s, i, lang, translations, arg); args.push_back(arg); continue; } @@ -724,7 +725,7 @@ static void translate_string(std::wstring_view s, Translations *translations, output += std::to_wstring(arg_number); ++arg_number; std::wstring arg; - translate_all(s, i, translations, arg); + translate_all(s, i, lang, translations, arg); args.push_back(std::move(arg)); } else { // This is an escape sequence *inside* the template string to translate itself. @@ -739,10 +740,10 @@ static void translate_string(std::wstring_view s, Translations *translations, if (translations != nullptr) { if (use_plural) toutput = translations->getPluralTranslation( - textdomain, output, number); + lang, textdomain, output, number); else toutput = translations->getTranslation( - textdomain, output); + lang, textdomain, output); } else { toutput = output; } @@ -780,7 +781,7 @@ static void translate_string(std::wstring_view s, Translations *translations, } static void translate_all(std::wstring_view s, size_t &i, - Translations *translations, std::wstring &res) + const std::vector &lang, Translations *translations, std::wstring &res) { res.clear(); res.reserve(s.length()); @@ -858,7 +859,7 @@ static void translate_all(std::wstring_view s, size_t &i, } } std::wstring translated; - translate_string(s, translations, textdomain, i, translated, use_plural, number); + translate_string(s, lang, translations, textdomain, i, translated, use_plural, number); res.append(translated); } else { // Another escape sequence, such as colors. Preserve it. @@ -868,17 +869,17 @@ static void translate_all(std::wstring_view s, size_t &i, } // Translate string server side -std::wstring translate_string(std::wstring_view s, Translations *translations) +std::wstring translate_string(std::wstring_view s, const std::vector &lang, Translations *translations) { size_t i = 0; std::wstring res; - translate_all(s, i, translations, res); + translate_all(s, i, lang, translations, res); return res; } std::wstring translate_string(std::wstring_view s) { - return translate_string(s, g_client_translations); + return translate_string(s, get_effective_locale(), g_client_translations); } static const std::array disallowed_dir_names = { diff --git a/src/util/string.h b/src/util/string.h index ca965decac..df05a2299e 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -655,7 +655,7 @@ std::vector > split(const std::basic_string &s, T delim) } [[nodiscard]] -std::wstring translate_string(std::wstring_view s, Translations *translations); +std::wstring translate_string(std::wstring_view s, const std::vector &lang, Translations *translations); [[nodiscard]] std::wstring translate_string(std::wstring_view s);