From 0e1a0e856f4bbda2c000efd036a58ce6719fd185 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 7 Nov 2023 11:06:14 +0100 Subject: [PATCH] Fix for SPE-2020 : Notification about temporary installed preset doesn't appear anymore Description of bug: During fixing of SPE-1845 there was made changes with 7280b2a0 commit. But those changes destroyed a initial behavior. All presets are selected correctly now, but user doesn't receive a notification about temporary installed presets, if any was. --- src/libslic3r/Preset.cpp | 20 ++++++++------ src/libslic3r/Preset.hpp | 21 +++++++++++++-- src/libslic3r/PresetBundle.cpp | 24 ++++++++++++----- src/libslic3r/PresetBundle.hpp | 2 ++ src/slic3r/GUI/Jobs/SLAImportJob.cpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 40 +++------------------------- src/slic3r/GUI/Plater.hpp | 2 +- 8 files changed, 58 insertions(+), 55 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 03ed690325..5405f983d7 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -781,7 +781,7 @@ static bool profile_print_params_same(const DynamicPrintConfig &cfg_old, const D // and select it, losing previous modifications. // Only a single profile could be edited at at the same time, which introduces complexity when loading // filament profiles for multi-extruder printers. -std::pair PresetCollection::load_external_preset( +ExternalPreset PresetCollection::load_external_preset( // Path to the profile source file (a G-code, an AMF or 3MF file, a config file) const std::string &path, // Name of the profile, derived from the source file name. @@ -804,7 +804,7 @@ std::pair PresetCollection::load_external_preset( const Preset &edited = this->get_edited_preset(); if ((edited.name == original_name || edited.name == inherits) && profile_print_params_same(edited.config, cfg)) // Just point to that already selected and edited profile. - return std::make_pair(&(*this->find_preset_internal(edited.name)), false); + return ExternalPreset(&(*this->find_preset_internal(edited.name)), false); } // Is there a preset already loaded with the name stored inside the config? std::deque::iterator it = this->find_preset_internal(original_name); @@ -818,7 +818,7 @@ std::pair PresetCollection::load_external_preset( // The preset exists and is visible and it matches the values stored inside config. if (select == LoadAndSelect::Always) this->select_preset(it - m_presets.begin()); - return std::make_pair(&(*it), false); + return ExternalPreset(&(*it), false); } if (! found && select != LoadAndSelect::Never && ! inherits.empty()) { // Try to use a system profile as a base to select the system profile @@ -830,14 +830,18 @@ std::pair PresetCollection::load_external_preset( // The system preset exists and it matches the values stored inside config. if (select == LoadAndSelect::Always) this->select_preset(it - m_presets.begin()); - return std::make_pair(&(*it), false); + return ExternalPreset(&(*it), false); } } if (found) { if (select != LoadAndSelect::Never) { + const size_t idx = it - m_presets.begin(); + // The newly selected preset can be activated AND have to be make as visible. + bool is_installed = !m_presets[idx].is_visible; + // Select the existing preset and override it with new values, so that // the differences will be shown in the preset editor against the referenced profile. - this->select_preset(it - m_presets.begin()); + this->select_preset(idx); // update dirty state only if it's needed if (!profile_print_params_same(it->config, cfg)) { @@ -855,7 +859,7 @@ std::pair PresetCollection::load_external_preset( //update_saved_preset_from_current_preset(); assert(this->get_edited_preset().is_dirty); } - return std::make_pair(&(*it), this->get_edited_preset().is_dirty); + return ExternalPreset(&(*it), this->get_edited_preset().is_dirty, is_installed); } if (inherits.empty()) { // Update the "inherits" field. @@ -886,7 +890,7 @@ std::pair PresetCollection::load_external_preset( // The preset exists and it matches the values stored inside config. if (select == LoadAndSelect::Always) this->select_preset(it - m_presets.begin()); - return std::make_pair(&(*it), false); + return ExternalPreset(&(*it), false); } // Form another profile name. } @@ -896,7 +900,7 @@ std::pair PresetCollection::load_external_preset( if (this->m_idx_selected != size_t(-1) && &this->get_selected_preset() == &preset) this->get_edited_preset().is_external = true; - return std::make_pair(&preset, false); + return ExternalPreset(&preset, false); } Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select) diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 850ec0e821..d87b2ade9d 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -280,6 +280,21 @@ struct PresetConfigSubstitutions { ConfigSubstitutions substitutions; }; +// This struct is used to get an information about loaded external preset +struct ExternalPreset +{ + Preset* preset { nullptr }; + bool is_modified { false }; + bool is_installed { false }; + + ExternalPreset(Preset* preset, bool modified, bool installed = false) + : preset(preset) + , is_modified(modified) + , is_installed(installed) {} + + virtual ~ExternalPreset() = default; +}; + // Substitutions having been performed during parsing a set of configuration files, for example when starting up // PrusaSlicer and reading the user Print / Filament / Printer profiles. using PresetsConfigSubstitutions = std::vector; @@ -320,7 +335,9 @@ public: Preset& load_preset(const std::string &path, const std::string &name, const DynamicPrintConfig &config, bool select = true); Preset& load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select = true); - // Returns a loaded preset, returns true if an existing preset was selected AND modified from config. + // Returns a loaded preset, + // returns is_modified as true if an existing preset was selected AND modified from config, + // returns is_installed as true if a preset was selected AND set as visible during selection. // In that case the successive filament loaded for a multi material printer should not be modified, but // an external preset should be created instead. enum class LoadAndSelect { @@ -331,7 +348,7 @@ public: // Select a profile only if it was modified. OnlyIfModified, }; - std::pair load_external_preset( + ExternalPreset load_external_preset( // Path to the profile source file (a G-code, an AMF or 3MF file, a config file) const std::string &path, // Name of the profile, derived from the source file name. diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 684558fff4..64be1f78ed 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -958,6 +958,8 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool { PrinterTechnology printer_technology = Preset::printer_technology(config); + tmp_installed_presets.clear(); + // The "compatible_printers" field should not have been exported into a config.ini or a G-code anyway, // but some of the alpha versions of Slic3r did. { @@ -1006,19 +1008,23 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool // 2) If the loading succeeded, split and load the config into print / filament / printer settings. // First load the print and printer presets. + std::set& tmp_installed_presets_ref = tmp_installed_presets; auto load_preset = [&config, &inherits, &inherits_values, &compatible_printers_condition, &compatible_printers_condition_values, &compatible_prints_condition, &compatible_prints_condition_values, - is_external, &name, &name_or_path] + is_external, &name, &name_or_path, &tmp_installed_presets_ref] (PresetCollection &presets, size_t idx, const std::string &key) { // Split the "compatible_printers_condition" and "inherits" values one by one from a single vector to the print & printer profiles. inherits = inherits_values[idx]; compatible_printers_condition = compatible_printers_condition_values[idx]; if (idx > 0 && idx - 1 < compatible_prints_condition_values.size()) compatible_prints_condition = compatible_prints_condition_values[idx - 1]; - if (is_external) - presets.load_external_preset(name_or_path, name, config.opt_string(key, true), config); + if (is_external) { + ExternalPreset ext_preset = presets.load_external_preset(name_or_path, name, config.opt_string(key, true), config); + if (ext_preset.is_installed) + tmp_installed_presets_ref.emplace(ext_preset.preset->name); + } else presets.load_preset(presets.path_from_name(name), name, config).save(); }; @@ -1040,8 +1046,12 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool compatible_printers_condition = compatible_printers_condition_values[1]; compatible_prints_condition = compatible_prints_condition_values.front(); Preset *loaded = nullptr; - if (is_external) - loaded = this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config).first; + if (is_external) { + ExternalPreset ext_preset = this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config); + loaded = ext_preset.preset; + if (ext_preset.is_installed) + tmp_installed_presets.emplace(ext_preset.preset->name); + } else { // called from Config Wizard. loaded= &this->filaments.load_preset(this->filaments.path_from_name(name), name, config); @@ -1075,13 +1085,15 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool cfg.opt_string("compatible_prints_condition", true) = compatible_prints_condition_values[i]; cfg.opt_string("inherits", true) = inherits_values[i + 1]; // Load all filament presets, but only select the first one in the preset dialog. - auto [loaded, modified] = this->filaments.load_external_preset(name_or_path, name, + auto [loaded, modified, installed] = this->filaments.load_external_preset(name_or_path, name, (i < int(old_filament_profile_names->values.size())) ? old_filament_profile_names->values[i] : "", std::move(cfg), any_modified ? PresetCollection::LoadAndSelect::Never : PresetCollection::LoadAndSelect::OnlyIfModified); any_modified |= modified; extr_names[i] = loaded->name; + if (installed) + tmp_installed_presets.emplace(loaded->name); } // Check if some preset was selected after loading from config file. diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 9c39ad36d2..1e6aa1caa1 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -83,6 +83,8 @@ public: }; ObsoletePresets obsolete_presets; + std::set tmp_installed_presets; + bool has_defauls_only() const { return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); } diff --git a/src/slic3r/GUI/Jobs/SLAImportJob.cpp b/src/slic3r/GUI/Jobs/SLAImportJob.cpp index e3a1ab0170..77c9714b94 100644 --- a/src/slic3r/GUI/Jobs/SLAImportJob.cpp +++ b/src/slic3r/GUI/Jobs/SLAImportJob.cpp @@ -161,7 +161,7 @@ void SLAImportJob::finalize(bool canceled, std::exception_ptr &eptr) if (Preset::printer_technology(config) == ptSLA) { wxGetApp().preset_bundle->load_config_model(name, std::move(config)); - p->plater->check_selected_presets_visibility(ptSLA); + p->plater->notify_about_installed_presets();; wxGetApp().load_current_presets(); } else { p->plater->get_notification_manager()->push_notification( diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index cc780b4b24..ede699645a 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1807,7 +1807,7 @@ bool MainFrame::load_config_file(const std::string &path) return false; } - m_plater->check_selected_presets_visibility(ptFFF); + m_plater->notify_about_installed_presets(); wxGetApp().load_current_presets(); return true; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 602b74d5b5..c2b8e8694f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2487,46 +2487,14 @@ bool Plater::priv::get_config_bool(const std::string &key) const return wxGetApp().app_config->get_bool(key); } -// After loading of the presets from project, check if they are visible. -// Set them to visible if they are not. -void Plater::check_selected_presets_visibility(PrinterTechnology loaded_printer_technology) +void Plater::notify_about_installed_presets() { - auto update_selected_preset_visibility = [](PresetCollection& presets, std::vector& names) { - if (!presets.get_selected_preset().is_visible) { - assert(presets.get_selected_preset().name == presets.get_edited_preset().name); - presets.get_selected_preset().is_visible = true; - presets.get_edited_preset().is_visible = true; - names.emplace_back(presets.get_selected_preset().name); - } - }; - - std::vector names; - PresetBundle* preset_bundle = wxGetApp().preset_bundle; - if (loaded_printer_technology == ptFFF) { - update_selected_preset_visibility(preset_bundle->prints, names); - for (const auto& extruder_filaments : preset_bundle->extruders_filaments) { - Preset* preset = preset_bundle->filaments.find_preset(extruder_filaments.get_selected_preset_name()); - if (preset && !preset->is_visible) { - preset->is_visible = true; - names.emplace_back(preset->name); - if (preset->name == preset_bundle->filaments.get_edited_preset().name) - preset_bundle->filaments.get_selected_preset().is_visible = true; - } - } - } - else { - update_selected_preset_visibility(preset_bundle->sla_prints, names); - update_selected_preset_visibility(preset_bundle->sla_materials, names); - } - update_selected_preset_visibility(preset_bundle->printers, names); - - preset_bundle->update_compatible(PresetSelectCompatibleType::Never); - + const auto& names = wxGetApp().preset_bundle->tmp_installed_presets; // show notification about temporarily installed presets if (!names.empty()) { std::string notif_text = into_u8(_L_PLURAL("The preset below was temporarily installed on the active instance of PrusaSlicer", "The presets below were temporarily installed on the active instance of PrusaSlicer", names.size())) + ":"; - for (std::string& name : names) + for (const std::string& name : names) notif_text += "\n - " + name; get_notification_manager()->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::PrintInfoNotificationLevel, notif_text); @@ -2672,7 +2640,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ Preset::normalize(config); PresetBundle* preset_bundle = wxGetApp().preset_bundle; preset_bundle->load_config_model(filename.string(), std::move(config)); - q->check_selected_presets_visibility(loaded_printer_technology); + q->notify_about_installed_presets(); if (loaded_printer_technology == ptFFF) CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &preset_bundle->project_config); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 46d21cef69..be4ebdfe0a 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -197,7 +197,7 @@ public: std::vector load_files(const std::vector& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false); // to be called on drag and drop bool load_files(const wxArrayString& filenames, bool delete_after_load = false); - void check_selected_presets_visibility(PrinterTechnology loaded_printer_technology); + void notify_about_installed_presets(); bool preview_zip_archive(const boost::filesystem::path& input_file);