QoL: Port profile value transfer on profile diff dialog from PrusaSlicer (#3737)

* DiffDialog: Implemented a transfer of options from one preset to another
Related to [Feature Request] #5384 - Copy values in Profile comparaison dialog

Cherry-picked from prusa3d/PrusaSlicer@0b8d7380ff

Co-authored-by: YuSanka <yusanka@gmail.com>

* Remove save button

* Sync with latest PS

* Use Orca button style

* Show tips about trasnfer disabled

---------

Co-authored-by: YuSanka <yusanka@gmail.com>
This commit is contained in:
Noisyfox 2024-01-24 23:18:52 +08:00 committed by GitHub
parent 48541be681
commit 55b6f2a588
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 422 additions and 108 deletions

View file

@ -1,3 +1,8 @@
///|/ Copyright (c) Prusa Research 2017 - 2023 Oleksandra Iushchenko @YuSanka, Enrico Turri @enricoturri1966, Lukáš Matěna @lukasmatena, Vojtěch Bubník @bubnikv, David Kocík @kocikdav, Vojtěch Král @vojtechkral
///|/ Copyright (c) 2019 John Drake @foxox
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#ifndef slic3r_PresetBundle_hpp_ #ifndef slic3r_PresetBundle_hpp_
#define slic3r_PresetBundle_hpp_ #define slic3r_PresetBundle_hpp_
@ -7,6 +12,7 @@
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <array>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#define DEFAULT_USER_FOLDER_NAME "default" #define DEFAULT_USER_FOLDER_NAME "default"
@ -247,6 +253,13 @@ public:
static const char *BBL_DEFAULT_PRINTER_MODEL; static const char *BBL_DEFAULT_PRINTER_MODEL;
static const char *BBL_DEFAULT_PRINTER_VARIANT; static const char *BBL_DEFAULT_PRINTER_VARIANT;
static const char *BBL_DEFAULT_FILAMENT; static const char *BBL_DEFAULT_FILAMENT;
static std::array<Preset::Type, 3> types_list(PrinterTechnology pt) {
if (pt == ptFFF)
return { Preset::TYPE_PRINTER, Preset::TYPE_PRINT, Preset::TYPE_FILAMENT };
return { Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL };
}
private: private:
//std::pair<PresetsConfigSubstitutions, std::string> load_system_presets(ForwardCompatibilitySubstitutionRule compatibility_rule); //std::pair<PresetsConfigSubstitutions, std::string> load_system_presets(ForwardCompatibilitySubstitutionRule compatibility_rule);
//BBS: add json related logic //BBS: add json related logic

View file

@ -2405,9 +2405,9 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
bool check_unsaved_preset_changes = false; bool check_unsaved_preset_changes = false;
if (check_unsaved_preset_changes) if (check_unsaved_preset_changes)
header = _L("All user presets will be deleted."); header = _L("All user presets will be deleted.");
int act_btns = UnsavedChangesDialog::ActionButtons::KEEP; int act_btns = ActionButtons::KEEP;
if (!check_unsaved_preset_changes) if (!check_unsaved_preset_changes)
act_btns |= UnsavedChangesDialog::ActionButtons::SAVE; act_btns |= ActionButtons::SAVE;
// Install bundles from resources if needed: // Install bundles from resources if needed:
std::vector<std::string> install_bundles; std::vector<std::string> install_bundles;

View file

@ -3758,8 +3758,7 @@ void GUI_App::request_user_logout()
bool transfer_preset_changes = false; bool transfer_preset_changes = false;
wxString header = _L("Some presets are modified.") + "\n" + wxString header = _L("Some presets are modified.") + "\n" +
_L("You can keep the modifield presets to the new project, discard or save changes as new presets."); _L("You can keep the modifield presets to the new project, discard or save changes as new presets.");
using ab = UnsavedChangesDialog::ActionButtons; wxGetApp().check_and_keep_current_preset_changes(_L("User logged out"), header, ActionButtons::KEEP | ActionButtons::SAVE, &transfer_preset_changes);
wxGetApp().check_and_keep_current_preset_changes(_L("User logged out"), header, ab::KEEP | ab::SAVE, &transfer_preset_changes);
m_device_manager->clean_user_info(); m_device_manager->clean_user_info();
GUI::wxGetApp().sidebar().load_ams_list({}, {}); GUI::wxGetApp().sidebar().load_ams_list({}, {});
@ -5606,11 +5605,11 @@ std::vector<std::pair<unsigned int, std::string>> GUI_App::get_selected_presets(
bool GUI_App::check_and_save_current_preset_changes(const wxString& caption, const wxString& header, bool remember_choice/* = true*/, bool dont_save_insted_of_discard/* = false*/) bool GUI_App::check_and_save_current_preset_changes(const wxString& caption, const wxString& header, bool remember_choice/* = true*/, bool dont_save_insted_of_discard/* = false*/)
{ {
if (has_current_preset_changes()) { if (has_current_preset_changes()) {
int act_buttons = UnsavedChangesDialog::ActionButtons::SAVE; int act_buttons = ActionButtons::SAVE;
if (dont_save_insted_of_discard) if (dont_save_insted_of_discard)
act_buttons |= UnsavedChangesDialog::ActionButtons::DONT_SAVE; act_buttons |= ActionButtons::DONT_SAVE;
if (remember_choice) if (remember_choice)
act_buttons |= UnsavedChangesDialog::ActionButtons::REMEMBER_CHOISE; act_buttons |= ActionButtons::REMEMBER_CHOISE;
UnsavedChangesDialog dlg(caption, header, "", act_buttons); UnsavedChangesDialog dlg(caption, header, "", act_buttons);
if (dlg.ShowModal() == wxID_CANCEL) if (dlg.ShowModal() == wxID_CANCEL)
return false; return false;

View file

@ -611,8 +611,41 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
wxGetApp().persist_window_geometry(this, true); wxGetApp().persist_window_geometry(this, true);
wxGetApp().persist_window_geometry(&m_settings_dialog, true); wxGetApp().persist_window_geometry(&m_settings_dialog, true);
// bind events from DiffDlg
bind_diff_dialog();
} }
void MainFrame::bind_diff_dialog()
{
auto get_tab = [](Preset::Type type) {
Tab* null_tab = nullptr;
for (Tab* tab : wxGetApp().tabs_list)
if (tab->type() == type)
return tab;
return null_tab;
};
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),
diff_dialog.get_selected_options(type));
};
auto process_options = [this](std::function<void(Preset::Type)> process) {
const Preset::Type diff_dlg_type = diff_dialog.view_type();
if (diff_dlg_type == Preset::TYPE_INVALID) {
for (const Preset::Type& type : diff_dialog.types_list() )
process(type);
}
else
process(diff_dlg_type);
};
diff_dialog.Bind(EVT_DIFF_DIALOG_TRANSFER, [process_options, transfer](SimpleEvent&) { process_options(transfer); });
}
#ifdef __WIN32__ #ifdef __WIN32__
WXLRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) WXLRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
@ -3599,9 +3632,6 @@ void MainFrame::RunScript(wxString js)
void MainFrame::technology_changed() void MainFrame::technology_changed()
{ {
// upadte DiffDlg
diff_dialog.update_presets();
// update menu titles // update menu titles
PrinterTechnology pt = plater()->printer_technology(); PrinterTechnology pt = plater()->printer_technology();
if (int id = m_menubar->FindMenu(pt == ptFFF ? _omitL("Material Settings") : _L("Filament Settings")); id != wxNOT_FOUND) if (int id = m_menubar->FindMenu(pt == ptFFF ? _omitL("Material Settings") : _L("Filament Settings")); id != wxNOT_FOUND)

View file

@ -131,6 +131,7 @@ class MainFrame : public DPIFrame
bool can_delete() const; bool can_delete() const;
bool can_delete_all() const; bool can_delete_all() const;
bool can_reslice() const; bool can_reslice() const;
void bind_diff_dialog();
// BBS // BBS
wxBoxSizer* create_side_tools(); wxBoxSizer* create_side_tools();

View file

@ -8299,10 +8299,9 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_
wxString header = _L("Some presets are modified.") + "\n" + wxString header = _L("Some presets are modified.") + "\n" +
(yes_or_no ? _L("You can keep the modified presets to the new project or discard them") : (yes_or_no ? _L("You can keep the modified presets to the new project or discard them") :
_L("You can keep the modifield presets to the new project, discard or save changes as new presets.")); _L("You can keep the modifield presets to the new project, discard or save changes as new presets."));
using ab = UnsavedChangesDialog::ActionButtons; int act_buttons = ActionButtons::KEEP | ActionButtons::REMEMBER_CHOISE;
int act_buttons = ab::KEEP | ab::REMEMBER_CHOISE;
if (!yes_or_no) if (!yes_or_no)
act_buttons |= ab::SAVE; act_buttons |= ActionButtons::SAVE;
return wxGetApp().check_and_keep_current_preset_changes(_L("Creating a new project"), header, act_buttons, &transfer_preset_changes); return wxGetApp().check_and_keep_current_preset_changes(_L("Creating a new project"), header, act_buttons, &transfer_preset_changes);
}; };
int result; int result;

View file

@ -222,7 +222,7 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(
auto check = [this](bool yes_or_no) { auto check = [this](bool yes_or_no) {
// if (yes_or_no) // if (yes_or_no)
// return true; // return true;
int act_btns = UnsavedChangesDialog::ActionButtons::SAVE; int act_btns = ActionButtons::SAVE;
return wxGetApp().check_and_keep_current_preset_changes(_L("Switching application language"), return wxGetApp().check_and_keep_current_preset_changes(_L("Switching application language"),
_L("Switching application language while some presets are modified."), act_btns); _L("Switching application language while some presets are modified."), act_btns);
}; };

View file

@ -37,7 +37,6 @@
#include "../Utils/FixModelByWin10.hpp" #include "../Utils/FixModelByWin10.hpp"
#include "../Utils/UndoRedo.hpp" #include "../Utils/UndoRedo.hpp"
#include "BitmapCache.hpp" #include "BitmapCache.hpp"
#include "SavePresetDialog.hpp"
#include "MsgDialog.hpp" #include "MsgDialog.hpp"
#include "ParamsDialog.hpp" #include "ParamsDialog.hpp"

View file

@ -1,3 +1,22 @@
///|/ Copyright (c) Prusa Research 2017 - 2023 Oleksandra Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Lukáš Hejl @hejllukas, Vojtěch Bubník @bubnikv, Pavel Mikuš @Godrak, Tomáš Mészáros @tamasmeszaros, David Kocík @kocikdav, Enrico Turri @enricoturri1966, Vojtěch Král @vojtechkral
///|/ Copyright (c) 2021 Martin Budden
///|/ Copyright (c) 2021 Ilya @xorza
///|/ Copyright (c) 2019 John Drake @foxox
///|/ Copyright (c) 2019 Matthias Urlichs @smurfix
///|/ Copyright (c) 2019 Thomas Moore
///|/ Copyright (c) 2019 Sijmen Schoon
///|/ Copyright (c) 2018 Martin Loidl @LoidlM
///|/
///|/ ported from lib/Slic3r/GUI/Tab.pm:
///|/ Copyright (c) Prusa Research 2016 - 2018 Vojtěch Bubník @bubnikv, Lukáš Matěna @lukasmatena
///|/ Copyright (c) 2015 - 2017 Joseph Lenox @lordofhyphens
///|/ Copyright (c) Slic3r 2012 - 2016 Alessandro Ranellucci @alranel
///|/ Copyright (c) 2016 Chow Loong Jin @hyperair
///|/ Copyright (c) 2012 QuantumConcepts
///|/ Copyright (c) 2012 Henrik Brix Andersen @henrikbrixandersen
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
// #include "libslic3r/GCodeSender.hpp" // #include "libslic3r/GCodeSender.hpp"
//#include "slic3r/Utils/Serial.hpp" //#include "slic3r/Utils/Serial.hpp"
#include "Tab.hpp" #include "Tab.hpp"
@ -1692,9 +1711,9 @@ void Tab::apply_searcher()
wxGetApp().sidebar().get_searcher().apply(m_config, m_type, m_mode); wxGetApp().sidebar().get_searcher().apply(m_config, m_type, m_mode);
} }
void Tab::cache_config_diff(const std::vector<std::string>& selected_options) void Tab::cache_config_diff(const std::vector<std::string>& selected_options, const DynamicPrintConfig* config/* = nullptr*/)
{ {
m_cache_config.apply_only(m_presets->get_edited_preset().config, selected_options); m_cache_config.apply_only(config ? *config : m_presets->get_edited_preset().config, selected_options);
} }
void Tab::apply_config_from_cache() void Tab::apply_config_from_cache()
@ -5076,6 +5095,32 @@ void Tab::compare_preset()
wxGetApp().mainframe->diff_dialog.show(m_type); wxGetApp().mainframe->diff_dialog.show(m_type);
} }
void Tab::transfer_options(const std::string &name_from, const std::string &name_to, std::vector<std::string> options)
{
if (options.empty())
return;
Preset* preset_from = m_presets->find_preset(name_from);
Preset* preset_to = m_presets->find_preset(name_to);
if (m_type == Preset::TYPE_PRINTER) {
auto it = std::find(options.begin(), options.end(), "extruders_count");
if (it != options.end()) {
// erase "extruders_count" option from the list
options.erase(it);
// cache the extruders count
static_cast<TabPrinter*>(this)->cache_extruder_cnt(&preset_from->config);
}
}
cache_config_diff(options, &preset_from->config);
if (name_to != m_presets->get_edited_preset().name )
select_preset(preset_to->name);
apply_config_from_cache();
load_current_preset();
}
// Save the current preset into file. // Save the current preset into file.
// This removes the "dirty" flag of the preset, possibly creates a new preset under a new name, // This removes the "dirty" flag of the preset, possibly creates a new preset under a new name,
// and activates the new preset. // and activates the new preset.
@ -5513,13 +5558,15 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
return sizer; return sizer;
} }
void TabPrinter::cache_extruder_cnt() void TabPrinter::cache_extruder_cnt(const DynamicPrintConfig* config/* = nullptr*/)
{ {
if (m_presets->get_edited_preset().printer_technology() == ptSLA) const DynamicPrintConfig& cached_config = config ? *config : m_presets->get_edited_preset().config;
if (Preset::printer_technology(cached_config) == ptSLA)
return; return;
// BBS. Get extruder count from preset instead of m_extruders_count. // get extruders count
m_cache_extruder_count = dynamic_cast<ConfigOptionFloats*>((m_presets->get_edited_preset().config).option("nozzle_diameter"))->values.size(); auto* nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(cached_config.option("nozzle_diameter"));
m_cache_extruder_count = nozzle_diameter->values.size(); //m_extruders_count;
} }
bool TabPrinter::apply_extruder_cnt_from_cache() bool TabPrinter::apply_extruder_cnt_from_cache()

View file

@ -1,3 +1,17 @@
///|/ Copyright (c) Prusa Research 2017 - 2023 Oleksandra Iushchenko @YuSanka, Tomáš Mészáros @tamasmeszaros, Vojtěch Bubník @bubnikv, Lukáš Matěna @lukasmatena, Enrico Turri @enricoturri1966, Vojtěch Král @vojtechkral
///|/ Copyright (c) 2019 John Drake @foxox
///|/ Copyright (c) 2018 Martin Loidl @LoidlM
///|/
///|/ ported from lib/Slic3r/GUI/Tab.pm:
///|/ Copyright (c) Prusa Research 2016 - 2018 Vojtěch Bubník @bubnikv, Lukáš Matěna @lukasmatena
///|/ Copyright (c) 2015 - 2017 Joseph Lenox @lordofhyphens
///|/ Copyright (c) Slic3r 2012 - 2016 Alessandro Ranellucci @alranel
///|/ Copyright (c) 2016 Chow Loong Jin @hyperair
///|/ Copyright (c) 2012 QuantumConcepts
///|/ Copyright (c) 2012 Henrik Brix Andersen @henrikbrixandersen
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#ifndef slic3r_Tab_hpp_ #ifndef slic3r_Tab_hpp_
#define slic3r_Tab_hpp_ #define slic3r_Tab_hpp_
@ -338,6 +352,7 @@ public:
void OnKeyDown(wxKeyEvent& event); void OnKeyDown(wxKeyEvent& event);
void compare_preset(); void compare_preset();
void transfer_options(const std::string&name_from, const std::string&name_to, std::vector<std::string> options);
//BBS: add project embedded preset relate logic //BBS: add project embedded preset relate logic
void save_preset(std::string name = std::string(), bool detach = false, bool save_to_project = false, bool from_input = false, std::string input_name = ""); void save_preset(std::string name = std::string(), bool detach = false, bool save_to_project = false, bool from_input = false, std::string input_name = "");
//void save_preset(std::string name = std::string(), bool detach = false); //void save_preset(std::string name = std::string(), bool detach = false);
@ -396,7 +411,7 @@ public:
void update_wiping_button_visibility(); void update_wiping_button_visibility();
void activate_option(const std::string& opt_key, const wxString& category); void activate_option(const std::string& opt_key, const wxString& category);
void apply_searcher(); void apply_searcher();
void cache_config_diff(const std::vector<std::string>& selected_options); void cache_config_diff(const std::vector<std::string>& selected_options, const DynamicPrintConfig* config = nullptr);
void apply_config_from_cache(); void apply_config_from_cache();
void show_timelapse_warning_dialog(); void show_timelapse_warning_dialog();
@ -625,7 +640,7 @@ public:
bool supports_printer_technology(const PrinterTechnology /* tech */) const override { return true; } bool supports_printer_technology(const PrinterTechnology /* tech */) const override { return true; }
wxSizer* create_bed_shape_widget(wxWindow* parent); wxSizer* create_bed_shape_widget(wxWindow* parent);
void cache_extruder_cnt(); void cache_extruder_cnt(const DynamicPrintConfig* config = nullptr);
bool apply_extruder_cnt_from_cache(); bool apply_extruder_cnt_from_cache();
}; };

View file

@ -1,3 +1,9 @@
///|/ Copyright (c) Prusa Research 2020 - 2023 Oleksandra Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Vojtěch Bubník @bubnikv, Enrico Turri @enricoturri1966, David Kocík @kocikdav
///|/ Copyright (c) 2021 Pascal de Bruijn @pmjdebruijn
///|/ Copyright (c) 2021 Sebastian Hammerl
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#include "UnsavedChangesDialog.hpp" #include "UnsavedChangesDialog.hpp"
#include <cstddef> #include <cstddef>
@ -5,7 +11,6 @@
#include <vector> #include <vector>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/nowide/convert.hpp>
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
@ -22,10 +27,6 @@
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "MsgDialog.hpp" #include "MsgDialog.hpp"
//#define FTS_FUZZY_MATCH_IMPLEMENTATION
//#include "fts_fuzzy_match.h"
#include "BitmapCache.hpp"
#include "PresetComboBoxes.hpp" #include "PresetComboBoxes.hpp"
#include "Widgets/RoundedRectangle.hpp" #include "Widgets/RoundedRectangle.hpp"
#include "Widgets/CheckBox.hpp" #include "Widgets/CheckBox.hpp"
@ -42,6 +43,9 @@ namespace Slic3r {
namespace GUI { namespace GUI {
wxDEFINE_EVENT(EVT_DIFF_DIALOG_TRANSFER, SimpleEvent);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ModelNode: a node inside DiffModel // ModelNode: a node inside DiffModel
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -105,8 +109,8 @@ ModelNode::ModelNode(ModelNode* parent, const wxString& text, const std::string&
ModelNode::ModelNode(ModelNode* parent, const wxString& text) : ModelNode::ModelNode(ModelNode* parent, const wxString& text) :
m_parent_win(parent->m_parent_win), m_parent_win(parent->m_parent_win),
m_parent(parent), m_parent(parent),
m_text(text), m_icon_name("node_dot"),
m_icon_name("node_dot") m_text(text)
{ {
UpdateIcons(); UpdateIcons();
} }
@ -143,11 +147,11 @@ ModelNode::ModelNode(ModelNode* parent, const wxString& text, const wxString& ol
m_parent(parent), m_parent(parent),
m_old_color(old_value.StartsWith("#") ? old_value : ""), m_old_color(old_value.StartsWith("#") ? old_value : ""),
m_new_color(new_value.StartsWith("#") ? new_value : ""), m_new_color(new_value.StartsWith("#") ? new_value : ""),
m_container(false),
m_text(text),
m_icon_name("empty"), m_icon_name("empty"),
m_text(text),
m_old_value(old_value), m_old_value(old_value),
m_new_value(new_value) m_new_value(new_value),
m_container(false)
{ {
// check if old/new_value is color // check if old/new_value is color
if (m_old_color.IsEmpty()) { if (m_old_color.IsEmpty()) {
@ -487,7 +491,7 @@ unsigned int DiffModel::GetChildren(const wxDataViewItem& parent, wxDataViewItem
for (const std::unique_ptr<ModelNode>& child : children) for (const std::unique_ptr<ModelNode>& child : children)
array.Add(wxDataViewItem((void*)child.get())); array.Add(wxDataViewItem((void*)child.get()));
return array.size(); return array.Count();
} }
@ -573,7 +577,7 @@ void DiffModel::Clear()
static std::string get_pure_opt_key(std::string opt_key) static std::string get_pure_opt_key(std::string opt_key)
{ {
int pos = opt_key.find("#"); const int pos = opt_key.find("#");
if (pos > 0) if (pos > 0)
boost::erase_tail(opt_key, opt_key.size() - pos); boost::erase_tail(opt_key, opt_key.size() - pos);
return opt_key; return opt_key;
@ -1824,35 +1828,11 @@ static std::string get_selection(PresetComboBox* preset_combo)
return into_u8(preset_combo->GetString(preset_combo->GetSelection())); return into_u8(preset_combo->GetString(preset_combo->GetSelection()));
} }
DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) void DiffPresetDialog::create_presets_sizer()
: DPIDialog(mainframe, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
m_pr_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology())
{ {
#if defined(__WXMSW__) m_presets_sizer = new wxBoxSizer(wxVERTICAL);
// ys_FIXME! temporary workaround for correct font scaling
// Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
// From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
#endif // __WXMSW__
int border = 10; for (auto new_type : { Preset::TYPE_PRINT, Preset::TYPE_SLA_PRINT, Preset::TYPE_FILAMENT, Preset::TYPE_SLA_MATERIAL, Preset::TYPE_PRINTER })
int em = em_unit();
SetBackgroundColour(*wxWHITE);
assert(wxGetApp().preset_bundle);
m_preset_bundle_left = std::make_unique<PresetBundle>(*wxGetApp().preset_bundle);
m_preset_bundle_right = std::make_unique<PresetBundle>(*wxGetApp().preset_bundle);
//m_top_info_line = new wxStaticText(this, wxID_ANY, "Select presets to compare");
m_top_info_line = new wxStaticText(this, wxID_ANY, _L("Select presets to compare"));
m_top_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold());
m_bottom_info_line = new wxStaticText(this, wxID_ANY, "");
m_bottom_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold());
wxBoxSizer* presets_sizer = new wxBoxSizer(wxVERTICAL);
for (auto new_type : { Preset::TYPE_PRINT, Preset::TYPE_FILAMENT, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL, Preset::TYPE_PRINTER })
{ {
const PresetCollection* collection = get_preset_collection(new_type); const PresetCollection* collection = get_preset_collection(new_type);
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
@ -1860,13 +1840,13 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
PresetComboBox* presets_right; PresetComboBox* presets_right;
ScalableButton* equal_bmp = new ScalableButton(this, wxID_ANY, "equal"); ScalableButton* equal_bmp = new ScalableButton(this, wxID_ANY, "equal");
auto add_preset_combobox = [collection, sizer, new_type, em, this](PresetComboBox** cb_, PresetBundle* preset_bundle) { auto add_preset_combobox = [collection, sizer, new_type, this](PresetComboBox** cb_, PresetBundle* preset_bundle) {
*cb_ = new PresetComboBox(this, new_type, wxSize(em * 35, -1), preset_bundle); *cb_ = new PresetComboBox(this, new_type, wxSize(em_unit() * 35, -1), preset_bundle);
PresetComboBox* cb = (*cb_); PresetComboBox* cb = (*cb_);
cb->set_selection_changed_function([this, new_type, preset_bundle, cb](int selection) { cb->set_selection_changed_function([this, new_type, preset_bundle, cb](int selection) {
if (m_view_type == Preset::TYPE_INVALID) { if (m_view_type == Preset::TYPE_INVALID) {
std::string preset_name = cb->GetString(selection).ToUTF8().data(); std::string preset_name = Preset::remove_suffix_modified(cb->GetString(selection).ToUTF8().data());
update_compatibility(Preset::remove_suffix_modified(preset_name), new_type, preset_bundle); update_compatibility(preset_name, new_type, preset_bundle);
} }
update_tree(); update_tree();
}); });
@ -1879,7 +1859,7 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
add_preset_combobox(&presets_left, m_preset_bundle_left.get()); add_preset_combobox(&presets_left, m_preset_bundle_left.get());
sizer->Add(equal_bmp, 0, wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL, 5); sizer->Add(equal_bmp, 0, wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL, 5);
add_preset_combobox(&presets_right, m_preset_bundle_right.get()); add_preset_combobox(&presets_right, m_preset_bundle_right.get());
presets_sizer->Add(sizer, 1, wxTOP, 5); m_presets_sizer->Add(sizer, 1, wxTOP, 5);
equal_bmp->Show(new_type == Preset::TYPE_PRINTER); equal_bmp->Show(new_type == Preset::TYPE_PRINTER);
m_preset_combos.push_back({ presets_left, equal_bmp, presets_right }); m_preset_combos.push_back({ presets_left, equal_bmp, presets_right });
@ -1892,7 +1872,10 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
update_tree(); update_tree();
}); });
} }
}
void DiffPresetDialog::create_show_all_presets_chb()
{
m_show_all_presets = new wxCheckBox(this, wxID_ANY, _L("Show all presets (including incompatible)")); m_show_all_presets = new wxCheckBox(this, wxID_ANY, _L("Show all presets (including incompatible)"));
m_show_all_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { m_show_all_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) {
bool show_all = m_show_all_presets->GetValue(); bool show_all = m_show_all_presets->GetValue();
@ -1905,27 +1888,189 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
if (m_view_type == Preset::TYPE_INVALID) if (m_view_type == Preset::TYPE_INVALID)
update_tree(); update_tree();
}); });
}
m_tree = new DiffViewCtrl(this, wxSize(em * 65, em * 40)); void DiffPresetDialog::create_info_lines()
{
const wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold();
m_top_info_line = new wxStaticText(this, wxID_ANY, _L("Select presets to compare"));
m_top_info_line->SetFont(font);
m_bottom_info_line = new wxStaticText(this, wxID_ANY, "");
m_bottom_info_line->SetFont(font);
}
void DiffPresetDialog::create_tree()
{
m_tree = new DiffViewCtrl(this, wxSize(em_unit() * 65, em_unit() * 40));
m_tree->AppendToggleColumn_(L"\u2714", DiffModel::colToggle, wxLinux ? 9 : 6);
m_tree->AppendBmpTextColumn("", DiffModel::colIconText, 35); m_tree->AppendBmpTextColumn("", DiffModel::colIconText, 35);
m_tree->AppendBmpTextColumn("Left Preset Value", DiffModel::colOldValue, 15); m_tree->AppendBmpTextColumn("Left Preset Value", DiffModel::colOldValue, 15);
m_tree->AppendBmpTextColumn("Right Preset Value",DiffModel::colNewValue, 15); m_tree->AppendBmpTextColumn("Right Preset Value",DiffModel::colNewValue, 15);
m_tree->Hide(); m_tree->Hide();
m_tree->GetColumn(DiffModel::colToggle)->SetHidden(true);
}
std::array<Preset::Type, 3> DiffPresetDialog::types_list() const
{
return PresetBundle::types_list(m_pr_technology);
}
void DiffPresetDialog::create_buttons()
{
wxFont font = this->GetFont().Scaled(1.4f);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Disabled),
std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
m_buttons = new wxBoxSizer(wxHORIZONTAL);
auto show_in_bottom_info = [this](const wxString& ext_line, wxEvent* e = nullptr) {
m_bottom_info_line->SetLabel(ext_line);
m_bottom_info_line->Show(true);
Layout();
if (e) e->Skip();
};
// Transfer
m_transfer_btn = new Button(this, L("Transfer"));
m_transfer_btn->SetBackgroundColor(btn_bg_green);
m_transfer_btn->SetBorderColor(wxColour(0, 150, 136));
m_transfer_btn->SetTextColor(wxColour("#FFFFFE"));
m_transfer_btn->SetMinSize(wxSize(-1, -1));
m_transfer_btn->SetCornerRadius(FromDIP(12));
m_transfer_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { button_event(Action::Transfer);});
auto enable_transfer = [this](const Preset::Type& type) {
const Preset& main_edited_preset = get_preset_collection(type, wxGetApp().preset_bundle)->get_edited_preset();
if (main_edited_preset.is_dirty)
return main_edited_preset.name == get_right_preset_name(type);
return true;
};
m_transfer_btn->Bind(wxEVT_UPDATE_UI, [this, enable_transfer, show_in_bottom_info](wxUpdateUIEvent& evt) {
bool enable = m_tree->has_selection();
if (enable) {
if (m_view_type == Preset::TYPE_INVALID) {
for (const Preset::Type& type : types_list())
if (!enable_transfer(type)) {
enable = false;
break;
}
}
else
enable = enable_transfer(m_view_type);
if (!enable && m_transfer_btn->IsShown()) {
show_in_bottom_info(_L("You can only transfer to current active profile because it has been modified."));
}
}
evt.Enable(enable);
});
m_transfer_btn->Bind(wxEVT_ENTER_WINDOW, [show_in_bottom_info](wxMouseEvent& e) {
show_in_bottom_info(_L("Transfer the selected options from left preset to the right.\n"
"Note: New modified presets will be selected in settings tabs after close this dialog."), &e); });
// Cancel
m_cancel_btn = new Button(this, L("Cancel"));
m_cancel_btn->SetTextColor(wxColour(107, 107, 107));
m_cancel_btn->SetMinSize(wxSize(-1, -1));
m_cancel_btn->SetCornerRadius(FromDIP(12));
m_cancel_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { button_event(Action::Discard);});
for (Button* btn : { m_transfer_btn, m_cancel_btn }) {
btn->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { update_bottom_info(); Layout(); e.Skip(); });
m_buttons->Add(btn, 1, wxLEFT, 5);
btn->SetFont(font);
}
m_buttons->Show(false);
}
void DiffPresetDialog::create_edit_sizer()
{
// Add check box for the edit mode
m_use_for_transfer = new wxCheckBox(this, wxID_ANY, _L("Transfer values from left to right"));
m_use_for_transfer->SetToolTip(_L("If enabled, this dialog can be used for transver selected values from left to right preset."));
m_use_for_transfer->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) {
bool use = m_use_for_transfer->GetValue();
m_tree->GetColumn(DiffModel::colToggle)->SetHidden(!use);
if (m_tree->IsShown()) {
m_buttons->Show(use);
Fit();
Refresh();
}
else
this->Layout();
});
// Add Buttons
create_buttons();
// Create and fill edit sizer
m_edit_sizer = new wxBoxSizer(wxHORIZONTAL);
m_edit_sizer->Add(m_use_for_transfer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);
m_edit_sizer->AddSpacer(em_unit() * 10);
m_edit_sizer->Add(m_buttons, 1, wxLEFT, 5);
m_edit_sizer->Show(false);
}
void DiffPresetDialog::complete_dialog_creation()
{
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
int border = 10;
topSizer->Add(m_top_info_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2 * border); topSizer->Add(m_top_info_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2 * border);
topSizer->Add(presets_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border); topSizer->Add(m_presets_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
topSizer->Add(m_show_all_presets, 0, wxEXPAND | wxALL, border); topSizer->Add(m_show_all_presets, 0, wxEXPAND | wxALL, border);
topSizer->Add(m_bottom_info_line, 0, wxEXPAND | wxALL, 2 * border);
topSizer->Add(m_tree, 1, wxEXPAND | wxALL, border); topSizer->Add(m_tree, 1, wxEXPAND | wxALL, border);
topSizer->Add(m_bottom_info_line, 0, wxEXPAND | wxALL, 2 * border);
topSizer->Add(m_edit_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 2 * border);
this->SetMinSize(wxSize(80 * em, 30 * em)); this->SetMinSize(wxSize(80 * em_unit(), 30 * em_unit()));
this->SetSizer(topSizer); this->SetSizer(topSizer);
topSizer->SetSizeHints(this); topSizer->SetSizeHints(this);
wxGetApp().UpdateDlgDarkUI(this); wxGetApp().UpdateDlgDarkUI(this);
} }
DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
: DPIDialog(mainframe, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
m_pr_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology())
{
#if defined(__WXMSW__)
// ys_FIXME! temporary workaround for correct font scaling
// Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
// From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
#endif // __WXMSW__
// Init bundles
assert(wxGetApp().preset_bundle);
m_preset_bundle_left = std::make_unique<PresetBundle>(*wxGetApp().preset_bundle);
m_preset_bundle_right = std::make_unique<PresetBundle>(*wxGetApp().preset_bundle);
// Create UI items
SetBackgroundColour(*wxWHITE);
create_info_lines();
create_presets_sizer();
create_show_all_presets_chb();
create_tree();
create_edit_sizer();
complete_dialog_creation();
}
void DiffPresetDialog::update_controls_visibility(Preset::Type type /* = Preset::TYPE_INVALID*/) void DiffPresetDialog::update_controls_visibility(Preset::Type type /* = Preset::TYPE_INVALID*/)
{ {
for (auto preset_combos : m_preset_combos) { for (auto preset_combos : m_preset_combos) {
@ -1951,6 +2096,8 @@ void DiffPresetDialog::update_bundles_from_app()
{ {
*m_preset_bundle_left = *wxGetApp().preset_bundle; *m_preset_bundle_left = *wxGetApp().preset_bundle;
*m_preset_bundle_right = *wxGetApp().preset_bundle; *m_preset_bundle_right = *wxGetApp().preset_bundle;
m_pr_technology = m_preset_bundle_left.get()->printers.get_edited_preset().printer_technology();
} }
void DiffPresetDialog::show(Preset::Type type /* = Preset::TYPE_INVALID*/) void DiffPresetDialog::show(Preset::Type type /* = Preset::TYPE_INVALID*/)
@ -1974,8 +2121,6 @@ void DiffPresetDialog::show(Preset::Type type /* = Preset::TYPE_INVALID*/)
void DiffPresetDialog::update_presets(Preset::Type type) void DiffPresetDialog::update_presets(Preset::Type type)
{ {
m_pr_technology = m_preset_bundle_left.get()->printers.get_edited_preset().printer_technology();
update_bundles_from_app(); update_bundles_from_app();
update_controls_visibility(type); update_controls_visibility(type);
@ -1999,6 +2144,14 @@ void DiffPresetDialog::update_presets(Preset::Type type)
update_tree(); update_tree();
} }
void DiffPresetDialog::update_bottom_info(wxString bottom_info)
{
const bool show_bottom_info = !m_tree->IsShown();
if (show_bottom_info)
m_bottom_info_line->SetLabel(bottom_info);
m_bottom_info_line->Show(show_bottom_info);
}
void DiffPresetDialog::update_tree() void DiffPresetDialog::update_tree()
{ {
Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher(); Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
@ -2091,9 +2244,12 @@ void DiffPresetDialog::update_tree()
bool tree_was_shown = m_tree->IsShown(); bool tree_was_shown = m_tree->IsShown();
m_tree->Show(show_tree); m_tree->Show(show_tree);
if (!show_tree)
m_bottom_info_line->SetLabel(bottom_info); bool can_transfer_options = m_view_type == Preset::TYPE_INVALID || get_left_preset_name(m_view_type) != get_right_preset_name(m_view_type);
m_bottom_info_line->Show(!show_tree); m_edit_sizer->Show(show_tree && can_transfer_options);
m_buttons->Show(m_edit_sizer->IsShown(size_t(0)) && m_use_for_transfer->GetValue());
update_bottom_info(bottom_info);
if (tree_was_shown == m_tree->IsShown()) if (tree_was_shown == m_tree->IsShown())
Layout(); Layout();
@ -2111,6 +2267,8 @@ void DiffPresetDialog::on_dpi_changed(const wxRect&)
int em = em_unit(); int em = em_unit();
msw_buttons_rescale(this, em, {wxID_CANCEL}); msw_buttons_rescale(this, em, {wxID_CANCEL});
for (auto btn : {m_transfer_btn, m_cancel_btn})
if (btn) btn->SetMinSize(UNSAVE_CHANGE_DIALOG_BUTTON_SIZE);
const wxSize& size = wxSize(80 * em, 30 * em); const wxSize& size = wxSize(80 * em, 30 * em);
SetMinSize(size); SetMinSize(size);
@ -2140,6 +2298,7 @@ void DiffPresetDialog::on_sys_color_changed()
preset_combos.equal_bmp->msw_rescale(); preset_combos.equal_bmp->msw_rescale();
preset_combos.presets_right->msw_rescale(); preset_combos.presets_right->msw_rescale();
} }
// msw_rescale updates just icons, so use it // msw_rescale updates just icons, so use it
m_tree->Rescale(); m_tree->Rescale();
Refresh(); Refresh();
@ -2203,6 +2362,25 @@ void DiffPresetDialog::update_compatibility(const std::string& preset_name, Pres
} }
} }
void DiffPresetDialog::button_event(Action act)
{
Hide();
if (act == Action::Transfer)
wxPostEvent(this, SimpleEvent(EVT_DIFF_DIALOG_TRANSFER));
}
std::string DiffPresetDialog::get_left_preset_name(Preset::Type type)
{
PresetComboBox* cb = m_preset_combos[int(type - Preset::TYPE_PRINT)].presets_left;
return Preset::remove_suffix_modified(get_selection(cb));
}
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));
}
} }
} // namespace Slic3r::GUI } // namespace Slic3r::GUI

View file

@ -1,3 +1,7 @@
///|/ Copyright (c) Prusa Research 2020 - 2023 Oleksandra Iushchenko @YuSanka, Lukáš Hejl @hejllukas, Vojtěch Bubník @bubnikv, David Kocík @kocikdav
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#ifndef slic3r_UnsavedChangesDialog_hpp_ #ifndef slic3r_UnsavedChangesDialog_hpp_
#define slic3r_UnsavedChangesDialog_hpp_ #define slic3r_UnsavedChangesDialog_hpp_
@ -17,6 +21,8 @@ class wxStaticText;
namespace Slic3r { namespace Slic3r {
namespace GUI{ namespace GUI{
wxDECLARE_EVENT(EVT_DIFF_DIALOG_TRANSFER, SimpleEvent);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ModelNode: a node inside DiffModel // ModelNode: a node inside DiffModel
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -101,7 +107,7 @@ public:
ModelNode* GetParent() { return m_parent; } ModelNode* GetParent() { return m_parent; }
ModelNodePtrArray& GetChildren() { return m_children; } ModelNodePtrArray& GetChildren() { return m_children; }
ModelNode* GetNthChild(unsigned int n) { return m_children[n].get(); } ModelNode* GetNthChild(unsigned int n) { return m_children[n].get(); }
unsigned int GetChildCount() const { return m_children.size(); } unsigned int GetChildCount() const { return (unsigned int)(m_children.size()); }
void Append(std::unique_ptr<ModelNode> child) { m_children.emplace_back(std::move(child)); } void Append(std::unique_ptr<ModelNode> child) { m_children.emplace_back(std::move(child)); }
@ -148,7 +154,7 @@ public:
}; };
DiffModel(wxWindow* parent); DiffModel(wxWindow* parent);
~DiffModel(){}; ~DiffModel() override = default;
void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; }
@ -228,6 +234,21 @@ public:
std::vector<std::string> selected_options(); std::vector<std::string> selected_options();
}; };
// Discard and Cancel buttons are always but next buttons are optional
enum ActionButtons {
TRANSFER = 1,
KEEP = 2,
SAVE = 4,
DONT_SAVE = 8,
REMEMBER_CHOISE = 0x10000
};
enum class Action {
Undef,
Transfer,
Discard,
Save
};
//------------------------------------------ //------------------------------------------
// UnsavedChangesDialog // UnsavedChangesDialog
@ -275,13 +296,6 @@ protected:
std::string m_app_config_key; std::string m_app_config_key;
enum class Action {
Undef,
Transfer, // Or KEEP
Save,
Discard,
};
static constexpr char ActTransfer[] = "transfer"; static constexpr char ActTransfer[] = "transfer";
static constexpr char ActDiscard[] = "discard"; static constexpr char ActDiscard[] = "discard";
static constexpr char ActSave[] = "save"; static constexpr char ActSave[] = "save";
@ -314,20 +328,12 @@ private:
std::string m_new_selected_preset_name; std::string m_new_selected_preset_name;
public: public:
// Discard and Cancel buttons are always but next buttons are optional
enum ActionButtons {
TRANSFER = 1,
KEEP = 2,
SAVE = 4,
DONT_SAVE = 8,
REMEMBER_CHOISE = 0x10000
};
// show unsaved changes when preset is switching // show unsaved changes when preset is switching
UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, bool no_transfer = false); UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, bool no_transfer = false);
// show unsaved changes for all another cases // show unsaved changes for all another cases
UnsavedChangesDialog(const wxString& caption, const wxString& header, const std::string& app_config_key, int act_buttons); UnsavedChangesDialog(const wxString& caption, const wxString& header, const std::string& app_config_key, int act_buttons);
~UnsavedChangesDialog(){}; ~UnsavedChangesDialog() override = default;
int ShowModal(); int ShowModal();
@ -394,7 +400,7 @@ class FullCompareDialog : public wxDialog
public: public:
FullCompareDialog(const wxString& option_name, const wxString& old_value, const wxString& new_value, FullCompareDialog(const wxString& option_name, const wxString& old_value, const wxString& new_value,
const wxString& old_value_header, const wxString& new_value_header); const wxString& old_value_header, const wxString& new_value_header);
~FullCompareDialog(){}; ~FullCompareDialog() override = default;
}; };
@ -404,20 +410,37 @@ public:
class DiffPresetDialog : public DPIDialog class DiffPresetDialog : public DPIDialog
{ {
DiffViewCtrl* m_tree { nullptr }; DiffViewCtrl* m_tree { nullptr };
wxBoxSizer* m_presets_sizer { nullptr };
wxStaticText* m_top_info_line { nullptr }; wxStaticText* m_top_info_line { nullptr };
wxStaticText* m_bottom_info_line { nullptr }; wxStaticText* m_bottom_info_line { nullptr };
wxCheckBox* m_show_all_presets { nullptr }; wxCheckBox* m_show_all_presets { nullptr };
wxCheckBox* m_use_for_transfer { nullptr };
Button* m_transfer_btn { nullptr };
Button* m_cancel_btn { nullptr };
wxBoxSizer* m_buttons { nullptr };
wxBoxSizer* m_edit_sizer { nullptr };
Preset::Type m_view_type { Preset::TYPE_INVALID }; Preset::Type m_view_type { Preset::TYPE_INVALID };
PrinterTechnology m_pr_technology; PrinterTechnology m_pr_technology;
std::unique_ptr<PresetBundle> m_preset_bundle_left; std::unique_ptr<PresetBundle> m_preset_bundle_left;
std::unique_ptr<PresetBundle> m_preset_bundle_right; std::unique_ptr<PresetBundle> m_preset_bundle_right;
void create_buttons();
void create_edit_sizer();
void complete_dialog_creation();
void create_presets_sizer();
void create_info_lines();
void create_tree();
void create_show_all_presets_chb();
void update_bottom_info(wxString bottom_info = "");
void update_tree(); void update_tree();
void update_bundles_from_app(); void update_bundles_from_app();
void update_controls_visibility(Preset::Type type = Preset::TYPE_INVALID); void update_controls_visibility(Preset::Type type = Preset::TYPE_INVALID);
void update_compatibility(const std::string& preset_name, Preset::Type type, PresetBundle* preset_bundle); void update_compatibility(const std::string& preset_name, Preset::Type type, PresetBundle* preset_bundle);
void button_event(Action act);
struct DiffPresets struct DiffPresets
{ {
PresetComboBox* presets_left { nullptr }; PresetComboBox* presets_left { nullptr };
@ -429,11 +452,21 @@ class DiffPresetDialog : public DPIDialog
public: public:
DiffPresetDialog(MainFrame*mainframe); DiffPresetDialog(MainFrame*mainframe);
~DiffPresetDialog(){}; ~DiffPresetDialog() override = default;
void show(Preset::Type type = Preset::TYPE_INVALID); void show(Preset::Type type = Preset::TYPE_INVALID);
void update_presets(Preset::Type type = Preset::TYPE_INVALID); void update_presets(Preset::Type type = Preset::TYPE_INVALID);
Preset::Type view_type() const { return m_view_type; }
PrinterTechnology printer_technology() const { return m_pr_technology; }
std::string get_left_preset_name(Preset::Type type);
std::string get_right_preset_name(Preset::Type type);
std::vector<std::string> get_selected_options(Preset::Type type) const { return std::move(m_tree->options(type, true)); }
std::array<Preset::Type, 3> types_list() const;
protected: protected:
void on_dpi_changed(const wxRect& suggested_rect) override; void on_dpi_changed(const wxRect& suggested_rect) override;
void on_sys_color_changed() override; void on_sys_color_changed() override;

View file

@ -771,7 +771,7 @@ bool GuideFrame::apply_config(AppConfig *app_config, PresetBundle *preset_bundle
check_unsaved_preset_changes = (enabled_vendors != old_enabled_vendors) || (enabled_filaments != old_enabled_filaments); check_unsaved_preset_changes = (enabled_vendors != old_enabled_vendors) || (enabled_filaments != old_enabled_filaments);
wxString header = _L("The configuration package is changed in previous Config Guide"); wxString header = _L("The configuration package is changed in previous Config Guide");
wxString caption = _L("Configuration package changed"); wxString caption = _L("Configuration package changed");
int act_btns = UnsavedChangesDialog::ActionButtons::KEEP|UnsavedChangesDialog::ActionButtons::SAVE; int act_btns = ActionButtons::KEEP|ActionButtons::SAVE;
if (check_unsaved_preset_changes && if (check_unsaved_preset_changes &&
!wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes)) !wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes))