diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 40cfcad89..473fc6b90 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -95,14 +95,15 @@ sub OnInit { warn $@ . "\n"; fatal_error(undef, $@); } - my $run_wizard = ! $self->{app_config}->exists; + my $app_conf_exists = $self->{app_config}->exists; # load settings - $self->{app_config}->load if ! $run_wizard; + $self->{app_config}->load if $app_conf_exists; $self->{app_config}->set('version', $Slic3r::VERSION); $self->{app_config}->save; # my $version_check = $self->{app_config}->get('version_check'); $self->{preset_updater} = Slic3r::PresetUpdater->new($VERSION_ONLINE_EVENT, $self->{app_config}); + Slic3r::GUI::set_preset_updater($self->{preset_updater}); eval { $self->{preset_updater}->config_update($self->{app_config}) }; if ($@) { warn $@ . "\n"; @@ -120,8 +121,6 @@ sub OnInit { warn $@ . "\n"; show_error(undef, $@); } - # TODO: check previously downloaded updates - $run_wizard = 1 if $self->{preset_bundle}->has_defauls_only; Slic3r::GUI::set_preset_bundle($self->{preset_bundle}); @@ -148,16 +147,8 @@ sub OnInit { # On OSX the UI was not initialized correctly if the wizard was called # before the UI was up and running. $self->CallAfter(sub { - # XXX: recreate_GUI ??? - # if ($slic3r_update) { - # # TODO - # } - # XXX: ? - if ($run_wizard) { - # Run the config wizard, don't offer the "reset user profile" checkbox. - Slic3r::GUI::config_wizard(1); - } - + Slic3r::GUI::config_wizard_startup($app_conf_exists); + # TODO: call periodically? $self->{preset_updater}->sync($self->{app_config}, $self->{preset_bundle}); }); @@ -209,15 +200,12 @@ sub recreate_GUI{ $self->{app_config}->save if $self->{app_config}->dirty; }); - my $run_wizard = 1 if $self->{preset_bundle}->has_defauls_only; - if ($run_wizard) { - # On OSX the UI was not initialized correctly if the wizard was called - # before the UI was up and running. - $self->CallAfter(sub { - # Run the config wizard, don't offer the "reset user profile" checkbox. - Slic3r::GUI::config_wizard(1); - }); - } + # On OSX the UI was not initialized correctly if the wizard was called + # before the UI was up and running. + $self->CallAfter(sub { + # Run the config wizard, don't offer the "reset user profile" checkbox. + Slic3r::GUI::config_wizard_startup(1); + }); } sub system_info { diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index 0f192c37c..4aef4d5c1 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -14,7 +14,7 @@ #include #define SLIC3R_FORK_NAME "Slic3r Prusa Edition" -#define SLIC3R_VERSION "1.39.0" +#define SLIC3R_VERSION "1.40.0" #define SLIC3R_BUILD "UNKNOWN" typedef int32_t coord_t; diff --git a/xs/src/slic3r/Config/Snapshot.hpp b/xs/src/slic3r/Config/Snapshot.hpp index a7b8a5aa5..584a37400 100644 --- a/xs/src/slic3r/Config/Snapshot.hpp +++ b/xs/src/slic3r/Config/Snapshot.hpp @@ -97,7 +97,7 @@ public: // Create a snapshot directory, copy the vendor config bundles, user print/filament/printer profiles, // create an index. - const Snapshot& take_snapshot(const AppConfig &app_config, Snapshot::Reason reason, const std::string &comment); + const Snapshot& take_snapshot(const AppConfig &app_config, Snapshot::Reason reason, const std::string &comment = ""); void restore_snapshot(const std::string &id, AppConfig &app_config); void restore_snapshot(const Snapshot &snapshot, AppConfig &app_config); diff --git a/xs/src/slic3r/GUI/AppConfig.cpp b/xs/src/slic3r/GUI/AppConfig.cpp index d0f2f1019..5104078b1 100644 --- a/xs/src/slic3r/GUI/AppConfig.cpp +++ b/xs/src/slic3r/GUI/AppConfig.cpp @@ -98,6 +98,10 @@ void AppConfig::load() } } + // Figure out if datadir has legacy presets + auto ini_ver = Semver::parse(get("version")); + m_legacy_datadir = ini_ver ? *ini_ver < Semver(1, 40, 0) : true; + // Override missing or keys with their defaults. this->set_defaults(); m_dirty = false; @@ -240,7 +244,6 @@ bool AppConfig::slic3r_update_avail() const Semver AppConfig::get_slic3r_version() const { - // TODO: move to Semver c-tor (???) auto res = Semver::parse(get("version")); if (! res) { throw std::runtime_error(std::string("Could not parse Slic3r version string in application config.")); diff --git a/xs/src/slic3r/GUI/AppConfig.hpp b/xs/src/slic3r/GUI/AppConfig.hpp index ffda083ec..88ba0a662 100644 --- a/xs/src/slic3r/GUI/AppConfig.hpp +++ b/xs/src/slic3r/GUI/AppConfig.hpp @@ -13,7 +13,7 @@ namespace Slic3r { class AppConfig { public: - AppConfig() : m_dirty(false) { this->reset(); } + AppConfig() : m_dirty(false), m_legacy_datadir(false) { this->reset(); } // Clear and reset to defaults. void reset(); @@ -98,6 +98,8 @@ public: // Get the default config path from Slic3r::data_dir(). static std::string config_path(); + + bool legacy_datadir() const { return m_legacy_datadir; } // Does the config file exist? static bool exists(); @@ -109,6 +111,8 @@ private: VendorMap m_vendors; // Has any value been modified since the config.ini has been last saved or loaded? bool m_dirty; + // Whether the existing version is before system profiles & configuration updating + bool m_legacy_datadir; }; }; // namespace Slic3r diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp index 5b49fc025..a059d234b 100644 --- a/xs/src/slic3r/GUI/ConfigWizard.cpp +++ b/xs/src/slic3r/GUI/ConfigWizard.cpp @@ -1,8 +1,8 @@ #include "ConfigWizard_private.hpp" -#include // XXX #include #include +#include #include #include @@ -17,6 +17,7 @@ #include "GUI.hpp" #include "slic3r/Utils/PresetUpdater.hpp" +// TODO: Wizard vs Assistant namespace Slic3r { namespace GUI { @@ -54,48 +55,80 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons const auto vendor_id = vendor.id; const auto &models = vendor.models; + auto *sizer = new wxBoxSizer(wxVERTICAL); + auto *printer_grid = new wxFlexGridSizer(models.size(), 0, 20); printer_grid->SetFlexibleDirection(wxVERTICAL); - SetSizer(printer_grid); + sizer->Add(printer_grid); auto namefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); namefont.SetWeight(wxFONTWEIGHT_BOLD); for (const auto &model : models) { auto *panel = new wxPanel(this); - auto *sizer = new wxBoxSizer(wxVERTICAL); - panel->SetSizer(sizer); + auto *col_sizer = new wxBoxSizer(wxVERTICAL); + panel->SetSizer(col_sizer); auto *title = new wxStaticText(panel, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); title->SetFont(namefont); - sizer->Add(title, 0, wxBOTTOM, 3); + col_sizer->Add(title, 0, wxBOTTOM, 3); auto bitmap_file = wxString::Format("printers/%s_%s.png", vendor.id, model.id); wxBitmap bitmap(GUI::from_u8(Slic3r::var(bitmap_file.ToStdString())), wxBITMAP_TYPE_PNG); auto *bitmap_widget = new wxStaticBitmap(panel, wxID_ANY, bitmap); - sizer->Add(bitmap_widget, 0, wxBOTTOM, 3); + col_sizer->Add(bitmap_widget, 0, wxBOTTOM, 3); - sizer->AddSpacer(20); + col_sizer->AddSpacer(20); const auto model_id = model.id; for (const auto &variant : model.variants) { - const auto variant_name = variant.name; - auto *cbox = new wxCheckBox(panel, wxID_ANY, wxString::Format("%s %s %s", variant.name, _(L("mm")), _(L("nozzle")))); - bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant_name); + const auto label = wxString::Format("%s %s %s", variant.name, _(L("mm")), _(L("nozzle"))); + auto *cbox = new Checkbox(panel, label, model_id, variant.name); + const size_t idx = cboxes.size(); + cboxes.push_back(cbox); + bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant.name); variants_checked += enabled; cbox->SetValue(enabled); - sizer->Add(cbox, 0, wxBOTTOM, 3); - cbox->Bind(wxEVT_CHECKBOX, [=](wxCommandEvent &event) { - this->variants_checked += event.IsChecked() ? 1 : -1; - PrinterPickerEvent evt(EVT_PRINTER_PICK, this->GetId(), std::move(vendor_id), std::move(model_id), std::move(variant_name), event.IsChecked()); - this->AddPendingEvent(evt); + col_sizer->Add(cbox, 0, wxBOTTOM, 3); + cbox->Bind(wxEVT_CHECKBOX, [this, idx](wxCommandEvent &event) { + if (idx >= this->cboxes.size()) { return; } + this->on_checkbox(this->cboxes[idx], event.IsChecked()); }); } printer_grid->Add(panel); } + auto *all_none_sizer = new wxBoxSizer(wxHORIZONTAL); + auto *sel_all = new wxButton(this, wxID_ANY, _(L("Select all"))); + auto *sel_none = new wxButton(this, wxID_ANY, _(L("Select none"))); + sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true); }); + sel_none->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(false); }); + all_none_sizer->AddStretchSpacer(); + all_none_sizer->Add(sel_all); + all_none_sizer->Add(sel_none); + sizer->AddStretchSpacer(); + sizer->Add(all_none_sizer, 0, wxEXPAND); + + SetSizer(sizer); +} + +void PrinterPicker::select_all(bool select) +{ + for (const auto &cb : cboxes) { + if (cb->GetValue() != select) { + cb->SetValue(select); + on_checkbox(cb, select); + } + } +} + +void PrinterPicker::on_checkbox(const Checkbox *cbox, bool checked) +{ + variants_checked += checked ? 1 : -1; + PrinterPickerEvent evt(EVT_PRINTER_PICK, GetId(), vendor_id, cbox->model, cbox->variant, checked); + AddPendingEvent(evt); } @@ -176,15 +209,10 @@ PageWelcome::PageWelcome(ConfigWizard *parent) : { append_text(_(L("Hello, welcome to Slic3r Prusa Edition! TODO: This text."))); - // const PresetBundle &bundle = wizard_p()->bundle_vendors; - // const auto &vendors = bundle.vendors; const auto &vendors = wizard_p()->vendors; - // const auto vendor_prusa = std::find(vendors.cbegin(), vendors.cend(), VendorProfile("PrusaResearch")); const auto vendor_prusa = vendors.find("PrusaResearch"); if (vendor_prusa != vendors.cend()) { - const auto &models = vendor_prusa->second.models; - AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors; printer_picker = new PrinterPicker(this, vendor_prusa->second, appconfig_vendors); @@ -550,6 +578,17 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) // priv +static const std::unordered_map> legacy_preset_map {{ + { "Original Prusa i3 MK2.ini", std::make_pair("MK2S", "0.4") }, + { "Original Prusa i3 MK2 MM Single Mode.ini", std::make_pair("MK2S", "0.4") }, + { "Original Prusa i3 MK2 MM Single Mode 0.6 nozzle.ini", std::make_pair("MK2S", "0.6") }, + { "Original Prusa i3 MK2 MultiMaterial.ini", std::make_pair("MK2S", "0.4") }, + { "Original Prusa i3 MK2 MultiMaterial 0.6 nozzle.ini", std::make_pair("MK2S", "0.6") }, + { "Original Prusa i3 MK2 0.25 nozzle.ini", std::make_pair("MK2S", "0.25") }, + { "Original Prusa i3 MK2 0.6 nozzle.ini", std::make_pair("MK2S", "0.6") }, + { "Original Prusa i3 MK3.ini", std::make_pair("MK3", "0.4") }, +}}; + void ConfigWizard::priv::load_vendors() { const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor"; @@ -569,13 +608,28 @@ void ConfigWizard::priv::load_vendors() const auto id = it->path().stem().string(); if (vendors.find(id) == vendors.end()) { auto vp = VendorProfile::from_ini(it->path()); - vendors_rsrc[vp.id] = it->path(); + vendors_rsrc[vp.id] = it->path().filename().string(); vendors[vp.id] = std::move(vp); } } } - appconfig_vendors.set_vendors(*GUI::get_app_config()); + // Load up the set of vendors / models / variants the user has had enabled up till now + const AppConfig *app_config = GUI::get_app_config(); + if (! app_config->legacy_datadir()) { + appconfig_vendors.set_vendors(*app_config); + } else { + // In case of legacy datadir, try to guess the preference based on the printer preset files that are present + const auto printer_dir = fs::path(Slic3r::data_dir()) / "printer"; + for (fs::directory_iterator it(printer_dir); it != fs::directory_iterator(); ++it) { + auto needle = legacy_preset_map.find(it->path().filename().string()); + if (needle == legacy_preset_map.end()) { continue; } + + const auto &model = needle->second.first; + const auto &variant = needle->second.second; + appconfig_vendors.set_variant("PrusaResearch", model, variant, true); + } + } } void ConfigWizard::priv::index_refresh() @@ -639,22 +693,28 @@ void ConfigWizard::priv::on_custom_setup() set_page(page_firmware); } -void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle) +void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, PresetUpdater *updater) { const bool is_custom_setup = page_welcome->page_next() == page_firmware; if (! is_custom_setup) { const auto enabled_vendors = appconfig_vendors.vendors(); + + // Install bundles from resources if needed: + std::vector install_bundles; for (const auto &vendor_rsrc : vendors_rsrc) { const auto vendor = enabled_vendors.find(vendor_rsrc.first); if (vendor == enabled_vendors.end()) { continue; } - + size_t size_sum = 0; for (const auto &model : vendor->second) { size_sum += model.second.size(); } if (size_sum == 0) { continue; } // This vendor needs to be installed - PresetBundle::install_vendor_configbundle(vendor_rsrc.second); + install_bundles.emplace_back(vendor_rsrc.second); + } + if (install_bundles.size() > 0) { + updater->install_bundles_rsrc(app_config, std::move(install_bundles)); } app_config->set_vendors(appconfig_vendors); @@ -732,14 +792,10 @@ ConfigWizard::ConfigWizard(wxWindow *parent) : ConfigWizard::~ConfigWizard() {} -bool ConfigWizard::run(wxWindow *parent, PresetBundle *preset_bundle) +void ConfigWizard::run(PresetBundle *preset_bundle, PresetUpdater *updater) { - ConfigWizard wizard(parent); - if (wizard.ShowModal() == wxID_OK) { - wizard.p->apply_config(GUI::get_app_config(), preset_bundle); - return true; - } else { - return false; + if (ShowModal() == wxID_OK) { + p->apply_config(GUI::get_app_config(), preset_bundle, updater); } } diff --git a/xs/src/slic3r/GUI/ConfigWizard.hpp b/xs/src/slic3r/GUI/ConfigWizard.hpp index 40ecf09a1..b34467011 100644 --- a/xs/src/slic3r/GUI/ConfigWizard.hpp +++ b/xs/src/slic3r/GUI/ConfigWizard.hpp @@ -8,6 +8,7 @@ namespace Slic3r { class PresetBundle; +class PresetUpdater; namespace GUI { @@ -22,7 +23,7 @@ public: ConfigWizard &operator=(const ConfigWizard &) = delete; ~ConfigWizard(); - static bool run(wxWindow *parent, PresetBundle *preset_bundle); + void run(PresetBundle *preset_bundle, PresetUpdater *updater); private: struct priv; std::unique_ptr p; diff --git a/xs/src/slic3r/GUI/ConfigWizard_private.hpp b/xs/src/slic3r/GUI/ConfigWizard_private.hpp index c93e0a80d..8aab1cc19 100644 --- a/xs/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/xs/src/slic3r/GUI/ConfigWizard_private.hpp @@ -15,6 +15,7 @@ #include #include "libslic3r/PrintConfig.hpp" +#include "slic3r/Utils/PresetUpdater.hpp" #include "AppConfig.hpp" #include "Preset.hpp" #include "BedShapeDialog.hpp" @@ -24,8 +25,6 @@ namespace fs = boost::filesystem; namespace Slic3r { namespace GUI { -// typedef std::unordered_map VendorMap; - enum { CONTENT_WIDTH = 500, @@ -38,9 +37,26 @@ enum { struct PrinterPicker: wxPanel { + struct Checkbox : wxCheckBox + { + Checkbox(wxWindow *parent, const wxString &label, const std::string &model, const std::string &variant) : + wxCheckBox(parent, wxID_ANY, label), + model(model), + variant(variant) + {} + + std::string model; + std::string variant; + }; + + const std::string vendor_id; + std::vector cboxes; unsigned variants_checked; PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors); + + void select_all(bool select); + void on_checkbox(const Checkbox *cbox, bool checked); }; struct ConfigWizardPage: wxPanel @@ -174,7 +190,7 @@ struct ConfigWizard::priv ConfigWizard *q; AppConfig appconfig_vendors; // TODO: use order-preserving container std::unordered_map vendors; // TODO: just set? - std::unordered_map vendors_rsrc; + std::unordered_map vendors_rsrc; std::unique_ptr custom_config; wxBoxSizer *topsizer = nullptr; @@ -208,7 +224,7 @@ struct ConfigWizard::priv void on_other_vendors(); void on_custom_setup(); - void apply_config(AppConfig *app_config, PresetBundle *preset_bundle); + void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, PresetUpdater *updater); }; diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index d70b47840..916c407af 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include "wxExtensions.hpp" @@ -50,6 +51,7 @@ #include "Preferences.hpp" #include "PresetBundle.hpp" +#include "../Utils/PresetUpdater.hpp" #include "../Config/Snapshot.hpp" namespace Slic3r { namespace GUI { @@ -179,6 +181,7 @@ wxFrame *g_wxMainFrame = nullptr; wxNotebook *g_wxTabPanel = nullptr; AppConfig *g_AppConfig = nullptr; PresetBundle *g_PresetBundle= nullptr; +PresetUpdater *g_PresetUpdater = nullptr; std::vector g_tabs_list; @@ -212,6 +215,11 @@ void set_preset_bundle(PresetBundle *preset_bundle) g_PresetBundle = preset_bundle; } +void set_preset_updater(PresetUpdater *updater) +{ + g_PresetUpdater = updater; +} + std::vector& get_tabs_list() { return g_tabs_list; @@ -442,23 +450,51 @@ bool check_unsaved_changes() return dialog->ShowModal() == wxID_YES; } -bool config_wizard(bool fresh_start) +void config_wizard_startup(bool app_config_exists) +{ + if (! app_config_exists || g_PresetBundle->has_defauls_only()) { + config_wizard(true); + } else if (g_AppConfig->legacy_datadir()) { + // Looks like user has legacy pre-vendorbundle data directory, + // explain what this is and run the wizard + + const auto msg = _(L("Configuration update")); + const auto ext_msg = _(L( + "Slic3r PE now uses an updated configuration structure.\n\n" + + "So called 'System presets' have been introduced, which hold the built-in default settings for various " + "printers. These System presets cannot be modified, instead, users now may create their" + "own presets inheriting settings from one of the System presets.\n" + "An inheriting preset may either inherit a particular value from its parent or override it with a customized value.\n\n" + + // TODO: Assistant vs Wizard + "Please proceed with the Configuration wizard that follows to set up the new presets " + "and to choose whether to enable automatic preset updates." + )); + wxMessageDialog dlg(NULL, msg, _(L("Configuration update")), wxOK|wxCENTRE); + dlg.SetExtendedMessage(ext_msg); + const auto res = dlg.ShowModal(); + + config_wizard(true); + } +} + +void config_wizard(bool fresh_start) // TODO: fresh_start useful ? { if (g_wxMainFrame == nullptr) throw std::runtime_error("Main frame not set"); // Exit wizard if there are unsaved changes and the user cancels the action. if (! check_unsaved_changes()) - return false; + return; - // TODO: Offer "reset user profile" ??? - if (! ConfigWizard::run(g_wxMainFrame, g_PresetBundle)) - return false; + // TODO: Offer "reset user profile" ??? + ConfigWizard wizard(g_wxMainFrame); + wizard.run(g_PresetBundle, g_PresetUpdater); // Load the currently selected preset into the GUI, update the preset selection box. for (Tab *tab : g_tabs_list) tab->load_current_preset(); - return true; } void open_preferences_dialog(int event_preferences) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 2a3667eb3..6a23ed4eb 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -25,6 +25,7 @@ namespace Slic3r { class PresetBundle; class PresetCollection; class AppConfig; +class PresetUpdater; class DynamicPrintConfig; class TabIface; @@ -76,6 +77,7 @@ void set_main_frame(wxFrame *main_frame); void set_tab_panel(wxNotebook *tab_panel); void set_app_config(AppConfig *app_config); void set_preset_bundle(PresetBundle *preset_bundle); +void set_preset_updater(PresetUpdater *updater); AppConfig* get_app_config(); wxApp* get_app(); @@ -88,8 +90,11 @@ extern void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int // to notify the user whether he is aware that some preset changes will be lost. extern bool check_unsaved_changes(); -// Opens the first-time configuration wizard, returns true if wizard is finished & accepted. -extern bool config_wizard(bool fresh_start); +// Checks if configuration wizard needs to run, calls config_wizard if so +extern void config_wizard_startup(bool app_config_exists); + +// Opens the configuration wizard, returns true if wizard is finished & accepted. +extern void config_wizard(bool fresh_start); // Create "Preferences" dialog after selecting menu "Preferences" in Perl part extern void open_preferences_dialog(int event_preferences); diff --git a/xs/src/slic3r/Utils/PresetUpdater.cpp b/xs/src/slic3r/Utils/PresetUpdater.cpp index 257c7f552..3291af7e0 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.cpp +++ b/xs/src/slic3r/Utils/PresetUpdater.cpp @@ -51,6 +51,11 @@ struct Update version(version) {} + Update(fs::path &&source, fs::path &&target) : + source(source), + target(std::move(target)) + {} + std::string name() { return source.stem().string(); } }; @@ -83,6 +88,7 @@ struct PresetUpdater::priv void check_install_indices() const; Updates config_update() const; + void perform_updates(AppConfig *app_config, Updates &&updates) const; }; PresetUpdater::priv::priv(int event, AppConfig *app_config) : @@ -121,6 +127,7 @@ bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &targe .on_complete([&](std::string body, unsigned http_status) { fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); file.write(body.c_str(), body.size()); + file.close(); fs::rename(tmp_path, target_path); res = true; }) @@ -269,6 +276,26 @@ Updates PresetUpdater::priv::config_update() const return updates; } +void PresetUpdater::priv::perform_updates(AppConfig *app_config, Updates &&updates) const +{ + SnapshotDB::singleton().take_snapshot(*app_config, Snapshot::SNAPSHOT_UPGRADE); + + for (const auto &update : updates) { + fs::copy_file(update.source, update.target, fs::copy_option::overwrite_if_exists); + + PresetBundle bundle; + bundle.load_configbundle(update.target.string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM); + + auto preset_remover = [](const Preset &preset) { + fs::remove(preset.file); + }; + + for (const auto &preset : bundle.prints) { preset_remover(preset); } + for (const auto &preset : bundle.filaments) { preset_remover(preset); } + for (const auto &preset : bundle.printers) { preset_remover(preset); } + } +} + PresetUpdater::PresetUpdater(int version_online_event, AppConfig *app_config) : p(new priv(version_online_event, app_config)) @@ -306,7 +333,7 @@ void PresetUpdater::config_update(AppConfig *app_config) { if (! p->enabled_config_update) { return; } - const auto updates = p->config_update(); + auto updates = p->config_update(); if (updates.size() > 0) { const auto msg = _(L("Configuration update is available. Would you like to install it?")); @@ -330,26 +357,23 @@ void PresetUpdater::config_update(AppConfig *app_config) std::cerr << "After modal" << std::endl; if (res == wxID_YES) { // User gave clearance, updates are go - - SnapshotDB::singleton().take_snapshot(*app_config, Snapshot::SNAPSHOT_UPGRADE, ""); - - for (const auto &update : updates) { - fs::copy_file(update.source, update.target, fs::copy_option::overwrite_if_exists); - - PresetBundle bundle; - bundle.load_configbundle(update.target.string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM); - - auto preset_remover = [](const Preset &preset) { - fs::remove(preset.file); - }; - - for (const auto &preset : bundle.prints) { preset_remover(preset); } - for (const auto &preset : bundle.filaments) { preset_remover(preset); } - for (const auto &preset : bundle.printers) { preset_remover(preset); } - } + p->perform_updates(app_config, std::move(updates)); } } } +void PresetUpdater::install_bundles_rsrc(AppConfig *app_config, std::vector &&bundles) +{ + Updates updates; + + for (const auto &bundle : bundles) { + auto path_in_rsrc = p->rsrc_path / bundle; + auto path_in_vendors = p->vendor_path / bundle; + updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors)); + } + + p->perform_updates(app_config, std::move(updates)); +} + } diff --git a/xs/src/slic3r/Utils/PresetUpdater.hpp b/xs/src/slic3r/Utils/PresetUpdater.hpp index 966dd1464..1499570db 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.hpp +++ b/xs/src/slic3r/Utils/PresetUpdater.hpp @@ -2,6 +2,7 @@ #define slic3r_PresetUpdate_hpp_ #include +#include namespace Slic3r { @@ -20,8 +21,8 @@ public: ~PresetUpdater(); void sync(AppConfig *app_config, PresetBundle *preset_bundle); - void config_update(AppConfig *app_config); + void install_bundles_rsrc(AppConfig *app_config, std::vector &&bundles); private: struct priv; std::unique_ptr p; diff --git a/xs/src/slic3r/Utils/Semver.hpp b/xs/src/slic3r/Utils/Semver.hpp index 2c27ce982..3e9276be6 100644 --- a/xs/src/slic3r/Utils/Semver.hpp +++ b/xs/src/slic3r/Utils/Semver.hpp @@ -32,8 +32,6 @@ public: ver.prerelease = prerelease ? std::strcpy(ver.prerelease, prerelease->c_str()) : nullptr; } - // TODO: throwing ctor ??? - static boost::optional parse(const std::string &str) { semver_t ver = semver_zero(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 46e4ace83..0d9f0b62e 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -60,10 +60,10 @@ void set_app_config(AppConfig *app_config) bool check_unsaved_changes() %code%{ RETVAL=Slic3r::GUI::check_unsaved_changes(); %}; -bool config_wizard(int fresh_start) +void config_wizard_startup(int app_config_exists) %code%{ try { - RETVAL = Slic3r::GUI::config_wizard(fresh_start != 0); + Slic3r::GUI::config_wizard_startup(app_config_exists != 0); } catch (std::exception& e) { croak("%s\n", e.what()); } @@ -75,6 +75,9 @@ void open_preferences_dialog(int preferences_event) void set_preset_bundle(PresetBundle *preset_bundle) %code%{ Slic3r::GUI::set_preset_bundle(preset_bundle); %}; +void set_preset_updater(PresetUpdater* updater) + %code%{ Slic3r::GUI::set_preset_updater(updater); %}; + void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_sizer) %code%{ Slic3r::GUI::add_frequently_changed_parameters((wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), diff --git a/xs/xsp/my.map b/xs/xsp/my.map index c1ca58827..393338f3b 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -238,7 +238,6 @@ Ref O_OBJECT_SLIC3R_T PresetUpdater* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T -Clone O_OBJECT_SLIC3R_T OctoPrint* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index 0214a158d..2539811b3 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -208,6 +208,8 @@ %typemap{Ref}{simple}; %typemap{PresetBundle*}; %typemap{Ref}{simple}; +%typemap{PresetUpdater*}; +%typemap{Ref}{simple}; %typemap{PresetHints*}; %typemap{Ref}{simple}; %typemap{TabIface*};