From 3b1f1d944410d3f9d4fd30ef7fe88909aa73de01 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 30 Aug 2022 16:41:35 +0200 Subject: [PATCH] Implementation for FR #7851 - "Rename" or "EDIT" Print / Filament Settings is missing --- src/libslic3r/Preset.cpp | 14 ++++- src/libslic3r/Preset.hpp | 4 +- src/slic3r/GUI/SavePresetDialog.cpp | 80 +++++++++++++++++++++-------- src/slic3r/GUI/SavePresetDialog.hpp | 8 +++ src/slic3r/GUI/Tab.cpp | 67 +++++++++++++++++++++++- src/slic3r/GUI/Tab.hpp | 2 + 6 files changed, 148 insertions(+), 27 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 52d44ca48..f740c874c 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1876,13 +1876,23 @@ bool PhysicalPrinterCollection::delete_preset_from_printers( const std::string& return true; } +void PhysicalPrinterCollection::rename_preset_in_printers(const std::string& old_preset_name, const std::string& new_preset_name) +{ + for (PhysicalPrinter& printer : m_printers) + if (printer.delete_preset(old_preset_name)) { + printer.add_preset(new_preset_name); + printer.update_preset_names_in_config(); + printer.save(); + } +} + // Get list of printers which have more than one preset and "preset_names" preset is one of them -std::vector PhysicalPrinterCollection::get_printers_with_preset(const std::string& preset_name) +std::vector PhysicalPrinterCollection::get_printers_with_preset(const std::string& preset_name, bool respect_only_preset /*= true*/) { std::vector printers; for (auto printer : m_printers) { - if (printer.preset_names.size() == 1) + if (!respect_only_preset && printer.preset_names.size() == 1) continue; if (printer.preset_names.find(preset_name) != printer.preset_names.end()) printers.emplace_back(printer.name); diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 58ab57cfd..1e2ab9e24 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -734,9 +734,9 @@ public: // If there is last preset for the printer and first_check== false, then delete this printer // returns true if all presets were deleted successfully. bool delete_preset_from_printers(const std::string& preset_name); - + void rename_preset_in_printers(const std::string& old_name, const std::string& new_name); // Get list of printers which have more than one preset and "preset_names" preset is one of them - std::vector get_printers_with_preset( const std::string &preset_name); + std::vector get_printers_with_preset( const std::string &preset_name, bool respect_only_preset = true); // Get list of printers which has only "preset_names" preset std::vector get_printers_with_only_preset( const std::string &preset_name); diff --git a/src/slic3r/GUI/SavePresetDialog.cpp b/src/slic3r/GUI/SavePresetDialog.cpp index 2a2e3bb10..974d771b9 100644 --- a/src/slic3r/GUI/SavePresetDialog.cpp +++ b/src/slic3r/GUI/SavePresetDialog.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include "libslic3r/PresetBundle.hpp" @@ -54,27 +55,42 @@ SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBox values.push_back(preset.name); } - wxStaticText* label_top = new wxStaticText(m_parent, wxID_ANY, from_u8((boost::format(_utf8(L("Save %s as:"))) % into_u8(tab->title())).str())); + 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")); - 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) - m_combo->Append(from_u8(value)); + if (m_parent->is_for_rename()) { +#ifdef _WIN32 + long style = wxBORDER_SIMPLE; +#else + long style = 0L; +#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(); }); + } + else { + 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) + m_combo->Append(from_u8(value)); - m_combo->Bind(wxEVT_TEXT, [this](wxCommandEvent&) { update(); }); + m_combo->Bind(wxEVT_TEXT, [this](wxCommandEvent&) { update(); }); #ifdef __WXOSX__ - // Under OSX wxEVT_TEXT wasn't invoked after change selection in combobox, - // So process wxEVT_COMBOBOX too - m_combo->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { update(); }); + // Under OSX wxEVT_TEXT wasn't invoked after change selection in combobox, + // So process wxEVT_COMBOBOX too + m_combo->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { update(); }); #endif //__WXOSX__ + } 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); - combo_sizer->Add(m_combo, 1, wxEXPAND, BORDER_W); + 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); sizer->Add(label_top, 0, wxEXPAND | wxTOP| wxBOTTOM, BORDER_W); sizer->Add(combo_sizer, 0, wxEXPAND | wxBOTTOM, BORDER_W); @@ -88,7 +104,8 @@ SavePresetDialog::Item::Item(Preset::Type type, const std::string& suffix, wxBox void SavePresetDialog::Item::update() { - m_preset_name = into_u8(m_combo->GetValue()); + bool rename = m_parent->is_for_rename(); + m_preset_name = into_u8(rename ? m_text_ctrl->GetValue() : m_combo->GetValue()); m_valid_type = Valid; wxString info_line; @@ -119,23 +136,34 @@ void SavePresetDialog::Item::update() const Preset* existing = m_presets->find_preset(m_preset_name, false); if (m_valid_type == Valid && existing && (existing->is_default || existing->is_system)) { - info_line = _L("Cannot overwrite a system profile."); + info_line = rename ? _L("The supplied name is used for a system profile.") : + _L("Cannot overwrite a system profile."); m_valid_type = NoValid; } if (m_valid_type == Valid && existing && (existing->is_external)) { - info_line = _L("Cannot overwrite an external profile."); + info_line = rename ? _L("The supplied name is used for a external profile.") : + _L("Cannot overwrite an external profile."); m_valid_type = NoValid; } - if (m_valid_type == Valid && existing && m_preset_name != m_presets->get_selected_preset_name()) + if (m_valid_type == Valid && existing) { - if (existing->is_compatible) - info_line = from_u8((boost::format(_u8L("Preset with name \"%1%\" already exists.")) % m_preset_name).str()); - 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; + 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; + } + else { + if (existing->is_compatible) + info_line = from_u8((boost::format(_u8L("Preset with name \"%1%\" already exists.")) % m_preset_name).str()); + 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; + } } if (m_valid_type == Valid && m_preset_name.empty()) { @@ -158,6 +186,9 @@ void SavePresetDialog::Item::update() m_valid_type = NoValid; } + if (!m_parent->get_info_line_extention().IsEmpty() && m_valid_type != NoValid) + info_line += "\n\n" + m_parent->get_info_line_extention(); + m_valid_label->SetLabel(info_line); m_valid_label->Show(!info_line.IsEmpty()); @@ -194,11 +225,18 @@ SavePresetDialog::SavePresetDialog(wxWindow* parent, Preset::Type type, std::str } SavePresetDialog::SavePresetDialog(wxWindow* parent, std::vector types, std::string suffix) - : DPIDialog(parent, wxID_ANY, _L("Save preset"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER) + : DPIDialog(parent, wxID_ANY, _L("Save presets"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER) { build(types, suffix); } +SavePresetDialog::SavePresetDialog(wxWindow* parent, Preset::Type type, bool rename, const wxString& info_line_extention) + : DPIDialog(parent, wxID_ANY, _L("Rename preset"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 5 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxICON_WARNING | wxRESIZE_BORDER), + m_use_for_rename(rename), + m_info_line_extention(info_line_extention) +{ + build(std::vector{type}); +} SavePresetDialog::~SavePresetDialog() { for (auto item : m_items) { diff --git a/src/slic3r/GUI/SavePresetDialog.hpp b/src/slic3r/GUI/SavePresetDialog.hpp index cc1ea1f24..1ecda7b7f 100644 --- a/src/slic3r/GUI/SavePresetDialog.hpp +++ b/src/slic3r/GUI/SavePresetDialog.hpp @@ -10,6 +10,7 @@ class wxString; class wxStaticText; class wxComboBox; +class wxTextCtrl; class wxStaticBitmap; namespace Slic3r { @@ -52,6 +53,7 @@ class SavePresetDialog : public DPIDialog SavePresetDialog* m_parent {nullptr}; wxStaticBitmap* m_valid_bmp {nullptr}; wxComboBox* m_combo {nullptr}; + wxTextCtrl* m_text_ctrl {nullptr}; wxStaticText* m_valid_label {nullptr}; PresetCollection* m_presets {nullptr}; @@ -68,11 +70,16 @@ class SavePresetDialog : public DPIDialog std::string m_ph_printer_name; std::string m_old_preset_name; + bool m_use_for_rename{false}; + wxString m_info_line_extention{wxEmptyString}; 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, Preset::Type type, bool rename, const wxString& info_line_extention); ~SavePresetDialog(); void AddItem(Preset::Type type, const std::string& suffix); @@ -84,6 +91,7 @@ public: void add_info_for_edit_ph_printer(wxBoxSizer *sizer); void update_info_for_edit_ph_printer(const std::string &preset_name); void layout(); + bool is_for_rename() { return m_use_for_rename; } protected: void on_dpi_changed(const wxRect& suggested_rect) override; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 8d3f78401..05aa7e2ea 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -29,6 +29,7 @@ #include #include +#include #include "wxExtensions.hpp" #include "PresetComboBoxes.hpp" #include @@ -150,6 +151,7 @@ void Tab::create_preset_tab() add_scaled_button(panel, &m_btn_compare_preset, "compare"); add_scaled_button(panel, &m_btn_save_preset, "save"); + add_scaled_button(panel, &m_btn_rename_preset, "edit"); add_scaled_button(panel, &m_btn_delete_preset, "cross"); if (m_type == Preset::Type::TYPE_PRINTER) add_scaled_button(panel, &m_btn_edit_ph_printer, "cog"); @@ -161,6 +163,8 @@ void Tab::create_preset_tab() m_btn_compare_preset->SetToolTip(_L("Compare this preset with some another")); // TRN "Save current Settings" m_btn_save_preset->SetToolTip(from_u8((boost::format(_utf8(L("Save current %s"))) % m_title).str())); + m_btn_rename_preset->SetToolTip(from_u8((boost::format(_utf8(L("Rename current %s"))) % m_title).str())); + m_btn_rename_preset->Hide(); m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); m_btn_delete_preset->Hide(); @@ -211,6 +215,8 @@ void Tab::create_preset_tab() m_hsizer->Add(m_presets_choice, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); m_hsizer->AddSpacer(int(4*scale_factor)); m_hsizer->Add(m_btn_save_preset, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->AddSpacer(int(4*scale_factor)); + m_hsizer->Add(m_btn_rename_preset, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(4 * scale_factor)); m_hsizer->Add(m_btn_delete_preset, 0, wxALIGN_CENTER_VERTICAL); if (m_btn_edit_ph_printer) { @@ -300,6 +306,7 @@ void Tab::create_preset_tab() m_btn_compare_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { compare_preset(); })); m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); })); + m_btn_rename_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { rename_preset(); })); m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); })); m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { toggle_show_hide_incompatible(); @@ -3183,6 +3190,7 @@ void Tab::update_btns_enabling() const Preset& preset = m_presets->get_edited_preset(); m_btn_delete_preset->Show((m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection()) || (!preset.is_default && !preset.is_system)); + m_btn_rename_preset->Show(!preset.is_default && !preset.is_system && !m_presets_choice->is_selected_physical_printer()); if (m_btn_edit_ph_printer) m_btn_edit_ph_printer->SetToolTip( m_preset_bundle->physical_printers.has_selection() ? @@ -3615,8 +3623,9 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach) update_tab_ui(); // Update the selection boxes at the plater. on_presets_changed(); - // If current profile is saved, "delete preset" button have to be enabled + // If current profile is saved, "delete/rename preset" buttons have to be shown m_btn_delete_preset->Show(); + m_btn_rename_preset->Show(!m_presets_choice->is_selected_physical_printer()); m_btn_delete_preset->GetParent()->Layout(); if (m_type == Preset::TYPE_PRINTER) @@ -3665,6 +3674,60 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach) update_description_lines(); } +void Tab::rename_preset() +{ + if (m_presets_choice->is_selected_physical_printer()) + return; + + Preset& selected_preset = m_presets->get_selected_preset(); + wxString msg; + + if (m_type == Preset::TYPE_PRINTER && !m_preset_bundle->physical_printers.empty()) { + // Check preset for rename in physical printers + std::vector ph_printers = m_preset_bundle->physical_printers.get_printers_with_preset(selected_preset.name); + if (!ph_printers.empty()) { + msg += _L_PLURAL("The physical printer below is based on the preset, you are going to rename.", + "The physical printers below are based on the preset, you are going to rename.", ph_printers.size()); + for (const std::string& printer : ph_printers) + msg += "\n \"" + from_u8(printer) + "\","; + msg.RemoveLast(); + msg += "\n" + _L_PLURAL("Note, that the selected preset will be renamed in this printer too.", + "Note, that the selected preset will be renamed in these printers too.", ph_printers.size()) + "\n\n"; + } + } + + // get new name + + SavePresetDialog dlg(m_parent, m_type, true, msg); + if (dlg.ShowModal() != wxID_OK) + return; + std::string new_name = into_u8(dlg.get_name()); + + if (new_name.empty() || new_name == m_presets->get_selected_preset().name) + return; + + // rename selected and edited presets + + std::string old_name = selected_preset.name; + std::string old_file_name = selected_preset.file; + + selected_preset.name = new_name; + boost::replace_last(selected_preset.file, old_name, new_name); + + Preset& edited_preset = m_presets->get_edited_preset(); + edited_preset.name = new_name; + boost::replace_last(edited_preset.file, old_name, new_name); + + // rename file with renamed preset configuration + boost::filesystem::rename(old_file_name, selected_preset.file); + + // rename selected preset in printers, if it's needed + if (!msg.IsEmpty()) + m_preset_bundle->physical_printers.rename_preset_in_printers(old_name, new_name); + + m_presets_choice->update(); +} + // Called for a currently selected preset. void Tab::delete_preset() { @@ -3692,7 +3755,7 @@ void Tab::delete_preset() { // Check preset for delete in physical printers // Ask a customer about next action, if there is a printer with just one preset and this preset is equal to delete - std::vector ph_printers = physical_printers.get_printers_with_preset(current_preset.name); + std::vector ph_printers = physical_printers.get_printers_with_preset(current_preset.name, false); std::vector ph_printers_only = physical_printers.get_printers_with_only_preset(current_preset.name); if (!ph_printers.empty()) { diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 40ceb1682..8ed11bf9d 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -168,6 +168,7 @@ protected: ScalableButton* m_search_btn; ScalableButton* m_btn_compare_preset; ScalableButton* m_btn_save_preset; + ScalableButton* m_btn_rename_preset; ScalableButton* m_btn_delete_preset; ScalableButton* m_btn_edit_ph_printer {nullptr}; ScalableButton* m_btn_hide_incompatible_presets; @@ -322,6 +323,7 @@ public: void compare_preset(); void save_preset(std::string name = std::string(), bool detach = false); + void rename_preset(); void delete_preset(); void toggle_show_hide_incompatible(); void update_show_hide_incompatible_button();