Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_perspective_camera
This commit is contained in:
commit
c5e4ada75b
20 changed files with 169 additions and 89 deletions
|
@ -729,7 +729,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
|
||||
m_placeholder_parser = print.placeholder_parser();
|
||||
m_placeholder_parser.update_timestamp();
|
||||
print.update_object_placeholders(m_placeholder_parser.config_writable());
|
||||
print.update_object_placeholders(m_placeholder_parser.config_writable(), ".gcode");
|
||||
|
||||
// Get optimal tool ordering to minimize tool switches of a multi-exruder print.
|
||||
// For a print by objects, find the 1st printing object.
|
||||
|
|
|
@ -1875,12 +1875,12 @@ int Print::get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion
|
|||
// Generate a recommended G-code output file name based on the format template, default extension, and template parameters
|
||||
// (timestamps, object placeholders derived from the model, current placeholder prameters and print statistics.
|
||||
// Use the final print statistics if available, or just keep the print statistics placeholders if not available yet (before G-code is finalized).
|
||||
std::string Print::output_filename() const
|
||||
std::string Print::output_filename(const std::string &filename_base) const
|
||||
{
|
||||
// Set the placeholders for the data know first after the G-code export is finished.
|
||||
// These values will be just propagated into the output file name.
|
||||
DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders();
|
||||
return this->PrintBase::output_filename(m_config.output_filename_format.value, "gcode", &config);
|
||||
return this->PrintBase::output_filename(m_config.output_filename_format.value, ".gcode", filename_base, &config);
|
||||
}
|
||||
/*
|
||||
// Shorten the dhms time by removing the seconds, rounding the dhm to full minutes
|
||||
|
|
|
@ -351,7 +351,7 @@ public:
|
|||
bool has_wipe_tower() const;
|
||||
const WipeTowerData& wipe_tower_data() const { return m_wipe_tower_data; }
|
||||
|
||||
std::string output_filename() const override;
|
||||
std::string output_filename(const std::string &filename_base = std::string()) const override;
|
||||
|
||||
// Accessed by SupportMaterial
|
||||
const PrintRegion* get_region(size_t idx) const { return m_regions[idx]; }
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Slic3r
|
|||
size_t PrintStateBase::g_last_timestamp = 0;
|
||||
|
||||
// Update "scale", "input_filename", "input_filename_base" placeholders from the current m_objects.
|
||||
void PrintBase::update_object_placeholders(DynamicConfig &config) const
|
||||
void PrintBase::update_object_placeholders(DynamicConfig &config, const std::string &default_ext) const
|
||||
{
|
||||
// get the first input file name
|
||||
std::string input_file;
|
||||
|
@ -40,25 +40,29 @@ void PrintBase::update_object_placeholders(DynamicConfig &config) const
|
|||
config.set_key_value("year", new ConfigOptionStrings(v_scale));
|
||||
if (! input_file.empty()) {
|
||||
// get basename with and without suffix
|
||||
const std::string input_basename = boost::filesystem::path(input_file).filename().string();
|
||||
config.set_key_value("input_filename", new ConfigOptionString(input_basename));
|
||||
const std::string input_basename_base = input_basename.substr(0, input_basename.find_last_of("."));
|
||||
config.set_key_value("input_filename_base", new ConfigOptionString(input_basename_base));
|
||||
const std::string input_filename = boost::filesystem::path(input_file).filename().string();
|
||||
const std::string input_filename_base = input_filename.substr(0, input_filename.find_last_of("."));
|
||||
config.set_key_value("input_filename", new ConfigOptionString(input_filename_base + default_ext));
|
||||
config.set_key_value("input_filename_base", new ConfigOptionString(input_filename_base));
|
||||
}
|
||||
}
|
||||
|
||||
// Generate an output file name based on the format template, default extension, and template parameters
|
||||
// (timestamps, object placeholders derived from the model, current placeholder prameters, print statistics - config_override)
|
||||
std::string PrintBase::output_filename(const std::string &format, const std::string &default_ext, const DynamicConfig *config_override) const
|
||||
std::string PrintBase::output_filename(const std::string &format, const std::string &default_ext, const std::string &filename_base, const DynamicConfig *config_override) const
|
||||
{
|
||||
DynamicConfig cfg;
|
||||
if (config_override != nullptr)
|
||||
cfg = *config_override;
|
||||
PlaceholderParser::update_timestamp(cfg);
|
||||
this->update_object_placeholders(cfg);
|
||||
this->update_object_placeholders(cfg, default_ext);
|
||||
if (! filename_base.empty()) {
|
||||
cfg.set_key_value("input_filename", new ConfigOptionString(filename_base + default_ext));
|
||||
cfg.set_key_value("input_filename_base", new ConfigOptionString(filename_base));
|
||||
}
|
||||
try {
|
||||
boost::filesystem::path filename = format.empty() ?
|
||||
cfg.opt_string("input_filename_base") + "." + default_ext :
|
||||
cfg.opt_string("input_filename_base") + default_ext :
|
||||
this->placeholder_parser().process(format, 0, &cfg);
|
||||
if (filename.extension().empty())
|
||||
filename = boost::filesystem::change_extension(filename, default_ext);
|
||||
|
@ -68,17 +72,17 @@ std::string PrintBase::output_filename(const std::string &format, const std::str
|
|||
}
|
||||
}
|
||||
|
||||
std::string PrintBase::output_filepath(const std::string &path) const
|
||||
std::string PrintBase::output_filepath(const std::string &path, const std::string &filename_base) const
|
||||
{
|
||||
// if we were supplied no path, generate an automatic one based on our first object's input file
|
||||
if (path.empty())
|
||||
// get the first input file name
|
||||
return (boost::filesystem::path(m_model.propose_export_file_name_and_path()).parent_path() / this->output_filename()).make_preferred().string();
|
||||
return (boost::filesystem::path(m_model.propose_export_file_name_and_path()).parent_path() / this->output_filename(filename_base)).make_preferred().string();
|
||||
|
||||
// if we were supplied a directory, use it and append our automatically generated filename
|
||||
boost::filesystem::path p(path);
|
||||
if (boost::filesystem::is_directory(p))
|
||||
return (p / this->output_filename()).make_preferred().string();
|
||||
return (p / this->output_filename(filename_base)).make_preferred().string();
|
||||
|
||||
// if we were supplied a file which is not a directory, use it
|
||||
return path;
|
||||
|
|
|
@ -318,8 +318,10 @@ public:
|
|||
const PlaceholderParser& placeholder_parser() const { return m_placeholder_parser; }
|
||||
PlaceholderParser& placeholder_parser() { return m_placeholder_parser; }
|
||||
|
||||
virtual std::string output_filename() const = 0;
|
||||
std::string output_filepath(const std::string &path) const;
|
||||
virtual std::string output_filename(const std::string &filename_base = std::string()) const = 0;
|
||||
// If the filename_base is set, it is used as the input for the template processing. In that case the path is expected to be the directory (may be empty).
|
||||
// If filename_set is empty, than the path may be a file or directory. If it is a file, then the macro will not be processed.
|
||||
std::string output_filepath(const std::string &path, const std::string &filename_base = std::string()) const;
|
||||
|
||||
protected:
|
||||
friend class PrintObjectBase;
|
||||
|
@ -334,9 +336,9 @@ protected:
|
|||
void throw_if_canceled() const { if (m_cancel_status) throw CanceledException(); }
|
||||
|
||||
// To be called by this->output_filename() with the format string pulled from the configuration layer.
|
||||
std::string output_filename(const std::string &format, const std::string &default_ext, const DynamicConfig *config_override = nullptr) const;
|
||||
std::string output_filename(const std::string &format, const std::string &default_ext, const std::string &filename_base, const DynamicConfig *config_override = nullptr) const;
|
||||
// Update "scale", "input_filename", "input_filename_base" placeholders from the current printable ModelObjects.
|
||||
void update_object_placeholders(DynamicConfig &config) const;
|
||||
void update_object_placeholders(DynamicConfig &config, const std::string &default_ext) const;
|
||||
|
||||
Model m_model;
|
||||
|
||||
|
|
|
@ -561,10 +561,10 @@ void SLAPrint::finalize()
|
|||
// Generate a recommended output file name based on the format template, default extension, and template parameters
|
||||
// (timestamps, object placeholders derived from the model, current placeholder prameters and print statistics.
|
||||
// Use the final print statistics if available, or just keep the print statistics placeholders if not available yet (before the output is finalized).
|
||||
std::string SLAPrint::output_filename() const
|
||||
std::string SLAPrint::output_filename(const std::string &filename_base) const
|
||||
{
|
||||
DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders();
|
||||
return this->PrintBase::output_filename(m_print_config.output_filename_format.value, "sl1", &config);
|
||||
return this->PrintBase::output_filename(m_print_config.output_filename_format.value, ".sl1", filename_base, &config);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -402,9 +402,9 @@ public:
|
|||
// Extracted value from the configuration objects
|
||||
Vec3d relative_correction() const;
|
||||
|
||||
std::string output_filename() const override;
|
||||
std::string output_filename(const std::string &filename_base = std::string()) const override;
|
||||
|
||||
const SLAPrintStatistics& print_statistics() const { return m_print_statistics; }
|
||||
const SLAPrintStatistics& print_statistics() const { return m_print_statistics; }
|
||||
|
||||
std::string validate() const override;
|
||||
|
||||
|
|
|
@ -67,6 +67,14 @@ PrinterTechnology BackgroundSlicingProcess::current_printer_technology() const
|
|||
return m_print->technology();
|
||||
}
|
||||
|
||||
std::string BackgroundSlicingProcess::output_filepath_for_project(const boost::filesystem::path &project_path)
|
||||
{
|
||||
assert(m_print != nullptr);
|
||||
if (project_path.empty())
|
||||
return m_print->output_filepath("");
|
||||
return m_print->output_filepath(project_path.parent_path().string(), project_path.stem().string());
|
||||
}
|
||||
|
||||
// This function may one day be merged into the Print, but historically the print was separated
|
||||
// from the G-code generator.
|
||||
void BackgroundSlicingProcess::process_fff()
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
#include "libslic3r/Print.hpp"
|
||||
|
@ -65,6 +67,9 @@ public:
|
|||
const PrintBase* current_print() const { return m_print; }
|
||||
const Print* fff_print() const { return m_fff_print; }
|
||||
const SLAPrint* sla_print() const { return m_sla_print; }
|
||||
// Take the project path (if provided), extract the name of the project, run it through the macro processor and save it next to the project file.
|
||||
// If the project_path is empty, just run output_filepath().
|
||||
std::string output_filepath_for_project(const boost::filesystem::path &project_path);
|
||||
|
||||
// Start the background processing. Returns false if the background processing was already running.
|
||||
bool start();
|
||||
|
|
|
@ -183,9 +183,13 @@ bool GUI_App::on_init_inner()
|
|||
// supplied as argument to --datadir; in that case we should still run the wizard
|
||||
preset_bundle->setup_directories();
|
||||
|
||||
app_conf_exists = app_config->exists();
|
||||
// load settings
|
||||
if (app_config->exists())
|
||||
app_conf_exists = app_config->exists();
|
||||
if (app_conf_exists) {
|
||||
app_config->load();
|
||||
}
|
||||
|
||||
app_config->set("version", SLIC3R_VERSION);
|
||||
app_config->save();
|
||||
|
||||
|
@ -248,16 +252,20 @@ bool GUI_App::on_init_inner()
|
|||
if (once) {
|
||||
once = false;
|
||||
|
||||
PresetUpdater::UpdateResult updater_result;
|
||||
try {
|
||||
if (!preset_updater->config_update()) {
|
||||
updater_result = preset_updater->config_update();
|
||||
if (updater_result == PresetUpdater::R_INCOMPAT_EXIT) {
|
||||
mainframe->Close();
|
||||
} else if (updater_result == PresetUpdater::R_INCOMPAT_CONFIGURED) {
|
||||
app_conf_exists = true;
|
||||
}
|
||||
} catch (const std::exception &ex) {
|
||||
show_error(nullptr, from_u8(ex.what()));
|
||||
}
|
||||
|
||||
CallAfter([this] {
|
||||
if (!config_wizard_startup(app_config->exists())) {
|
||||
if (!config_wizard_startup(app_conf_exists)) {
|
||||
// Only notify if there was no wizard so as not to bother too much ...
|
||||
preset_updater->slic3r_update_notify();
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ static wxString dots("…", wxConvUTF8);
|
|||
class GUI_App : public wxApp
|
||||
{
|
||||
bool m_initialized { false };
|
||||
bool app_conf_exists{ false };
|
||||
|
||||
wxColour m_color_label_modified;
|
||||
wxColour m_color_label_sys;
|
||||
|
|
|
@ -74,7 +74,7 @@ void ImGuiWrapper::set_language(const std::string &language)
|
|||
ranges = ImGui::GetIO().Fonts->GetGlyphRangesCyrillic();
|
||||
} else if (lang == "jp") {
|
||||
ranges = ImGui::GetIO().Fonts->GetGlyphRangesJapanese();
|
||||
} else if (lang == "kr") {
|
||||
} else if (lang == "ko") {
|
||||
ranges = ImGui::GetIO().Fonts->GetGlyphRangesKorean();
|
||||
} else if (lang == "zh") {
|
||||
ranges = ImGui::GetIO().Fonts->GetGlyphRangesChineseSimplifiedCommon();
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
|
@ -671,7 +669,8 @@ Sidebar::Sidebar(Plater *parent)
|
|||
auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
combo_and_btn_sizer->Add(*combo, 1, wxEXPAND);
|
||||
if ((*combo)->edit_btn)
|
||||
combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxLEFT|wxRIGHT, int(0.3*wxGetApp().em_unit()));
|
||||
combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT,
|
||||
int(0.3*wxGetApp().em_unit()));
|
||||
|
||||
auto *sizer_presets = this->p->sizer_presets;
|
||||
auto *sizer_filaments = this->p->sizer_filaments;
|
||||
|
@ -777,7 +776,8 @@ void Sidebar::init_filament_combo(PresetComboBox **combo, const int extr_idx) {
|
|||
|
||||
auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
combo_and_btn_sizer->Add(*combo, 1, wxEXPAND);
|
||||
combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxLEFT | wxRIGHT, int(0.3*wxGetApp().em_unit()));
|
||||
combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
|
||||
int(0.3*wxGetApp().em_unit()));
|
||||
|
||||
auto /***/sizer_filaments = this->p->sizer_filaments;
|
||||
sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | wxBOTTOM, 1);
|
||||
|
@ -2971,9 +2971,16 @@ wxString Plater::priv::get_project_filename(const wxString& extension) const
|
|||
void Plater::priv::set_project_filename(const wxString& filename)
|
||||
{
|
||||
boost::filesystem::path full_path = into_path(filename);
|
||||
// remove extension
|
||||
while (full_path.has_extension())
|
||||
{
|
||||
boost::filesystem::path ext = full_path.extension();
|
||||
if (boost::iequals(ext.string(), ".amf")) {
|
||||
// Remove the first extension.
|
||||
full_path.replace_extension("");
|
||||
// It may be ".zip.amf".
|
||||
if (boost::iequals(full_path.extension().string(), ".zip"))
|
||||
// Remove the 2nd extension.
|
||||
full_path.replace_extension("");
|
||||
} else {
|
||||
// Remove just one extension.
|
||||
full_path.replace_extension("");
|
||||
}
|
||||
|
||||
|
@ -3492,7 +3499,7 @@ void Plater::export_gcode()
|
|||
unsigned int state = this->p->update_restart_background_process(false, false);
|
||||
if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID)
|
||||
return;
|
||||
default_output_file = this->p->background_process.current_print()->output_filepath(into_path(get_project_filename()).string());
|
||||
default_output_file = this->p->background_process.output_filepath_for_project(into_path(get_project_filename(".3mf")));
|
||||
}
|
||||
catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
|
@ -3737,7 +3744,7 @@ void Plater::send_gcode()
|
|||
unsigned int state = this->p->update_restart_background_process(false, false);
|
||||
if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID)
|
||||
return;
|
||||
default_output_file = this->p->background_process.current_print()->output_filepath(into_path(get_project_filename(".3mf")).string());
|
||||
default_output_file = this->p->background_process.output_filepath_for_project(into_path(get_project_filename(".3mf")));
|
||||
}
|
||||
catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "wxExtensions.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
@ -19,6 +20,7 @@
|
|||
#include "libslic3r/GCode/PreviewData.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "../Utils/MacDarkMode.hpp"
|
||||
|
||||
using Slic3r::GUI::from_u8;
|
||||
|
||||
|
@ -389,7 +391,15 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in,
|
|||
static Slic3r::GUI::BitmapCache cache;
|
||||
|
||||
#ifdef __APPLE__
|
||||
const float scale_factor = win != nullptr ? win->GetContentScaleFactor() : 1.0f;
|
||||
// Note: win->GetContentScaleFactor() is not used anymore here because it tends to
|
||||
// return bogus results quite often (such as 1.0 on Retina or even 0.0).
|
||||
// We're using the max scaling factor across all screens because it's very likely to be good enough.
|
||||
|
||||
static float max_scaling_factor = NAN;
|
||||
if (std::isnan(max_scaling_factor)) {
|
||||
max_scaling_factor = Slic3r::GUI::mac_max_scaling_factor();
|
||||
}
|
||||
const float scale_factor = win != nullptr ? max_scaling_factor : 1.0f;
|
||||
#else
|
||||
(void)(win);
|
||||
const float scale_factor = 1.0f;
|
||||
|
@ -2656,7 +2666,7 @@ ScalableButton::ScalableButton( wxWindow * parent,
|
|||
if (style & wxNO_BORDER)
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
#endif // __WXMSW__
|
||||
|
||||
|
||||
SetBitmap(create_scaled_bitmap(parent, icon_name));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace GUI {
|
|||
|
||||
#if __APPLE__
|
||||
extern bool mac_dark_mode();
|
||||
extern double mac_max_scaling_factor();
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#import "MacDarkMode.hpp"
|
||||
|
||||
#import <algorithm>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/NSScreen.h>
|
||||
|
||||
|
||||
@implementation MacDarkMode
|
||||
|
@ -15,6 +18,17 @@ bool mac_dark_mode()
|
|||
|
||||
}
|
||||
|
||||
double mac_max_scaling_factor()
|
||||
{
|
||||
double scaling = 1.;
|
||||
if ([NSScreen screens] == nil) {
|
||||
scaling = [[NSScreen mainScreen] backingScaleFactor];
|
||||
} else {
|
||||
for (int i = 0; i < [[NSScreen screens] count]; ++ i)
|
||||
scaling = std::max<double>(scaling, [[[NSScreen screens] objectAtIndex:0] backingScaleFactor]);
|
||||
}
|
||||
return scaling;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -567,9 +567,9 @@ void PresetUpdater::slic3r_update_notify()
|
|||
}
|
||||
}
|
||||
|
||||
bool PresetUpdater::config_update() const
|
||||
PresetUpdater::UpdateResult PresetUpdater::config_update() const
|
||||
{
|
||||
if (! p->enabled_config_update) { return true; }
|
||||
if (! p->enabled_config_update) { return R_NOOP; }
|
||||
|
||||
auto updates = p->get_config_updates();
|
||||
if (updates.incompats.size() > 0) {
|
||||
|
@ -603,15 +603,15 @@ bool PresetUpdater::config_update() const
|
|||
p->perform_updates(std::move(updates));
|
||||
GUI::ConfigWizard wizard(nullptr, GUI::ConfigWizard::RR_DATA_INCOMPAT);
|
||||
if (! wizard.run(GUI::wxGetApp().preset_bundle, this)) {
|
||||
return false;
|
||||
return R_INCOMPAT_EXIT;
|
||||
}
|
||||
GUI::wxGetApp().load_current_presets();
|
||||
return R_INCOMPAT_CONFIGURED;
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "User wants to exit Slic3r, bye...";
|
||||
return false;
|
||||
return R_INCOMPAT_EXIT;
|
||||
}
|
||||
}
|
||||
else if (updates.updates.size() > 0) {
|
||||
} else if (updates.updates.size() > 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Update of %1% bundles available. Asking for confirmation ...") % updates.updates.size();
|
||||
|
||||
std::vector<GUI::MsgUpdateConfig::Update> updates_msg;
|
||||
|
@ -633,14 +633,16 @@ bool PresetUpdater::config_update() const
|
|||
auto *app_config = GUI::wxGetApp().app_config;
|
||||
GUI::wxGetApp().preset_bundle->load_presets(*app_config);
|
||||
GUI::wxGetApp().load_current_presets();
|
||||
return R_UPDATE_INSTALLED;
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "User refused the update";
|
||||
return R_UPDATE_REJECT;
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "No configuration updates available.";
|
||||
}
|
||||
|
||||
return true;
|
||||
return R_NOOP;
|
||||
}
|
||||
|
||||
void PresetUpdater::install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot) const
|
||||
|
|
|
@ -28,9 +28,17 @@ public:
|
|||
// If version check is enabled, check if chaced online slic3r version is newer, notify if so.
|
||||
void slic3r_update_notify();
|
||||
|
||||
enum UpdateResult {
|
||||
R_NOOP,
|
||||
R_INCOMPAT_EXIT,
|
||||
R_INCOMPAT_CONFIGURED,
|
||||
R_UPDATE_INSTALLED,
|
||||
R_UPDATE_REJECT,
|
||||
};
|
||||
|
||||
// If updating is enabled, check if updates are available in cache, if so, ask about installation.
|
||||
// A false return value implies Slic3r should exit due to incompatibility of configuration.
|
||||
bool config_update() const;
|
||||
UpdateResult config_update() const;
|
||||
|
||||
// "Update" a list of bundles from resources (behaves like an online update).
|
||||
void install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot = true) const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue