diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a16222c86b..898890f6e5 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2866,7 +2866,7 @@ void Tab::load_current_preset() } on_presets_changed(); if (printer_technology == ptFFF) { - static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; + static_cast(this)->m_initial_extruders_count = static_cast(m_presets->get_selected_preset().config.option("nozzle_diameter"))->values.size(); //static_cast(this)->m_extruders_count; const Preset* parent_preset = m_presets->get_selected_preset_parent(); static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); @@ -3131,6 +3131,10 @@ void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, m_dependent_tabs = { Preset::Type::TYPE_SLA_PRINT, Preset::Type::TYPE_SLA_MATERIAL }; } + // check and apply extruders count for printer preset + if (m_type == Preset::TYPE_PRINTER) + static_cast(this)->apply_extruder_cnt_from_cache(); + // check if there is something in the cache to move to the new selected preset if (!m_cache_config.empty()) { m_presets->get_edited_preset().config.apply(m_cache_config); @@ -3184,8 +3188,18 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr } else if (dlg.move_preset()) // move selected changes { + std::vector selected_options = dlg.get_selected_options(); + 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 + if (m_type == Preset::TYPE_PRINTER) + static_cast(this)->cache_extruder_cnt(); + } + // copy selected options to the cache from edited preset - m_cache_config.apply_only(*m_config, dlg.get_selected_options()); + m_cache_config.apply_only(*m_config, selected_options); } return true; @@ -3593,6 +3607,25 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent) return sizer; } +void TabPrinter::cache_extruder_cnt() +{ + if (m_presets->get_edited_preset().printer_technology() == ptSLA) + return; + + m_cache_extruder_count = m_extruders_count; +} + +void TabPrinter::apply_extruder_cnt_from_cache() +{ + if (m_presets->get_edited_preset().printer_technology() == ptSLA) + return; + + if (m_cache_extruder_count > 0) { + m_presets->get_edited_preset().set_num_extruders(m_cache_extruder_count); + m_cache_extruder_count = 0; + } +} + void Tab::compatible_widget_reload(PresetDependencies &deps) { bool has_any = ! m_config->option(deps.key_list)->values.empty(); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index a97153f470..9bddebeab1 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -411,6 +411,7 @@ public: size_t m_extruders_count_old = 0; size_t m_initial_extruders_count; size_t m_sys_extruders_count; + size_t m_cache_extruder_count = 0; PrinterTechnology m_printer_technology = ptFFF; @@ -437,6 +438,8 @@ public: bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; } wxSizer* create_bed_shape_widget(wxWindow* parent); + void cache_extruder_cnt(); + void apply_extruder_cnt_from_cache(); }; class TabSLAMaterial : public Tab diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 2fa89266e2..bebc01c782 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -712,47 +712,71 @@ wxString get_string_from_enum(const std::string& opt_key, const DynamicPrintConf return from_u8(_utf8(names[static_cast(val)])); } -static wxString get_string_value(const std::string& opt_key, const DynamicPrintConfig& config) +static int get_id_from_opt_key(std::string opt_key) { + int pos = opt_key.find("#"); + if (pos > 0) { + boost::erase_head(opt_key, pos + 1); + return atoi(opt_key.c_str()); + } + return 0; +} + +static std::string get_pure_opt_key(std::string opt_key) +{ + int pos = opt_key.find("#"); + if (pos > 0) + boost::erase_tail(opt_key, opt_key.size() - pos); + return opt_key; +} + +static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& config) +{ + int opt_idx = get_id_from_opt_key(opt_key); + opt_key = get_pure_opt_key(opt_key); + + if (config.option(opt_key)->is_nil()) + return _L("N/A"); + wxString out; // FIXME controll, if opt_key has index - int opt_idx = 0; - ConfigOptionType type = config.def()->options.at(opt_key).type; + const ConfigOptionDef* opt = config.def()->get(opt_key); + bool is_nullable = opt->nullable; - switch (type) { + switch (opt->type) { case coInt: return from_u8((boost::format("%1%") % config.opt_int(opt_key)).str()); case coInts: { - const ConfigOptionInts* opt = config.opt(opt_key); - if (opt) - return from_u8((boost::format("%1%") % opt->get_at(opt_idx)).str()); - break; + int val = is_nullable ? + config.opt(opt_key)->get_at(opt_idx) : + config.opt(opt_key)->get_at(opt_idx); + return from_u8((boost::format("%1%") % val).str()); } case coBool: return config.opt_bool(opt_key) ? "true" : "false"; case coBools: { - const ConfigOptionBools* opt = config.opt(opt_key); - if (opt) - return opt->get_at(opt_idx) ? "true" : "false"; - break; + bool val = is_nullable ? + config.opt(opt_key)->get_at(opt_idx) : + config.opt(opt_key)->get_at(opt_idx); + return val ? "true" : "false"; } case coPercent: return from_u8((boost::format("%1%%%") % int(config.optptr(opt_key)->getFloat())).str()); case coPercents: { - const ConfigOptionPercents* opt = config.opt(opt_key); - if (opt) - return from_u8((boost::format("%1%%%") % int(opt->get_at(opt_idx))).str()); - break; + double val = is_nullable ? + config.opt(opt_key)->get_at(opt_idx) : + config.opt(opt_key)->get_at(opt_idx); + return from_u8((boost::format("%1%%%") % int(val)).str()); } case coFloat: return double_to_string(config.opt_float(opt_key)); case coFloats: { - const ConfigOptionFloats* opt = config.opt(opt_key); - if (opt) - return double_to_string(opt->get_at(opt_idx)); - break; + double val = is_nullable ? + config.opt(opt_key)->get_at(opt_idx) : + config.opt(opt_key)->get_at(opt_idx); + return double_to_string(val); } case coString: return from_u8(config.opt_string(opt_key)); @@ -896,7 +920,23 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres m_tree_model->AddPreset(type, from_u8(presets->get_edited_preset().name)); // Collect dirty options. - for (const std::string& opt_key : presets->current_dirty_options()) { + const bool deep_compare = (type == Preset::TYPE_PRINTER || type == Preset::TYPE_SLA_MATERIAL); + auto dirty_options = presets->current_dirty_options(deep_compare); + auto dirty_options_ = presets->current_dirty_options(); + + // process changes of extruders count + if (type == Preset::TYPE_PRINTER && + old_config.opt("extruder_colour")->values.size() != new_config.opt("extruder_colour")->values.size()) { + wxString local_label = _L("Extruders count"); + wxString old_val = from_u8((boost::format("%1%") % old_config.opt("extruder_colour")->values.size()).str()); + wxString new_val = from_u8((boost::format("%1%") % new_config.opt("extruder_colour")->values.size()).str()); + + ItemData item_data = { "extruders_count", local_label, old_val, new_val, type }; + m_items_map.emplace(m_tree_model->AddOption(type, _L("General"), _L("Capabilities"), local_label, old_val, new_val), item_data); + + } + + for (const std::string& opt_key : /*presets->current_dirty_options()*/dirty_options) { const Search::Option& option = searcher.get_option(opt_key); ItemData item_data = { opt_key, option.label_local, get_string_value(opt_key, old_config), get_string_value(opt_key, new_config), type }; @@ -915,9 +955,12 @@ std::vector UnsavedChangesDialog::get_unselected_options(Preset::Ty { std::vector ret; - for (auto item : m_items_map) + for (auto item : m_items_map) { + if (item.second.opt_key == "extruders_count") + continue; if (item.second.type == type && !m_tree_model->IsEnabledItem(item.first)) - ret.emplace_back(item.second.opt_key); + ret.emplace_back(get_pure_opt_key(item.second.opt_key)); + } return ret; } @@ -926,9 +969,9 @@ std::vector UnsavedChangesDialog::get_selected_options() { std::vector ret; - for (auto item : m_items_map) + for (auto item : m_items_map) if (m_tree_model->IsEnabledItem(item.first)) - ret.emplace_back(item.second.opt_key); + ret.emplace_back(get_pure_opt_key(item.second.opt_key)); return ret; }