diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index 177d8d708..f3a1d5988 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -139,6 +139,9 @@ void AppConfig::set_defaults()
         if (get("default_action_on_select_preset").empty())
             set("default_action_on_select_preset", "none");     // , "transfer", "discard" or "save" 
 
+        if (get("default_action_on_new_project").empty())
+            set("default_action_on_new_project", "none");       // , "keep(transfer)", "discard" or "save" 
+
         if (get("color_mapinulation_panel").empty())
             set("color_mapinulation_panel", "0");
 
diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp
index 3f388f485..ee6e3d5ab 100644
--- a/src/slic3r/GUI/ConfigWizard.cpp
+++ b/src/slic3r/GUI/ConfigWizard.cpp
@@ -41,6 +41,7 @@
 #include "format.hpp"
 #include "MsgDialog.hpp"
 #include "libslic3r/libslic3r.h"
+#include "UnsavedChangesDialog.hpp"
 
 #if defined(__linux__) && defined(__WXGTK3__)
 #define wxLinux_gtk3 true
@@ -741,10 +742,10 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
     const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
     const auto text_clr = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
     const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
-    wxString first_line = _L("Filaments marked with <b>*</b> are <b>not</b> compatible with some installed printers.");
+    wxString first_line = format_wxstr(_L("%1% marked with <b>*</b> are <b>not</b> compatible with some installed printers."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials"));
     wxString text;
     if (all_printers) {
-        wxString second_line = _L("All installed printers are compatible with the selected filament.");
+        wxString second_line = format_wxstr(_L("All installed printers are compatible with the selected %1%."), materials->technology == T_FFF ? _L("filament") : _L("SLA material"));
         text = wxString::Format(
             "<html>"
             "<style>"
@@ -764,7 +765,7 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
             , second_line
             );
     } else {
-        wxString second_line = _L("Only the following installed printers are compatible with the selected filament:");
+        wxString second_line = printer_names.empty() ? "" : format_wxstr(_L("Only the following installed printers are compatible with the selected %1%:"), materials->technology == T_FFF ? _L("filament") : _L("SLA material"));
         text = wxString::Format(
             "<html>"
             "<style>"
@@ -2473,8 +2474,16 @@ static std::string get_first_added_preset(const std::map<std::string, std::strin
     return *diff.begin();
 }
 
-bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater)
+bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater, bool& apply_keeped_changes)
 {
+    wxString header, caption = _L("Configuration is editing from ConfigWizard");
+    bool check_unsaved_preset_changes = page_welcome->reset_user_profile();
+    if (check_unsaved_preset_changes)
+        header = _L("All user presets will be deleted.");
+    int act_btns = UnsavedChangesDialog::ActionButtons::KEEP;
+    if (!check_unsaved_preset_changes)
+        act_btns |= UnsavedChangesDialog::ActionButtons::SAVE;
+
     const auto enabled_vendors = appconfig_new.vendors();
 
     // Install bundles from resources if needed:
@@ -2500,6 +2509,9 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
             install_bundles.emplace_back(pair.first);
         }
     }
+    if (!check_unsaved_preset_changes)
+        if ((check_unsaved_preset_changes = install_bundles.size() > 0))
+            header = _L_PLURAL("New vendor was installed and one of its printer will be activated", "New vendors were installed and one of theirs printer will be activated", install_bundles.size());
 
 #ifdef __linux__
     // Desktop integration on Linux
@@ -2531,6 +2543,10 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
     if (snapshot && ! take_config_snapshot_cancel_on_error(*app_config, snapshot_reason, "", _u8L("Continue with applying configuration changes?")))
         return false;
 
+    if (check_unsaved_preset_changes &&
+        !wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes))
+        return false;
+
     if (install_bundles.size() > 0) {
         // Install bundles from resources.
         // Don't create snapshot - we've already done that above if applicable.
@@ -2586,17 +2602,52 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
         }
     }
 
+    // if unsaved changes was not cheched till this moment
+    if (!check_unsaved_preset_changes) {
+        if ((check_unsaved_preset_changes = !preferred_model.empty())) {
+            header = _L("A new Printer was installed and it will be activated.");
+            if (!wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes))
+                return false;
+        }
+        else if ((check_unsaved_preset_changes = enabled_vendors_old != enabled_vendors)) {
+            header = _L("Some Printers were uninstalled.");
+            if (!wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes))
+                return false;
+        }
+    }
+
     std::string first_added_filament, first_added_sla_material;
-    auto apply_section = [this, app_config](const std::string& section_name, std::string& first_added_preset) {
+    auto get_first_added_material_preset = [this, app_config](const std::string& section_name, std::string& first_added_preset) {
         if (appconfig_new.has_section(section_name)) {
             // get first of new added preset names
             const std::map<std::string, std::string>& old_presets = app_config->has_section(section_name) ? app_config->get_section(section_name) : std::map<std::string, std::string>();
             first_added_preset = get_first_added_preset(old_presets, appconfig_new.get_section(section_name));
-            app_config->set_section(section_name, appconfig_new.get_section(section_name));
         }
     };
-    apply_section(AppConfig::SECTION_FILAMENTS, first_added_filament);
-    apply_section(AppConfig::SECTION_MATERIALS, first_added_sla_material);
+    get_first_added_material_preset(AppConfig::SECTION_FILAMENTS, first_added_filament);
+    get_first_added_material_preset(AppConfig::SECTION_MATERIALS, first_added_sla_material);
+
+    // if unsaved changes was not cheched till this moment
+    if (!check_unsaved_preset_changes) {
+        if ((check_unsaved_preset_changes = !first_added_filament.empty() || !first_added_sla_material.empty())) {
+            header = format_wxstr(_L("A new %1% was installed and it will be activated."), !first_added_filament.empty() ? _L("Filament") : _L("SLA material"));
+            if (!wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes))
+                return false;
+        }
+        else {
+            bool is_filaments_changed = app_config->get_section(AppConfig::SECTION_FILAMENTS) != appconfig_new.get_section(AppConfig::SECTION_FILAMENTS);
+            bool is_sla_materials_changed = app_config->get_section(AppConfig::SECTION_MATERIALS) != appconfig_new.get_section(AppConfig::SECTION_MATERIALS);
+            if ((check_unsaved_preset_changes = is_filaments_changed || is_sla_materials_changed)) {
+                header = format_wxstr(_L("Some %1% were uninstalled."), is_filaments_changed ? _L("Filaments") : _L("SLA materials"));
+                if (!wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes))
+                    return false;
+            }
+        }
+    }
+
+    // apply materials in app_config
+    for (const std::string& section_name : {AppConfig::SECTION_FILAMENTS, AppConfig::SECTION_MATERIALS})
+        app_config->set_section(section_name, appconfig_new.get_section(section_name));
 
     app_config->set_vendors(appconfig_new);
 
@@ -2624,10 +2675,16 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
 
     page_mode->serialize_mode(app_config);
 
-    preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem, 
-                                {preferred_model, preferred_variant, first_added_filament, first_added_sla_material});
+    if (check_unsaved_preset_changes)
+        preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem, 
+                                    {preferred_model, preferred_variant, first_added_filament, first_added_sla_material});
 
     if (page_custom->custom_wanted()) {
+        // if unsaved changes was not cheched till this moment
+        if (!check_unsaved_preset_changes && 
+            !wxGetApp().check_and_keep_current_preset_changes(caption, _L("Custom printer was installed and it will be activated."), act_btns, &apply_keeped_changes))
+            return false;
+
         page_firmware->apply_custom_config(*custom_config);
         page_bed->apply_custom_config(*custom_config);
         page_diams->apply_custom_config(*custom_config);
@@ -2851,8 +2908,13 @@ bool ConfigWizard::run(RunReason reason, StartPage start_page)
     p->set_start_page(start_page);
 
     if (ShowModal() == wxID_OK) {
-        if (! p->apply_config(app.app_config, app.preset_bundle, app.preset_updater))
+        bool apply_keeped_changes = false;
+        if (! p->apply_config(app.app_config, app.preset_bundle, app.preset_updater, apply_keeped_changes))
             return false;
+
+        if (apply_keeped_changes)
+            app.apply_keeped_preset_modifications();
+
         app.app_config->set_legacy_datadir(false);
         app.update_mode();
         app.obj_manipul()->update_ui_from_settings();
diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp
index 84def4202..d4b1fac04 100644
--- a/src/slic3r/GUI/ConfigWizard_private.hpp
+++ b/src/slic3r/GUI/ConfigWizard_private.hpp
@@ -611,7 +611,7 @@ struct ConfigWizard::priv
 
     bool on_bnt_finish();
     bool check_and_install_missing_materials(Technology technology, const std::string &only_for_model_id = std::string());
-    bool apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater);
+    bool apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater, bool& apply_keeped_changes);
     // #ys_FIXME_alise
     void update_presets_in_config(const std::string& section, const std::string& alias_key, bool add);
 #ifdef __linux__
diff --git a/src/slic3r/GUI/ExtraRenderers.cpp b/src/slic3r/GUI/ExtraRenderers.cpp
index 5fe86db27..533b59398 100644
--- a/src/slic3r/GUI/ExtraRenderers.cpp
+++ b/src/slic3r/GUI/ExtraRenderers.cpp
@@ -323,15 +323,19 @@ wxWindow* BitmapChoiceRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelR
 
     c_editor->SetSelection(atoi(data.GetText().c_str()));
 
-    // to avoid event propagation to other sidebar items
-    c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
-            evt.StopPropagation();
+    
 #ifdef __linux__
-            // FinishEditing grabs new selection and triggers config update. We better call
-            // it explicitly, automatic update on KILL_FOCUS didn't work on Linux.
-            this->FinishEditing();
-#endif
+    c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
+        // to avoid event propagation to other sidebar items
+        evt.StopPropagation();
+        // FinishEditing grabs new selection and triggers config update. We better call
+        // it explicitly, automatic update on KILL_FOCUS didn't work on Linux.
+        this->FinishEditing();
     });
+#else
+    // to avoid event propagation to other sidebar items
+    c_editor->Bind(wxEVT_COMBOBOX, [](wxCommandEvent& evt) { evt.StopPropagation(); });
+#endif
 
     return c_editor;
 }
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 8689f43cd..9c08159fc 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -694,7 +694,6 @@ GUI_App::GUI_App(EAppMode mode)
     , m_app_mode(mode)
     , m_em_unit(10)
     , m_imgui(new ImGuiWrapper())
-    , m_wizard(nullptr)
 	, m_removable_drive_manager(std::make_unique<RemovableDriveManager>())
 	, m_other_instance_message_handler(std::make_unique<OtherInstanceMessageHandler>())
 {
@@ -1333,8 +1332,6 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
 
     dlg.Update(30, _L("Recreating") + dots);
     old_main_frame->Destroy();
-    // For this moment ConfigWizard is deleted, invalidate it.
-    m_wizard = nullptr;
 
     dlg.Update(80, _L("Loading of current presets") + dots);
     m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
@@ -1409,8 +1406,6 @@ void GUI_App::update_ui_from_settings()
         m_force_colors_update = false;
         mainframe->force_color_changed();
         mainframe->diff_dialog.force_color_changed();
-        if (m_wizard)
-            m_wizard->force_color_changed();
     }
 #endif
     mainframe->update_ui_from_settings();
@@ -1871,8 +1866,9 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
 #endif
         case ConfigMenuTakeSnapshot:
             // Take a configuration snapshot.
-            if (check_and_save_current_preset_changes()) {
-                wxTextEntryDialog dlg(nullptr, _L("Taking configuration snapshot"), _L("Snapshot name"));
+            if (wxString action_name = _L("Taking a configuration snapshot");
+                check_and_save_current_preset_changes(action_name, _L("Some presets are modified and the unsaved changes will not be captured by the configuration snapshot."), false, true)) {
+                wxTextEntryDialog dlg(nullptr, action_name, _L("Snapshot name"));
                 UpdateDlgDarkUI(&dlg);
                 
                 // set current normal font for dialog children, 
@@ -1888,7 +1884,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
             }
             break;
         case ConfigMenuSnapshots:
-            if (check_and_save_current_preset_changes()) {
+            if (check_and_save_current_preset_changes(_L("Loading a configuration snapshot"), "", false)) {
                 std::string on_snapshot;
                 if (Config::SnapshotDB::singleton().is_on_snapshot(*app_config))
                     on_snapshot = app_config->get("on_snapshot");
@@ -1910,9 +1906,6 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
 
                         // Load the currently selected preset into the GUI, update the preset selection box.
                         load_current_presets();
-
-                        // update config wizard in respect to the new config
-                        update_wizard_from_config();
                     } catch (std::exception &ex) {
                         GUI::show_error(nullptr, _L("Failed to activate configuration snapshot.") + "\n" + into_u8(ex.what()));
                     }
@@ -2081,13 +2074,28 @@ std::vector<std::pair<unsigned int, std::string>> GUI_App::get_selected_presets(
     return ret;
 }
 
-// This is called when closing the application, when loading a config file or when starting the config wizard
-// to notify the user whether he is aware that some preset changes will be lost.
-bool GUI_App::check_and_save_current_preset_changes(const wxString& header, const wxString& caption)
+// To notify the user whether he is aware that some preset changes will be lost,
+// UnsavedChangesDialog: "Discard / Save / Cancel"
+// This is called when:
+// - Close Application & Current project isn't saved
+// - Load Project      & Current project isn't saved
+// - Undo / Redo with change of print technologie
+// - Loading snapshot
+// - Loading config_file/bundle
+// UnsavedChangesDialog: "Don't save / Save / Cancel"
+// 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*/)
 {
-    if (/*this->plater()->model().objects.empty() && */has_current_preset_changes()) {
-        UnsavedChangesDialog dlg(header, caption);
-        if (wxGetApp().app_config->get("default_action_on_close_application") == "none" && dlg.ShowModal() == wxID_CANCEL)
+    if (has_current_preset_changes()) {
+        const std::string app_config_key = remember_choice ? "default_action_on_close_application" : "";
+        int act_buttons = UnsavedChangesDialog::ActionButtons::SAVE;
+        if (dont_save_insted_of_discard)
+            act_buttons |= UnsavedChangesDialog::ActionButtons::DONT_SAVE;
+        UnsavedChangesDialog dlg(caption, header, app_config_key, act_buttons);
+        std::string act = app_config_key.empty() ? "none" : wxGetApp().app_config->get(app_config_key);
+        if (act == "none" && dlg.ShowModal() == wxID_CANCEL)
             return false;
 
         if (dlg.save_preset())  // save selected changes
@@ -2095,18 +2103,122 @@ bool GUI_App::check_and_save_current_preset_changes(const wxString& header, cons
             for (const std::pair<std::string, Preset::Type>& nt : dlg.get_names_and_types())
                 preset_bundle->save_changes_for_preset(nt.first, nt.second, dlg.get_unselected_options(nt.second));
 
+            load_current_presets(false);
+
             // if we saved changes to the new presets, we should to 
             // synchronize config.ini with the current selections.
             preset_bundle->export_selections(*app_config);
 
-            wxMessageBox(_L_PLURAL("The preset modifications are successfully saved", 
-                                   "The presets modifications are successfully saved", dlg.get_names_and_types().size()));
+            MessageDialog(nullptr, _L_PLURAL("The preset modifications are successfully saved", 
+                                             "The presets modifications are successfully saved", dlg.get_names_and_types().size())).ShowModal();
         }
     }
 
     return true;
 }
 
+void GUI_App::apply_keeped_preset_modifications()
+{
+    PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
+    for (Tab* tab : tabs_list) {
+        if (tab->supports_printer_technology(printer_technology))
+            tab->apply_config_from_cache();
+    }
+    load_current_presets(false);
+}
+
+// This is called when creating new project or load another project
+// OR close ConfigWizard
+// to ask the user what should we do with unsaved changes for presets.
+// New Project          => Current project is saved    => UnsavedChangesDialog: "Keep / Discard / Cancel"
+//                      => 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*/)
+{
+    if (has_current_preset_changes()) {
+        bool is_called_from_configwizard = postponed_apply_of_keeped_changes != nullptr;
+
+        const std::string app_config_key = is_called_from_configwizard ? "" : "default_action_on_new_project";
+        UnsavedChangesDialog dlg(caption, header, app_config_key, action_buttons);
+        std::string act = app_config_key.empty() ? "none" : wxGetApp().app_config->get(app_config_key);
+        if (act == "none" && dlg.ShowModal() == wxID_CANCEL)
+            return false;
+
+        auto reset_modifications = [this, is_called_from_configwizard]() {
+            if (is_called_from_configwizard)
+                return; // no need to discared changes. It will be done fromConfigWizard closing
+
+            PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
+            for (const Tab* const tab : tabs_list) {
+                if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty())
+                    tab->m_presets->discard_current_changes();
+            }
+            load_current_presets(false);
+        };
+
+        if (dlg.discard())
+            reset_modifications();
+        else  // save selected changes
+        {
+            const auto& preset_names_and_types = dlg.get_names_and_types();
+            if (dlg.save_preset()) {
+                for (const std::pair<std::string, Preset::Type>& nt : preset_names_and_types)
+                    preset_bundle->save_changes_for_preset(nt.first, nt.second, dlg.get_unselected_options(nt.second));
+
+                // 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("The preset modifications are successfully saved",
+                    "The presets modifications are successfully saved", preset_names_and_types.size());
+                if (!is_called_from_configwizard)
+                    text += "\n\n" + _L("For new project all modifications will be reseted");
+
+                MessageDialog(nullptr, text).ShowModal();
+                reset_modifications();
+            }
+            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 std::pair<std::string, Preset::Type>& nt : preset_names_and_types) {
+                    Preset::Type type = nt.second;
+                    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();
+                        }
+                    }
+                    tab->cache_config_diff(selected_options);
+                    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();
+            }
+        }
+    }
+
+    return true;
+}
+
+bool GUI_App::can_load_project()
+{
+    int saved_project = plater()->save_project_if_dirty(_L("Loading a new project while the current project is modified."));
+    if (saved_project == wxID_CANCEL ||
+        (plater()->is_project_dirty() && saved_project == wxID_NO && 
+         !check_and_save_current_preset_changes(_L("Project is loading"), _L("Loading a new project while some presets are modified."))))
+        return false;
+    return true;
+}
+
 bool GUI_App::check_print_host_queue()
 {
     wxString dirty;
@@ -2164,17 +2276,6 @@ void GUI_App::load_current_presets(bool check_printer_presets_ /*= true*/)
 		}
 }
 
-void GUI_App::update_wizard_from_config()
-{
-    if (!m_wizard)
-        return;
-    // If ConfigWizard was created before changing of the configuration,
-    // we have to destroy it to have possibility to create it again in respect to the new config's parameters
-    m_wizard->Reparent(nullptr);
-    m_wizard->Destroy();
-    m_wizard = nullptr;
-}
-
 bool GUI_App::OnExceptionInMainLoop()
 {
     generic_exception_handle();
@@ -2336,19 +2437,12 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage
     wxCHECK_MSG(mainframe != nullptr, false, "Internal error: Main frame not created / null");
 
     if (reason == ConfigWizard::RR_USER) {
-        wxString header = _L("Updates to Configuration Wizard may cause an another preset selection and lost of preset modification as a result.\n"
-                             "So, check unsaved changes and save them if necessary.") + "\n";
-        if (!check_and_save_current_preset_changes(header, _L("ConfigWizard is opening")) ||
-            preset_updater->config_update(app_config->orig_version(), PresetUpdater::UpdateParams::FORCED_BEFORE_WIZARD) == PresetUpdater::R_ALL_CANCELED)
+        if (preset_updater->config_update(app_config->orig_version(), PresetUpdater::UpdateParams::FORCED_BEFORE_WIZARD) == PresetUpdater::R_ALL_CANCELED)
             return false;
     }
 
-    if (! m_wizard) {
-        wxBusyCursor wait;
-        m_wizard = new ConfigWizard(mainframe);
-    }
-
-    const bool res = m_wizard->run(reason, start_page);
+    auto wizard = new ConfigWizard(mainframe);
+    const bool res = wizard->run(reason, start_page);
 
     if (res) {
         load_current_presets();
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 3171f3b03..60a143144 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -150,7 +150,6 @@ private:
 
     std::unique_ptr<ImGuiWrapper> m_imgui;
     std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
-    ConfigWizard* m_wizard;    // Managed by wxWindow tree
 	std::unique_ptr <OtherInstanceMessageHandler> m_other_instance_message_handler;
     std::unique_ptr <wxSingleInstanceChecker> m_single_instance_checker;
     std::string m_instance_hash_string;
@@ -246,11 +245,13 @@ 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& header = wxString(), const wxString& caption = wxString());
+    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);
+    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            can_load_project();
     bool            check_print_host_queue();
     bool            checked_tab(Tab* tab);
     void            load_current_presets(bool check_printer_presets = true);
-    void            update_wizard_from_config();
 
     wxString        current_language_code() const { return m_wxLocale->GetCanonicalName(); }
 	// Translate the language code to a code, for which Prusa Research maintains translations. Defaults to "en_US".
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 7c019337e..44f04ef5f 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -4071,7 +4071,7 @@ void ObjectList::fix_through_netfabb()
             msg += ": " + from_u8(model_name) + "\n";
         else {
             msg += ":\n";
-            for (size_t i = 0; i < model_names.size(); ++i)
+            for (int i = 0; i < int(model_names.size()); ++i)
                 msg += (i == model_idx ? " > " : "   ") + from_u8(model_names[i]) + "\n";
             msg += "\n";
         }
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 89b6a6bea..027e9ce97 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -222,13 +222,14 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
         }
 
         if (m_plater != nullptr) {
-            int saved_project = m_plater->save_project_if_dirty();
+            int saved_project = m_plater->save_project_if_dirty(_L("Closing PrusaSlicer. Current project is modified."));
             if (saved_project == wxID_CANCEL) {
                 event.Veto();
                 return;
             }
             // check unsaved changes only if project wasn't saved
-            else if (saved_project == wxID_NO && event.CanVeto() && !wxGetApp().check_and_save_current_preset_changes()) {
+            else if (saved_project == wxID_NO && event.CanVeto() && 
+                     !wxGetApp().check_and_save_current_preset_changes(_L("PrusaSlicer is closing"), _L("Closing PrusaSlicer while some presets are modified."))) {
                 event.Veto();
                 return;
             }
@@ -820,7 +821,10 @@ bool MainFrame::is_active_and_shown_tab(Tab* tab)
 
 bool MainFrame::can_start_new_project() const
 {
-    return (m_plater != nullptr) && (!m_plater->get_project_filename(".3mf").IsEmpty() || GetTitle().StartsWith('*') || !m_plater->model().objects.empty());
+    return m_plater && (!m_plater->get_project_filename(".3mf").IsEmpty() || 
+                        GetTitle().StartsWith('*')||
+                        wxGetApp().has_current_preset_changes() || 
+                        !m_plater->model().objects.empty() );
 }
 
 bool MainFrame::can_save() const
@@ -852,13 +856,14 @@ void MainFrame::save_project()
     save_project_as(m_plater->get_project_filename(".3mf"));
 }
 
-void MainFrame::save_project_as(const wxString& filename)
+bool MainFrame::save_project_as(const wxString& filename)
 {
     bool ret = (m_plater != nullptr) ? m_plater->export_3mf(into_path(filename)) : false;
     if (ret) {
 //        wxGetApp().update_saved_preset_from_current_preset();
         m_plater->reset_project_dirty_after_save();
     }
+    return ret;
 }
 
 bool MainFrame::can_export_model() const
@@ -1151,8 +1156,10 @@ void MainFrame::init_menubar_as_editor()
         Bind(wxEVT_MENU, [this](wxCommandEvent& evt) {
             size_t file_id = evt.GetId() - wxID_FILE1;
             wxString filename = m_recent_projects.GetHistoryFile(file_id);
-            if (wxFileExists(filename))
-                m_plater->load_project(filename);
+            if (wxFileExists(filename)) {
+                if (wxGetApp().can_load_project())
+                    m_plater->load_project(filename);
+            }
             else
             {
                 //wxMessageDialog msg(this, _L("The selected project is no longer available.\nDo you want to remove it from the recent projects list?"), _L("Error"), wxYES_NO | wxYES_DEFAULT);
@@ -1772,7 +1779,7 @@ void MainFrame::export_config()
 // Load a config file containing a Print, Filament & Printer preset.
 void MainFrame::load_config_file()
 {
-    if (!wxGetApp().check_and_save_current_preset_changes())
+    if (!wxGetApp().check_and_save_current_preset_changes(_L("Loading of a configuration file"), "", false))
         return;
     wxFileDialog dlg(this, _L("Select configuration to load:"),
         !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
@@ -1803,7 +1810,8 @@ bool MainFrame::load_config_file(const std::string &path)
 
 void MainFrame::export_configbundle(bool export_physical_printers /*= false*/)
 {
-    if (!wxGetApp().check_and_save_current_preset_changes())
+    if (!wxGetApp().check_and_save_current_preset_changes(_L("Exporting configuration bundle"),
+                                                          _L("Some presets are modified and the unsaved changes will not be exported into configuration bundle."), false, true))
         return;
     // validate current configuration in case it's dirty
     auto err = wxGetApp().preset_bundle->full_config().validate();
@@ -1835,7 +1843,7 @@ void MainFrame::export_configbundle(bool export_physical_printers /*= false*/)
 // but that behavior was not documented and likely buggy.
 void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool reset_user_profile*/)
 {
-    if (!wxGetApp().check_and_save_current_preset_changes())
+    if (!wxGetApp().check_and_save_current_preset_changes(_L("Loading of a configuration bundle"), "", false))
         return;
     if (file.IsEmpty()) {
         wxFileDialog dlg(this, _L("Select configuration to load:"),
diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp
index 487d002af..1b66a6052 100644
--- a/src/slic3r/GUI/MainFrame.hpp
+++ b/src/slic3r/GUI/MainFrame.hpp
@@ -190,7 +190,7 @@ public:
     bool can_save() const;
     bool can_save_as() const;
     void save_project();
-    void save_project_as(const wxString& filename = wxString());
+    bool save_project_as(const wxString& filename = wxString());
 
     void        add_to_recent_projects(const wxString& filename);
     void        technology_changed();
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 8ec91662f..f4b7e758a 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1575,16 +1575,22 @@ struct Plater::priv
 
     bool is_project_dirty() const { return dirty_state.is_dirty(); }
     void update_project_dirty_from_presets() { dirty_state.update_from_presets(); }
-    int save_project_if_dirty() {
+    int save_project_if_dirty(const wxString& reason) {
         int res = wxID_NO;
         if (dirty_state.is_dirty()) {
             MainFrame* mainframe = wxGetApp().mainframe;
             if (mainframe->can_save_as()) {
-                //wxMessageDialog dlg(mainframe, _L("Do you want to save the changes to the current project ?"), wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL);
-                MessageDialog dlg(mainframe, _L("Do you want to save the changes to the current project ?"), wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL);
-                res = dlg.ShowModal();
+                wxString suggested_project_name;
+                wxString project_name = suggested_project_name = get_project_filename(".3mf");
+                if (suggested_project_name.IsEmpty()) {
+                    fs::path output_file = get_export_file_path(FT_3MF);
+                    suggested_project_name = output_file.empty() ? _L("Untitled") : from_u8(output_file.stem().string());
+                }
+                res = MessageDialog(mainframe, reason + "\n" + format_wxstr(_L("Do you want to save the changes to \"%1%\"?"), suggested_project_name), 
+                                    wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL).ShowModal();
                 if (res == wxID_YES)
-                    mainframe->save_project_as(wxGetApp().plater()->get_project_filename());
+                    if (!mainframe->save_project_as(project_name))
+                        res = wxID_CANCEL;
             }
         }
         return res;
@@ -1644,6 +1650,7 @@ struct Plater::priv
     std::vector<size_t> load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool used_inches = false);
     std::vector<size_t> load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false);
 
+    fs::path get_export_file_path(GUI::FileType file_type);
     wxString get_export_file(GUI::FileType file_type);
 
     const Selection& get_selection() const;
@@ -2599,22 +2606,8 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
     return obj_idxs;
 }
 
-wxString Plater::priv::get_export_file(GUI::FileType file_type)
+fs::path Plater::priv::get_export_file_path(GUI::FileType file_type)
 {
-    wxString wildcard;
-    switch (file_type) {
-        case FT_STL:
-        case FT_AMF:
-        case FT_3MF:
-        case FT_GCODE:
-        case FT_OBJ:
-            wildcard = file_wildcards(file_type);
-        break;
-        default:
-            wildcard = file_wildcards(FT_MODEL);
-        break;
-    }
-
     // Update printbility state of each of the ModelInstances.
     this->update_print_volume_state();
 
@@ -2639,7 +2632,31 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type)
         if (output_file.empty() && !model.objects.empty())
             // Find the file name of the first object.
             output_file = this->model.objects[0]->get_export_filename();
+
+        if (output_file.empty())
+            // Use _L("Untitled") name
+            output_file = into_path(_L("Untitled"));
     }
+    return output_file;
+}
+
+wxString Plater::priv::get_export_file(GUI::FileType file_type)
+{
+    wxString wildcard;
+    switch (file_type) {
+        case FT_STL:
+        case FT_AMF:
+        case FT_3MF:
+        case FT_GCODE:
+        case FT_OBJ:
+            wildcard = file_wildcards(file_type);
+        break;
+        default:
+            wildcard = file_wildcards(FT_MODEL);
+        break;
+    }
+
+    fs::path output_file = get_export_file_path(file_type);
 
     wxString dlg_title;
     switch (file_type) {
@@ -4714,8 +4731,10 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
     if (printer_technology_changed) {
         // Switching the printer technology when jumping forwards / backwards in time. Switch to the last active printer profile of the other type.
         std::string s_pt = (it_snapshot->snapshot_data.printer_technology == ptFFF) ? "FFF" : "SLA";
-        if (!wxGetApp().check_and_save_current_preset_changes(format_wxstr(_L(
-            "%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."), s_pt)))
+        if (!wxGetApp().check_and_save_current_preset_changes(_L("Undo / Redo is processing"), 
+//            format_wxstr(_L("%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."), s_pt)))
+            format_wxstr(_L("Switching the printer technology from %1% to %2%.\n"
+                            "Some %1% presets were modified, which will be lost after switching the printer technology."), s_pt =="FFF" ? "SLA" : "FFF", s_pt), false))
             // Don't switch the profiles.
             return;
     }
@@ -4893,7 +4912,7 @@ Plater::Plater(wxWindow *parent, MainFrame *main_frame)
 
 bool Plater::is_project_dirty() const { return p->is_project_dirty(); }
 void Plater::update_project_dirty_from_presets() { p->update_project_dirty_from_presets(); }
-int  Plater::save_project_if_dirty() { return p->save_project_if_dirty(); }
+int  Plater::save_project_if_dirty(const wxString& reason) { return p->save_project_if_dirty(reason); }
 void Plater::reset_project_dirty_after_save() { p->reset_project_dirty_after_save(); }
 void Plater::reset_project_dirty_initial_presets() { p->reset_project_dirty_initial_presets(); }
 #if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
@@ -4910,8 +4929,20 @@ SLAPrint&       Plater::sla_print()         { return p->sla_print; }
 
 void Plater::new_project()
 {
-    if (p->save_project_if_dirty() == wxID_CANCEL)
+    if (int saved_project = p->save_project_if_dirty(_L("Creating a new project while the current project is modified.")); saved_project == wxID_CANCEL)
         return;
+    else {
+        wxString header = _L("Creating a new project while some presets are modified.") + "\n" + 
+                          (saved_project == wxID_YES ? _L("You can keep presets modifications to the new project or discard them") :
+                          _L("You can keep presets modifications to the new project, discard them or save changes as new presets.\n"
+                             "Note, if changes will be saved than new project wouldn't keep them"));
+        using ab = UnsavedChangesDialog::ActionButtons;
+        int act_buttons = ab::KEEP;
+        if (saved_project == wxID_NO)
+            act_buttons |= ab::SAVE;
+        if (!wxGetApp().check_and_keep_current_preset_changes(_L("New Project is creating"), header, act_buttons))
+            return;
+    }
 
     p->select_view_3D("3D");
     take_snapshot(_L("New Project"));
@@ -4923,7 +4954,7 @@ void Plater::new_project()
 
 void Plater::load_project()
 {
-    if (p->save_project_if_dirty() == wxID_CANCEL)
+    if (!wxGetApp().can_load_project())
         return;
 
     // Ask user for a project file name.
@@ -5219,7 +5250,8 @@ bool Plater::load_files(const wxArrayString& filenames)
 
             switch (load_type) {
             case LoadType::OpenProject: {
-                load_project(from_path(*it));
+                if (wxGetApp().can_load_project())
+                    load_project(from_path(*it));
                 break;
             }
             case LoadType::LoadGeometry: {
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 5406a8a6e..c03681a34 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -140,7 +140,7 @@ public:
 
     bool is_project_dirty() const;
     void update_project_dirty_from_presets();
-    int  save_project_if_dirty();
+    int  save_project_if_dirty(const wxString& reason);
     void reset_project_dirty_after_save();
     void reset_project_dirty_initial_presets();
 #if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index d8af0e887..0687399b2 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -73,7 +73,7 @@ void PreferencesDialog::build(size_t selected_tab)
 	// Add "General" tab
 	m_optgroup_general = create_options_tab(_L("General"), tabs);
 	m_optgroup_general->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
-		if (opt_key == "default_action_on_close_application" || opt_key == "default_action_on_select_preset")
+		if (opt_key == "default_action_on_close_application" || opt_key == "default_action_on_select_preset" || opt_key == "default_action_on_new_project")
 			m_values[opt_key] = boost::any_cast<bool>(value) ? "none" : "discard";
 		else
 		    m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
@@ -186,19 +186,28 @@ void PreferencesDialog::build(size_t selected_tab)
 		option = Option(def, "single_instance");
 		m_optgroup_general->append_single_option_line(option);
 
-		def.label = L("Ask for unsaved changes when closing application");
+		def.label = L("Ask for unsaved changes when closing application or loading new project");
 		def.type = coBool;
-		def.tooltip = L("When closing the application, always ask for unsaved changes");
+		def.tooltip = L("Always ask for unsaved changes, when: \n"
+						"- Closing PrusaSlicer while some presets are modified,\n"
+						"- Loading a new project while some presets are modified");
 		def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_close_application") == "none" });
 		option = Option(def, "default_action_on_close_application");
 		m_optgroup_general->append_single_option_line(option);
 
 		def.label = L("Ask for unsaved changes when selecting new preset");
 		def.type = coBool;
-		def.tooltip = L("Always ask for unsaved changes when selecting new preset");
+		def.tooltip = L("Always ask for unsaved changes when selecting new preset or resetting a preset");
 		def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_select_preset") == "none" });
 		option = Option(def, "default_action_on_select_preset");
 		m_optgroup_general->append_single_option_line(option);
+
+		def.label = L("Ask for unsaved changes when creating new project");
+		def.type = coBool;
+		def.tooltip = L("Always ask for unsaved changes when creating new project");
+		def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_new_project") == "none" });
+		option = Option(def, "default_action_on_new_project");
+		m_optgroup_general->append_single_option_line(option);
 	}
 #ifdef _WIN32
 	else {
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 5effa3599..4ee733942 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -1216,12 +1216,20 @@ void Tab::cache_config_diff(const std::vector<std::string>& selected_options)
 
 void Tab::apply_config_from_cache()
 {
+    bool was_applied = false;
+    // check and apply extruders count for printer preset
+    if (m_type == Preset::TYPE_PRINTER)
+        was_applied = static_cast<TabPrinter*>(this)->apply_extruder_cnt_from_cache();
+
     if (!m_cache_config.empty()) {
         m_presets->get_edited_preset().config.apply(m_cache_config);
         m_cache_config.clear();
 
-        update_dirty();
+        was_applied = true;
     }
+
+    if (was_applied)
+        update_dirty();
 }
 
 
@@ -3322,10 +3330,6 @@ 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<TabPrinter*>(this)->apply_extruder_cnt_from_cache();
-
         // check if there is something in the cache to move to the new selected preset
         apply_config_from_cache();
 
@@ -3862,15 +3866,17 @@ void TabPrinter::cache_extruder_cnt()
     m_cache_extruder_count = m_extruders_count;
 }
 
-void TabPrinter::apply_extruder_cnt_from_cache()
+bool TabPrinter::apply_extruder_cnt_from_cache()
 {
     if (m_presets->get_edited_preset().printer_technology() == ptSLA)
-        return;
+        return false;
 
     if (m_cache_extruder_count > 0) {
         m_presets->get_edited_preset().set_num_extruders(m_cache_extruder_count);
         m_cache_extruder_count = 0;
+        return true;
     }
+    return false;
 }
 
 bool Tab::validate_custom_gcodes()
diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp
index 74585f2aa..5b7983711 100644
--- a/src/slic3r/GUI/Tab.hpp
+++ b/src/slic3r/GUI/Tab.hpp
@@ -469,7 +469,7 @@ public:
 
 	wxSizer*	create_bed_shape_widget(wxWindow* parent);
 	void		cache_extruder_cnt();
-	void		apply_extruder_cnt_from_cache();
+	bool		apply_extruder_cnt_from_cache();
 };
 
 class TabSLAMaterial : public Tab
diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp
index ef480f60f..40cfa548a 100644
--- a/src/slic3r/GUI/UnsavedChangesDialog.cpp
+++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp
@@ -727,14 +727,21 @@ void DiffViewCtrl::item_value_changed(wxDataViewEvent& event)
     m_empty_selection = selected_options().empty();
 }
 
-std::vector<std::string> DiffViewCtrl::unselected_options(Preset::Type type)
+bool DiffViewCtrl::has_unselected_options()
+{
+    for (auto item : m_items_map)
+        if (!model->IsEnabledItem(item.first))
+            return true;
+
+    return false;
+}
+
+std::vector<std::string> DiffViewCtrl::options(Preset::Type type, bool selected)
 {
     std::vector<std::string> ret;
 
     for (auto item : m_items_map) {
-        if (item.second.opt_key == "extruders_count")
-            continue;
-        if (item.second.type == type && !model->IsEnabledItem(item.first))
+        if (item.second.type == type && model->IsEnabledItem(item.first) == selected)
             ret.emplace_back(get_pure_opt_key(item.second.opt_key));
     }
 
@@ -757,20 +764,24 @@ std::vector<std::string> DiffViewCtrl::selected_options()
 //          UnsavedChangesDialog
 //------------------------------------------
 
-UnsavedChangesDialog::UnsavedChangesDialog(const wxString& header, const wxString& caption/* = wxString()*/)
-    : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, (caption.IsEmpty() ? _L("PrusaSlicer is closing") : caption) + ": " + _L("Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
-{
-    m_app_config_key = "default_action_on_close_application";
+static std::string none{"none"};
 
+UnsavedChangesDialog::UnsavedChangesDialog(const wxString& caption, const wxString& header, 
+                                           const std::string& app_config_key, int act_buttons)
+    : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, caption + ": " + _L("Unsaved Changes"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
+    m_app_config_key(app_config_key),
+    m_buttons(act_buttons)
+{
     build(Preset::TYPE_INVALID, nullptr, "", header);
 
-    const std::string& def_action = wxGetApp().app_config->get(m_app_config_key);
-    if (def_action == "none")
+    const std::string& def_action = m_app_config_key.empty() ? none : wxGetApp().app_config->get(m_app_config_key);
+    if (def_action == none)
         this->CenterOnScreen();
     else {
-        m_exit_action = def_action == ActSave ? Action::Save : Action::Discard;
-        if (m_exit_action == Action::Save)
-            save(nullptr);
+        m_exit_action = def_action == ActTransfer   ? Action::Transfer  :
+                        def_action == ActSave       ? Action::Save      : Action::Discard;
+        if (m_exit_action != Action::Discard)
+            save(nullptr, m_exit_action == Action::Save);
     }
 }
 
@@ -782,7 +793,7 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, PresetCollection*
     build(type, dependent_presets, new_selected_preset);
 
     const std::string& def_action = wxGetApp().app_config->get(m_app_config_key);
-    if (def_action == "none") {
+    if (def_action == none) {
         if (wxGetApp().mainframe->is_dlg_layout() && wxGetApp().mainframe->m_settings_dialog.HasFocus())
             this->SetPosition(wxGetApp().mainframe->m_settings_dialog.GetPosition());
         this->CenterOnScreen();
@@ -833,7 +844,8 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
 
         (*btn)->Bind(wxEVT_BUTTON, [this, close_act, dependent_presets](wxEvent&) {
             update_config(close_act);
-            if (close_act == Action::Save && !save(dependent_presets))
+            bool save_names_and_types = close_act == Action::Save || (close_act == Action::Transfer && ActionButtons::KEEP & m_buttons);
+            if (save_names_and_types && !save(dependent_presets, close_act == Action::Save))
                 return;
             close(close_act);
         });
@@ -842,13 +854,26 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
         (*btn)->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { show_info_line(Action::Undef); e.Skip(); });
     };
 
-    const PresetCollection* switched_presets = type == Preset::TYPE_INVALID ? nullptr : wxGetApp().get_tab(type)->get_presets();
-    if (dependent_presets && switched_presets && (type == dependent_presets->type() ?
-        dependent_presets->get_edited_preset().printer_technology() == dependent_presets->find_preset(new_selected_preset)->printer_technology() :
-        switched_presets->get_edited_preset().printer_technology() == switched_presets->find_preset(new_selected_preset)->printer_technology()))
-        add_btn(&m_transfer_btn, m_move_btn_id, "paste_menu", Action::Transfer, _L("Transfer"));
-    add_btn(&m_discard_btn, m_continue_btn_id, dependent_presets ? "switch_presets" : "exit", Action::Discard, _L("Discard"), false);
-    add_btn(&m_save_btn, m_save_btn_id, "save", Action::Save, _L("Save"));
+    // "Transfer" / "Keep" button
+    if (ActionButtons::TRANSFER & m_buttons) {
+        const PresetCollection* switched_presets = type == Preset::TYPE_INVALID ? nullptr : wxGetApp().get_tab(type)->get_presets();
+        if (dependent_presets && switched_presets && (type == dependent_presets->type() ?
+            dependent_presets->get_edited_preset().printer_technology() == dependent_presets->find_preset(new_selected_preset)->printer_technology() :
+            switched_presets->get_edited_preset().printer_technology() == switched_presets->find_preset(new_selected_preset)->printer_technology()))
+            add_btn(&m_transfer_btn, m_move_btn_id, "paste_menu", Action::Transfer, switched_presets->get_edited_preset().name == new_selected_preset ? _L("Keep") : _L("Transfer"));
+    }
+    if (!m_transfer_btn && (ActionButtons::KEEP & m_buttons))
+        add_btn(&m_transfer_btn, m_move_btn_id, "paste_menu", Action::Transfer, _L("Keep"));
+
+    { // "Don't save" / "Discard" button
+        std::string btn_icon    = (ActionButtons::DONT_SAVE & m_buttons) ? "" : (dependent_presets || (ActionButtons::KEEP & m_buttons)) ? "switch_presets" : "exit";
+        wxString    btn_label   = (ActionButtons::DONT_SAVE & m_buttons) ? _L("Don't save") : _L("Discard");
+        add_btn(&m_discard_btn, m_continue_btn_id, btn_icon, Action::Discard, btn_label, false);
+    }
+
+    // "Save" button
+    if (ActionButtons::SAVE & m_buttons) 
+        add_btn(&m_save_btn, m_save_btn_id, "save", Action::Save, _L("Save"));
 
     ScalableButton* cancel_btn = new ScalableButton(this, wxID_CANCEL, "cross", _L("Cancel"), wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, true, 24);
     buttons->Add(cancel_btn, 1, wxLEFT|wxRIGHT, 5);
@@ -859,34 +884,42 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
     m_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold());
     m_info_line->Hide();
 
-    m_remember_choice = new wxCheckBox(this, wxID_ANY, _L("Remember my choice"));
-    m_remember_choice->SetValue(wxGetApp().app_config->get(m_app_config_key) != "none");
-    m_remember_choice->Bind(wxEVT_CHECKBOX, [type, this](wxCommandEvent& evt)
-    {
-        if (!evt.IsChecked())
-            return;
-        wxString preferences_item = type == Preset::TYPE_INVALID ? _L("Ask for unsaved changes when closing application") : 
-                                                                   _L("Ask for unsaved changes when selecting new preset");
-        wxString msg =
-            _L("PrusaSlicer will remember your action.") + "\n\n" +
-            (type == Preset::TYPE_INVALID ?
-                _L("You will not be asked about the unsaved changes the next time you close PrusaSlicer.") :
-                _L("You will not be asked about the unsaved changes the next time you switch a preset.")) + "\n\n" +
-                format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto be asked about unsaved changes again."), preferences_item);
+    if (!m_app_config_key.empty()) {
+        m_remember_choice = new wxCheckBox(this, wxID_ANY, _L("Remember my choice"));
+        m_remember_choice->SetValue(wxGetApp().app_config->get(m_app_config_key) != none);
+        m_remember_choice->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& evt)
+        {
+            if (!evt.IsChecked())
+                return;
+            wxString preferences_item = m_app_config_key == "default_action_on_new_project"     ? _L("Ask for unsaved changes when creating new project") : 
+                                        m_app_config_key == "default_action_on_select_preset"   ? _L("Ask for unsaved changes when selecting new preset") :
+                                                                                                  _L("Ask for unsaved changes when ??closing application??") ;
+            wxString action = m_app_config_key == "default_action_on_new_project"   ? _L("You will not be asked about the unsaved changes the next time you create new project") : 
+                              m_app_config_key == "default_action_on_select_preset" ? _L("You will not be asked about the unsaved changes the next time you switch a preset") :
+                                                                                      _L("You will not be asked about the unsaved changes the next time you: \n"
+                                                                                            "- close the application,\n"
+                                                                                            "- load project,\n"
+                                                                                            "- process Undo / Redo with change of print technologie,\n"
+                                                                                            "- take/load snapshot,\n"
+                                                                                            "- load config file/bundle,\n"
+                                                                                            "- export config_bundle") ;
+            wxString msg = _L("PrusaSlicer will remember your action.") + "\n\n" + action + "\n\n" +
+                           format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto be asked about unsaved changes again."), preferences_item);
     
-        //wxMessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
-        MessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
-        if (dialog.ShowModal() == wxID_CANCEL)
-            m_remember_choice->SetValue(false);
-    });
+            MessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
+            if (dialog.ShowModal() == wxID_CANCEL)
+                m_remember_choice->SetValue(false);
+        });
+    }
 
     wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
 
     topSizer->Add(m_action_line,0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
     topSizer->Add(m_tree,       1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
     topSizer->Add(m_info_line,  0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2*border);
-    topSizer->Add(buttons,      0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
-    topSizer->Add(m_remember_choice, 0, wxEXPAND | wxALL, border);
+    topSizer->Add(buttons,      0, wxEXPAND | wxALL, border);
+    if (m_remember_choice)
+        topSizer->Add(m_remember_choice, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, border);
 
     update(type, dependent_presets, new_selected_preset, header);
 
@@ -905,10 +938,12 @@ void UnsavedChangesDialog::show_info_line(Action action, std::string preset_name
         if (action == Action::Undef)
             text = _L("Some fields are too long to fit. Right mouse click reveals the full text.");
         else if (action == Action::Discard)
-            text = _L("All settings changes will be discarded.");
+            text = ActionButtons::DONT_SAVE & m_buttons ? _L("All settings changes will not be saved") :_L("All settings changes will be discarded.");
         else {
             if (preset_name.empty())
-                text = action == Action::Save ? _L("Save the selected options.") : _L("Transfer the selected settings to the newly selected preset.");
+                text = action == Action::Save           ? _L("Save the selected options.") : 
+                       ActionButtons::KEEP & m_buttons  ? _L("Keep the selected settings.") :
+                                                          _L("Transfer the selected settings to the newly selected preset.");
             else
                 text = format_wxstr(
                     action == Action::Save ?
@@ -927,7 +962,7 @@ void UnsavedChangesDialog::show_info_line(Action action, std::string preset_name
 
 void UnsavedChangesDialog::update_config(Action action)
 {
-    if (!m_remember_choice->GetValue())
+    if (!m_remember_choice || !m_remember_choice->GetValue())
         return;
 
     std::string act = action == Action::Transfer ? ActTransfer :
@@ -941,7 +976,7 @@ void UnsavedChangesDialog::close(Action action)
     this->EndModal(wxID_CLOSE);
 }
 
-bool UnsavedChangesDialog::save(PresetCollection* dependent_presets)
+bool UnsavedChangesDialog::save(PresetCollection* dependent_presets, bool show_save_preset_dialog/* = true*/)
 {
     names_and_types.clear();
 
@@ -979,7 +1014,7 @@ bool UnsavedChangesDialog::save(PresetCollection* dependent_presets)
             }
 
 
-        if (!types_for_save.empty()) {
+        if (show_save_preset_dialog && !types_for_save.empty()) {
             SavePresetDialog save_dlg(this, types_for_save);
             if (save_dlg.ShowModal() != wxID_OK) {
                 m_exit_action = Action::Discard;
@@ -1164,16 +1199,24 @@ void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent
     PresetCollection* presets = dependent_presets;
 
     // activate buttons and labels
-    m_save_btn      ->Bind(wxEVT_ENTER_WINDOW, [this, presets]              (wxMouseEvent& e) { show_info_line(Action::Save, presets ? presets->get_selected_preset().name : ""); e.Skip(); });
+    if (m_save_btn)
+        m_save_btn    ->Bind(wxEVT_ENTER_WINDOW, [this, presets]                           (wxMouseEvent& e) { show_info_line(Action::Save, presets ? presets->get_selected_preset().name : ""); e.Skip(); });
     if (m_transfer_btn) {
-        bool is_empty_name = type != dependent_presets->type();
-        m_transfer_btn  ->Bind(wxEVT_ENTER_WINDOW, [this, new_selected_preset, is_empty_name]  (wxMouseEvent& e) { show_info_line(Action::Transfer, is_empty_name ? "" : new_selected_preset); e.Skip(); });
+        bool is_empty_name = dependent_presets && type != dependent_presets->type();
+        m_transfer_btn->Bind(wxEVT_ENTER_WINDOW, [this, new_selected_preset, is_empty_name](wxMouseEvent& e) { show_info_line(Action::Transfer, is_empty_name ? "" : new_selected_preset); e.Skip(); });
     }
-    m_discard_btn  ->Bind(wxEVT_ENTER_WINDOW, [this]                       (wxMouseEvent& e) { show_info_line(Action::Discard); e.Skip(); });
-
+    if (m_discard_btn)
+        m_discard_btn ->Bind(wxEVT_ENTER_WINDOW, [this]                                    (wxMouseEvent& e) { show_info_line(Action::Discard); e.Skip(); });
 
     if (type == Preset::TYPE_INVALID) {
-        m_action_line->SetLabel(header + "\n" + _L("The following presets were modified:"));
+        PrinterTechnology printer_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
+        int presets_cnt = 0;
+        for (Tab* tab : wxGetApp().tabs_list)
+            if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty())
+                presets_cnt++;
+        m_action_line->SetLabel((header.IsEmpty() ? "" : header + "\n\n") + //_L("The following presets were modified:"));
+                                + _L_PLURAL("The following preset was modified",
+                                            "The following presets were modified", presets_cnt));
     }
     else {
         wxString action_msg;
diff --git a/src/slic3r/GUI/UnsavedChangesDialog.hpp b/src/slic3r/GUI/UnsavedChangesDialog.hpp
index 9dbaf6e99..42f93f660 100644
--- a/src/slic3r/GUI/UnsavedChangesDialog.hpp
+++ b/src/slic3r/GUI/UnsavedChangesDialog.hpp
@@ -220,8 +220,9 @@ public:
     void        context_menu(wxDataViewEvent& event);
     void        item_value_changed(wxDataViewEvent& event);
     void        set_em_unit(int em) { m_em_unit = em; }
+    bool        has_unselected_options();
 
-    std::vector<std::string> unselected_options(Preset::Type type);
+    std::vector<std::string> options(Preset::Type type, bool selected);
     std::vector<std::string> selected_options();
 };
 
@@ -261,10 +262,22 @@ class UnsavedChangesDialog : public DPIDialog
     Action m_exit_action {Action::Undef};
     // preset names which are modified in SavePresetDialog and related types
     std::vector<std::pair<std::string, Preset::Type>>  names_and_types;
+    // additional action buttons used in dialog
+    int m_buttons { ActionButtons::TRANSFER | ActionButtons::SAVE };
 
 public:
-    UnsavedChangesDialog(const wxString& header, const wxString& caption = wxString());
+    // Discard and Cancel buttons are always but next buttons are optional
+    enum ActionButtons {
+        TRANSFER  = 1,
+        KEEP      = 2,
+        SAVE      = 4,
+        DONT_SAVE = 8,
+    };
+
+    // show unsaved changes when preset is switching
     UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset);
+    // show unsaved changes for all another cases
+    UnsavedChangesDialog(const wxString& caption, const wxString& header, const std::string& app_config_key, int act_buttons);
     ~UnsavedChangesDialog() {}
 
     void build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header = "");
@@ -273,7 +286,8 @@ public:
     void show_info_line(Action action, std::string preset_name = "");
     void update_config(Action action);
     void close(Action action);
-    bool save(PresetCollection* dependent_presets);
+    // save information about saved presets and their types to names_and_types and show SavePresetDialog to set the names for new presets
+    bool save(PresetCollection* dependent_presets, bool show_save_preset_dialog = true);
 
     bool save_preset() const        { return m_exit_action == Action::Save;     }
     bool transfer_changes() const   { return m_exit_action == Action::Transfer; }
@@ -284,8 +298,10 @@ public:
     // short version of the previous function, for the case, when just one preset is modified
     std::string get_preset_name() { return names_and_types[0].first; }
 
-    std::vector<std::string> get_unselected_options(Preset::Type type)  { return m_tree->unselected_options(type); }
+    std::vector<std::string> get_unselected_options(Preset::Type type)  { return m_tree->options(type, false); }
+    std::vector<std::string> get_selected_options  (Preset::Type type)  { return m_tree->options(type, true); }
     std::vector<std::string> get_selected_options()                     { return m_tree->selected_options(); }
+    bool                     has_unselected_options()                   { return m_tree->has_unselected_options(); }
 
 protected:
     void on_dpi_changed(const wxRect& suggested_rect) override;
diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp
index 29d474dca..97c6cb2a5 100644
--- a/src/slic3r/Utils/PresetUpdater.cpp
+++ b/src/slic3r/Utils/PresetUpdater.cpp
@@ -720,8 +720,13 @@ void PresetUpdater::slic3r_update_notify()
 	}
 }
 
-static void reload_configs_update_gui()
+static bool reload_configs_update_gui()
 {
+	wxString header = _L("Configuration Updates causes a lost of preset modification.\n"
+						 "So, check unsaved changes and save them if necessary.");
+	if (!GUI::wxGetApp().check_and_save_current_preset_changes(_L("Updater is processing"), header, false ))
+		return false;
+
 	// Reload global configuration
 	auto* app_config = GUI::wxGetApp().app_config;
 	// System profiles should not trigger any substitutions, user profiles may trigger substitutions, but these substitutions
@@ -730,7 +735,8 @@ static void reload_configs_update_gui()
 	GUI::wxGetApp().preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem);
 	GUI::wxGetApp().load_current_presets();
 	GUI::wxGetApp().plater()->set_bed_shape();
-	GUI::wxGetApp().update_wizard_from_config();
+
+	return true;
 }
 
 PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3r_version, UpdateParams params) const
@@ -803,9 +809,9 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
 			const auto res = dlg.ShowModal();
 			if (res == wxID_OK) {
 				BOOST_LOG_TRIVIAL(info) << "User wants to update...";
-				if (! p->perform_updates(std::move(updates)))
+				if (! p->perform_updates(std::move(updates)) ||
+					! reload_configs_update_gui())
 					return R_INCOMPAT_EXIT;
-				reload_configs_update_gui();
 				return R_UPDATE_INSTALLED;
 			}
 			else {
@@ -833,9 +839,9 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
 			const auto res = dlg.ShowModal();
 			if (res == wxID_OK) {
 				BOOST_LOG_TRIVIAL(debug) << "User agreed to perform the update";
-				if (! p->perform_updates(std::move(updates)))
+				if (! p->perform_updates(std::move(updates)) ||
+					! reload_configs_update_gui())
 					return R_ALL_CANCELED;
-				reload_configs_update_gui();
 				return R_UPDATE_INSTALLED;
 			}
 			else {
@@ -886,8 +892,8 @@ void PresetUpdater::on_update_notification_confirm()
 	const auto res = dlg.ShowModal();
 	if (res == wxID_OK) {
 		BOOST_LOG_TRIVIAL(debug) << "User agreed to perform the update";
-		if (p->perform_updates(std::move(p->waiting_updates))) {
-			reload_configs_update_gui();
+		if (p->perform_updates(std::move(p->waiting_updates)) &&
+			reload_configs_update_gui()) {
 			p->has_waiting_updates = false;
 		}
 	}