mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-17 02:22:17 +00:00
fix crash when opening preference dialog
This commit is contained in:
@@ -6199,7 +6199,7 @@ static const wxLanguageInfo* linux_get_existing_locale_language(const wxLanguage
|
||||
if (! it->empty()) {
|
||||
const std::string &locale = *it;
|
||||
const wxLanguageInfo* lang = wxLocale::FindLanguageInfo(from_u8(locale));
|
||||
if (wxLocale::IsAvailable(lang->Language))
|
||||
if (lang != nullptr && wxLocale::IsAvailable(lang->Language))
|
||||
return lang;
|
||||
}
|
||||
return language;
|
||||
@@ -6241,7 +6241,10 @@ bool GUI_App::select_language()
|
||||
names.Alloc(language_infos.size());
|
||||
|
||||
// Some valid language should be selected since the application start up.
|
||||
const wxLanguage current_language = wxLanguage(m_wxLocale->GetLanguage());
|
||||
const wxString active_language_code = current_language_code();
|
||||
const wxLanguageInfo* active_language_info = wxLocale::FindLanguageInfo(active_language_code);
|
||||
const wxLanguage current_language = active_language_info != nullptr ? wxLanguage(active_language_info->Language) : wxLanguage(m_wxLocale->GetLanguage());
|
||||
const wxString active_lang_prefix = active_language_code.BeforeFirst('_');
|
||||
int init_selection = -1;
|
||||
int init_selection_alt = -1;
|
||||
int init_selection_default = -1;
|
||||
@@ -6249,9 +6252,9 @@ bool GUI_App::select_language()
|
||||
if (wxLanguage(language_infos[i]->Language) == current_language)
|
||||
// The dictionary matches the active language and country.
|
||||
init_selection = i;
|
||||
else if ((language_infos[i]->CanonicalName.BeforeFirst('_') == m_wxLocale->GetCanonicalName().BeforeFirst('_')) ||
|
||||
else if ((language_infos[i]->CanonicalName.BeforeFirst('_') == active_lang_prefix) ||
|
||||
// if the active language is Slovak, mark the Czech language as active.
|
||||
(language_infos[i]->CanonicalName.BeforeFirst('_') == "cs" && m_wxLocale->GetCanonicalName().BeforeFirst('_') == "sk"))
|
||||
(language_infos[i]->CanonicalName.BeforeFirst('_') == "cs" && active_lang_prefix == "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")
|
||||
@@ -6369,7 +6372,10 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||
language_info = wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US);
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << boost::format("Switching wxLocales to %1%") % language_info->CanonicalName.ToUTF8().data();
|
||||
const wxLanguageInfo *translation_language_info = language_info;
|
||||
const wxString requested_language_code = translation_language_info->CanonicalName;
|
||||
const wxLanguageInfo *locale_language_info = translation_language_info;
|
||||
BOOST_LOG_TRIVIAL(trace) << boost::format("Requested translation language %1%") % requested_language_code.ToUTF8().data();
|
||||
|
||||
// Select language for locales. This language may be different from the language of the dictionary.
|
||||
//if (language_info == m_language_info_best || language_info == m_language_info_system) {
|
||||
@@ -6382,8 +6388,8 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||
// language_info = m_language_info_system;
|
||||
|
||||
// Alternate language code.
|
||||
wxLanguage language_dict = wxLanguage(language_info->Language);
|
||||
if (language_info->CanonicalName.BeforeFirst('_') == "sk") {
|
||||
wxLanguage language_dict = wxLanguage(translation_language_info->Language);
|
||||
if (translation_language_info->CanonicalName.BeforeFirst('_') == "sk") {
|
||||
// Slovaks understand Czech well. Give them the Czech translation.
|
||||
language_dict = wxLANGUAGE_CZECH;
|
||||
BOOST_LOG_TRIVIAL(info) << "Using Czech dictionaries for Slovak language";
|
||||
@@ -6392,19 +6398,34 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||
#ifdef __linux__
|
||||
// If we can't find this locale , try to use different one for the language
|
||||
// instead of just reporting that it is impossible to switch.
|
||||
if (! wxLocale::IsAvailable(language_info->Language) && m_language_info_system) {
|
||||
std::string original_lang = into_u8(language_info->CanonicalName);
|
||||
language_info = linux_get_existing_locale_language(language_info, m_language_info_system);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Can't switch language to %1% (missing locales). Using %2% instead.")
|
||||
% original_lang % language_info->CanonicalName.ToUTF8().data();
|
||||
if (!wxLocale::IsAvailable(locale_language_info->Language) && m_language_info_system) {
|
||||
std::string original_lang = into_u8(locale_language_info->CanonicalName);
|
||||
locale_language_info = linux_get_existing_locale_language(locale_language_info, m_language_info_system);
|
||||
if (locale_language_info != nullptr && locale_language_info != translation_language_info) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Can't use locale %1% directly (missing locales). Using locale %2% instead.")
|
||||
% original_lang % locale_language_info->CanonicalName.ToUTF8().data();
|
||||
}
|
||||
}
|
||||
|
||||
if (locale_language_info == nullptr || !wxLocale::IsAvailable(locale_language_info->Language)) {
|
||||
auto try_locale = [](const wxLanguageInfo* candidate) -> const wxLanguageInfo* {
|
||||
return (candidate && wxLocale::IsAvailable(candidate->Language)) ? candidate : nullptr;
|
||||
};
|
||||
const wxLanguageInfo* fallback_locale_info =
|
||||
try_locale(m_wxLocale ? wxLocale::GetLanguageInfo(wxLanguage(m_wxLocale->GetLanguage())) : nullptr);
|
||||
if (!fallback_locale_info) fallback_locale_info = try_locale(m_language_info_system);
|
||||
if (!fallback_locale_info) fallback_locale_info = try_locale(m_language_info_best);
|
||||
if (!fallback_locale_info) fallback_locale_info = try_locale(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US));
|
||||
if (!fallback_locale_info) fallback_locale_info = try_locale(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_UK));
|
||||
if (fallback_locale_info != nullptr) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Using fallback locale %1% while keeping translation dictionary %2%.")
|
||||
% fallback_locale_info->CanonicalName.ToUTF8().data() % requested_language_code.ToUTF8().data();
|
||||
locale_language_info = fallback_locale_info;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! wxLocale::IsAvailable(language_info->Language)&&initial) {
|
||||
language_info = wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_UK);
|
||||
app_config->set("language", language_info->CanonicalName.ToUTF8().data());
|
||||
}
|
||||
else if (initial) {
|
||||
if (initial) {
|
||||
// bbs supported languages
|
||||
//TODO: use a global one with Preference
|
||||
//wxLanguage supported_languages[]{
|
||||
@@ -6438,9 +6459,11 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||
//}
|
||||
}
|
||||
|
||||
if (! wxLocale::IsAvailable(language_info->Language)) {
|
||||
BOOST_LOG_TRIVIAL(trace) << boost::format("Switching wxLocales to %1%") % locale_language_info->CanonicalName.ToUTF8().data();
|
||||
|
||||
if (!wxLocale::IsAvailable(locale_language_info->Language)) {
|
||||
// Loading the language dictionary failed.
|
||||
wxString message = "Switching Orca Slicer to language " + language_info->CanonicalName + " failed.";
|
||||
wxString message = "Switching Orca Slicer to language " + requested_language_code + " failed.";
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
// likely some linux system
|
||||
message += "\nYou may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n";
|
||||
@@ -6458,12 +6481,13 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||
//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);
|
||||
m_wxLocale->Init(locale_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_imgui->set_language(into_u8(language_info->CanonicalName));
|
||||
m_active_language_code = requested_language_code;
|
||||
m_imgui->set_language(into_u8(requested_language_code));
|
||||
|
||||
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
|
||||
//wxSetlocale(LC_NUMERIC, "C");
|
||||
@@ -6751,49 +6775,57 @@ void GUI_App::show_ip_address_enter_dialog_handler(wxCommandEvent& evt)
|
||||
|
||||
void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_option)
|
||||
{
|
||||
bool app_layout_changed = false;
|
||||
bool need_recreate_gui = false;
|
||||
std::string pending_language;
|
||||
{
|
||||
// the dialog needs to be destroyed before the call to recreate_GUI()
|
||||
// or sometimes the application crashes into wxDialogBase() destructor
|
||||
// so we put it into an inner scope
|
||||
PreferencesDialog dlg(mainframe, open_on_tab, highlight_option);
|
||||
dlg.ShowModal();
|
||||
this->plater_->get_current_canvas3D()->force_set_focus();
|
||||
// BBS
|
||||
//app_layout_changed = dlg.settings_layout_changed();
|
||||
need_recreate_gui = dlg.recreate_GUI();
|
||||
pending_language = dlg.pending_language();
|
||||
if (!need_recreate_gui) {
|
||||
this->plater_->get_current_canvas3D()->force_set_focus();
|
||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
|
||||
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
|
||||
#else
|
||||
if (dlg.seq_top_layer_only_changed())
|
||||
if (dlg.seq_top_layer_only_changed())
|
||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
this->plater_->reload_print();
|
||||
this->plater_->reload_print();
|
||||
#ifdef _WIN32
|
||||
if (is_editor()) {
|
||||
if (app_config->get("associate_3mf") == "true")
|
||||
associate_files(L"3mf");
|
||||
if (app_config->get("associate_stl") == "true")
|
||||
associate_files(L"stl");
|
||||
if (app_config->get("associate_step") == "true") {
|
||||
associate_files(L"step");
|
||||
associate_files(L"stp");
|
||||
if (is_editor()) {
|
||||
if (app_config->get("associate_3mf") == "true")
|
||||
associate_files(L"3mf");
|
||||
if (app_config->get("associate_stl") == "true")
|
||||
associate_files(L"stl");
|
||||
if (app_config->get("associate_step") == "true") {
|
||||
associate_files(L"step");
|
||||
associate_files(L"stp");
|
||||
}
|
||||
associate_url(L"orcaslicer");
|
||||
}
|
||||
else {
|
||||
if (app_config->get("associate_gcode") == "true")
|
||||
associate_files(L"gcode");
|
||||
}
|
||||
associate_url(L"orcaslicer");
|
||||
}
|
||||
else {
|
||||
if (app_config->get("associate_gcode") == "true")
|
||||
associate_files(L"gcode");
|
||||
}
|
||||
#endif // _WIN32
|
||||
}
|
||||
}
|
||||
|
||||
// BBS
|
||||
/*
|
||||
if (app_layout_changed) {
|
||||
// hide full main_sizer for mainFrame
|
||||
mainframe->GetSizer()->Show(false);
|
||||
mainframe->update_layout();
|
||||
mainframe->select_tab(size_t(0));
|
||||
}*/
|
||||
if (!pending_language.empty()) {
|
||||
const std::string previous_language = app_config->get("language");
|
||||
app_config->set("language", pending_language);
|
||||
if (!load_language(wxString::FromUTF8(pending_language), false)) {
|
||||
app_config->set("language", previous_language);
|
||||
if (this->plater_)
|
||||
this->plater_->get_current_canvas3D()->force_set_focus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_recreate_gui)
|
||||
recreate_GUI(_L("Changing application language"));
|
||||
}
|
||||
|
||||
bool GUI_App::has_unsaved_preset_changes() const
|
||||
|
||||
Reference in New Issue
Block a user