diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 9a641c7c0..e54802770 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -104,6 +104,7 @@ const std::string& shortkey_alt_prefix() bool config_wizard_startup(bool app_config_exists) { if (!app_config_exists || wxGetApp().preset_bundle->printers.size() <= 1) { + wxGetApp().switch_language(); config_wizard(ConfigWizard::RR_DATA_EMPTY); return true; } else if (get_app_config()->legacy_datadir()) { diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 04ea99505..9390c8c5d 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" @@ -255,7 +258,7 @@ bool GUI_App::on_init_inner() CallAfter([this] { if (!config_wizard_startup(app_conf_exists)) { - // Only notify if there was not wizard so as not to bother too much ... + // Only notify if there was no wizard so as not to bother too much ... preset_updater->slic3r_update_notify(); } preset_updater->sync(preset_bundle); @@ -518,35 +521,61 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) dialog.GetPaths(input_files); } -// select language from the list of installed languages -bool GUI_App::select_language( wxArrayString & names, - wxArrayLong & identifiers) +bool GUI_App::switch_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; + if (select_language()) { + save_language(); + _3DScene::remove_all_canvases(); + recreate_GUI(); + return true; + } else { + return false; } - 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]); +} + +// select language from the list of installed languages +bool GUI_App::select_language() +{ + 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); + } + + 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; } @@ -559,21 +588,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; } } @@ -591,36 +619,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) @@ -757,14 +780,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu) if ( dialog.ShowModal() == wxID_CANCEL) return; - wxArrayString names; - wxArrayLong identifiers; - get_installed_languages(names, identifiers); - if (select_language(names, identifiers)) { - save_language(); - _3DScene::remove_all_canvases();// remove all canvas before recreate GUI - recreate_GUI(); - } + switch_language(); break; } case ConfigMenuFlashFirmware: diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 716bb8fd0..1f3ba9071 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,18 +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 select_language(wxArrayString & names, wxArrayLong & identifiers); + bool switch_language(); + 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();