From 30831af8a5f9c640598a0149bdf70deae7444dcb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 15 Sep 2022 16:48:02 +0200 Subject: [PATCH] DiffDialog: Implemented a transfer of the selected options from left preset to the right and save them to the new preset * Related to #6130 - Feature Request: Profile settings, Save AND Transfer + SavePresetDialog: Refactoring --- src/libslic3r/Preset.cpp | 49 +++++++++ src/libslic3r/Preset.hpp | 4 + src/libslic3r/PresetBundle.cpp | 67 ++++++++++-- src/libslic3r/PresetBundle.hpp | 8 +- src/slic3r/GUI/GUI_App.cpp | 6 +- src/slic3r/GUI/MainFrame.cpp | 10 +- src/slic3r/GUI/PresetComboBoxes.cpp | 1 - src/slic3r/GUI/SavePresetDialog.cpp | 134 +++++++++++++----------- src/slic3r/GUI/SavePresetDialog.hpp | 19 +++- src/slic3r/GUI/UnsavedChangesDialog.cpp | 54 ++++++++-- src/slic3r/GUI/UnsavedChangesDialog.hpp | 15 ++- 11 files changed, 271 insertions(+), 96 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 3803c3c7a3..5d152ea17c 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -924,6 +924,55 @@ void PresetCollection::save_current_preset(const std::string &new_name, bool det this->get_selected_preset().save(); } +Preset& PresetCollection::get_preset_with_name(const std::string& new_name, const Preset* initial_preset) +{ + // 1) Find the preset with a new_name or create a new one, + // initialize it with the preset_to config. + auto it = this->find_preset_internal(new_name); + if (it != m_presets.end() && it->name == new_name) { + // Preset with the same name found. + Preset& preset = *it; + if (!preset.is_default && !preset.is_external && !preset.is_system) { + // Overwriting an existing preset if it isn't default/external/system + preset.config = initial_preset->config; + // The newly saved preset can be activated -> make it visible. + preset.is_visible = true; + } + return preset; + } + + // Creating a new preset. + Preset& preset = *m_presets.insert(it, *initial_preset); + std::string& inherits = preset.inherits(); + std::string old_name = preset.name; + preset.name = new_name; + preset.file = this->path_from_name(new_name); + preset.vendor = nullptr; + preset.alias.clear(); + preset.renamed_from.clear(); + if (preset.is_system) { + // Inheriting from a system preset. + inherits = old_name; + } + else if (inherits.empty()) { + // Inheriting from a user preset. Link the new preset to the old preset. + // inherits = old_name; + } + else { + // Inherited from a user preset. Just maintain the "inherited" flag, + // meaning it will inherit from either the system preset, or the inherited user preset. + } + preset.is_default = false; + preset.is_system = false; + preset.is_external = false; + // The newly saved preset can be activated -> make it visible. + preset.is_visible = true; + // Just system presets have aliases + preset.alias.clear(); + + return preset; +} + bool PresetCollection::delete_current_preset() { const Preset &selected = this->get_selected_preset(); diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 839ebca460..aa801a84fd 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -341,6 +341,10 @@ public: // All presets are marked as not modified and the new preset is activated. void save_current_preset(const std::string &new_name, bool detach = false); + // Find the preset with a new_name or create a new one, + // initialize it with the initial_preset config. + Preset& PresetCollection::get_preset_with_name(const std::string& new_name, const Preset* initial_preset); + // Delete the current preset, activate the first visible preset. // returns true if the preset was deleted successfully. bool delete_current_preset(); diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index d98998cc40..176b098761 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -425,16 +425,24 @@ void PresetBundle::load_installed_printers(const AppConfig &config) preset.set_visible_from_appconfig(config); } -const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& preset_type, const std::string& alias) const +PresetCollection& PresetBundle::get_presets(Preset::Type type) +{ + assert(type >= Preset::TYPE_PRINT && type <= Preset::TYPE_PRINTER); + + return type == Preset::TYPE_PRINT ? prints : + type == Preset::TYPE_SLA_PRINT ? sla_prints : + type == Preset::TYPE_FILAMENT ? filaments : + type == Preset::TYPE_SLA_MATERIAL ? sla_materials : printers; +} + + +const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& preset_type, const std::string& alias) { // there are not aliases for Printers profiles if (preset_type == Preset::TYPE_PRINTER || preset_type == Preset::TYPE_INVALID) return alias; - const PresetCollection& presets = preset_type == Preset::TYPE_PRINT ? prints : - preset_type == Preset::TYPE_SLA_PRINT ? sla_prints : - preset_type == Preset::TYPE_FILAMENT ? filaments : - sla_materials; + const PresetCollection& presets = get_presets(preset_type); return presets.get_preset_name_by_alias(alias); } @@ -442,10 +450,7 @@ const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& p void PresetBundle::save_changes_for_preset(const std::string& new_name, Preset::Type type, const std::vector& unselected_options) { - PresetCollection& presets = type == Preset::TYPE_PRINT ? prints : - type == Preset::TYPE_SLA_PRINT ? sla_prints : - type == Preset::TYPE_FILAMENT ? filaments : - type == Preset::TYPE_SLA_MATERIAL ? sla_materials : printers; + PresetCollection& presets = get_presets(type); // if we want to save just some from selected options if (!unselected_options.empty()) { @@ -468,6 +473,50 @@ void PresetBundle::save_changes_for_preset(const std::string& new_name, Preset:: } } +bool PresetBundle::transfer_and_save(Preset::Type type, const std::string& preset_from_name, const std::string& preset_to_name, + const std::string& preset_new_name, const std::vector& options) +{ + if (options.empty()) + return false; + + PresetCollection& presets = get_presets(type); + + const Preset* preset_from = presets.find_preset(preset_from_name, false, false); + const Preset* preset_to = presets.find_preset(preset_to_name, false, false); + if (!preset_from || !preset_to) + return false; + + // Find the preset with a new_name or create a new one, + // initialize it with the preset_to config. + Preset& preset = presets.get_preset_with_name(preset_new_name, preset_to); + if (preset.is_default || preset.is_external || preset.is_system) + // Cannot overwrite the default preset. + return false; + + // Apply options from the preset_from_name. + preset.config.apply_only(preset_from->config, options); + + // Store new_name preset to disk. + preset.save(); + + // update selection + presets.select_preset_by_name(preset_new_name, true); + + // Mark the print & filament enabled if they are compatible with the currently selected preset. + // If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible. + update_compatible(PresetSelectCompatibleType::Never); + + if (type == Preset::TYPE_PRINTER) + copy_bed_model_and_texture_if_needed(preset.config); + + if (type == Preset::TYPE_FILAMENT) { + // synchronize the first filament presets. + set_filament_preset(0, filaments.get_selected_preset_name()); + } + + return true; +} + void PresetBundle::load_installed_filaments(AppConfig &config) { if (! config.has_section(AppConfig::SECTION_FILAMENTS)) { diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 0213069679..549a132866 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -54,6 +54,8 @@ public: // extruders.size() should be the same as printers.get_edited_preset().config.nozzle_diameter.size() std::vector filament_presets; + PresetCollection& get_presets(Preset::Type preset_type); + // The project configuration values are kept separated from the print/filament/printer preset, // they are being serialized / deserialized from / to the .amf, .3mf, .config, .gcode, // and they are being used by slicing core. @@ -142,11 +144,15 @@ public: // If the "vendor" section is missing, enable all models and variants of the particular vendor. void load_installed_printers(const AppConfig &config); - const std::string& get_preset_name_by_alias(const Preset::Type& preset_type, const std::string& alias) const; + const std::string& get_preset_name_by_alias(const Preset::Type& preset_type, const std::string& alias); // Save current preset of a provided type under a new name. If the name is different from the old one, // Unselected option would be reverted to the beginning values void save_changes_for_preset(const std::string& new_name, Preset::Type type, const std::vector& unselected_options); + // Transfer options form preset_from_name preset to preset_to_name preset and save preset_to_name preset as new new_name preset + // Return false, if new preset wasn't saved + bool transfer_and_save(Preset::Type type, const std::string& preset_from_name, const std::string& preset_to_name, + const std::string& new_name, const std::vector& options); static const char *PRUSA_BUNDLE; private: diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index c054a2e3bc..b03010b17f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2540,8 +2540,7 @@ bool GUI_App::check_and_save_current_preset_changes(const wxString& caption, con // synchronize config.ini with the current selections. preset_bundle->export_selections(*app_config); - MessageDialog(nullptr, _L_PLURAL("The preset modifications are successfully saved", - "The presets modifications are successfully saved", dlg.get_names_and_types().size())).ShowModal(); + MessageDialog(nullptr, dlg.msg_success_saved_modifications(dlg.get_names_and_types().size())).ShowModal(); } } @@ -2601,8 +2600,7 @@ bool GUI_App::check_and_keep_current_preset_changes(const wxString& caption, con // synchronize config.ini with the current selections. preset_bundle->export_selections(*app_config); - wxString text = _L_PLURAL("The preset modifications are successfully saved", - "The presets modifications are successfully saved", preset_names_and_types.size()); + wxString text = dlg.msg_success_saved_modifications(preset_names_and_types.size()); if (!is_called_from_configwizard) text += "\n\n" + _L("For new project all modifications will be reseted"); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 3875d8cdf7..0c83551769 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -296,13 +296,7 @@ void MainFrame::bind_diff_dialog() auto transfer = [this, get_tab](Preset::Type type) { get_tab(type)->transfer_options(diff_dialog.get_left_preset_name(type), diff_dialog.get_right_preset_name(type), - std::move(diff_dialog.get_selected_options(type))); - }; - - auto save = [this, get_tab](Preset::Type type) { - get_tab(type)->save_options(diff_dialog.get_left_preset_name(type), - diff_dialog.get_right_preset_name(type), - std::move(diff_dialog.get_selected_options(type))); + diff_dialog.get_selected_options(type)); }; auto process_options = [this](std::function process) { @@ -318,8 +312,6 @@ void MainFrame::bind_diff_dialog() }; diff_dialog.Bind(EVT_DIFF_DIALOG_TRANSFER, [this, process_options, transfer](SimpleEvent&) { process_options(transfer); }); - - diff_dialog.Bind(EVT_DIFF_DIALOG_SAVE, [this, process_options, save](SimpleEvent&) { process_options(save); }); } diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 7f781e243e..65469e6a03 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -38,7 +38,6 @@ #include "../Utils/UndoRedo.hpp" #include "BitmapCache.hpp" #include "PhysicalPrinterDialog.hpp" -#include "SavePresetDialog.hpp" #include "MsgDialog.hpp" // A workaround for a set of issues related to text fitting into gtk widgets: diff --git a/src/slic3r/GUI/SavePresetDialog.cpp b/src/slic3r/GUI/SavePresetDialog.cpp index 974d771b95..89a5d7a8de 100644 --- a/src/slic3r/GUI/SavePresetDialog.cpp +++ b/src/slic3r/GUI/SavePresetDialog.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include "libslic3r/PresetBundle.hpp" @@ -22,25 +21,23 @@ using Slic3r::GUI::format_wxstr; namespace Slic3r { namespace GUI { -#define BORDER_W 10 - +constexpr auto BORDER_W = 10; //----------------------------------------------- // SavePresetDialog::Item //----------------------------------------------- -SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBoxSizer* sizer, SavePresetDialog* parent): - m_type(type), - m_parent(parent) +std::string SavePresetDialog::Item::get_init_preset_name(const std::string &suffix) { - Tab* tab = wxGetApp().get_tab(m_type); - assert(tab); - m_presets = tab->get_presets(); + PresetBundle* preset_bundle = m_parent->get_preset_bundle(); + if (!preset_bundle) + preset_bundle = wxGetApp().preset_bundle; + m_presets = &preset_bundle->get_presets(m_type); const Preset& sel_preset = m_presets->get_selected_preset(); - std::string preset_name = sel_preset.is_default ? "Untitled" : - sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : - sel_preset.name; + std::string preset_name = sel_preset.is_default ? "Untitled" : + sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : + sel_preset.name; // if name contains extension if (boost::iends_with(preset_name, ".ini")) { @@ -48,18 +45,11 @@ SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBox preset_name.resize(len); } - std::vector values; - for (const Preset& preset : *m_presets) { - if (preset.is_default || preset.is_system || preset.is_external) - continue; - values.push_back(preset.name); - } - - std::string label_str = m_parent->is_for_rename() ?_utf8(L("Rename %s to:")) : _utf8(L("Save %s as:")); - wxStaticText* label_top = new wxStaticText(m_parent, wxID_ANY, from_u8((boost::format(label_str) % into_u8(tab->title())).str())); - - m_valid_bmp = new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("tick_mark")); + return preset_name; +} +void SavePresetDialog::Item::init_input_name_ctrl(wxBoxSizer *input_name_sizer, const std::string preset_name) +{ if (m_parent->is_for_rename()) { #ifdef _WIN32 long style = wxBORDER_SIMPLE; @@ -68,10 +58,19 @@ SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBox #endif m_text_ctrl = new wxTextCtrl(m_parent, wxID_ANY, from_u8(preset_name), wxDefaultPosition, wxSize(35 * wxGetApp().em_unit(), -1), style); m_text_ctrl->Bind(wxEVT_TEXT, [this](wxCommandEvent&) { update(); }); + + input_name_sizer->Add(m_text_ctrl,1, wxEXPAND, BORDER_W); } else { + std::vector values; + for (const Preset&preset : *m_presets) { + if (preset.is_default || preset.is_system || preset.is_external) + continue; + values.push_back(preset.name); + } + m_combo = new wxComboBox(m_parent, wxID_ANY, from_u8(preset_name), wxDefaultPosition, wxSize(35 * wxGetApp().em_unit(), -1)); - for (const std::string& value : values) + for (const std::string&value : values) m_combo->Append(from_u8(value)); m_combo->Bind(wxEVT_TEXT, [this](wxCommandEvent&) { update(); }); @@ -80,20 +79,34 @@ SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBox // So process wxEVT_COMBOBOX too m_combo->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { update(); }); #endif //__WXOSX__ - } - m_valid_label = new wxStaticText(m_parent, wxID_ANY, ""); + input_name_sizer->Add(m_combo, 1, wxEXPAND, BORDER_W); + } +} + +wxString SavePresetDialog::Item::get_top_label_text() const +{ + const std::string label_str = m_parent->is_for_rename() ?_u8L("Rename %s to:") : _u8L("Save %s as:"); + Tab* tab = wxGetApp().get_tab(m_type); + return from_u8((boost::format(label_str) % into_u8(tab->title())).str()); +} + +SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBoxSizer* sizer, SavePresetDialog* parent): + m_type(type), + m_parent(parent), + m_valid_bmp(new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("tick_mark"))), + m_valid_label(new wxStaticText(m_parent, wxID_ANY, "")) +{ m_valid_label->SetFont(wxGetApp().bold_font()); - wxBoxSizer* combo_sizer = new wxBoxSizer(wxHORIZONTAL); - combo_sizer->Add(m_valid_bmp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, BORDER_W); - if (m_parent->is_for_rename()) - combo_sizer->Add(m_text_ctrl,1, wxEXPAND, BORDER_W); - else - combo_sizer->Add(m_combo, 1, wxEXPAND, BORDER_W); + wxStaticText* label_top = new wxStaticText(m_parent, wxID_ANY, get_top_label_text()); + + wxBoxSizer* input_name_sizer = new wxBoxSizer(wxHORIZONTAL); + input_name_sizer->Add(m_valid_bmp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, BORDER_W); + init_input_name_ctrl(input_name_sizer, get_init_preset_name(suffix)); sizer->Add(label_top, 0, wxEXPAND | wxTOP| wxBOTTOM, BORDER_W); - sizer->Add(combo_sizer, 0, wxEXPAND | wxBOTTOM, BORDER_W); + sizer->Add(input_name_sizer,0, wxEXPAND | wxBOTTOM, BORDER_W); sizer->Add(m_valid_label, 0, wxEXPAND | wxLEFT, 3*BORDER_W); if (m_type == Preset::TYPE_PRINTER) @@ -107,7 +120,7 @@ void SavePresetDialog::Item::update() bool rename = m_parent->is_for_rename(); m_preset_name = into_u8(rename ? m_text_ctrl->GetValue() : m_combo->GetValue()); - m_valid_type = Valid; + m_valid_type = ValidationType::Valid; wxString info_line; const char* unusable_symbols = "<>[]:/\\|?*\""; @@ -117,44 +130,44 @@ void SavePresetDialog::Item::update() if (m_preset_name.find_first_of(unusable_symbols[i]) != std::string::npos) { info_line = _L("The supplied name is not valid;") + "\n" + _L("the following characters are not allowed:") + " " + unusable_symbols; - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; break; } } - if (m_valid_type == Valid && m_preset_name.find(unusable_suffix) != std::string::npos) { + if (m_valid_type == ValidationType::Valid && m_preset_name.find(unusable_suffix) != std::string::npos) { info_line = _L("The supplied name is not valid;") + "\n" + _L("the following suffix is not allowed:") + "\n\t" + from_u8(PresetCollection::get_suffix_modified()); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } - if (m_valid_type == Valid && m_preset_name == "- default -") { + if (m_valid_type == ValidationType::Valid && m_preset_name == "- default -") { info_line = _L("The supplied name is not available."); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } const Preset* existing = m_presets->find_preset(m_preset_name, false); - if (m_valid_type == Valid && existing && (existing->is_default || existing->is_system)) { + if (m_valid_type == ValidationType::Valid && existing && (existing->is_default || existing->is_system)) { info_line = rename ? _L("The supplied name is used for a system profile.") : _L("Cannot overwrite a system profile."); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } - if (m_valid_type == Valid && existing && (existing->is_external)) { + if (m_valid_type == ValidationType::Valid && existing && (existing->is_external)) { info_line = rename ? _L("The supplied name is used for a external profile.") : _L("Cannot overwrite an external profile."); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } - if (m_valid_type == Valid && existing) + if (m_valid_type == ValidationType::Valid && existing) { if (m_preset_name == m_presets->get_selected_preset_name()) { if (!rename && m_presets->get_edited_preset().is_dirty) info_line = _L("Just save preset modifications"); else info_line = _L("Nothing changed"); - m_valid_type = Valid; + m_valid_type = ValidationType::Valid; } else { if (existing->is_compatible) @@ -162,31 +175,31 @@ void SavePresetDialog::Item::update() else info_line = from_u8((boost::format(_u8L("Preset with name \"%1%\" already exists and is incompatible with selected printer.")) % m_preset_name).str()); info_line += "\n" + _L("Note: This preset will be replaced after saving"); - m_valid_type = Warning; + m_valid_type = ValidationType::Warning; } } - if (m_valid_type == Valid && m_preset_name.empty()) { + if (m_valid_type == ValidationType::Valid && m_preset_name.empty()) { info_line = _L("The name cannot be empty."); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } - if (m_valid_type == Valid && m_preset_name.find_first_of(' ') == 0) { + if (m_valid_type == ValidationType::Valid && m_preset_name.find_first_of(' ') == 0) { info_line = _L("The name cannot start with space character."); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } - if (m_valid_type == Valid && m_preset_name.find_last_of(' ') == m_preset_name.length()-1) { + if (m_valid_type == ValidationType::Valid && m_preset_name.find_last_of(' ') == m_preset_name.length()-1) { info_line = _L("The name cannot end with space character."); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } - if (m_valid_type == Valid && m_presets->get_preset_name_by_alias(m_preset_name) != m_preset_name) { + if (m_valid_type == ValidationType::Valid && m_presets->get_preset_name_by_alias(m_preset_name) != m_preset_name) { info_line = _L("The name cannot be the same as a preset alias name."); - m_valid_type = NoValid; + m_valid_type = ValidationType::NoValid; } - if (!m_parent->get_info_line_extention().IsEmpty() && m_valid_type != NoValid) + if (!m_parent->get_info_line_extention().IsEmpty() && m_valid_type != ValidationType::NoValid) info_line += "\n\n" + m_parent->get_info_line_extention(); m_valid_label->SetLabel(info_line); @@ -202,14 +215,14 @@ void SavePresetDialog::Item::update() void SavePresetDialog::Item::update_valid_bmp() { - std::string bmp_name = m_valid_type == Warning ? "exclamation" : - m_valid_type == NoValid ? "cross" : "tick_mark" ; + std::string bmp_name = m_valid_type == ValidationType::Warning ? "exclamation" : + m_valid_type == ValidationType::NoValid ? "cross" : "tick_mark" ; m_valid_bmp->SetBitmap(*get_bmp_bundle(bmp_name)); } void SavePresetDialog::Item::accept() { - if (m_valid_type == Warning) + if (m_valid_type == ValidationType::Warning) m_presets->delete_preset(m_preset_name); } @@ -224,8 +237,9 @@ SavePresetDialog::SavePresetDialog(wxWindow* parent, Preset::Type type, std::str build(std::vector{type}, suffix); } -SavePresetDialog::SavePresetDialog(wxWindow* parent, std::vector types, std::string suffix) - : DPIDialog(parent, wxID_ANY, _L("Save presets"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER) +SavePresetDialog::SavePresetDialog(wxWindow* parent, std::vector types, std::string suffix, PresetBundle* preset_bundle/* = nullptr*/) + : DPIDialog(parent, wxID_ANY, _L("Save presets"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER), + m_preset_bundle(preset_bundle) { build(types, suffix); } diff --git a/src/slic3r/GUI/SavePresetDialog.hpp b/src/slic3r/GUI/SavePresetDialog.hpp index 1ecda7b7fd..aec58ac7a3 100644 --- a/src/slic3r/GUI/SavePresetDialog.hpp +++ b/src/slic3r/GUI/SavePresetDialog.hpp @@ -29,7 +29,7 @@ class SavePresetDialog : public DPIDialog struct Item { - enum ValidationType + enum class ValidationType { Valid, NoValid, @@ -41,15 +41,15 @@ class SavePresetDialog : public DPIDialog void update_valid_bmp(); void accept(); - bool is_valid() const { return m_valid_type != NoValid; } + bool is_valid() const { return m_valid_type != ValidationType::NoValid; } Preset::Type type() const { return m_type; } std::string preset_name() const { return m_preset_name; } private: Preset::Type m_type; - ValidationType m_valid_type; std::string m_preset_name; + ValidationType m_valid_type {ValidationType::NoValid}; SavePresetDialog* m_parent {nullptr}; wxStaticBitmap* m_valid_bmp {nullptr}; wxComboBox* m_combo {nullptr}; @@ -58,7 +58,11 @@ class SavePresetDialog : public DPIDialog PresetCollection* m_presets {nullptr}; - void update(); + std::string get_init_preset_name(const std::string &suffix); + void init_input_name_ctrl(wxBoxSizer *input_name_sizer, std::string preset_name); + wxString get_top_label_text() const ; + + void update(); }; std::vector m_items; @@ -73,17 +77,22 @@ class SavePresetDialog : public DPIDialog bool m_use_for_rename{false}; wxString m_info_line_extention{wxEmptyString}; + PresetBundle* m_preset_bundle{ nullptr }; + public: const wxString& get_info_line_extention() { return m_info_line_extention; } SavePresetDialog(wxWindow* parent, Preset::Type type, std::string suffix = ""); - SavePresetDialog(wxWindow* parent, std::vector types, std::string suffix = ""); + SavePresetDialog(wxWindow* parent, std::vector types, std::string suffix = "", PresetBundle* preset_bundle = nullptr); SavePresetDialog(wxWindow* parent, Preset::Type type, bool rename, const wxString& info_line_extention); ~SavePresetDialog(); void AddItem(Preset::Type type, const std::string& suffix); + void set_preset_bundle(PresetBundle* preset_bundle) { m_preset_bundle = preset_bundle; } + PresetBundle* get_preset_bundle() const { return m_preset_bundle; } + std::string get_name(); std::string get_name(Preset::Type type); diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 9bcb9def0b..7fdec251ce 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -36,7 +36,6 @@ namespace Slic3r { namespace GUI { wxDEFINE_EVENT(EVT_DIFF_DIALOG_TRANSFER, SimpleEvent); -wxDEFINE_EVENT(EVT_DIFF_DIALOG_SAVE, SimpleEvent); // ---------------------------------------------------------------------------- @@ -1336,6 +1335,12 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres searcher.sort_options_by_label(); } +wxString UnsavedChangesDialog::msg_success_saved_modifications(size_t saved_presets_cnt) +{ + return _L_PLURAL("The preset modifications are successfully saved", + "The presets modifications are successfully saved", static_cast(saved_presets_cnt)); +} + void UnsavedChangesDialog::on_dpi_changed(const wxRect& suggested_rect) { int em = em_unit(); @@ -1488,10 +1493,11 @@ void DiffPresetDialog::create_presets_sizer() PresetComboBox*cb = (*cb_); cb->show_modif_preset_separately(); cb->set_selection_changed_function([this, new_type, preset_bundle, cb](int selection) { - if (m_view_type == Preset::TYPE_INVALID) { - std::string preset_name = Preset::remove_suffix_modified(cb->GetString(selection).ToUTF8().data()); + std::string preset_name = Preset::remove_suffix_modified(cb->GetString(selection).ToUTF8().data()); + if (m_view_type == Preset::TYPE_INVALID) update_compatibility(preset_name, new_type, preset_bundle); - } + // update selection inside of related presets + preset_bundle->get_presets(new_type).select_preset_by_name(preset_name, true); update_tree(); }); if (collection->get_selected_idx() != (size_t)-1) @@ -2002,10 +2008,47 @@ void DiffPresetDialog::update_compatibility(const std::string& preset_name, Pres } } +bool DiffPresetDialog::save() +{ + presets_to_saves.clear(); + + std::vector types_for_save; + + for (const Preset::Type& type : m_pr_technology == ptFFF ? std::initializer_list{Preset::TYPE_PRINTER, Preset::TYPE_PRINT, Preset::TYPE_FILAMENT} : + std::initializer_list{Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL }) + if (!m_tree->options(type, true).empty()) { + types_for_save.emplace_back(type); + presets_to_saves.emplace_back(PresetToSave{ type, get_left_preset_name(type), get_right_preset_name(type), get_right_preset_name(type) }); + } + + if (!types_for_save.empty()) { + SavePresetDialog save_dlg(this, types_for_save, _u8L("Modified"), m_preset_bundle_right.get()); + if (save_dlg.ShowModal() != wxID_OK) + return false; + + for (auto& preset : presets_to_saves) { + const std::string& name = save_dlg.get_name(preset.type); + if (!name.empty()) + preset.new_name = name; + } + } + return true; +} + void DiffPresetDialog::button_event(Action act) { if (act == Action::Save) { - wxPostEvent(this, SimpleEvent(EVT_DIFF_DIALOG_SAVE)); + if (save()) { + size_t saved_cnt = 0; + for (const auto& preset : presets_to_saves) + if (wxGetApp().preset_bundle->transfer_and_save(preset.type, preset.from_name, preset.to_name, preset.new_name, m_tree->options(preset.type, true))) + saved_cnt++; + + if (saved_cnt > 0) + MessageDialog(nullptr, UnsavedChangesDialog::msg_success_saved_modifications(saved_cnt)).ShowModal(); + + update_presets(); + } } else { Hide(); @@ -2022,7 +2065,6 @@ std::string DiffPresetDialog::get_left_preset_name(Preset::Type type) std::string DiffPresetDialog::get_right_preset_name(Preset::Type type) { - PresetComboBox* cb = m_preset_combos[int(type - Preset::TYPE_PRINT)].presets_right; return Preset::remove_suffix_modified(get_selection(cb)); } diff --git a/src/slic3r/GUI/UnsavedChangesDialog.hpp b/src/slic3r/GUI/UnsavedChangesDialog.hpp index 2397c419e2..a303593ca8 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.hpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.hpp @@ -16,7 +16,6 @@ namespace Slic3r { namespace GUI{ wxDECLARE_EVENT(EVT_DIFF_DIALOG_TRANSFER, SimpleEvent); -wxDECLARE_EVENT(EVT_DIFF_DIALOG_SAVE, SimpleEvent); // ---------------------------------------------------------------------------- // ModelNode: a node inside DiffModel @@ -321,6 +320,8 @@ public: std::vector get_selected_options() { return m_tree->selected_options(); } bool has_unselected_options() { return m_tree->has_unselected_options(); } + static wxString msg_success_saved_modifications(size_t saved_presets_cnt); + protected: void on_dpi_changed(const wxRect& suggested_rect) override; void on_sys_color_changed() override; @@ -376,6 +377,7 @@ class DiffPresetDialog : public DPIDialog void update_compatibility(const std::string& preset_name, Preset::Type type, PresetBundle* preset_bundle); void button_event(Action act); + bool save(); struct DiffPresets { @@ -386,6 +388,17 @@ class DiffPresetDialog : public DPIDialog std::vector m_preset_combos; + // attributes witch are used for save preset + struct PresetToSave + { + Preset::Type type; + std::string from_name; + std::string to_name; + std::string new_name; + }; + + std::vector presets_to_saves; + public: DiffPresetDialog(MainFrame*mainframe); ~DiffPresetDialog() override = default;