diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 626e62cd8e..c076c31661 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3,6 +3,8 @@ #include "GUI_ObjectManipulation.hpp" #include "I18N.hpp" +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include "libslic3r/Utils.hpp" #include "libslic3r/Model.hpp" @@ -516,10 +519,7 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) bool GUI_App::switch_language() { - wxArrayString names; - wxArrayLong identifiers; - get_installed_languages(names, identifiers); - if (select_language(names, identifiers)) { + if (select_language()) { save_language(); _3DScene::remove_all_canvases(); recreate_GUI(); @@ -530,34 +530,48 @@ bool GUI_App::switch_language() } // select language from the list of installed languages -bool GUI_App::select_language( wxArrayString & names, - wxArrayLong & identifiers) +bool GUI_App::select_language() { - wxCHECK_MSG(names.Count() == identifiers.Count(), false, - _(L("Array of language names and identifiers should have the same size."))); - int init_selection = 0; - long current_language = m_wxLocale ? m_wxLocale->GetLanguage() : wxLANGUAGE_UNKNOWN; - for (auto lang : identifiers) { - if (lang == current_language) - break; - ++init_selection; + const auto langs = get_installed_languages(); + wxArrayString names; + names.Alloc(langs.size()); + + int init_selection = -1; + const auto current_language = m_wxLocale ? m_wxLocale->GetLanguage() : wxLocale::GetSystemLanguage(); + + for (size_t i = 0; i < langs.size(); i++) { + const auto lang = langs[i]->Language; + const bool is_english = lang >= wxLANGUAGE_ENGLISH && lang <= wxLANGUAGE_ENGLISH_ZIMBABWE; + + if (lang == current_language || (current_language == wxLANGUAGE_UNKNOWN && is_english)) { + init_selection = i; + } + + names.Add(langs[i]->Description); } - if (init_selection == identifiers.size()) - init_selection = 0; - long index = wxGetSingleChoiceIndex(_(L("Select the language")), _(L("Language")), - names, init_selection); - if (index != -1) - { - m_wxLocale = new wxLocale; - m_wxLocale->Init(identifiers[index]); + + const long index = wxGetSingleChoiceIndex( + _(L("Select the language")), + _(L("Language")), names, init_selection >= 0 ? init_selection : 0); + + if (index != -1) { + const wxLanguageInfo *lang = langs[index]; + if (lang->Language == current_language) { + // There was no change + return false; + } + + m_wxLocale = new wxLocale; // FIXME: leak? + m_wxLocale->Init(lang->Language); m_wxLocale->AddCatalogLookupPathPrefix(from_u8(localization_dir())); m_wxLocale->AddCatalog("Slic3rPE"); //FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only. wxSetlocale(LC_NUMERIC, "C"); Preset::update_suffix_modified(); - m_imgui->set_language(m_wxLocale->GetCanonicalName().ToUTF8().data()); + m_imgui->set_language(into_u8(lang->CanonicalName)); return true; } + return false; } @@ -570,21 +584,20 @@ bool GUI_App::load_language() if (language.IsEmpty()) return false; - wxArrayString names; - wxArrayLong identifiers; - get_installed_languages(names, identifiers); - for (size_t i = 0; i < identifiers.Count(); i++) + + const auto langs = get_installed_languages(); + for (const wxLanguageInfo *info : langs) { - if (wxLocale::GetLanguageCanonicalName(identifiers[i]) == language) + if (info->CanonicalName == language) { m_wxLocale = new wxLocale; - m_wxLocale->Init(identifiers[i]); + m_wxLocale->Init(info->Language); m_wxLocale->AddCatalogLookupPathPrefix(from_u8(localization_dir())); m_wxLocale->AddCatalog("Slic3rPE"); //FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only. wxSetlocale(LC_NUMERIC, "C"); Preset::update_suffix_modified(); - m_imgui->set_language(m_wxLocale->GetCanonicalName().ToUTF8().data()); + m_imgui->set_language(into_u8(info->CanonicalName)); return true; } } @@ -602,36 +615,31 @@ void GUI_App::save_language() app_config->save(); } -// get list of installed languages -void GUI_App::get_installed_languages(wxArrayString & names, wxArrayLong & identifiers) +// Get a list of installed languages +std::vector GUI_App::get_installed_languages() { - names.Clear(); - identifiers.Clear(); + std::vector res; wxDir dir(from_u8(localization_dir())); wxString filename; const wxLanguageInfo * langinfo; wxString name = wxLocale::GetLanguageName(wxLANGUAGE_DEFAULT); - if (!name.IsEmpty()) - { - names.Add(_(L("Default"))); - identifiers.Add(wxLANGUAGE_DEFAULT); + if (!name.IsEmpty()) { + res.push_back(wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT)); } - for (bool cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_DIRS); - cont; cont = dir.GetNext(&filename)) - { + + for (bool cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_DIRS); cont; cont = dir.GetNext(&filename)) { langinfo = wxLocale::FindLanguageInfo(filename); - if (langinfo != NULL) - { + if (langinfo != NULL) { auto full_file_name = dir.GetName() + wxFileName::GetPathSeparator() + filename + wxFileName::GetPathSeparator() + "Slic3rPE" + wxT(".mo"); - if (wxFileExists(full_file_name)) - { - names.Add(langinfo->Description); - identifiers.Add(langinfo->Language); + if (wxFileExists(full_file_name)) { + res.push_back(langinfo); } } } + + return res; } Tab* GUI_App::get_tab(Preset::Type type) diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index e6b94ece6f..500348f08e 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -19,6 +19,7 @@ class wxMenuItem; class wxMenuBar; class wxTopLevelWindow; class wxNotebook; +class wxLanguageInfo; namespace Slic3r { class AppConfig; @@ -119,19 +120,16 @@ public: void keyboard_shortcuts(); void load_project(wxWindow *parent, wxString& input_file); void import_model(wxWindow *parent, wxArrayString& input_files); - static bool catch_error(std::function cb, -// wxMessageDialog* message_dialog, - const std::string& err); -// void notify(/*message*/); + static bool catch_error(std::function cb, const std::string& err); void persist_window_geometry(wxTopLevelWindow *window, bool default_maximized = false); void update_ui_from_settings(); bool switch_language(); - bool select_language(wxArrayString & names, wxArrayLong & identifiers); + bool select_language(); bool load_language(); void save_language(); - void get_installed_languages(wxArrayString & names, wxArrayLong & identifiers); + std::vector get_installed_languages(); Tab* get_tab(Preset::Type type); ConfigOptionMode get_mode();