Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
commit
a8f7bb54a5
4 changed files with 190 additions and 145 deletions
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-08-29 11:15+0200\n"
|
"POT-Creation-Date: 2019-08-29 14:09+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -138,6 +138,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/BedShapeDialog.cpp:91 src/slic3r/GUI/ConfigWizard.cpp:123
|
#: src/slic3r/GUI/BedShapeDialog.cpp:91 src/slic3r/GUI/ConfigWizard.cpp:123
|
||||||
#: src/slic3r/GUI/ConfigWizard.cpp:576 src/slic3r/GUI/ConfigWizard.cpp:590
|
#: src/slic3r/GUI/ConfigWizard.cpp:576 src/slic3r/GUI/ConfigWizard.cpp:590
|
||||||
|
#: src/slic3r/GUI/GUI_ObjectLayers.cpp:135
|
||||||
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:390
|
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:390
|
||||||
#: src/slic3r/GUI/WipeTowerDialog.cpp:84 src/slic3r/GUI/wxExtensions.cpp:509
|
#: src/slic3r/GUI/WipeTowerDialog.cpp:84 src/slic3r/GUI/wxExtensions.cpp:509
|
||||||
#: src/libslic3r/PrintConfig.cpp:70 src/libslic3r/PrintConfig.cpp:77
|
#: src/libslic3r/PrintConfig.cpp:70 src/libslic3r/PrintConfig.cpp:77
|
||||||
|
@ -398,7 +399,7 @@ msgstr ""
|
||||||
msgid "Welcome"
|
msgid "Welcome"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigWizard.cpp:309 src/slic3r/GUI/GUI_App.cpp:773
|
#: src/slic3r/GUI/ConfigWizard.cpp:309 src/slic3r/GUI/GUI_App.cpp:783
|
||||||
#, possible-c-format
|
#, possible-c-format
|
||||||
msgid "Run %s"
|
msgid "Run %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -645,6 +646,7 @@ msgid "%s doesn't support percentage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/Field.cpp:174 src/slic3r/GUI/Field.cpp:197
|
#: src/slic3r/GUI/Field.cpp:174 src/slic3r/GUI/Field.cpp:197
|
||||||
|
#: src/slic3r/GUI/GUI_ObjectLayers.cpp:337
|
||||||
msgid "Invalid numeric input."
|
msgid "Invalid numeric input."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1203,7 +1205,7 @@ msgstr ""
|
||||||
msgid "Notice"
|
msgid "Notice"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:132
|
#: src/slic3r/GUI/GUI_App.cpp:133
|
||||||
#, possible-c-format
|
#, possible-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s has encountered an error. It was likely caused by running out of memory. "
|
"%s has encountered an error. It was likely caused by running out of memory. "
|
||||||
|
@ -1213,96 +1215,96 @@ msgid ""
|
||||||
"The application will now terminate."
|
"The application will now terminate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:135
|
#: src/slic3r/GUI/GUI_App.cpp:136
|
||||||
msgid "Fatal error"
|
msgid "Fatal error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:301
|
#: src/slic3r/GUI/GUI_App.cpp:299
|
||||||
#, possible-c-format
|
#, possible-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n"
|
"PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n"
|
||||||
"while OpenGL version %s, render %s, vendor %s was detected."
|
"while OpenGL version %s, render %s, vendor %s was detected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:304
|
#: src/slic3r/GUI/GUI_App.cpp:302
|
||||||
msgid "You may need to update your graphics card driver."
|
msgid "You may need to update your graphics card driver."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:307
|
#: src/slic3r/GUI/GUI_App.cpp:305
|
||||||
msgid ""
|
msgid ""
|
||||||
"As a workaround, you may run PrusaSlicer with a software rendered 3D "
|
"As a workaround, you may run PrusaSlicer with a software rendered 3D "
|
||||||
"graphics by running prusa-slicer.exe with the --sw_renderer parameter."
|
"graphics by running prusa-slicer.exe with the --sw_renderer parameter."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:309
|
#: src/slic3r/GUI/GUI_App.cpp:307
|
||||||
msgid "Unsupported OpenGL version"
|
msgid "Unsupported OpenGL version"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:460
|
#: src/slic3r/GUI/GUI_App.cpp:458
|
||||||
msgid "Changing of an application language"
|
msgid "Changing of an application language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:468 src/slic3r/GUI/GUI_App.cpp:477
|
#: src/slic3r/GUI/GUI_App.cpp:466 src/slic3r/GUI/GUI_App.cpp:475
|
||||||
msgid "Recreating"
|
msgid "Recreating"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:481
|
#: src/slic3r/GUI/GUI_App.cpp:479
|
||||||
msgid "Loading of current presets"
|
msgid "Loading of current presets"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:489
|
#: src/slic3r/GUI/GUI_App.cpp:487
|
||||||
msgid "Loading of a mode view"
|
msgid "Loading of a mode view"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:569
|
#: src/slic3r/GUI/GUI_App.cpp:567
|
||||||
msgid "Choose one file (3MF/AMF):"
|
msgid "Choose one file (3MF/AMF):"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:581
|
#: src/slic3r/GUI/GUI_App.cpp:579
|
||||||
msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):"
|
msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:617
|
#: src/slic3r/GUI/GUI_App.cpp:641
|
||||||
msgid "Select the language"
|
msgid "Select the language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:617
|
#: src/slic3r/GUI/GUI_App.cpp:641
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:776
|
#: src/slic3r/GUI/GUI_App.cpp:786
|
||||||
msgid "&Configuration Snapshots"
|
msgid "&Configuration Snapshots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:776
|
#: src/slic3r/GUI/GUI_App.cpp:786
|
||||||
msgid "Inspect / activate configuration snapshots"
|
msgid "Inspect / activate configuration snapshots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:777
|
#: src/slic3r/GUI/GUI_App.cpp:787
|
||||||
msgid "Take Configuration &Snapshot"
|
msgid "Take Configuration &Snapshot"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:777
|
#: src/slic3r/GUI/GUI_App.cpp:787
|
||||||
msgid "Capture a configuration snapshot"
|
msgid "Capture a configuration snapshot"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:780
|
#: src/slic3r/GUI/GUI_App.cpp:790
|
||||||
msgid "&Preferences"
|
msgid "&Preferences"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:786
|
#: src/slic3r/GUI/GUI_App.cpp:796
|
||||||
msgid "Application preferences"
|
msgid "Application preferences"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:789 src/slic3r/GUI/wxExtensions.cpp:3041
|
#: src/slic3r/GUI/GUI_App.cpp:799 src/slic3r/GUI/wxExtensions.cpp:3041
|
||||||
msgid "Simple"
|
msgid "Simple"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:789
|
#: src/slic3r/GUI/GUI_App.cpp:799
|
||||||
msgid "Simple View Mode"
|
msgid "Simple View Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:790 src/slic3r/GUI/GUI_ObjectList.cpp:97
|
#: src/slic3r/GUI/GUI_App.cpp:800 src/slic3r/GUI/GUI_ObjectList.cpp:97
|
||||||
#: src/slic3r/GUI/GUI_ObjectList.cpp:620 src/slic3r/GUI/Tab.cpp:1058
|
#: src/slic3r/GUI/GUI_ObjectList.cpp:620 src/slic3r/GUI/Tab.cpp:1058
|
||||||
#: src/slic3r/GUI/Tab.cpp:1073 src/slic3r/GUI/Tab.cpp:1171
|
#: src/slic3r/GUI/Tab.cpp:1073 src/slic3r/GUI/Tab.cpp:1171
|
||||||
#: src/slic3r/GUI/Tab.cpp:1174 src/slic3r/GUI/Tab.cpp:1682
|
#: src/slic3r/GUI/Tab.cpp:1174 src/slic3r/GUI/Tab.cpp:1682
|
||||||
|
@ -1313,77 +1315,98 @@ msgstr ""
|
||||||
msgid "Advanced"
|
msgid "Advanced"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:790
|
#: src/slic3r/GUI/GUI_App.cpp:800
|
||||||
msgid "Advanced View Mode"
|
msgid "Advanced View Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:791 src/slic3r/GUI/wxExtensions.cpp:3043
|
#: src/slic3r/GUI/GUI_App.cpp:801 src/slic3r/GUI/wxExtensions.cpp:3043
|
||||||
msgid "Expert"
|
msgid "Expert"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:791
|
#: src/slic3r/GUI/GUI_App.cpp:801
|
||||||
msgid "Expert View Mode"
|
msgid "Expert View Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:796
|
#: src/slic3r/GUI/GUI_App.cpp:806
|
||||||
msgid "Mode"
|
msgid "Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:796
|
#: src/slic3r/GUI/GUI_App.cpp:806
|
||||||
#, possible-c-format
|
#, possible-c-format
|
||||||
msgid "%s View Mode"
|
msgid "%s View Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:798
|
#: src/slic3r/GUI/GUI_App.cpp:808
|
||||||
msgid "Change Application &Language"
|
msgid "Change Application &Language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:800
|
#: src/slic3r/GUI/GUI_App.cpp:810
|
||||||
msgid "Flash printer &firmware"
|
msgid "Flash printer &firmware"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:800
|
#: src/slic3r/GUI/GUI_App.cpp:810
|
||||||
msgid "Upload a firmware image into an Arduino based printer"
|
msgid "Upload a firmware image into an Arduino based printer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:812
|
#: src/slic3r/GUI/GUI_App.cpp:822
|
||||||
msgid "Taking configuration snapshot"
|
msgid "Taking configuration snapshot"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:812
|
#: src/slic3r/GUI/GUI_App.cpp:822
|
||||||
msgid "Snapshot name"
|
msgid "Snapshot name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:855
|
#: src/slic3r/GUI/GUI_App.cpp:865
|
||||||
msgid ""
|
msgid ""
|
||||||
"Switching the language will trigger application restart.\n"
|
"Switching the language will trigger application restart.\n"
|
||||||
"You will lose content of the plater."
|
"You will lose content of the plater."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:857
|
#: src/slic3r/GUI/GUI_App.cpp:867
|
||||||
msgid "Do you want to proceed?"
|
msgid "Do you want to proceed?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:858
|
#: src/slic3r/GUI/GUI_App.cpp:868
|
||||||
msgid "Language selection"
|
msgid "Language selection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:881
|
#: src/slic3r/GUI/GUI_App.cpp:891
|
||||||
msgid "&Configuration"
|
msgid "&Configuration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:903
|
#: src/slic3r/GUI/GUI_App.cpp:913
|
||||||
msgid "The presets on the following tabs were modified"
|
msgid "The presets on the following tabs were modified"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:903 src/slic3r/GUI/Tab.cpp:3130
|
#: src/slic3r/GUI/GUI_App.cpp:913 src/slic3r/GUI/Tab.cpp:3130
|
||||||
msgid "Discard changes and continue anyway?"
|
msgid "Discard changes and continue anyway?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_App.cpp:906
|
#: src/slic3r/GUI/GUI_App.cpp:916
|
||||||
msgid "Unsaved Presets"
|
msgid "Unsaved Presets"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/GUI_ObjectLayers.cpp:27
|
||||||
|
msgid "Start at height"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/GUI_ObjectLayers.cpp:27
|
||||||
|
msgid "Stop at height"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/GUI_ObjectLayers.cpp:27 src/slic3r/GUI/Tab.cpp:1030
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:66
|
||||||
|
msgid "Layer height"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/GUI_ObjectLayers.cpp:153
|
||||||
|
msgid "Remove layer range"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/GUI_ObjectLayers.cpp:162
|
||||||
|
msgid "Add layer range"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_ObjectList.cpp:34 src/slic3r/GUI/GUI_ObjectList.cpp:88
|
#: src/slic3r/GUI/GUI_ObjectList.cpp:34 src/slic3r/GUI/GUI_ObjectList.cpp:88
|
||||||
#: src/slic3r/GUI/GUI_ObjectList.cpp:611 src/libslic3r/PrintConfig.cpp:67
|
#: src/slic3r/GUI/GUI_ObjectList.cpp:611 src/libslic3r/PrintConfig.cpp:67
|
||||||
#: src/libslic3r/PrintConfig.cpp:160 src/libslic3r/PrintConfig.cpp:392
|
#: src/libslic3r/PrintConfig.cpp:160 src/libslic3r/PrintConfig.cpp:392
|
||||||
|
@ -4050,10 +4073,6 @@ msgstr ""
|
||||||
msgid "Layers and perimeters"
|
msgid "Layers and perimeters"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1030 src/libslic3r/PrintConfig.cpp:66
|
|
||||||
msgid "Layer height"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1034
|
#: src/slic3r/GUI/Tab.cpp:1034
|
||||||
msgid "Vertical shells"
|
msgid "Vertical shells"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -18,6 +18,7 @@ src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
|
||||||
src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
|
src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
|
||||||
src/slic3r/GUI/GUI.cpp
|
src/slic3r/GUI/GUI.cpp
|
||||||
src/slic3r/GUI/GUI_App.cpp
|
src/slic3r/GUI/GUI_App.cpp
|
||||||
|
src/slic3r/GUI/GUI_ObjectLayers.cpp
|
||||||
src/slic3r/GUI/GUI_ObjectList.cpp
|
src/slic3r/GUI/GUI_ObjectList.cpp
|
||||||
src/slic3r/GUI/GUI_ObjectManipulation.cpp
|
src/slic3r/GUI/GUI_ObjectManipulation.cpp
|
||||||
src/slic3r/GUI/GUI_ObjectSettings.cpp
|
src/slic3r/GUI/GUI_ObjectSettings.cpp
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <cstdlib>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
@ -229,11 +230,8 @@ bool GUI_App::on_init_inner()
|
||||||
init_label_colours();
|
init_label_colours();
|
||||||
init_fonts();
|
init_fonts();
|
||||||
|
|
||||||
wxString language = wxEmptyString;
|
|
||||||
if (app_config->has("translation_language"))
|
|
||||||
language = app_config->get("translation_language");
|
|
||||||
// If load_language() fails, the application closes.
|
// If load_language() fails, the application closes.
|
||||||
load_language(language);
|
load_language(wxString(), true);
|
||||||
|
|
||||||
// Suppress the '- default -' presets.
|
// Suppress the '- default -' presets.
|
||||||
preset_bundle->set_default_suppressed(app_config->get("no_defaults") == "1");
|
preset_bundle->set_default_suppressed(app_config->get("no_defaults") == "1");
|
||||||
|
@ -600,132 +598,156 @@ bool GUI_App::switch_language()
|
||||||
// select language from the list of installed languages
|
// select language from the list of installed languages
|
||||||
bool GUI_App::select_language()
|
bool GUI_App::select_language()
|
||||||
{
|
{
|
||||||
const std::vector<const wxLanguageInfo*> langs = get_installed_languages();
|
wxArrayString translations = wxTranslations::Get()->GetAvailableTranslations(SLIC3R_APP_KEY);
|
||||||
|
std::vector<const wxLanguageInfo*> language_infos;
|
||||||
|
language_infos.emplace_back(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH));
|
||||||
|
for (size_t i = 0; i < translations.GetCount(); ++ i) {
|
||||||
|
const wxLanguageInfo *langinfo = wxLocale::FindLanguageInfo(translations[i]);
|
||||||
|
if (langinfo != nullptr)
|
||||||
|
language_infos.emplace_back(langinfo);
|
||||||
|
}
|
||||||
|
sort_remove_duplicates(language_infos);
|
||||||
|
std::sort(language_infos.begin(), language_infos.end(), [](const wxLanguageInfo* l, const wxLanguageInfo* r) { return l->Description < r->Description; });
|
||||||
|
|
||||||
wxArrayString names;
|
wxArrayString names;
|
||||||
names.Alloc(langs.size());
|
names.Alloc(language_infos.size());
|
||||||
|
|
||||||
// Some valid language should be selected since the application start up.
|
// Some valid language should be selected since the application start up.
|
||||||
assert(m_wxLocale != nullptr);
|
const wxLanguage current_language = wxLanguage(m_wxLocale->GetLanguage());
|
||||||
const auto current_language = m_wxLocale->GetLanguage();
|
int init_selection = -1;
|
||||||
int init_selection = 0;
|
int init_selection_alt = -1;
|
||||||
for (size_t i = 0; i < langs.size(); ++ i) {
|
int init_selection_default = -1;
|
||||||
if (langs[i]->Language == current_language)
|
for (size_t i = 0; i < language_infos.size(); ++ i) {
|
||||||
|
if (wxLanguage(language_infos[i]->Language) == current_language)
|
||||||
|
// The dictionary matches the active language and country.
|
||||||
init_selection = i;
|
init_selection = i;
|
||||||
names.Add(langs[i]->Description);
|
else if ((language_infos[i]->CanonicalName.BeforeFirst('_') == m_wxLocale->GetCanonicalName().BeforeFirst('_')) ||
|
||||||
|
// if the active language is Slovak, mark the Czech language as active.
|
||||||
|
(language_infos[i]->CanonicalName.BeforeFirst('_') == "cs" && m_wxLocale->GetCanonicalName().BeforeFirst('_') == "sk"))
|
||||||
|
// The dictionary matches the active language, it does not necessarily match the country.
|
||||||
|
init_selection_alt = i;
|
||||||
|
if (language_infos[i]->CanonicalName.BeforeFirst('_') == "en")
|
||||||
|
// This will be the default selection if the active language does not match any dictionary.
|
||||||
|
init_selection_default = i;
|
||||||
|
names.Add(language_infos[i]->Description);
|
||||||
}
|
}
|
||||||
|
if (init_selection == -1)
|
||||||
|
// This is the dictionary matching the active language.
|
||||||
|
init_selection = init_selection_alt;
|
||||||
|
if (init_selection != -1)
|
||||||
|
// This is the language to highlight in the choice dialog initially.
|
||||||
|
init_selection_default = init_selection;
|
||||||
|
|
||||||
const long index = wxGetSingleChoiceIndex(_(L("Select the language")), _(L("Language")), names, init_selection);
|
const long index = wxGetSingleChoiceIndex(_(L("Select the language")), _(L("Language")), names, init_selection_default);
|
||||||
// Try to load a new language.
|
// Try to load a new language.
|
||||||
if (index != -1 && langs[index]->Language != current_language && this->load_language(langs[index]->CanonicalName)) {
|
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.
|
// Save language at application config.
|
||||||
app_config->set("translation_language", m_wxLocale->GetCanonicalName().ToUTF8().data());
|
app_config->set("translation_language", m_wxLocale->GetCanonicalName().ToUTF8().data());
|
||||||
app_config->save();
|
app_config->save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the language code before underscore, if there is underscore.
|
return false;
|
||||||
static wxString language_code_short(const wxString &language_code)
|
|
||||||
{
|
|
||||||
size_t idx_underscore = language_code.find('_');
|
|
||||||
return (idx_underscore != wxString::npos) ? language_code.substr(0, idx_underscore) : language_code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load gettext translation files and activate them at the start of the application,
|
// Load gettext translation files and activate them at the start of the application,
|
||||||
// based on the "translation_language" key stored in the application config.
|
// based on the "translation_language" key stored in the application config.
|
||||||
bool GUI_App::load_language(wxString language)
|
bool GUI_App::load_language(wxString language, bool initial)
|
||||||
{
|
{
|
||||||
if (language.IsEmpty()) {
|
if (initial) {
|
||||||
int lang = wxLocale::GetSystemLanguage();
|
// There is a static list of lookup path prefixes in wxWidgets. Add ours.
|
||||||
if (lang != wxLANGUAGE_UNKNOWN) {
|
wxFileTranslationsLoader::AddCatalogLookupPathPrefix(from_u8(localization_dir()));
|
||||||
const wxLanguageInfo *info = wxLocale::GetLanguageInfo(lang);
|
// Get the active language from PrusaSlicer.ini, or empty string if the key does not exist.
|
||||||
if (info != nullptr)
|
language = app_config->get("translation_language");
|
||||||
language = info->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;
|
||||||
|
// Set the current translation's language to default, otherwise GetBestTranslation() may not work (see the wxWidgets source code).
|
||||||
|
wxTranslations::Get()->SetLanguage(wxLANGUAGE_DEFAULT);
|
||||||
|
// Let the wxFileTranslationsLoader enumerate all translation dictionaries for PrusaSlicer
|
||||||
|
// and try to match them with the system specific "preferred languages".
|
||||||
|
// There seems to be a support for that on Windows and OSX, while on Linuxes the code just returns wxLocale::GetSystemLanguage().
|
||||||
|
// The last parameter gets added to the list of detected dictionaries. This is a workaround
|
||||||
|
// 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())
|
||||||
|
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())
|
if (language.IsEmpty())
|
||||||
language = "en_US";
|
language = "en_US";
|
||||||
|
}
|
||||||
|
|
||||||
|
language_info = wxLocale::FindLanguageInfo(language);
|
||||||
|
if (language_info == nullptr || language_info->LayoutDirection == wxLayout_RightToLeft) {
|
||||||
|
// We don't support right-to-left rendering (Hebrew, Arabic ...), therefore we switch to English.
|
||||||
|
language = "en_US";
|
||||||
|
language_info = wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US);
|
||||||
|
}
|
||||||
|
|
||||||
// Alternate language code.
|
// Alternate language code.
|
||||||
wxString language_code_alt = language_code_short(language);
|
wxLanguage language_dict = wxLanguage(language_info->Language);
|
||||||
if (language_code_alt == "sk")
|
if (language.BeforeFirst('_') == "sk")
|
||||||
// Slovaks understand Czech well. Give them the Czech translation.
|
// Slovaks understand Czech well. Give them the Czech translation.
|
||||||
language_code_alt = "cz";
|
language_dict = wxLANGUAGE_CZECH;
|
||||||
|
|
||||||
const wxLanguageInfo *info = nullptr;
|
if (! wxLocale::IsAvailable(language_info->Language)) {
|
||||||
for (const wxLanguageInfo *this_info : get_installed_languages()) {
|
|
||||||
if (this_info->CanonicalName == language) {
|
|
||||||
// The language matches exactly, including the country suffix. Use it.
|
|
||||||
info = this_info;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (language_code_short(this_info->CanonicalName) == language_code_alt)
|
|
||||||
// Alternatively try to match just the language without the country suffix.
|
|
||||||
info = this_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString canonical_name;
|
|
||||||
if (info == nullptr) {
|
|
||||||
// Fallback for user languages, for which we do not have dictionaries.
|
|
||||||
canonical_name = "en_EN";
|
|
||||||
info = wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US);
|
|
||||||
} else
|
|
||||||
canonical_name = info->CanonicalName;
|
|
||||||
|
|
||||||
wxLocale *new_locale = new wxLocale;
|
|
||||||
if (info == nullptr || ! new_locale->Init(info->Language)) {
|
|
||||||
// Loading the language dictionary failed.
|
// Loading the language dictionary failed.
|
||||||
wxString message = "Switching PrusaSlicer to language " + canonical_name + " failed.";
|
wxString message = "Switching PrusaSlicer to language " + language_info->CanonicalName + " failed.";
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||||
// likely some linux system
|
// likely some linux system
|
||||||
"\nYou may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n";
|
message += "\nYou may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n";
|
||||||
#endif
|
#endif
|
||||||
delete new_locale;
|
if (initial)
|
||||||
if (m_wxLocale == nullptr)
|
|
||||||
message + "\n\nApplication will close.";
|
message + "\n\nApplication will close.";
|
||||||
wxMessageBox(message, "PrusaSlicer - Switching language failed", wxOK | wxICON_ERROR);
|
wxMessageBox(message, "PrusaSlicer - Switching language failed", wxOK | wxICON_ERROR);
|
||||||
if (m_wxLocale == nullptr)
|
if (initial)
|
||||||
std::terminate();
|
std::exit(EXIT_FAILURE);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
wxLocale *old_locale = m_wxLocale;
|
|
||||||
m_wxLocale = new_locale;
|
// Release the old locales, create new locales.
|
||||||
m_wxLocale->AddCatalogLookupPathPrefix(from_u8(localization_dir()));
|
//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<wxLocale>();
|
||||||
|
m_wxLocale->Init(language_info->Language);
|
||||||
|
// Override language at the active wxTranslations class (which is stored in the active m_wxLocale)
|
||||||
|
// to load possibly different dictionary, for example, load Czech dictionary for Slovak language.
|
||||||
|
wxTranslations::Get()->SetLanguage(language_dict);
|
||||||
m_wxLocale->AddCatalog(SLIC3R_APP_KEY);
|
m_wxLocale->AddCatalog(SLIC3R_APP_KEY);
|
||||||
m_imgui->set_language(into_u8(info->CanonicalName));
|
m_imgui->set_language(into_u8(language_info->CanonicalName));
|
||||||
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
|
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
|
||||||
wxSetlocale(LC_NUMERIC, "C");
|
wxSetlocale(LC_NUMERIC, "C");
|
||||||
Preset::update_suffix_modified();
|
Preset::update_suffix_modified();
|
||||||
//FIXME Why the following line crashes?
|
|
||||||
// delete old_locale;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a list of installed languages (languages for which we have dictionaries).
|
|
||||||
std::vector<const wxLanguageInfo*> GUI_App::get_installed_languages()
|
|
||||||
{
|
|
||||||
wxDir dir(from_u8(localization_dir()));
|
|
||||||
wxString filename;
|
|
||||||
std::vector<const wxLanguageInfo*> res;
|
|
||||||
res.emplace_back(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US));
|
|
||||||
for (bool cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_DIRS); cont; cont = dir.GetNext(&filename)) {
|
|
||||||
const wxLanguageInfo *langinfo = wxLocale::FindLanguageInfo(filename);
|
|
||||||
if (langinfo != nullptr) {
|
|
||||||
auto full_file_name = dir.GetName() + wxFileName::GetPathSeparator() +
|
|
||||||
filename + wxFileName::GetPathSeparator() + SLIC3R_APP_KEY + wxT(".mo");
|
|
||||||
if (wxFileExists(full_file_name))
|
|
||||||
res.push_back(langinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Remove duplicated "en_EN" and possible others.
|
|
||||||
sort_remove_duplicates(res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tab* GUI_App::get_tab(Preset::Type type)
|
Tab* GUI_App::get_tab(Preset::Type type)
|
||||||
{
|
{
|
||||||
for (Tab* tab: tabs_list)
|
for (Tab* tab: tabs_list)
|
||||||
|
@ -1019,7 +1041,7 @@ wxString GUI_App::current_language_code_safe() const
|
||||||
{ "uk", "uk_UA", },
|
{ "uk", "uk_UA", },
|
||||||
{ "zh", "zh_CN", },
|
{ "zh", "zh_CN", },
|
||||||
};
|
};
|
||||||
wxString language_code = language_code_short(this->current_language_code());
|
wxString language_code = this->current_language_code().BeforeFirst('_');
|
||||||
auto it = mapping.find(language_code);
|
auto it = mapping.find(language_code);
|
||||||
if (it != mapping.end())
|
if (it != mapping.end())
|
||||||
language_code = it->second;
|
language_code = it->second;
|
||||||
|
|
|
@ -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
|
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
|
// Note: for 100% Scale m_em_unit = 10 -> it's a good enough coefficient for a size setting of controls
|
||||||
|
|
||||||
wxLocale* m_wxLocale{ nullptr };
|
std::unique_ptr<wxLocale> 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<ImGuiWrapper> m_imgui;
|
std::unique_ptr<ImGuiWrapper> m_imgui;
|
||||||
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
||||||
|
@ -132,7 +136,7 @@ public:
|
||||||
void update_ui_from_settings();
|
void update_ui_from_settings();
|
||||||
|
|
||||||
bool switch_language();
|
bool switch_language();
|
||||||
bool load_language(wxString language);
|
bool load_language(wxString language, bool initial);
|
||||||
|
|
||||||
Tab* get_tab(Preset::Type type);
|
Tab* get_tab(Preset::Type type);
|
||||||
ConfigOptionMode get_mode();
|
ConfigOptionMode get_mode();
|
||||||
|
@ -144,7 +148,7 @@ public:
|
||||||
bool checked_tab(Tab* tab);
|
bool checked_tab(Tab* tab);
|
||||||
void load_current_presets();
|
void load_current_presets();
|
||||||
|
|
||||||
wxString current_language_code() const { assert(m_wxLocale != nullptr); return m_wxLocale->GetCanonicalName(); }
|
wxString current_language_code() const { return m_wxLocale->GetCanonicalName(); }
|
||||||
// Translate the language code to a code, for which Prusa Research maintains translations. Defaults to "en_US".
|
// Translate the language code to a code, for which Prusa Research maintains translations. Defaults to "en_US".
|
||||||
wxString current_language_code_safe() const;
|
wxString current_language_code_safe() const;
|
||||||
|
|
||||||
|
@ -187,7 +191,6 @@ private:
|
||||||
void window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false);
|
void window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false);
|
||||||
void window_pos_sanitize(wxTopLevelWindow* window);
|
void window_pos_sanitize(wxTopLevelWindow* window);
|
||||||
bool select_language();
|
bool select_language();
|
||||||
std::vector<const wxLanguageInfo*> get_installed_languages();
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
void associate_3mf_files();
|
void associate_3mf_files();
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
|
|
Loading…
Reference in a new issue