Fixed crash on switching the application language.
This crash was caused by the RemovableDriveManager and 3DConnexion detection services not being stopped correctly. The fix executes all the tasks of the MainFrame at the language switch, that are normally performed on application shut down.
This commit is contained in:
parent
fb10e27778
commit
d4ac4df21c
4 changed files with 49 additions and 59 deletions
|
@ -433,46 +433,30 @@ float GUI_App::toolbar_icon_scale(const bool is_limited/* = false*/) const
|
|||
|
||||
void GUI_App::recreate_GUI()
|
||||
{
|
||||
// Weird things happen as the Paint messages are floating around the windows being destructed.
|
||||
// Avoid the Paint messages by hiding the main window.
|
||||
// Also the application closes much faster without these unnecessary screen refreshes.
|
||||
// In addition, there were some crashes due to the Paint events sent to already destructed windows.
|
||||
mainframe->Show(false);
|
||||
mainframe->shutdown();
|
||||
|
||||
const auto msg_name = _(L("Changing of an application language")) + dots;
|
||||
wxProgressDialog dlg(msg_name, msg_name);
|
||||
dlg.Pulse();
|
||||
|
||||
// to make sure nobody accesses data from the soon-to-be-destroyed widgets:
|
||||
tabs_list.clear();
|
||||
plater_ = nullptr;
|
||||
|
||||
dlg.Update(10, _(L("Recreating")) + dots);
|
||||
|
||||
MainFrame* topwindow = mainframe;
|
||||
MainFrame *old_main_frame = mainframe;
|
||||
mainframe = new MainFrame();
|
||||
sidebar().obj_list()->init_objects(); // propagate model objects to object list
|
||||
|
||||
if (topwindow) {
|
||||
// Propagate model objects to object list.
|
||||
sidebar().obj_list()->init_objects();
|
||||
SetTopWindow(mainframe);
|
||||
|
||||
dlg.Update(30, _(L("Recreating")) + dots);
|
||||
topwindow->Destroy();
|
||||
|
||||
// For this moment ConfigWizard is deleted, invalidate it
|
||||
old_main_frame->Destroy();
|
||||
// For this moment ConfigWizard is deleted, invalidate it.
|
||||
m_wizard = nullptr;
|
||||
}
|
||||
|
||||
dlg.Update(80, _(L("Loading of current presets")) + dots);
|
||||
|
||||
m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
|
||||
|
||||
load_current_presets();
|
||||
|
||||
mainframe->Show(true);
|
||||
|
||||
dlg.Update(90, _(L("Loading of a mode view")) + dots);
|
||||
|
||||
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
|
||||
* change min hight of object list to the normal min value (15 * wxGetApp().em_unit())
|
||||
* after first whole Mainframe updating/layouting
|
||||
|
@ -480,7 +464,6 @@ void GUI_App::recreate_GUI()
|
|||
const int list_min_height = 15 * em_unit();
|
||||
if (obj_list()->GetMinSize().GetY() > list_min_height)
|
||||
obj_list()->SetMinSize(wxSize(-1, list_min_height));
|
||||
|
||||
update_mode();
|
||||
|
||||
// #ys_FIXME_delete_after_testing Do we still need this ?
|
||||
|
@ -575,7 +558,6 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const
|
|||
bool GUI_App::switch_language()
|
||||
{
|
||||
if (select_language()) {
|
||||
_3DScene::remove_all_canvases();
|
||||
recreate_GUI();
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -109,7 +109,28 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
|||
event.Veto();
|
||||
return;
|
||||
}
|
||||
this->shutdown();
|
||||
// propagate event
|
||||
event.Skip();
|
||||
});
|
||||
|
||||
Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& event) {
|
||||
if (m_plater != nullptr && event.GetActive())
|
||||
m_plater->on_activate();
|
||||
event.Skip();
|
||||
});
|
||||
|
||||
wxGetApp().persist_window_geometry(this, true);
|
||||
|
||||
update_ui_from_settings(); // FIXME (?)
|
||||
|
||||
if (m_plater != nullptr)
|
||||
m_plater->show_action_buttons(true);
|
||||
}
|
||||
|
||||
// Called when closing the application and when switching the application language.
|
||||
void MainFrame::shutdown()
|
||||
{
|
||||
if (m_plater)
|
||||
m_plater->stop_jobs();
|
||||
|
||||
|
@ -140,23 +161,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
|||
// to avoid any manipulations with them from App->wxEVT_IDLE after of the mainframe closing
|
||||
wxGetApp().tabs_list.clear();
|
||||
wxGetApp().plater_ = nullptr;
|
||||
|
||||
// propagate event
|
||||
event.Skip();
|
||||
});
|
||||
|
||||
Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& event) {
|
||||
if (m_plater != nullptr && event.GetActive())
|
||||
m_plater->on_activate();
|
||||
event.Skip();
|
||||
});
|
||||
|
||||
wxGetApp().persist_window_geometry(this, true);
|
||||
|
||||
update_ui_from_settings(); // FIXME (?)
|
||||
|
||||
if (m_plater != nullptr)
|
||||
m_plater->show_action_buttons(true);
|
||||
}
|
||||
|
||||
void MainFrame::update_title()
|
||||
|
|
|
@ -100,6 +100,9 @@ public:
|
|||
MainFrame();
|
||||
~MainFrame() = default;
|
||||
|
||||
// Called when closing the application and when switching the application language.
|
||||
void shutdown();
|
||||
|
||||
Plater* plater() { return m_plater; }
|
||||
|
||||
void update_title();
|
||||
|
|
|
@ -434,6 +434,7 @@ void RemovableDriveManager::shutdown()
|
|||
#endif
|
||||
|
||||
m_initialized = false;
|
||||
m_callback_evt_handler = nullptr;
|
||||
}
|
||||
|
||||
bool RemovableDriveManager::set_and_verify_last_save_path(const std::string &path)
|
||||
|
|
Loading…
Reference in a new issue