ENH: update save preset logic

1.Automatically transfer setting by default
2.Fix some translation

jira:NONE

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I72fe2a34bd22eb06435925617e2951bf1591d2c1
This commit is contained in:
xun.zhang 2025-01-16 10:04:15 +08:00 committed by lane.wei
parent ce54aa8a84
commit a1091f9a37
10 changed files with 227 additions and 122 deletions

View File

@ -297,6 +297,10 @@ void AppConfig::set_defaults()
set("units", "0");
}
if (get("auto_transfer_when_switch_preset").empty()) {
set("auto_transfer_when_switch_preset", "true");
}
if (get("sync_user_preset").empty()) {
set_bool("sync_user_preset", false);
}

View File

@ -126,12 +126,13 @@ float RetinaHelper::get_scale_factor() { return float(m_window->GetContentScaleF
#endif
std::string& get_object_limited_text() {
static std::string object_limited_text = _u8L("An object is laid on the left/right nozzle only area.\n"
std::string get_object_limited_text() {
std::string object_limited_text = _u8L("An object is laid on the left/right nozzle only area.\n"
"Please make sure the filaments used by this object on this area are not mapped to the other nozzles.");
return object_limited_text;
}
// serve as a text container, not the real text
std::string& get_object_clashed_text() {
static std::string object_clashed_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");
@ -9997,7 +9998,7 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
SLICING_LIMIT_ERROR,
SLICING_HEIGHT_OUTSIDE
};
const static std::vector<std::string> extruder_name_list= {_u8L("left nozzle"), _u8L("right nozzle")}; // in ui, we treat extruder as nozzle
const std::vector<std::string> extruder_name_list= {_u8L("left nozzle"), _u8L("right nozzle")}; // in ui, we treat extruder as nozzle
std::string text;
ErrorType error = ErrorType::PLATER_WARNING;
const ModelObject* conflictObj=nullptr;

View File

@ -6221,7 +6221,7 @@ std::vector<std::pair<unsigned int, std::string>> GUI_App::get_selected_presets(
// This is called when:
// - Exporting config_bundle
// - Taking snapshot
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*/, ForceOption force_op/* = Discard*/)
{
if (has_current_preset_changes()) {
int act_buttons = UnsavedChangesDialog::ActionButtons::SAVE;
@ -6230,11 +6230,8 @@ bool GUI_App::check_and_save_current_preset_changes(const wxString& caption, con
if (remember_choice)
act_buttons |= UnsavedChangesDialog::ActionButtons::REMEMBER_CHOISE;
UnsavedChangesDialog dlg(caption, header, "", act_buttons);
if (dlg.ShowModal() == wxID_CANCEL)
return false;
if (dlg.save_preset()) // save selected changes
{
auto handle_save_action = [this,&dlg](){
//BBS: add project embedded preset relate logic
for (const UnsavedChangesDialog::PresetData& nt : dlg.get_names_and_types())
preset_bundle->save_changes_for_preset(nt.name, nt.type, dlg.get_unselected_options(nt.type), nt.save_to_project);
@ -6249,6 +6246,21 @@ bool GUI_App::check_and_save_current_preset_changes(const wxString& caption, con
//MessageDialog(nullptr, _L_PLURAL("Modifications to the preset have been saved",
// "Modifications to the presets have been saved", dlg.get_names_and_types().size())).ShowModal();
};
if (force_op == ForceOption::fopDiscard)
return true;
if (force_op == ForceOption::fopSave) {
handle_save_action();
return true;
}
if (dlg.ShowModal() == wxID_CANCEL)
return false;
if (dlg.save_preset()) // save selected changes
{
handle_save_action();
}
}
@ -6272,14 +6284,12 @@ void GUI_App::apply_keeped_preset_modifications()
// => Current project isn't saved => UnsavedChangesDialog: "Keep / Discard / Save / Cancel"
// Close ConfigWizard => Current project is saved => UnsavedChangesDialog: "Keep / Discard / Save / Cancel"
// Note: no_nullptr postponed_apply_of_keeped_changes indicates that thie function is called after ConfigWizard is closed
bool GUI_App::check_and_keep_current_preset_changes(const wxString& caption, const wxString& header, int action_buttons, bool* postponed_apply_of_keeped_changes/* = nullptr*/)
bool GUI_App::check_and_keep_current_preset_changes(const wxString& caption, const wxString& header, int action_buttons, bool* postponed_apply_of_keeped_changes/* = nullptr*/, ForceOption force_op)
{
if (has_current_preset_changes()) {
bool is_called_from_configwizard = postponed_apply_of_keeped_changes != nullptr;
UnsavedChangesDialog dlg(caption, header, "", action_buttons);
if (dlg.ShowModal() == wxID_CANCEL)
return false;
auto reset_modifications = [this, is_called_from_configwizard]() {
//if (is_called_from_configwizard)
@ -6291,59 +6301,89 @@ bool GUI_App::check_and_keep_current_preset_changes(const wxString& caption, con
tab->m_presets->discard_current_changes();
}
load_current_presets(false);
};
};
auto handle_discard_option = [ this, reset_modifications](){
reset_modifications();
};
auto handle_save_option = [this,&dlg, reset_modifications]() {
const auto& preset_names_and_types = dlg.get_names_and_types();
for (const UnsavedChangesDialog::PresetData& nt : preset_names_and_types)
preset_bundle->save_changes_for_preset(nt.name, nt.type, dlg.get_unselected_options(nt.type), nt.save_to_project);
// if we saved changes to the new presets, we should to
// synchronize config.ini with the current selections.
preset_bundle->export_selections(*app_config);
//wxString text = _L_PLURAL("Modifications to the preset have been saved",
// "Modifications to the presets have been saved", preset_names_and_types.size());
//if (!is_called_from_configwizard)
// text += "\n\n" + _L("All modifications will be discarded for new project.");
//MessageDialog(nullptr, text).ShowModal();
reset_modifications();
};
auto handle_transfer_option = [this, &dlg, is_called_from_configwizard, postponed_apply_of_keeped_changes, reset_modifications]() {
const auto& preset_names_and_types = dlg.get_names_and_types();
// execute this part of code only if not all modifications are keeping to the new project
// OR this function is called when ConfigWizard is closed and "Keep modifications" is selected
for (const UnsavedChangesDialog::PresetData& nt : preset_names_and_types) {
Preset::Type type = nt.type;
Tab* tab = get_tab(type);
std::vector<std::string> selected_options = dlg.get_selected_options(type);
if (type == Preset::TYPE_PRINTER) {
auto it = std::find(selected_options.begin(), selected_options.end(), "extruders_count");
if (it != selected_options.end()) {
// erase "extruders_count" option from the list
selected_options.erase(it);
// cache the extruders count
static_cast<TabPrinter*>(tab)->cache_extruder_cnt();
}
}
std::vector<std::string> selected_options2;
std::transform(selected_options.begin(), selected_options.end(), std::back_inserter(selected_options2), [](auto& o) {
auto i = o.find('#');
return i != std::string::npos ? o.substr(0, i) : o;
});
tab->cache_config_diff(selected_options2);
if (!is_called_from_configwizard)
tab->m_presets->discard_current_changes();
}
if (is_called_from_configwizard)
*postponed_apply_of_keeped_changes = true;
else
apply_keeped_preset_modifications();
};
if (force_op == ForceOption::fopDiscard) {
handle_discard_option();
return true;
}
if (force_op == ForceOption::fopTransfer) {
handle_transfer_option();
return true;
}
if (force_op == ForceOption::fopSave) {
handle_save_option();
return true;
}
if (dlg.ShowModal() == wxID_CANCEL)
return false;
if (dlg.discard())
reset_modifications();
handle_discard_option();
else // save selected changes
{
//BBS: add project embedded preset relate logic
const auto& preset_names_and_types = dlg.get_names_and_types();
if (dlg.save_preset()) {
for (const UnsavedChangesDialog::PresetData& nt : preset_names_and_types)
preset_bundle->save_changes_for_preset(nt.name, nt.type, dlg.get_unselected_options(nt.type), nt.save_to_project);
// if we saved changes to the new presets, we should to
// synchronize config.ini with the current selections.
preset_bundle->export_selections(*app_config);
//wxString text = _L_PLURAL("Modifications to the preset have been saved",
// "Modifications to the presets have been saved", preset_names_and_types.size());
//if (!is_called_from_configwizard)
// text += "\n\n" + _L("All modifications will be discarded for new project.");
//MessageDialog(nullptr, text).ShowModal();
reset_modifications();
handle_save_option();
}
else if (dlg.transfer_changes() && (dlg.has_unselected_options() || is_called_from_configwizard)) {
// execute this part of code only if not all modifications are keeping to the new project
// OR this function is called when ConfigWizard is closed and "Keep modifications" is selected
for (const UnsavedChangesDialog::PresetData& nt : preset_names_and_types) {
Preset::Type type = nt.type;
Tab* tab = get_tab(type);
std::vector<std::string> selected_options = dlg.get_selected_options(type);
if (type == Preset::TYPE_PRINTER) {
auto it = std::find(selected_options.begin(), selected_options.end(), "extruders_count");
if (it != selected_options.end()) {
// erase "extruders_count" option from the list
selected_options.erase(it);
// cache the extruders count
static_cast<TabPrinter*>(tab)->cache_extruder_cnt();
}
}
std::vector<std::string> selected_options2;
std::transform(selected_options.begin(), selected_options.end(), std::back_inserter(selected_options2), [](auto & o) {
auto i = o.find('#');
return i != std::string::npos ? o.substr(0, i) : o;
});
tab->cache_config_diff(selected_options2);
if (!is_called_from_configwizard)
tab->m_presets->discard_current_changes();
}
if (is_called_from_configwizard)
*postponed_apply_of_keeped_changes = true;
else
apply_keeped_preset_modifications();
handle_transfer_option();
}
}
}

View File

@ -18,6 +18,7 @@
#include "slic3r/GUI/HMS.hpp"
#include "slic3r/GUI/Jobs/UpgradeNetworkJob.hpp"
#include "slic3r/GUI/HttpServer.hpp"
#include "slic3r/GUI/UnsavedChangesDialog.hpp"
#include "../Utils/PrintHost.hpp"
#include "slic3r/GUI/GLEnums.hpp"
@ -52,7 +53,6 @@ class wxBookCtrlBase;
class Notebook;
struct wxLanguageInfo;
namespace Slic3r {
class AppConfig;
@ -518,9 +518,9 @@ public:
bool has_current_preset_changes() const;
void update_saved_preset_from_current_preset();
std::vector<std::pair<unsigned int, std::string>> get_selected_presets() const;
bool check_and_save_current_preset_changes(const wxString& caption, const wxString& header, bool remember_choice = true, bool use_dont_save_insted_of_discard = false);
bool check_and_save_current_preset_changes(const wxString& caption, const wxString& header, bool remember_choice = true, bool use_dont_save_insted_of_discard = false, ForceOption force_op = ForceOption::fopDiscard);
void apply_keeped_preset_modifications();
bool check_and_keep_current_preset_changes(const wxString& caption, const wxString& header, int action_buttons, bool* postponed_apply_of_keeped_changes = nullptr);
bool check_and_keep_current_preset_changes(const wxString& caption, const wxString& header, int action_buttons, bool* postponed_apply_of_keeped_changes = nullptr, ForceOption force_op = ForceOption::fopDiscard);
bool can_load_project();
bool check_print_host_queue();
bool checked_tab(Tab* tab);

View File

@ -2665,7 +2665,9 @@ bool Sidebar::is_new_project_in_gcode3mf()
confirm_dlg.update_text(filename + " " + _L("will be closed before modify filament. Do you want to continue?"));
confirm_dlg.on_show();
if (!is_cancle) {
if (is_cancle) {
this->printer_combox()->update();
} else {
p->plater->new_project();
}
return is_cancle;
@ -5485,51 +5487,6 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}
}
if (load_config) {
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (dev) {
MachineObject *obj = dev->get_selected_machine();
if (obj && obj->is_info_ready()) {
if (obj->m_extder_data.extders.size() > 0) {
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
Preset &printer_preset = preset_bundle->printers.get_selected_preset();
double preset_nozzle_diameter = 0.4;
const ConfigOption *opt = printer_preset.config.option("nozzle_diameter");
if (opt) preset_nozzle_diameter = static_cast<const ConfigOptionFloatsNullable *>(opt)->values[0];
float machine_nozzle_diameter = obj->m_extder_data.extders[0].current_nozzle_diameter;
std::string machine_type = obj->printer_type;
if (obj->is_support_upgrade_kit && obj->installed_upgrade_kit) machine_type = "C12";
if (printer_preset.get_current_printer_type(preset_bundle) != machine_type || !is_approx((float) preset_nozzle_diameter, machine_nozzle_diameter)) {
Preset *machine_preset = get_printer_preset(obj);
if (machine_preset != nullptr) {
std::string printer_model = machine_preset->config.option<ConfigOptionString>("printer_model")->value;
bool sync_printer_info = false;
if (!wxGetApp().app_config->has("sync_after_load_file_show_flag")) {
wxString tips = from_u8((boost::format(_u8L("Connected printer is %s. It must match the project preset for printing.\n")) % printer_model).str());
tips += _L("Do you want to sync the printer information and automatically switch the preset?");
TipsDialog dlg(wxGetApp().mainframe, _L("Tips"), tips, "sync_after_load_file_show_flag", wxYES_NO);
if (dlg.ShowModal() == wxID_YES) { sync_printer_info = true; }
}
else {
sync_printer_info = wxGetApp().app_config->get("sync_after_load_file_show_flag") == "true";
}
if (sync_printer_info) {
update_objects_position_when_select_preset([&obj, machine_preset]() {
Tab *printer_tab = GUI::wxGetApp().get_tab(Preset::Type::TYPE_PRINTER);
printer_tab->select_preset(machine_preset->name);
if (obj->is_multi_extruders()) GUI::wxGetApp().sidebar().sync_extruder_list();
});
}
}
}
}
}
}
}
if (new_model) delete new_model;
@ -10492,6 +10449,70 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString &project_
bool Plater::try_sync_preset_with_connected_printer()
{
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev)
return false;
MachineObject* obj = dev->get_selected_machine();
if (!obj || !obj->is_info_ready() || obj->m_extder_data.extders.size() <= 0)
return false;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
Preset& printer_preset = preset_bundle->printers.get_selected_preset();
double preset_nozzle_diameter = 0.4;
if (auto opt = printer_preset.config.option("nozzle_diameter"); opt) {
preset_nozzle_diameter = static_cast<const ConfigOptionFloatsNullable*>(opt)->values[0];
}
float machine_nozzle_diameter = obj->m_extder_data.extders[0].current_nozzle_diameter;
std::string printer_type = obj->printer_type;
// handle p1p with upgraded kit
if (obj->is_support_upgrade_kit && obj->installed_upgrade_kit)
printer_type = "C12";
// same printer and same nozzle diameter, return false
if (printer_preset.get_current_printer_type(preset_bundle) == printer_type && is_approx((float)(preset_nozzle_diameter), machine_nozzle_diameter))
return false;
// can not find the preset for connected printer, return false
Preset* machine_preset = get_printer_preset(obj);
if (!machine_preset)
return false;
std::string printer_model = machine_preset->config.option<ConfigOptionString>("printer_model")->value;
bool sync_printer_info = false;
bool is_multi_extruder = machine_preset->config.option<ConfigOptionFloatsNullable>("nozzle_diameter")->values.size() > 1;
if (!wxGetApp().app_config->has("sync_after_load_file_show_flag")) {
wxString tips;
if (is_multi_extruder) {
tips=from_u8((boost::format(_u8L("The currently connected printer, %s, is a %s model.\nTo use this printer for printing, please switch the printer model of the project file to %s,\nand sync the nozzle type and AMS quantity information from the connected printer.")) %obj->dev_name% printer_model%printer_model).str());
}
else {
tips = from_u8((boost::format(_u8L("The currently connected printer, %s, is a %s model.\nTo use this printer for printing, please switch the printer model of project file to %s.")) % obj->dev_name % printer_model % printer_model).str());
}
TipsDialog dlg(wxGetApp().mainframe, _L("Tips"), tips, "sync_after_load_file_show_flag", wxYES_NO);
if (dlg.ShowModal() == wxID_YES) { sync_printer_info = true; }
}
else {
sync_printer_info = wxGetApp().app_config->get("sync_after_load_file_show_flag") == "true";
}
if (!sync_printer_info)
return false;
update_objects_position_when_select_preset([&obj, machine_preset]() {
Tab* printer_tab = GUI::wxGetApp().get_tab(Preset::Type::TYPE_PRINTER);
printer_tab->select_preset(machine_preset->name);
if (obj->is_multi_extruders()) GUI::wxGetApp().sidebar().sync_extruder_list();
});
return true;
}
// BBS: FIXME, missing resotre logic
int Plater::load_project(wxString const &filename2,
wxString const& originfile)
@ -10611,6 +10632,11 @@ int Plater::load_project(wxString const &filename2,
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " load project done";
m_loading_project = false;
// only pop up in 3mf
if (!this->m_exported_file && !this->m_only_gcode){
try_sync_preset_with_connected_printer();
}
return wx_dlg_id;
}
@ -15489,7 +15515,7 @@ int Plater::select_sliced_plate(int plate_index)
return ret;
}
extern std::string& get_object_limited_text();
extern std::string get_object_limited_text();
extern std::string& get_object_clashed_text();
void Plater::validate_current_plate(bool& model_fits, bool& validate_error)

View File

@ -239,6 +239,8 @@ public:
void render_project_state_debug_window() const;
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
bool try_sync_preset_with_connected_printer();
Sidebar& sidebar();
const Model& model() const;
Model& model();

View File

@ -1158,7 +1158,8 @@ wxWindow* PreferencesDialog::create_general_page()
#endif
50, "single_instance");
auto item_bed_type_follow_preset = create_item_checkbox(_L("Auto plate type"), page,
auto item_auto_transfer_when_switch_preset = create_item_checkbox(_L("Automatically transfer modified value when switching process and filament presets"), page,_L("Default behavior for handling modified values when switching process and filament presets. After closing, a popup will appear to ask each time"), 50, "auto_transfer_when_switch_preset");
auto item_bed_type_follow_preset = create_item_checkbox(_L("Auto plate type"), page,
_L("Studio will remember build plate selected last time for certain printer model."), 50,
"user_bed_type");
//auto item_hints = create_item_checkbox(_L("Show \"Tip of the day\" notification after start"), page, _L("If enabled, useful hints are displayed at startup."), 50, "show_hints");
@ -1271,6 +1272,7 @@ wxWindow* PreferencesDialog::create_general_page()
sizer_page->Add(item_multi_machine, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_step_mesh_setting, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_beta_version_update, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_auto_transfer_when_switch_preset, 0, wxTOP, FromDIP(3));
sizer_page->Add(_3d_settings, 0, wxTOP | wxEXPAND, FromDIP(20));
sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_show_shells_in_preview_settings, 0, wxTOP, FromDIP(3));

View File

@ -33,7 +33,6 @@
#include "Plater.hpp"
#include "MainFrame.hpp"
#include "format.hpp"
#include "UnsavedChangesDialog.hpp"
#include "SavePresetDialog.hpp"
#include "MsgDialog.hpp"
#include "Notebook.hpp"
@ -4745,6 +4744,9 @@ void Tab::update_preset_choice()
bool Tab::select_preset(
std::string preset_name, bool delete_current /*=false*/, const std::string &last_selected_ph_printer_name /* =""*/, bool force_select, bool force_no_transfer)
{
auto app_config = wxGetApp().app_config;
bool auto_transfer = app_config->get("auto_transfer_when_switch_preset") == "true";
ForceOption option = auto_transfer ? ForceOption::fopTransfer : ForceOption::fopNone;
BOOST_LOG_TRIVIAL(info) << boost::format("select preset, name %1%, delete_current %2%")
%preset_name %delete_current;
if (preset_name.empty()) {
@ -4809,7 +4811,11 @@ bool Tab::select_preset(
if (force_no_transfer) {
no_transfer = true;
}
if (current_dirty && ! may_discard_current_dirty_preset(nullptr, preset_name, no_transfer) && !force_select) {
ForceOption option_for_dirty_preset = ForceOption::fopNone;
if (current_dirty && print_tab) {
option_for_dirty_preset = option;
}
if (current_dirty && ! may_discard_current_dirty_preset(nullptr, preset_name, no_transfer,false,option_for_dirty_preset) && !force_select) {
canceled = true;
BOOST_LOG_TRIVIAL(info) << boost::format("current dirty and cancelled");
} else if (print_tab) {
@ -4824,7 +4830,7 @@ bool Tab::select_preset(
bool new_preset_compatible = is_compatible_with_print(dependent.get_edited_preset_with_vendor_profile(),
m_presets->get_preset_with_vendor_profile(*m_presets->find_preset(preset_name, true)), printer_profile);
if (! canceled)
canceled = old_preset_dirty && ! new_preset_compatible && ! may_discard_current_dirty_preset(&dependent, preset_name) && !force_select;
canceled = old_preset_dirty && ! new_preset_compatible && ! may_discard_current_dirty_preset(&dependent, preset_name,false,false,option) && !force_select;
if (! canceled) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
m_dependent_tabs.emplace_back((printer_technology == ptFFF) ? Preset::Type::TYPE_FILAMENT : Preset::Type::TYPE_SLA_MATERIAL);
@ -4869,7 +4875,7 @@ bool Tab::select_preset(
pu.old_preset_dirty = (old_printer_technology == pu.technology) && pu.presets->current_is_dirty();
pu.new_preset_compatible = (new_printer_technology == pu.technology) && is_compatible_with_printer(pu.presets->get_edited_preset_with_vendor_profile(), new_printer_preset_with_vendor_profile);
if (!canceled)
canceled = pu.old_preset_dirty && !pu.new_preset_compatible && !may_discard_current_dirty_preset(pu.presets, preset_name, false, no_transfer_variant) && !force_select;
canceled = pu.old_preset_dirty && !pu.new_preset_compatible && !may_discard_current_dirty_preset(pu.presets, preset_name, false, no_transfer_variant,option) && !force_select;
}
if (!canceled) {
for (PresetUpdate &pu : updates) {
@ -5042,16 +5048,13 @@ bool Tab::select_preset(
// If the current preset is dirty, the user is asked whether the changes may be discarded.
// if the current preset was not dirty, or the user agreed to discard the changes, 1 is returned.
bool Tab::may_discard_current_dirty_preset(PresetCollection *presets /*= nullptr*/, const std::string &new_printer_name /*= ""*/, bool no_transfer, bool no_transfer_variant)
bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr*/, const std::string& new_printer_name /*= ""*/, bool no_transfer, bool no_transfer_variant, ForceOption force_op)
{
if (presets == nullptr) presets = m_presets;
UnsavedChangesDialog dlg(m_type, presets, new_printer_name, no_transfer);
if (dlg.ShowModal() == wxID_CANCEL)
return false;
if (dlg.save_preset()) // save selected changes
{
auto handle_save_action = [&dlg, this, presets]() {
const std::vector<std::string>& unselected_options = dlg.get_unselected_options(presets->type());
const std::string& name = dlg.get_preset_name();
//BBS: add project embedded preset relate logic
@ -5077,14 +5080,14 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection *presets /*= nullptr
if (presets->type() == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1)
wxGetApp().plater()->force_filament_colors_update();
}
}
else if (dlg.transfer_changes()) // move selected changes
{
};
auto handle_transfer_action = [&dlg, this, presets, no_transfer, no_transfer_variant]() {
std::vector<std::string> selected_options = dlg.get_selected_options();
if (!no_transfer && no_transfer_variant) {
auto & options_list = wxGetApp().get_tab(presets->type())->m_options_list;
auto& options_list = wxGetApp().get_tab(presets->type())->m_options_list;
bool has_variants = false;
for (auto &opt : selected_options) {
for (auto& opt : selected_options) {
if (auto n = opt.find('#'); n != std::string::npos) {
auto iter = options_list.lower_bound(opt.substr(0, n));
if (iter == options_list.end() || opt.compare(0, n, iter->first)) {
@ -5117,6 +5120,26 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection *presets /*= nullptr
}
else
wxGetApp().get_tab(presets->type())->cache_config_diff(selected_options);
};
if (force_op == ForceOption::fopSave) {
handle_save_action();
return true;
}
if (force_op == ForceOption::fopTransfer) {
handle_transfer_action();
return true;
}
if (dlg.ShowModal() == wxID_CANCEL)
return false;
if (dlg.save_preset()) {
handle_save_action();
}
else if (dlg.transfer_changes()) {
handle_transfer_action();
}
return true;

View File

@ -40,6 +40,7 @@
#include "ParamsPanel.hpp"
#include "Widgets/RoundedRectangle.hpp"
#include "Widgets/TextInput.hpp"
#include "UnsavedChangesDialog.hpp"
class TabCtrl;
class ComboBox;
@ -334,7 +335,7 @@ public:
void update_preset_choice();
// Select a new preset, possibly delete the current one.
bool select_preset(std::string preset_name = "", bool delete_current = false, const std::string &last_selected_ph_printer_name = "", bool force_select = false, bool force_no_transfer = false);
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = "", bool no_transfer = false, bool no_transfer_variant = false);
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = "", bool no_transfer = false, bool no_transfer_variant = false, ForceOption force_op = ForceOption::fopNone);
virtual void clear_pages();
virtual void update_description_lines();

View File

@ -245,6 +245,12 @@ struct PresetItem
wxString new_value;
};
enum ForceOption {
fopTransfer,
fopSave,
fopDiscard,
fopNone
};
class UnsavedChangesDialog : public DPIDialog
{