Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenricoturri1966 <enricoturri@seznam.cz>2021-04-06 14:17:29 +0300
committerenricoturri1966 <enricoturri@seznam.cz>2021-04-06 14:17:29 +0300
commit5d4b7c03b603945cec03e270faca14f957f08cb0 (patch)
treea0e57235fc0f0b456419c5c6de0726342282672d /src/slic3r
parent144e37c2745b188c99e8c88fde7c6f4da3603ef3 (diff)
Extended interface of project dirty state manager
Diffstat (limited to 'src/slic3r')
-rw-r--r--src/slic3r/GUI/GUI_App.cpp8
-rw-r--r--src/slic3r/GUI/GUI_ObjectList.cpp10
-rw-r--r--src/slic3r/GUI/MainFrame.cpp48
-rw-r--r--src/slic3r/GUI/MainFrame.hpp9
-rw-r--r--src/slic3r/GUI/Plater.cpp103
-rw-r--r--src/slic3r/GUI/Plater.hpp10
-rw-r--r--src/slic3r/GUI/ProjectDirtyStateManager.cpp20
-rw-r--r--src/slic3r/GUI/ProjectDirtyStateManager.hpp10
-rw-r--r--src/slic3r/GUI/Tab.cpp7
9 files changed, 219 insertions, 6 deletions
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index b22cd6009..793ef80b7 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -904,6 +904,14 @@ bool GUI_App::on_init_inner()
}
else
load_current_presets();
+
+#if ENABLE_PROJECT_DIRTY_STATE
+ if (plater_ != nullptr) {
+// plater_->reset_project_initial_presets();
+ plater_->update_project_dirty_from_presets();
+ }
+#endif // ENABLE_PROJECT_DIRTY_STATE
+
mainframe->Show(true);
obj_list()->set_min_height();
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 58560c8bd..bce64f9ea 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -7,6 +7,9 @@
#include "GUI_App.hpp"
#include "I18N.hpp"
#include "Plater.hpp"
+#if ENABLE_PROJECT_DIRTY_STATE
+#include "MainFrame.hpp"
+#endif // ENABLE_PROJECT_DIRTY_STATE
#include "OptionsGroup.hpp"
#include "Tab.hpp"
@@ -1457,12 +1460,15 @@ void ObjectList::load_shape_object(const std::string& type_name)
if (obj_idx < 0)
return;
- take_snapshot(_(L("Add Shape")));
+ take_snapshot(_L("Add Shape"));
// Create mesh
BoundingBoxf3 bb;
TriangleMesh mesh = create_mesh(type_name, bb);
- load_mesh_object(mesh, _(L("Shape")) + "-" + _(type_name));
+ load_mesh_object(mesh, _L("Shape") + "-" + _(type_name));
+#if ENABLE_PROJECT_DIRTY_STATE
+ wxGetApp().mainframe->update_title();
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center)
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 35b1c16d8..832ebc257 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -206,6 +206,11 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
// declare events
Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& event) {
+#if ENABLE_PROJECT_DIRTY_STATE
+ if (m_plater != nullptr)
+ m_plater->save_project_if_dirty();
+#endif // ENABLE_PROJECT_DIRTY_STATE
+
if (event.CanVeto() && !wxGetApp().check_unsaved_changes()) {
event.Veto();
return;
@@ -487,8 +492,14 @@ void MainFrame::update_title()
// m_plater->get_project_filename() produces file name including path, but excluding extension.
// Don't try to remove the extension, it would remove part of the file name after the last dot!
wxString project = from_path(into_path(m_plater->get_project_filename()).filename());
+#if ENABLE_PROJECT_DIRTY_STATE
+ wxString dirty_marker = (!m_plater->model().objects.empty() && m_plater->is_project_dirty()) ? "*" : "";
+ if (!dirty_marker.empty() || !project.empty())
+ title = dirty_marker + project + " - ";
+#else
if (!project.empty())
title += (project + " - ");
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
std::string build_id = wxGetApp().is_editor() ? SLIC3R_BUILD_ID : GCODEVIEWER_BUILD_ID;
@@ -668,11 +679,37 @@ bool MainFrame::can_start_new_project() const
return (m_plater != nullptr) && (!m_plater->get_project_filename(".3mf").IsEmpty() || !m_plater->model().objects.empty());
}
+#if ENABLE_PROJECT_DIRTY_STATE
bool MainFrame::can_save() const
{
+ return (m_plater != nullptr) && !m_plater->model().objects.empty() && !m_plater->get_project_filename().empty() && m_plater->is_project_dirty();
+}
+
+bool MainFrame::can_save_as() const
+{
return (m_plater != nullptr) && !m_plater->model().objects.empty();
}
+void MainFrame::save_project()
+{
+ save_project_as(m_plater->get_project_filename(".3mf"));
+}
+
+void MainFrame::save_project_as(const wxString& filename)
+{
+ bool ret = (m_plater != nullptr) ? m_plater->export_3mf(into_path(filename)) : false;
+ if (ret) {
+// wxGetApp().update_saved_preset_from_current_preset();
+ m_plater->reset_project_dirty_after_save();
+ }
+}
+#else
+bool MainFrame::can_save() const
+{
+ return (m_plater != nullptr) && !m_plater->model().objects.empty();
+}
+#endif // ENABLE_PROJECT_DIRTY_STATE
+
bool MainFrame::can_export_model() const
{
return (m_plater != nullptr) && !m_plater->model().objects.empty();
@@ -977,16 +1014,27 @@ void MainFrame::init_menubar_as_editor()
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_recent_projects.GetCount() > 0); }, recent_projects_submenu->GetId());
+#if ENABLE_PROJECT_DIRTY_STATE
+ append_menu_item(fileMenu, wxID_ANY, _L("&Save Project") + "\tCtrl+S", _L("Save current project file"),
+ [this](wxCommandEvent&) { save_project(); }, "save", nullptr,
+ [this](){return m_plater != nullptr && can_save(); }, this);
+#else
append_menu_item(fileMenu, wxID_ANY, _L("&Save Project") + "\tCtrl+S", _L("Save current project file"),
[this](wxCommandEvent&) { if (m_plater) m_plater->export_3mf(into_path(m_plater->get_project_filename(".3mf"))); }, "save", nullptr,
[this](){return m_plater != nullptr && can_save(); }, this);
+#endif // ENABLE_PROJECT_DIRTY_STATE
#ifdef __APPLE__
append_menu_item(fileMenu, wxID_ANY, _L("Save Project &as") + dots + "\tCtrl+Shift+S", _L("Save current project file as"),
#else
append_menu_item(fileMenu, wxID_ANY, _L("Save Project &as") + dots + "\tCtrl+Alt+S", _L("Save current project file as"),
#endif // __APPLE__
+#if ENABLE_PROJECT_DIRTY_STATE
+ [this](wxCommandEvent&) { save_project_as(); }, "save", nullptr,
+ [this](){return m_plater != nullptr && can_save_as(); }, this);
+#else
[this](wxCommandEvent&) { if (m_plater) m_plater->export_3mf(); }, "save", nullptr,
[this](){return m_plater != nullptr && can_save(); }, this);
+#endif // ENABLE_PROJECT_DIRTY_STATE
fileMenu->AppendSeparator();
diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp
index 0971fdc77..307cdf1ae 100644
--- a/src/slic3r/GUI/MainFrame.hpp
+++ b/src/slic3r/GUI/MainFrame.hpp
@@ -91,7 +91,9 @@ class MainFrame : public DPIFrame
void on_value_changed(wxCommandEvent&);
bool can_start_new_project() const;
+#if !ENABLE_PROJECT_DIRTY_STATE
bool can_save() const;
+#endif // !ENABLE_PROJECT_DIRTY_STATE
bool can_export_model() const;
bool can_export_toolpaths() const;
bool can_export_supports() const;
@@ -184,6 +186,13 @@ public:
// Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig
void on_config_changed(DynamicPrintConfig* cfg) const ;
+#if ENABLE_PROJECT_DIRTY_STATE
+ bool can_save() const;
+ bool can_save_as() const;
+ void save_project();
+ void save_project_as(const wxString& filename = wxString());
+#endif // ENABLE_PROJECT_DIRTY_STATE
+
void add_to_recent_projects(const wxString& filename);
PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; }
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 0434d2555..9de4641c0 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1393,7 +1393,13 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
this->MSWUpdateDragImageOnLeave();
#endif // WIN32
+#if ENABLE_PROJECT_DIRTY_STATE
+ bool res = (m_plater != nullptr) ? m_plater->load_files(filenames) : false;
+ wxGetApp().mainframe->update_title();
+ return res;
+#else
return (m_plater != nullptr) ? m_plater->load_files(filenames) : false;
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
// State to manage showing after export notifications and device ejecting
@@ -1511,9 +1517,26 @@ struct Plater::priv
priv(Plater *q, MainFrame *main_frame);
~priv();
+#if ENABLE_PROJECT_DIRTY_STATE
+ bool is_project_dirty() const { return dirty_state.is_dirty(); }
+ void update_project_dirty_from_presets() { dirty_state.update_from_presets(); }
+ bool save_project_if_dirty() {
+ if (dirty_state.is_dirty()) {
+ MainFrame* mainframe = wxGetApp().mainframe;
+ if (mainframe->can_save_as()) {
+ wxMessageDialog dlg(mainframe, _L("Do you want to save the changes to the current project ?"), wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL);
+ if (dlg.ShowModal() == wxID_CANCEL)
+ return false;
+ mainframe->save_project_as(wxGetApp().plater()->get_project_filename());
+ }
+ }
+ return true;
+ }
+ void reset_project_dirty_after_save() { dirty_state.reset_after_save(); }
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
void render_project_state_debug_window() const { dirty_state.render_debug_window(); }
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
+#endif // ENABLE_PROJECT_DIRTY_STATE
enum class UpdateParams {
FORCE_FULL_SCREEN_REFRESH = 1,
@@ -4216,6 +4239,11 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name)
}
this->undo_redo_stack().take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), view3D->get_canvas3d()->get_gizmos_manager(), snapshot_data);
this->undo_redo_stack().release_least_recently_used();
+
+#if ENABLE_PROJECT_DIRTY_STATE
+ dirty_state.update_from_undo_redo_stack(undo_redo_stack_main(), undo_redo_stack());
+#endif // ENABLE_PROJECT_DIRTY_STATE
+
// Save the last active preset name of a particular printer technology.
((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name();
BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot taken: " << snapshot_name << ", Undo / Redo stack memory: " << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) << log_memory_info();
@@ -4346,6 +4374,10 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
if (! view3D->is_layers_editing_enabled() && this->layers_height_allowed() && new_variable_layer_editing_active)
view3D->get_canvas3d()->force_main_toolbar_left_action(view3D->get_canvas3d()->get_main_toolbar_item_id("layersediting"));
}
+
+#if ENABLE_PROJECT_DIRTY_STATE
+ dirty_state.update_from_undo_redo_stack(undo_redo_stack_main(), undo_redo_stack());
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */)
@@ -4429,9 +4461,15 @@ Plater::Plater(wxWindow *parent, MainFrame *main_frame)
// Initialization performed in the private c-tor
}
+#if ENABLE_PROJECT_DIRTY_STATE
+bool Plater::is_project_dirty() const { return p->is_project_dirty(); }
+void Plater::update_project_dirty_from_presets() { p->update_project_dirty_from_presets(); }
+bool Plater::save_project_if_dirty() { return p->save_project_if_dirty(); }
+void Plater::reset_project_dirty_after_save() { p->reset_project_dirty_after_save(); }
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
void Plater::render_project_state_debug_window() const { p->render_project_state_debug_window(); }
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
+#endif // ENABLE_PROJECT_DIRTY_STATE
Sidebar& Plater::sidebar() { return *p->sidebar; }
Model& Plater::model() { return p->model; }
@@ -4442,12 +4480,30 @@ SLAPrint& Plater::sla_print() { return p->sla_print; }
void Plater::new_project()
{
+#if ENABLE_PROJECT_DIRTY_STATE
+ if (!p->save_project_if_dirty())
+ return;
+#endif // ENABLE_PROJECT_DIRTY_STATE
+
p->select_view_3D("3D");
+#if ENABLE_PROJECT_DIRTY_STATE
+ take_snapshot(_L("New Project"));
+ Plater::SuppressSnapshots suppress(this);
+ reset();
+// reset_project_initial_presets();
+ update_project_dirty_from_presets();
+#else
wxPostEvent(p->view3D->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL));
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
void Plater::load_project()
{
+#if ENABLE_PROJECT_DIRTY_STATE
+ if (!p->save_project_if_dirty())
+ return;
+#endif // ENABLE_PROJECT_DIRTY_STATE
+
// Ask user for a project file name.
wxString input_file;
wxGetApp().load_project(this, input_file);
@@ -4471,8 +4527,16 @@ void Plater::load_project(const wxString& filename)
std::vector<size_t> res = load_files(input_paths);
// if res is empty no data has been loaded
+#if ENABLE_PROJECT_DIRTY_STATE
+ if (!res.empty()) {
+ p->set_project_filename(filename);
+// reset_project_initial_presets();
+ update_project_dirty_from_presets();
+ }
+#else
if (!res.empty())
p->set_project_filename(filename);
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
void Plater::add_model(bool imperial_units/* = false*/)
@@ -4503,7 +4567,13 @@ void Plater::add_model(bool imperial_units/* = false*/)
}
Plater::TakeSnapshot snapshot(this, snapshot_label);
+#if ENABLE_PROJECT_DIRTY_STATE
+ std::vector<size_t> res = load_files(paths, true, false, imperial_units);
+ if (!res.empty())
+ wxGetApp().mainframe->update_title();
+#else
load_files(paths, true, false, imperial_units);
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
void Plater::import_sl1_archive()
@@ -5187,24 +5257,39 @@ void Plater::export_amf()
}
}
+#if ENABLE_PROJECT_DIRTY_STATE
+bool Plater::export_3mf(const boost::filesystem::path& output_path)
+#else
void Plater::export_3mf(const boost::filesystem::path& output_path)
+#endif // ENABLE_PROJECT_DIRTY_STATE
{
if (p->model.objects.empty()
|| canvas3D()->get_gizmos_manager().is_in_editing_mode(true))
+#if ENABLE_PROJECT_DIRTY_STATE
+ return false;
+#else
return;
+#endif // ENABLE_PROJECT_DIRTY_STATE
wxString path;
bool export_config = true;
- if (output_path.empty())
- {
+ if (output_path.empty()) {
path = p->get_export_file(FT_3MF);
+#if ENABLE_PROJECT_DIRTY_STATE
+ if (path.empty()) { return false; }
+#else
if (path.empty()) { return; }
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
else
path = from_path(output_path);
if (!path.Lower().EndsWith(".3mf"))
+#if ENABLE_PROJECT_DIRTY_STATE
+ return false;
+#else
return;
+#endif // ENABLE_PROJECT_DIRTY_STATE
DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure();
const std::string path_u8 = into_u8(path);
@@ -5212,6 +5297,19 @@ void Plater::export_3mf(const boost::filesystem::path& output_path)
bool full_pathnames = wxGetApp().app_config->get("export_sources_full_pathnames") == "1";
ThumbnailData thumbnail_data;
p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true, true, true);
+#if ENABLE_PROJECT_DIRTY_STATE
+ bool ret = Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_data);
+ if (ret) {
+ // Success
+ p->statusbar()->set_status_text(format_wxstr(_L("3MF file exported to %s"), path));
+ p->set_project_filename(path);
+ }
+ else {
+ // Failure
+ p->statusbar()->set_status_text(format_wxstr(_L("Error exporting 3MF file %s"), path));
+ }
+ return ret;
+#else
if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_data)) {
// Success
p->statusbar()->set_status_text(format_wxstr(_L("3MF file exported to %s"), path));
@@ -5221,6 +5319,7 @@ void Plater::export_3mf(const boost::filesystem::path& output_path)
// Failure
p->statusbar()->set_status_text(format_wxstr(_L("Error exporting 3MF file %s"), path));
}
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
void Plater::reload_from_disk()
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index f2d60d801..ead9679c7 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -130,9 +130,15 @@ public:
Plater &operator=(const Plater &) = delete;
~Plater() = default;
+#if ENABLE_PROJECT_DIRTY_STATE
+ bool is_project_dirty() const;
+ void update_project_dirty_from_presets();
+ bool save_project_if_dirty();
+ void reset_project_dirty_after_save();
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
void render_project_state_debug_window() const;
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
+#endif // ENABLE_PROJECT_DIRTY_STATE
Sidebar& sidebar();
Model& model();
@@ -201,7 +207,11 @@ public:
void export_gcode(bool prefer_removable);
void export_stl(bool extended = false, bool selection_only = false);
void export_amf();
+#if ENABLE_PROJECT_DIRTY_STATE
+ bool export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path());
+#else
void export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path());
+#endif // ENABLE_PROJECT_DIRTY_STATE
void reload_from_disk();
void reload_all_from_disk();
bool has_toolpaths_to_export() const;
diff --git a/src/slic3r/GUI/ProjectDirtyStateManager.cpp b/src/slic3r/GUI/ProjectDirtyStateManager.cpp
index 9a19676b2..5cf7274bb 100644
--- a/src/slic3r/GUI/ProjectDirtyStateManager.cpp
+++ b/src/slic3r/GUI/ProjectDirtyStateManager.cpp
@@ -2,12 +2,32 @@
#include "ProjectDirtyStateManager.hpp"
#include "ImGuiWrapper.hpp"
#include "GUI_App.hpp"
+#include "MainFrame.hpp"
#if ENABLE_PROJECT_DIRTY_STATE
namespace Slic3r {
namespace GUI {
+void ProjectDirtyStateManager::update_from_undo_redo_stack(const Slic3r::UndoRedo::Stack& main_stack, const Slic3r::UndoRedo::Stack& active_stack)
+{
+ if (!wxGetApp().initialized())
+ return;
+
+ wxGetApp().mainframe->update_title();
+}
+
+void ProjectDirtyStateManager::update_from_presets()
+{
+ wxGetApp().mainframe->update_title();
+}
+
+void ProjectDirtyStateManager::reset_after_save()
+{
+ m_state.reset();
+ wxGetApp().mainframe->update_title();
+}
+
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
void ProjectDirtyStateManager::render_debug_window() const
{
diff --git a/src/slic3r/GUI/ProjectDirtyStateManager.hpp b/src/slic3r/GUI/ProjectDirtyStateManager.hpp
index 81ac28915..b488c00bb 100644
--- a/src/slic3r/GUI/ProjectDirtyStateManager.hpp
+++ b/src/slic3r/GUI/ProjectDirtyStateManager.hpp
@@ -4,6 +4,9 @@
#if ENABLE_PROJECT_DIRTY_STATE
namespace Slic3r {
+namespace UndoRedo {
+class Stack;
+} // namespace UndoRedo
namespace GUI {
class ProjectDirtyStateManager
@@ -14,12 +17,19 @@ class ProjectDirtyStateManager
bool presets{ false };
bool is_dirty() const { return plater || presets; }
+ void reset() {
+ plater = false;
+ presets = false;
+ }
};
DirtyState m_state;
public:
bool is_dirty() const { return m_state.is_dirty(); }
+ void update_from_undo_redo_stack(const Slic3r::UndoRedo::Stack& main_stack, const Slic3r::UndoRedo::Stack& active_stack);
+ void update_from_presets();
+ void reset_after_save();
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
void render_debug_window() const;
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 11c4875eb..97117f418 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -1215,9 +1215,8 @@ void Tab::apply_config_from_cache()
// to update number of "filament" selection boxes when the number of extruders change.
void Tab::on_presets_changed()
{
- if (wxGetApp().plater() == nullptr) {
+ if (wxGetApp().plater() == nullptr)
return;
- }
// Instead of PostEvent (EVT_TAB_PRESETS_CHANGED) just call update_presets
wxGetApp().plater()->sidebar().update_presets(m_type);
@@ -1235,6 +1234,10 @@ void Tab::on_presets_changed()
// clear m_dependent_tabs after first update from select_preset()
// to avoid needless preset loading from update() function
m_dependent_tabs.clear();
+
+#if ENABLE_PROJECT_DIRTY_STATE
+ wxGetApp().plater()->update_project_dirty_from_presets();
+#endif // ENABLE_PROJECT_DIRTY_STATE
}
void Tab::build_preset_description_line(ConfigOptionsGroup* optgroup)