diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index fbcd34a3f6..a8de4a135d 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -191,7 +191,7 @@ sub _init_menubar { # File menu my $fileMenu = Wx::Menu->new; { - wxTheApp->append_menu_item($fileMenu, L("Open STL/OBJ/AMF…\tCtrl+O"), L('Open a model'), sub { + wxTheApp->append_menu_item($fileMenu, L("Open STL/OBJ/AMF/3MF…\tCtrl+O"), L('Open a model'), sub { $self->{plater}->add if $self->{plater}; }, undef, undef); #'brick_add.png'); $self->_append_menu_item($fileMenu, L("&Load Config…\tCtrl+L"), L('Load exported configuration file'), sub { diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 8bc282474e..5949efb377 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -82,15 +82,27 @@ void wxCheckListBoxComboPopup::OnCheckListBox(wxCommandEvent& evt) { // forwards the checklistbox event to the owner wxComboCtrl - wxComboCtrl* cmb = GetComboCtrl(); - if (cmb != nullptr) + if (m_check_box_events_status == OnCheckListBoxFunction::FreeToProceed ) { - wxCommandEvent event(wxEVT_CHECKLISTBOX, cmb->GetId()); - event.SetEventObject(cmb); - cmb->ProcessWindowEvent(event); + wxComboCtrl* cmb = GetComboCtrl(); + if (cmb != nullptr) { + wxCommandEvent event(wxEVT_CHECKLISTBOX, cmb->GetId()); + event.SetEventObject(cmb); + cmb->ProcessWindowEvent(event); + } } evt.Skip(); + + #ifndef _WIN32 // events are sent differently on OSX+Linux vs Win (more description in header file) + if ( m_check_box_events_status == OnCheckListBoxFunction::RefuseToProceed ) + // this happens if the event was resent by OnListBoxSelection - next call to OnListBoxSelection is due to user clicking the text, so the function should + // explicitly change the state on the checkbox + m_check_box_events_status = OnCheckListBoxFunction::WasRefusedLastTime; + else + // if the user clicked the checkbox square, this event was sent before OnListBoxSelection was called, so we don't want it to resend it + m_check_box_events_status = OnCheckListBoxFunction::RefuseToProceed; + #endif } void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt) @@ -100,9 +112,14 @@ void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt) int selId = GetSelection(); if (selId != wxNOT_FOUND) { - Check((unsigned int)selId, !IsChecked((unsigned int)selId)); - SetSelection(wxNOT_FOUND); + #ifndef _WIN32 + if (m_check_box_events_status == OnCheckListBoxFunction::RefuseToProceed) + #endif + Check((unsigned int)selId, !IsChecked((unsigned int)selId)); + m_check_box_events_status = OnCheckListBoxFunction::FreeToProceed; // so the checkbox reacts to square-click the next time + + SetSelection(wxNOT_FOUND); wxCommandEvent event(wxEVT_CHECKLISTBOX, GetId()); event.SetInt(selId); event.SetEventObject(this); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index ed8bb9276a..3667c7905b 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -13,6 +13,21 @@ class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup wxString m_text; + // Events sent on mouseclick are quite complex. Function OnListBoxSelection is supposed to pass the event to the checkbox, which works fine on + // Win. On OSX and Linux the events are generated differently - clicking on the checkbox square generates the event twice (and the square + // therefore seems not to respond). + // This enum is meant to save current state of affairs, i.e., if the event forwarding is ok to do or not. It is only used on Linux + // and OSX by some #ifdefs. It also stores information whether OnListBoxSelection is supposed to change the checkbox status, + // or if it changed status on its own already (which happens when the square is clicked). More comments in OnCheckListBox(...) + // There indeed is a better solution, maybe making a custom event used for the event passing to distinguish the original and passed message + // and blocking one of them on OSX and Linux. Feel free to refactor, but carefully test on all platforms. + enum class OnCheckListBoxFunction{ + FreeToProceed, + RefuseToProceed, + WasRefusedLastTime + } m_check_box_events_status = OnCheckListBoxFunction::FreeToProceed; + + public: virtual bool Create(wxWindow* parent); virtual wxWindow* GetControl(); diff --git a/xs/src/slic3r/Utils/PresetUpdater.cpp b/xs/src/slic3r/Utils/PresetUpdater.cpp index fcbe20fb7f..a5208e3c26 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.cpp +++ b/xs/src/slic3r/Utils/PresetUpdater.cpp @@ -409,6 +409,17 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons for (const auto &preset : bundle.prints) { preset_remover(preset); } for (const auto &preset : bundle.filaments) { preset_remover(preset); } for (const auto &preset : bundle.printers) { preset_remover(preset); } + + // Also apply the `obsolete_presets` property, removing obsolete ini files + auto obsolete_remover = [](const char *subdir, const std::string &preset) { + auto path = fs::path(Slic3r::data_dir()) / subdir / preset; + path += ".ini"; + fs::remove(path); + }; + + for (const auto &name : bundle.obsolete_presets.prints) { obsolete_remover("print", name); } + for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("filament", name); } + for (const auto &name : bundle.obsolete_presets.printers) { obsolete_remover("printer", name); } } } }