diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 2082728cc4..b592c4289b 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -101,11 +101,14 @@ sub OnInit { $self->{app_config}->set('version', $Slic3r::VERSION); $self->{app_config}->save; - Slic3r::PresetUpdater::init_vendors(); - # my $version_check = $self->{app_config}->get('version_check'); $self->{preset_updater} = Slic3r::PresetUpdater->new($VERSION_ONLINE_EVENT, $self->{app_config}); - my $slic3r_update = $self->{app_config}->slic3r_update_avail; + eval { $self->{preset_updater}->config_update() }; + if ($@) { + warn $@ . "\n"; + fatal_error(undef, $@); + } + # my $slic3r_update = $self->{app_config}->slic3r_update_avail; Slic3r::GUI::set_app_config($self->{app_config}); Slic3r::GUI::load_language(); @@ -123,6 +126,7 @@ sub OnInit { Slic3r::GUI::set_preset_bundle($self->{preset_bundle}); # application frame + print STDERR "Creating main frame...\n"; Wx::Image::FindHandlerType(wxBITMAP_TYPE_PNG) || Wx::Image::AddHandler(Wx::PNGHandler->new); $self->{mainframe} = my $frame = Slic3r::GUI::MainFrame->new( # If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden. @@ -145,9 +149,9 @@ sub OnInit { # before the UI was up and running. $self->CallAfter(sub { # XXX: recreate_GUI ??? - if ($slic3r_update) { - # TODO - } + # if ($slic3r_update) { + # # TODO + # } # XXX: ? if ($run_wizard) { # Run the config wizard, don't offer the "reset user profile" checkbox. @@ -159,6 +163,7 @@ sub OnInit { # The following event is emited by the C++ menu implementation of application language change. EVT_COMMAND($self, -1, $LANGUAGE_CHANGE_EVENT, sub{ + print STDERR "LANGUAGE_CHANGE_EVENT\n"; $self->recreate_GUI; }); @@ -179,6 +184,7 @@ sub OnInit { } sub recreate_GUI{ + print STDERR "recreate_GUI\n"; my ($self) = @_; my $topwindow = $self->GetTopWindow(); $self->{mainframe} = my $frame = Slic3r::GUI::MainFrame->new( diff --git a/xs/src/semver/semver.c b/xs/src/semver/semver.c index 3e4a30e3a0..0285fe40ef 100644 --- a/xs/src/semver/semver.c +++ b/xs/src/semver/semver.c @@ -632,4 +632,5 @@ semver_copy(const semver_t *ver) { if (ver->prerelease != NULL) { res.prerelease = strdup(ver->prerelease); } -} \ No newline at end of file + return res; +} diff --git a/xs/src/slic3r/Config/Version.cpp b/xs/src/slic3r/Config/Version.cpp index 95b3caf1a3..5430e569c4 100644 --- a/xs/src/slic3r/Config/Version.cpp +++ b/xs/src/slic3r/Config/Version.cpp @@ -141,7 +141,7 @@ size_t Index::load(const boost::filesystem::path &path) return m_configs.size(); } -Index::const_iterator Index::find(const Semver &ver) +Index::const_iterator Index::find(const Semver &ver) const { Version key; key.config_version = ver; @@ -163,12 +163,11 @@ Index::const_iterator Index::recommended() const std::vector Index::load_db() { - boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir()); - boost::filesystem::path vendor_dir = data_dir / "vendor"; + boost::filesystem::path cache_dir = boost::filesystem::path(Slic3r::data_dir()) / "cache"; std::vector index_db; std::string errors_cummulative; - for (auto &dir_entry : boost::filesystem::directory_iterator(vendor_dir)) + for (auto &dir_entry : boost::filesystem::directory_iterator(cache_dir)) if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".idx")) { Index idx; try { diff --git a/xs/src/slic3r/Config/Version.hpp b/xs/src/slic3r/Config/Version.hpp index 43512e82f5..c010a1748b 100644 --- a/xs/src/slic3r/Config/Version.hpp +++ b/xs/src/slic3r/Config/Version.hpp @@ -62,7 +62,7 @@ public: const_iterator begin() const { return m_configs.begin(); } const_iterator end() const { return m_configs.end(); } - const_iterator find(const Semver &ver); + const_iterator find(const Semver &ver) const; const std::vector& configs() const { return m_configs; } // Finds a recommended config to be installed for the current Slic3r version. // Returns configs().end() if such version does not exist in the index. This shall never happen diff --git a/xs/src/slic3r/GUI/AppConfig.hpp b/xs/src/slic3r/GUI/AppConfig.hpp index cac2759f1a..ffda083ec3 100644 --- a/xs/src/slic3r/GUI/AppConfig.hpp +++ b/xs/src/slic3r/GUI/AppConfig.hpp @@ -69,12 +69,13 @@ public: void clear_section(const std::string §ion) { m_storage[section].clear(); } + typedef std::map>> VendorMap; bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const; void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable); void set_vendors(const AppConfig &from); - void set_vendors(const std::map>> &vendors) { m_vendors = vendors; m_dirty = true; } - void set_vendors(std::map>> &&vendors) { m_vendors = std::move(vendors); m_dirty = true; } - const std::map>> vendors() const { return m_vendors; } + void set_vendors(const VendorMap &vendors) { m_vendors = vendors; m_dirty = true; } + void set_vendors(VendorMap &&vendors) { m_vendors = std::move(vendors); m_dirty = true; } + const VendorMap& vendors() const { return m_vendors; } // return recent/skein_directory or recent/config_directory or empty string. std::string get_last_dir() const; @@ -105,7 +106,7 @@ private: // Map of section, name -> value std::map> m_storage; // Map of enabled vendors / models / variants - std::map>> m_vendors; + VendorMap m_vendors; // Has any value been modified since the config.ini has been last saved or loaded? bool m_dirty; }; diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp index 52a896704d..f353ab7f7e 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,7 +17,6 @@ #include "GUI.hpp" #include "slic3r/Utils/PresetUpdater.hpp" -namespace fs = boost::filesystem; namespace Slic3r { namespace GUI { @@ -62,25 +61,25 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons auto namefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); namefont.SetWeight(wxFONTWEIGHT_BOLD); - for (auto model = models.cbegin(); model != models.cend(); ++model) { + for (const auto &model : models) { auto *panel = new wxPanel(this); auto *sizer = new wxBoxSizer(wxVERTICAL); panel->SetSizer(sizer); - auto *title = new wxStaticText(panel, wxID_ANY, model->name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + auto *title = new wxStaticText(panel, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); title->SetFont(namefont); sizer->Add(title, 0, wxBOTTOM, 3); - auto bitmap_file = wxString::Format("printers/%s_%s.png", vendor.id, model->id); + 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); sizer->AddSpacer(20); - const auto model_id = model->id; + const auto model_id = model.id; - for (const auto &variant : model->variants) { + 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); @@ -177,16 +176,18 @@ 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 vendor_prusa = std::find(vendors.cbegin(), vendors.cend(), VendorProfile("PrusaResearch")); + // 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->models; + const auto &models = vendor_prusa->second.models; AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors; - printer_picker = new PrinterPicker(this, *vendor_prusa, appconfig_vendors); + printer_picker = new PrinterPicker(this, vendor_prusa->second, appconfig_vendors); printer_picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) { appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable); this->on_variant_checked(); @@ -248,14 +249,17 @@ PageVendors::PageVendors(ConfigWizard *parent) : { append_text(_(L("Pick another vendor supported by Slic3r PE:"))); - const PresetBundle &bundle = wizard_p()->bundle_vendors; + // const PresetBundle &bundle = wizard_p()->bundle_vendors; + // const auto &vendors = wizard_p()->vendors; auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); boldfont.SetWeight(wxFONTWEIGHT_BOLD); AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors; wxArrayString choices_vendors; - for (const auto &vendor : bundle.vendors) { + // for (const auto &vendor : vendors) { + for (const auto vendor_pair : wizard_p()->vendors) { + const auto &vendor = vendor_pair.second; if (vendor.id == "PrusaResearch") { continue; } auto *picker = new PrinterPicker(this, vendor, appconfig_vendors); @@ -549,9 +553,25 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) void ConfigWizard::priv::load_vendors() { const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor"; + const auto rsrc_vendor_dir = fs::path(resources_dir()) / "profiles"; + + // Load vendors from the "vendors" directory in datadir for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) { if (it->path().extension() == ".ini") { - bundle_vendors.load_configbundle(it->path().string(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY); + auto vp = VendorProfile::from_ini(it->path()); + vendors[vp.id] = std::move(vp); + } + } + + // Additionally load up vendors from the application resources directory, but only those not seen in the datadir + for (fs::directory_iterator it(rsrc_vendor_dir); it != fs::directory_iterator(); ++it) { + if (it->path().extension() == ".ini") { + 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[vp.id] = std::move(vp); + } } } @@ -624,6 +644,19 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese const bool is_custom_setup = page_welcome->page_next() == page_firmware; if (! is_custom_setup) { + const auto enabled_vendors = appconfig_vendors.vendors(); + 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); + } + app_config->set_vendors(appconfig_vendors); app_config->set("version_check", page_update->version_check ? "1" : "0"); app_config->set("preset_update", page_update->preset_update ? "1" : "0"); diff --git a/xs/src/slic3r/GUI/ConfigWizard_private.hpp b/xs/src/slic3r/GUI/ConfigWizard_private.hpp index 652328aaad..137b276b85 100644 --- a/xs/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/xs/src/slic3r/GUI/ConfigWizard_private.hpp @@ -4,6 +4,9 @@ #include "ConfigWizard.hpp" #include +#include +#include +#include #include #include @@ -13,13 +16,16 @@ #include "libslic3r/PrintConfig.hpp" #include "AppConfig.hpp" -#include "PresetBundle.hpp" +#include "Preset.hpp" +// #include "PresetBundle.hpp" #include "BedShapeDialog.hpp" +namespace fs = boost::filesystem; namespace Slic3r { namespace GUI { +// typedef std::unordered_map VendorMap; enum { CONTENT_WIDTH = 500, @@ -168,7 +174,9 @@ struct ConfigWizard::priv { ConfigWizard *q; AppConfig appconfig_vendors; - PresetBundle bundle_vendors; + // PresetBundle bundle_vendors; + std::unordered_map vendors; + std::unordered_map vendors_rsrc; std::unique_ptr custom_config; wxBoxSizer *topsizer = nullptr; diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 39bfbd3981..26f0ff5947 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -5,6 +5,8 @@ #include "AppConfig.hpp" #include +#include +#include #include #include #include @@ -75,6 +77,11 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem { static const std::string printer_model_key = "printer_model:"; const std::string id = path.stem().string(); + + if (! boost::filesystem::exists(path)) { + throw std::runtime_error((boost::format("Cannot load Vendor Config Bundle `%1%`: File not found: `%2%`.") % id % path).str()); + } + VendorProfile res(id); auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp index d6ccfd4505..8855bf1e78 100644 --- a/xs/src/slic3r/GUI/Preset.hpp +++ b/xs/src/slic3r/GUI/Preset.hpp @@ -58,7 +58,8 @@ public: }; std::vector models; - VendorProfile(std::string id) : id(std::move(id)), config_version(0, 0, 0) {} + VendorProfile() {} + VendorProfile(std::string id) : id(std::move(id)) {} static VendorProfile from_ini(const boost::filesystem::path &path, bool load_all=true); static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true); diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index ad27bf8c68..d1d66df60a 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -701,8 +701,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla const VendorProfile *vendor_profile = nullptr; if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) { - boost::filesystem::path fspath(path); - auto vp = VendorProfile::from_ini(tree, fspath.stem().string()); + auto vp = VendorProfile::from_ini(tree, path); if (vp.num_variants() == 0) return 0; vendor_profile = &(*this->vendors.insert(vp).first); diff --git a/xs/src/slic3r/Utils/PresetUpdater.cpp b/xs/src/slic3r/Utils/PresetUpdater.cpp index a16a6d8894..28b9773213 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.cpp +++ b/xs/src/slic3r/Utils/PresetUpdater.cpp @@ -1,21 +1,32 @@ #include "PresetUpdater.hpp" +#include // XXX +#include #include +#include #include #include #include #include #include +#include #include "libslic3r/Utils.hpp" #include "slic3r/GUI/GUI.hpp" #include "slic3r/GUI/PresetBundle.hpp" #include "slic3r/Utils/Http.hpp" -#include "slic3r/Utils/Semver.hpp" +#include "slic3r/Config/Version.hpp" +#include "slic3r/Config/Snapshot.hpp" namespace fs = boost::filesystem; +using Slic3r::GUI::Config::Index; +using Slic3r::GUI::Config::Version; +using Slic3r::GUI::Config::Snapshot; +using Slic3r::GUI::Config::SnapshotDB; +// XXX: Prevent incomplete file downloads: download a tmp file, then move +// Delete incomplete ones on startup. namespace Slic3r { @@ -27,26 +38,55 @@ enum { SLIC3R_VERSION_BODY_MAX = 256, }; + +struct Update +{ + fs::path source; + fs::path target; + Version version; + + Update(const fs::path &source, fs::path &&target, const Version &version) : + source(source), + target(std::move(target)), + version(version) + {} + + std::string name() { return source.stem().string(); } +}; + +typedef std::vector Updates; + + struct PresetUpdater::priv { int version_online_event; + AppConfig *app_config; bool version_check; bool preset_update; fs::path cache_path; + fs::path rsrc_path; + fs::path vendor_path; + bool cancel; std::thread thread; - priv(int event); + priv(int event, AppConfig *app_config); void download(const std::set vendors) const; + + void check_install_indices() const; + Updates config_update() const; }; -PresetUpdater::priv::priv(int event) : +PresetUpdater::priv::priv(int event, AppConfig *app_config) : version_online_event(event), + app_config(app_config), version_check(false), preset_update(false), cache_path(fs::path(Slic3r::data_dir()) / "cache"), + rsrc_path(fs::path(resources_dir()) / "profiles"), + vendor_path(fs::path(Slic3r::data_dir()) / "vendor"), cancel(false) {} @@ -91,11 +131,119 @@ void PresetUpdater::priv::download(const std::set vendors) const } } +void PresetUpdater::priv::check_install_indices() const +{ + for (fs::directory_iterator it(rsrc_path); it != fs::directory_iterator(); ++it) { + const auto &path = it->path(); + if (path.extension() == ".idx") { + const auto path_in_cache = cache_path / path.filename(); + + // TODO: compare versions + if (! fs::exists(path_in_cache)) { + fs::copy_file(path, path_in_cache, fs::copy_option::overwrite_if_exists); + } + } + } +} + +Updates PresetUpdater::priv::config_update() const +{ + priv::check_install_indices(); + const auto index_db = Index::load_db(); // TODO: Keep in Snapshots singleton? + + Updates updates; + + for (const auto idx : index_db) { + const auto bundle_path = vendor_path / (idx.vendor() + ".ini"); + + // If the bundle doesn't exist at all, update from resources + // if (! fs::exists(bundle_path)) { + // auto path_in_rsrc = rsrc_path / (idx.vendor() + ".ini"); + + // // Otherwise load it and check for chached updates + // const auto rsrc_vp = VendorProfile::from_ini(path_in_rsrc, false); + + // const auto rsrc_ver = idx.find(rsrc_vp.config_version); + // if (rsrc_ver == idx.end()) { + // // TODO: throw + // } + + // if (fs::exists(path_in_rsrc)) { + // updates.emplace_back(bundle_path, std::move(path_in_rsrc), *rsrc_ver); + // } else { + // // XXX: ??? + // } + + // continue; + // } + + if (! fs::exists(bundle_path)) { + continue; + } + + // Perform a basic load and check the version + const auto vp = VendorProfile::from_ini(bundle_path, false); + + const auto ver_current = idx.find(vp.config_version); + if (ver_current == idx.end()) { + // TODO: throw + } + + const auto recommended = idx.recommended(); + if (recommended == idx.end()) { + // TODO: throw + } + + if (! ver_current->is_current_slic3r_supported()) { + + // TODO: Downgrade situation + + } else if (recommended->config_version > ver_current->config_version) { + // Config bundle update situation + + auto path_in_cache = cache_path / (idx.vendor() + ".ini"); + const auto cached_vp = VendorProfile::from_ini(path_in_cache, false); + if (cached_vp.config_version == recommended->config_version) { + updates.emplace_back(bundle_path, std::move(path_in_cache), *ver_current); + } else { + // XXX: ??? + } + } + } + + // Check for bundles that don't have an index + // for (fs::directory_iterator it(rsrc_path); it != fs::directory_iterator(); ++it) { + // if (it->path().extension() == ".ini") { + // const auto &path = it->path(); + // const auto vendor_id = path.stem().string(); + + // const auto needle = std::find_if(index_db.begin(), index_db.end(), [&vendor_id](const Index &idx) { + // return idx.vendor() == vendor_id; + // }); + // if (needle != index_db.end()) { + // continue; + // } + + // auto vp = VendorProfile::from_ini(path, false); + // auto path_in_data = vendor_path / path.filename(); + + // if (! fs::exists(path_in_data)) { + // Version version; + // version.config_version = vp.config_version; + // updates.emplace_back(path, std::move(path_in_data), version); + // } + // } + // } + + return updates; +} + + PresetUpdater::PresetUpdater(int version_online_event, AppConfig *app_config) : - p(new priv(version_online_event)) + p(new priv(version_online_event, app_config)) { p->preset_update = app_config->get("preset_update") == "1"; - // preset_update implies version_check: + // preset_update implies version_check: // XXX: not any more p->version_check = p->preset_update || app_config->get("version_check") == "1"; } @@ -123,19 +271,49 @@ void PresetUpdater::download(PresetBundle *preset_bundle) })); } -void PresetUpdater::init_vendors() +void PresetUpdater::config_update() { - const auto vendors_rources = fs::path(resources_dir()) / "profiles"; - const auto vendors_data = fs::path(Slic3r::data_dir()) / "vendor"; + const auto updates = p->config_update(); + if (updates.size() > 0) { + const auto msg = _(L("Configuration update is available. Would you like to install it?")); - for (fs::directory_iterator it(vendors_rources); it != fs::directory_iterator(); ++it) { - if (it->path().extension() == ".ini") { - auto vp = VendorProfile::from_ini(it->path(), false); - const auto path_in_data = vendors_data / it->path().filename(); + auto ext_msg = _(L( + "Note that a full configuration snapshot will be created first. It can then be restored at any time " + "should there be a problem with the new version.\n\n" + "Updated configuration bundles:\n" + )); - if (! fs::exists(path_in_data) || VendorProfile::from_ini(path_in_data, false).config_version < vp.config_version) { - // FIXME: update vendor bundle properly when snapshotting is ready - PresetBundle::install_vendor_configbundle(it->path()); + for (const auto &update : updates) { + ext_msg += update.target.stem().string() + " " + update.version.config_version.to_string(); + if (! update.version.comment.empty()) { + ext_msg += std::string(" (") + update.version.comment + ")"; + } + ext_msg += "\n"; + } + + wxMessageDialog dlg(NULL, msg, _(L("Configuration update")), wxYES_NO|wxCENTRE); + dlg.SetExtendedMessage(ext_msg); + const auto res = dlg.ShowModal(); + std::cerr << "After modal" << std::endl; + if (res == wxID_YES) { + // User gave clearance, updates are go + + // TODO: Comment? + SnapshotDB::singleton().take_snapshot(*p->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); } } } } diff --git a/xs/src/slic3r/Utils/PresetUpdater.hpp b/xs/src/slic3r/Utils/PresetUpdater.hpp index b10c61784b..8fd6e45289 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.hpp +++ b/xs/src/slic3r/Utils/PresetUpdater.hpp @@ -21,7 +21,7 @@ public: void download(PresetBundle *preset_bundle); // XXX - static void init_vendors(); + void config_update(); private: struct priv; std::unique_ptr p; diff --git a/xs/src/slic3r/Utils/Semver.hpp b/xs/src/slic3r/Utils/Semver.hpp index a1f4a92e86..2c27ce9826 100644 --- a/xs/src/slic3r/Utils/Semver.hpp +++ b/xs/src/slic3r/Utils/Semver.hpp @@ -11,7 +11,6 @@ namespace Slic3r { -// FIXME:: operators=: leak, return class Semver { @@ -20,6 +19,8 @@ public: struct Minor { const int i; Minor(int i) : i(i) {} }; struct Patch { const int i; Patch(int i) : i(i) {} }; + Semver() : ver(semver_zero()) {} + Semver(int major, int minor, int patch, boost::optional metadata = boost::none, boost::optional prerelease = boost::none) diff --git a/xs/xsp/Utils_PresetUpdater.xsp b/xs/xsp/Utils_PresetUpdater.xsp index 1cb9f1c39e..4c1a637e49 100644 --- a/xs/xsp/Utils_PresetUpdater.xsp +++ b/xs/xsp/Utils_PresetUpdater.xsp @@ -8,5 +8,5 @@ %name{Slic3r::PresetUpdater} class PresetUpdater { PresetUpdater(int version_online_event, AppConfig *app_config); void download(PresetBundle* preset_bundle); - static void init_vendors(); + void config_update(); };