From 78697b2acfd3a4fbbb0b49b955f6a2b12df72326 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 29 Aug 2019 15:35:28 +0200 Subject: [PATCH] Improvement of selection of language / dictionaries. When switching the languages, if the newly selected dictionary is "compatible" with the system best language or user's locale, then the system best language locale or user's locale is activated, not the locale connected to the dictionary. --- src/slic3r/GUI/GUI_App.cpp | 54 +++++++++++++++++++++++--------------- src/slic3r/GUI/GUI_App.hpp | 6 ++++- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a01d885ec9..0f1040d42a 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -640,11 +640,20 @@ bool GUI_App::select_language() const long index = wxGetSingleChoiceIndex(_(L("Select the language")), _(L("Language")), names, init_selection_default); // Try to load a new language. - if (index != -1 && (init_selection == -1 || init_selection != index) && this->load_language(language_infos[index]->CanonicalName, false)) { - // Save language at application config. - app_config->set("translation_language", m_wxLocale->GetCanonicalName().ToUTF8().data()); - app_config->save(); - return true; + if (index != -1 && (init_selection == -1 || init_selection != index)) { + const wxLanguageInfo *new_language_info = language_infos[index]; + if (new_language_info == m_language_info_best || new_language_info == m_language_info_system) { + // The newly selected profile matches user's default profile exactly. That's great. + } else if (m_language_info_best != nullptr && new_language_info->CanonicalName.BeforeFirst('_') == m_language_info_best->CanonicalName.BeforeFirst('_')) + new_language_info = m_language_info_best; + else if (m_language_info_system != nullptr && new_language_info->CanonicalName.BeforeFirst('_') == m_language_info_system->CanonicalName.BeforeFirst('_')) + new_language_info = m_language_info_system; + if (this->load_language(new_language_info->CanonicalName, false)) { + // Save language at application config. + app_config->set("translation_language", m_wxLocale->GetCanonicalName().ToUTF8().data()); + app_config->save(); + return true; + } } return false; @@ -659,20 +668,12 @@ bool GUI_App::load_language(wxString language, bool initial) wxFileTranslationsLoader::AddCatalogLookupPathPrefix(from_u8(localization_dir())); // Get the active language from PrusaSlicer.ini, or empty string if the key does not exist. language = app_config->get("translation_language"); - } - - const wxLanguageInfo *language_info = wxLocale::FindLanguageInfo(language); - if (language_info == nullptr) - language.clear(); - - if (language.IsEmpty()) { - const wxLanguage lang_system = wxLanguage(wxLocale::GetSystemLanguage()); - const wxLanguageInfo *lang_info_system = nullptr; - if (lang_system != wxLANGUAGE_UNKNOWN) { - lang_info_system = wxLocale::GetLanguageInfo(lang_system); - if (lang_info_system != nullptr) - language = lang_info_system->CanonicalName; - } + // Get the system language. + { + const wxLanguage lang_system = wxLanguage(wxLocale::GetSystemLanguage()); + if (lang_system != wxLANGUAGE_UNKNOWN) + m_language_info_system = wxLocale::GetLanguageInfo(lang_system); + } { // Allocating a temporary locale will switch the default wxTranslations to its internal wxTranslations instance. wxLocale temp_locale; @@ -685,8 +686,19 @@ bool GUI_App::load_language(wxString language, bool initial) // for not having the English dictionary. Let's hope wxWidgets of various versions process this call the same way. wxString best_language = wxTranslations::Get()->GetBestTranslation(SLIC3R_APP_KEY, wxLANGUAGE_ENGLISH); if (! best_language.IsEmpty()) - language = best_language; + m_language_info_best = wxLocale::FindLanguageInfo(best_language); } + } + + const wxLanguageInfo *language_info = wxLocale::FindLanguageInfo(language); + if (language_info == nullptr) + language.clear(); + + if (language.IsEmpty()) { + if (m_language_info_system != nullptr && m_language_info_system->LayoutDirection != wxLayout_RightToLeft) + language = m_language_info_system->CanonicalName; + if (m_language_info_best != nullptr && m_language_info_best->LayoutDirection != wxLayout_RightToLeft) + language = m_language_info_best->CanonicalName; if (language.IsEmpty()) language = "en_US"; } @@ -721,7 +733,7 @@ bool GUI_App::load_language(wxString language, bool initial) } // Release the old locales, create new locales. - + //FIXME wxWidgets cause havoc if the current locale is deleted. We just forget it causing memory leaks for now. m_wxLocale.release(); m_wxLocale = Slic3r::make_unique(); m_wxLocale->Init(language_info->Language); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 83017f1764..a8043e9915 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -88,7 +88,11 @@ class GUI_App : public wxApp size_t m_em_unit; // width of a "m"-symbol in pixels for current system font // Note: for 100% Scale m_em_unit = 10 -> it's a good enough coefficient for a size setting of controls - std::unique_ptr m_wxLocale; + std::unique_ptr m_wxLocale; + // System language, from locales, owned by wxWidgets. + const wxLanguageInfo *m_language_info_system = nullptr; + // Best translation language, provided by Windows or OSX, owned by wxWidgets. + const wxLanguageInfo *m_language_info_best = nullptr; std::unique_ptr m_imgui; std::unique_ptr m_printhost_job_queue;