2017-09-19 11:55:48 +00:00
|
|
|
#ifndef slic3r_Preset_hpp_
|
|
|
|
#define slic3r_Preset_hpp_
|
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
#include <deque>
|
|
|
|
|
2018-04-11 11:12:08 +00:00
|
|
|
#include <boost/filesystem/path.hpp>
|
|
|
|
#include <boost/property_tree/ptree_fwd.hpp>
|
|
|
|
|
2018-12-04 16:56:49 +00:00
|
|
|
#include "libslic3r/libslic3r.h"
|
|
|
|
#include "libslic3r/PrintConfig.hpp"
|
2018-04-11 11:12:08 +00:00
|
|
|
#include "slic3r/Utils/Semver.hpp"
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
class wxBitmap;
|
2017-10-25 10:53:31 +00:00
|
|
|
class wxChoice;
|
2017-09-19 11:55:48 +00:00
|
|
|
class wxBitmapComboBox;
|
2017-10-25 10:53:31 +00:00
|
|
|
class wxItemContainer;
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
namespace Slic3r {
|
|
|
|
|
2018-03-29 15:54:43 +00:00
|
|
|
class AppConfig;
|
2018-04-13 12:49:33 +00:00
|
|
|
class PresetBundle;
|
2018-03-29 15:54:43 +00:00
|
|
|
|
2018-04-19 10:08:59 +00:00
|
|
|
namespace GUI {
|
|
|
|
class BitmapCache;
|
2018-10-09 10:41:05 +00:00
|
|
|
class PresetComboBox;
|
2018-04-19 10:08:59 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 18:30:05 +00:00
|
|
|
enum ConfigFileType
|
|
|
|
{
|
|
|
|
CONFIG_FILE_TYPE_UNKNOWN,
|
|
|
|
CONFIG_FILE_TYPE_APP_CONFIG,
|
|
|
|
CONFIG_FILE_TYPE_CONFIG,
|
|
|
|
CONFIG_FILE_TYPE_CONFIG_BUNDLE,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree);
|
|
|
|
|
2018-03-09 15:37:33 +00:00
|
|
|
class VendorProfile
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
std::string name;
|
|
|
|
std::string id;
|
2018-04-11 11:12:08 +00:00
|
|
|
Semver config_version;
|
2018-03-09 15:37:33 +00:00
|
|
|
std::string config_update_url;
|
|
|
|
|
|
|
|
struct PrinterVariant {
|
|
|
|
PrinterVariant() {}
|
|
|
|
PrinterVariant(const std::string &name) : name(name) {}
|
|
|
|
std::string name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrinterModel {
|
|
|
|
PrinterModel() {}
|
2018-03-13 11:39:57 +00:00
|
|
|
std::string id;
|
2018-03-09 15:37:33 +00:00
|
|
|
std::string name;
|
2018-07-31 13:09:57 +00:00
|
|
|
PrinterTechnology technology;
|
2018-03-09 15:37:33 +00:00
|
|
|
std::vector<PrinterVariant> variants;
|
|
|
|
PrinterVariant* variant(const std::string &name) {
|
|
|
|
for (auto &v : this->variants)
|
|
|
|
if (v.name == name)
|
|
|
|
return &v;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
|
|
|
|
};
|
2018-03-13 11:39:57 +00:00
|
|
|
std::vector<PrinterModel> models;
|
|
|
|
|
2018-04-12 18:04:48 +00:00
|
|
|
VendorProfile() {}
|
|
|
|
VendorProfile(std::string id) : id(std::move(id)) {}
|
2018-04-11 11:12:08 +00:00
|
|
|
|
|
|
|
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);
|
2018-03-09 15:37:33 +00:00
|
|
|
|
|
|
|
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
|
|
|
|
|
|
|
|
bool operator< (const VendorProfile &rhs) const { return this->id < rhs.id; }
|
|
|
|
bool operator==(const VendorProfile &rhs) const { return this->id == rhs.id; }
|
|
|
|
};
|
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
class Preset
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum Type
|
|
|
|
{
|
|
|
|
TYPE_INVALID,
|
|
|
|
TYPE_PRINT,
|
2018-11-16 16:36:23 +00:00
|
|
|
TYPE_SLA_PRINT,
|
2017-09-19 11:55:48 +00:00
|
|
|
TYPE_FILAMENT,
|
2018-07-31 13:09:57 +00:00
|
|
|
TYPE_SLA_MATERIAL,
|
2017-09-19 11:55:48 +00:00
|
|
|
TYPE_PRINTER,
|
|
|
|
};
|
|
|
|
|
2017-09-20 08:03:53 +00:00
|
|
|
Preset(Type type, const std::string &name, bool is_default = false) : type(type), is_default(is_default), name(name) {}
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
Type type = TYPE_INVALID;
|
|
|
|
|
|
|
|
// The preset represents a "default" set of properties,
|
|
|
|
// pulled from the default values of the PrintConfig (see PrintConfigDef for their definitions).
|
|
|
|
bool is_default;
|
|
|
|
// External preset points to a configuration, which has been loaded but not imported
|
|
|
|
// into the Slic3r default configuration location.
|
|
|
|
bool is_external = false;
|
2018-03-09 15:37:33 +00:00
|
|
|
// System preset is read-only.
|
|
|
|
bool is_system = false;
|
2018-04-06 11:18:12 +00:00
|
|
|
// Preset is visible, if it is associated with a printer model / variant that is enabled in the AppConfig
|
|
|
|
// or if it has no printer model / variant association.
|
2017-09-19 11:55:48 +00:00
|
|
|
// Also the "default" preset is only visible, if it is the only preset in the list.
|
|
|
|
bool is_visible = true;
|
|
|
|
// Has this preset been modified?
|
|
|
|
bool is_dirty = false;
|
2017-11-10 16:27:05 +00:00
|
|
|
// Is this preset compatible with the currently active printer?
|
|
|
|
bool is_compatible = true;
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
// Name of the preset, usually derived form the file name.
|
|
|
|
std::string name;
|
|
|
|
// File name of the preset. This could be a Print / Filament / Printer preset,
|
2018-03-09 15:37:33 +00:00
|
|
|
// or a Configuration file bundling the Print + Filament + Printer presets (in that case is_external and possibly is_system will be true),
|
2017-09-19 11:55:48 +00:00
|
|
|
// or it could be a G-code (again, is_external will be true).
|
|
|
|
std::string file;
|
2018-03-09 15:37:33 +00:00
|
|
|
// If this is a system profile, then there should be a vendor data available to display at the UI.
|
|
|
|
const VendorProfile *vendor = nullptr;
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
// Has this profile been loaded?
|
|
|
|
bool loaded = false;
|
|
|
|
|
|
|
|
// Configuration data, loaded from a file, or set from the defaults.
|
|
|
|
DynamicPrintConfig config;
|
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
void save();
|
|
|
|
|
|
|
|
// Return a label of this preset, consisting of a name and a "(modified)" suffix, if this preset is dirty.
|
|
|
|
std::string label() const;
|
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
// Set the is_dirty flag if the provided config is different from the active one.
|
2017-09-20 08:03:53 +00:00
|
|
|
void set_dirty(const DynamicPrintConfig &config) { this->is_dirty = ! this->config.diff(config).empty(); }
|
2017-10-25 10:53:31 +00:00
|
|
|
void set_dirty(bool dirty = true) { this->is_dirty = dirty; }
|
2017-09-19 11:55:48 +00:00
|
|
|
void reset_dirty() { this->is_dirty = false; }
|
2017-10-25 10:53:31 +00:00
|
|
|
|
2018-12-04 16:56:49 +00:00
|
|
|
bool is_compatible_with_print(const Preset &active_print) const;
|
2017-12-19 15:48:14 +00:00
|
|
|
bool is_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config) const;
|
2017-12-18 14:07:38 +00:00
|
|
|
bool is_compatible_with_printer(const Preset &active_printer) const;
|
2017-12-19 15:48:14 +00:00
|
|
|
|
2018-06-27 14:57:42 +00:00
|
|
|
// Returns the name of the preset, from which this preset inherits.
|
2018-06-28 18:13:01 +00:00
|
|
|
static std::string& inherits(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("inherits", true)->value; }
|
2018-06-27 14:57:42 +00:00
|
|
|
std::string& inherits() { return Preset::inherits(this->config); }
|
|
|
|
const std::string& inherits() const { return Preset::inherits(const_cast<Preset*>(this)->config); }
|
|
|
|
|
2018-12-04 16:56:49 +00:00
|
|
|
// Returns the "compatible_prints_condition".
|
|
|
|
static std::string& compatible_prints_condition(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("compatible_prints_condition", true)->value; }
|
|
|
|
std::string& compatible_prints_condition() {
|
|
|
|
assert(this->type == TYPE_FILAMENT || this->type == TYPE_SLA_MATERIAL);
|
|
|
|
return Preset::compatible_prints_condition(this->config);
|
|
|
|
}
|
|
|
|
const std::string& compatible_prints_condition() const { return const_cast<Preset*>(this)->compatible_prints_condition(); }
|
|
|
|
|
2018-06-27 14:57:42 +00:00
|
|
|
// Returns the "compatible_printers_condition".
|
2018-06-28 18:13:01 +00:00
|
|
|
static std::string& compatible_printers_condition(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("compatible_printers_condition", true)->value; }
|
2018-12-04 16:56:49 +00:00
|
|
|
std::string& compatible_printers_condition() {
|
|
|
|
assert(this->type == TYPE_PRINT || this->type == TYPE_SLA_PRINT || this->type == TYPE_FILAMENT || this->type == TYPE_SLA_MATERIAL);
|
|
|
|
return Preset::compatible_printers_condition(this->config);
|
|
|
|
}
|
|
|
|
const std::string& compatible_printers_condition() const { return const_cast<Preset*>(this)->compatible_printers_condition(); }
|
2018-06-27 14:57:42 +00:00
|
|
|
|
2018-07-31 13:09:57 +00:00
|
|
|
static PrinterTechnology& printer_technology(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionEnum<PrinterTechnology>>("printer_technology", true)->value; }
|
|
|
|
PrinterTechnology& printer_technology() { return Preset::printer_technology(this->config); }
|
|
|
|
const PrinterTechnology& printer_technology() const { return Preset::printer_technology(const_cast<Preset*>(this)->config); }
|
|
|
|
|
2017-11-10 16:27:05 +00:00
|
|
|
// Mark this preset as compatible if it is compatible with active_printer.
|
2018-12-04 16:56:49 +00:00
|
|
|
bool update_compatible(const Preset &active_printer, const DynamicPrintConfig *extra_config, const Preset *active_print = nullptr);
|
2017-10-25 10:53:31 +00:00
|
|
|
|
2018-03-29 15:54:43 +00:00
|
|
|
// Set is_visible according to application config
|
|
|
|
void set_visible_from_appconfig(const AppConfig &app_config);
|
|
|
|
|
2017-11-01 18:30:05 +00:00
|
|
|
// Resize the extruder specific fields, initialize them with the content of the 1st extruder.
|
|
|
|
void set_num_extruders(unsigned int n) { set_num_extruders(this->config, n); }
|
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
// Sort lexicographically by a preset name. The preset name shall be unique across a single PresetCollection.
|
|
|
|
bool operator<(const Preset &other) const { return this->name < other.name; }
|
2017-10-30 17:41:50 +00:00
|
|
|
|
2017-11-01 18:30:05 +00:00
|
|
|
static const std::vector<std::string>& print_options();
|
|
|
|
static const std::vector<std::string>& filament_options();
|
|
|
|
// Printer options contain the nozzle options.
|
|
|
|
static const std::vector<std::string>& printer_options();
|
|
|
|
// Nozzle options of the printer options.
|
|
|
|
static const std::vector<std::string>& nozzle_options();
|
2018-07-31 13:09:57 +00:00
|
|
|
|
|
|
|
static const std::vector<std::string>& sla_printer_options();
|
|
|
|
static const std::vector<std::string>& sla_material_options();
|
2018-11-16 16:36:23 +00:00
|
|
|
static const std::vector<std::string>& sla_print_options();
|
2018-07-31 13:09:57 +00:00
|
|
|
|
2018-10-31 15:22:36 +00:00
|
|
|
static void update_suffix_modified();
|
|
|
|
static void normalize(DynamicPrintConfig &config);
|
|
|
|
// Report configuration fields, which are misplaced into a wrong group, remove them from the config.
|
|
|
|
static std::string remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config);
|
2017-11-01 18:30:05 +00:00
|
|
|
|
2017-10-30 17:41:50 +00:00
|
|
|
protected:
|
|
|
|
friend class PresetCollection;
|
|
|
|
friend class PresetBundle;
|
2017-11-01 18:30:05 +00:00
|
|
|
// Resize the extruder specific vectors ()
|
|
|
|
static void set_num_extruders(DynamicPrintConfig &config, unsigned int n);
|
2017-10-30 17:41:50 +00:00
|
|
|
static const std::string& suffix_modified();
|
|
|
|
static std::string remove_suffix_modified(const std::string &name);
|
2017-09-19 11:55:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Collections of presets of the same type (one of the Print, Filament or Printer type).
|
|
|
|
class PresetCollection
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Initialize the PresetCollection with the "- default -" preset.
|
2018-08-03 12:14:25 +00:00
|
|
|
PresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name = "- default -");
|
2017-10-25 10:53:31 +00:00
|
|
|
~PresetCollection();
|
|
|
|
|
2018-03-29 15:54:43 +00:00
|
|
|
typedef std::deque<Preset>::iterator Iterator;
|
|
|
|
typedef std::deque<Preset>::const_iterator ConstIterator;
|
2018-08-01 09:09:51 +00:00
|
|
|
Iterator begin() { return m_presets.begin() + m_num_default_presets; }
|
2018-10-31 15:22:36 +00:00
|
|
|
ConstIterator begin() const { return m_presets.cbegin() + m_num_default_presets; }
|
|
|
|
ConstIterator cbegin() const { return m_presets.cbegin() + m_num_default_presets; }
|
2018-08-01 09:09:51 +00:00
|
|
|
Iterator end() { return m_presets.end(); }
|
2018-10-31 15:22:36 +00:00
|
|
|
ConstIterator end() const { return m_presets.cend(); }
|
|
|
|
ConstIterator cend() const { return m_presets.cend(); }
|
2018-03-29 15:54:43 +00:00
|
|
|
|
2017-12-19 18:51:22 +00:00
|
|
|
void reset(bool delete_files);
|
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
Preset::Type type() const { return m_type; }
|
|
|
|
std::string name() const;
|
|
|
|
const std::deque<Preset>& operator()() const { return m_presets; }
|
2017-09-19 11:55:48 +00:00
|
|
|
|
2018-08-01 09:09:51 +00:00
|
|
|
// Add default preset at the start of the collection, increment the m_default_preset counter.
|
2018-08-03 12:14:25 +00:00
|
|
|
void add_default_preset(const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &preset_name);
|
2018-08-01 09:09:51 +00:00
|
|
|
|
2017-10-02 15:35:00 +00:00
|
|
|
// Load ini files of the particular type from the provided directory path.
|
|
|
|
void load_presets(const std::string &dir_path, const std::string &subdir);
|
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
// Load a preset from an already parsed config file, insert it into the sorted sequence of presets
|
|
|
|
// and select it, losing previous modifications.
|
|
|
|
Preset& load_preset(const std::string &path, const std::string &name, const DynamicPrintConfig &config, bool select = true);
|
2017-11-02 15:21:34 +00:00
|
|
|
Preset& load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select = true);
|
2017-10-25 10:53:31 +00:00
|
|
|
|
2018-06-22 12:17:03 +00:00
|
|
|
Preset& load_external_preset(
|
|
|
|
// Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
|
|
|
|
const std::string &path,
|
|
|
|
// Name of the profile, derived from the source file name.
|
|
|
|
const std::string &name,
|
|
|
|
// Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored.
|
|
|
|
const std::string &original_name,
|
|
|
|
// Config to initialize the preset from.
|
|
|
|
const DynamicPrintConfig &config,
|
|
|
|
// Select the preset after loading?
|
|
|
|
bool select = true);
|
|
|
|
|
2017-10-26 15:17:39 +00:00
|
|
|
// Save the preset under a new name. If the name is different from the old one,
|
|
|
|
// a new preset is stored into the list of presets.
|
|
|
|
// All presets are marked as not modified and the new preset is activated.
|
|
|
|
void save_current_preset(const std::string &new_name);
|
|
|
|
|
|
|
|
// Delete the current preset, activate the first visible preset.
|
|
|
|
void delete_current_preset();
|
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
// Load default bitmap to be placed at the wxBitmapComboBox of a MainFrame.
|
|
|
|
bool load_bitmap_default(const std::string &file_name);
|
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items.
|
|
|
|
void set_bitmap_compatible (const wxBitmap *bmp) { m_bitmap_compatible = bmp; }
|
|
|
|
void set_bitmap_incompatible(const wxBitmap *bmp) { m_bitmap_incompatible = bmp; }
|
2018-03-12 15:04:32 +00:00
|
|
|
void set_bitmap_lock (const wxBitmap *bmp) { m_bitmap_lock = bmp; }
|
|
|
|
void set_bitmap_lock_open (const wxBitmap *bmp) { m_bitmap_lock_open = bmp; }
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
// Enable / disable the "- default -" preset.
|
|
|
|
void set_default_suppressed(bool default_suppressed);
|
2017-11-01 18:30:05 +00:00
|
|
|
bool is_default_suppressed() const { return m_default_suppressed; }
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
// Select a preset. If an invalid index is provided, the first visible preset is selected.
|
|
|
|
Preset& select_preset(size_t idx);
|
|
|
|
// Return the selected preset, without the user modifications applied.
|
|
|
|
Preset& get_selected_preset() { return m_presets[m_idx_selected]; }
|
|
|
|
const Preset& get_selected_preset() const { return m_presets[m_idx_selected]; }
|
2017-11-10 16:27:05 +00:00
|
|
|
int get_selected_idx() const { return m_idx_selected; }
|
2018-07-31 13:09:57 +00:00
|
|
|
// Returns the name of the selected preset, or an empty string if no preset is selected.
|
|
|
|
std::string get_selected_preset_name() const { return (m_idx_selected == -1) ? std::string() : this->get_selected_preset().name; }
|
2018-03-12 15:04:32 +00:00
|
|
|
// For the current edited preset, return the parent preset if there is one.
|
|
|
|
// If there is no parent preset, nullptr is returned.
|
|
|
|
// The parent preset may be a system preset or a user preset, which will be
|
|
|
|
// reflected by the UI.
|
|
|
|
const Preset* get_selected_preset_parent() const;
|
2018-04-09 14:50:17 +00:00
|
|
|
// get parent preset for some child preset
|
|
|
|
const Preset* get_preset_parent(const Preset& child) const;
|
|
|
|
// Return the selected preset including the user modifications.
|
2017-09-19 11:55:48 +00:00
|
|
|
Preset& get_edited_preset() { return m_edited_preset; }
|
|
|
|
const Preset& get_edited_preset() const { return m_edited_preset; }
|
2018-04-06 13:42:52 +00:00
|
|
|
|
|
|
|
// used to update preset_choice from Tab
|
|
|
|
const std::deque<Preset>& get_presets() { return m_presets; }
|
|
|
|
int get_idx_selected() { return m_idx_selected; }
|
2018-07-23 13:44:01 +00:00
|
|
|
static const std::string& get_suffix_modified();
|
2018-04-06 13:42:52 +00:00
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
// Return a preset possibly with modifications.
|
2018-10-31 15:22:36 +00:00
|
|
|
Preset& default_preset(size_t idx = 0) { assert(idx < m_num_default_presets); return m_presets[idx]; }
|
|
|
|
const Preset& default_preset(size_t idx = 0) const { assert(idx < m_num_default_presets); return m_presets[idx]; }
|
|
|
|
virtual const Preset& default_preset_for(const DynamicPrintConfig & /* config */) const { return this->default_preset(); }
|
2017-10-25 10:53:31 +00:00
|
|
|
// Return a preset by an index. If the preset is active, a temporary copy is returned.
|
2017-09-19 11:55:48 +00:00
|
|
|
Preset& preset(size_t idx) { return (int(idx) == m_idx_selected) ? m_edited_preset : m_presets[idx]; }
|
|
|
|
const Preset& preset(size_t idx) const { return const_cast<PresetCollection*>(this)->preset(idx); }
|
2017-12-13 13:44:27 +00:00
|
|
|
void discard_current_changes() { m_presets[m_idx_selected].reset_dirty(); m_edited_preset = m_presets[m_idx_selected]; }
|
2017-10-25 10:53:31 +00:00
|
|
|
|
|
|
|
// Return a preset by its name. If the preset is active, a temporary copy is returned.
|
|
|
|
// If a preset is not found by its name, null is returned.
|
|
|
|
Preset* find_preset(const std::string &name, bool first_visible_if_not_found = false);
|
|
|
|
const Preset* find_preset(const std::string &name, bool first_visible_if_not_found = false) const
|
|
|
|
{ return const_cast<PresetCollection*>(this)->find_preset(name, first_visible_if_not_found); }
|
|
|
|
|
|
|
|
size_t first_visible_idx() const;
|
2018-04-13 12:49:33 +00:00
|
|
|
// Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
|
|
|
|
// If one of the prefered_alternates is compatible, select it.
|
|
|
|
template<typename PreferedCondition>
|
|
|
|
size_t first_compatible_idx(PreferedCondition prefered_condition) const
|
|
|
|
{
|
2018-08-01 09:09:51 +00:00
|
|
|
size_t i = m_default_suppressed ? m_num_default_presets : 0;
|
2018-04-13 12:49:33 +00:00
|
|
|
size_t n = this->m_presets.size();
|
|
|
|
size_t i_compatible = n;
|
|
|
|
for (; i < n; ++ i)
|
|
|
|
if (m_presets[i].is_compatible) {
|
|
|
|
if (prefered_condition(m_presets[i].name))
|
|
|
|
return i;
|
|
|
|
if (i_compatible == n)
|
|
|
|
// Store the first compatible profile into i_compatible.
|
|
|
|
i_compatible = i;
|
|
|
|
}
|
|
|
|
return (i_compatible == n) ? 0 : i_compatible;
|
|
|
|
}
|
|
|
|
// Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
|
|
|
|
size_t first_compatible_idx() const { return this->first_compatible_idx([](const std::string&){return true;}); }
|
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
// Return index of the first visible preset. Certainly at least the '- default -' preset shall be visible.
|
|
|
|
// Return the first visible preset. Certainly at least the '- default -' preset shall be visible.
|
2017-11-10 16:27:05 +00:00
|
|
|
Preset& first_visible() { return this->preset(this->first_visible_idx()); }
|
|
|
|
const Preset& first_visible() const { return this->preset(this->first_visible_idx()); }
|
|
|
|
Preset& first_compatible() { return this->preset(this->first_compatible_idx()); }
|
2018-04-13 12:49:33 +00:00
|
|
|
template<typename PreferedCondition>
|
|
|
|
Preset& first_compatible(PreferedCondition prefered_condition) { return this->preset(this->first_compatible_idx(prefered_condition)); }
|
2017-11-10 16:27:05 +00:00
|
|
|
const Preset& first_compatible() const { return this->preset(this->first_compatible_idx()); }
|
2017-10-25 10:53:31 +00:00
|
|
|
|
|
|
|
// Return number of presets including the "- default -" preset.
|
2018-08-01 09:09:51 +00:00
|
|
|
size_t size() const { return m_presets.size(); }
|
|
|
|
bool has_defaults_only() const { return m_presets.size() <= m_num_default_presets; }
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
// For Print / Filament presets, disable those, which are not compatible with the printer.
|
2018-04-13 12:49:33 +00:00
|
|
|
template<typename PreferedCondition>
|
2018-12-04 16:56:49 +00:00
|
|
|
void update_compatible(const Preset &active_printer, const Preset *active_print, bool select_other_if_incompatible, PreferedCondition prefered_condition)
|
2018-04-13 12:49:33 +00:00
|
|
|
{
|
2018-12-04 16:56:49 +00:00
|
|
|
if (this->update_compatible_internal(active_printer, active_print, select_other_if_incompatible) == (size_t)-1)
|
2018-04-13 12:49:33 +00:00
|
|
|
// Find some other compatible preset, or the "-- default --" preset.
|
|
|
|
this->select_preset(this->first_compatible_idx(prefered_condition));
|
|
|
|
}
|
2018-12-04 16:56:49 +00:00
|
|
|
void update_compatible(const Preset &active_printer, const Preset *active_print, bool select_other_if_incompatible)
|
|
|
|
{ this->update_compatible(active_printer, active_print, select_other_if_incompatible, [](const std::string&){return true;}); }
|
2017-09-19 11:55:48 +00:00
|
|
|
|
|
|
|
size_t num_visible() const { return std::count_if(m_presets.begin(), m_presets.end(), [](const Preset &preset){return preset.is_visible;}); }
|
2017-10-25 10:53:31 +00:00
|
|
|
|
|
|
|
// Compare the content of get_selected_preset() with get_edited_preset() configs, return true if they differ.
|
2017-12-13 13:44:27 +00:00
|
|
|
bool current_is_dirty() const { return ! this->current_dirty_options().empty(); }
|
2017-10-25 10:53:31 +00:00
|
|
|
// Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
|
2018-08-08 15:47:59 +00:00
|
|
|
std::vector<std::string> current_dirty_options(const bool deep_compare = false) const
|
|
|
|
{ return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), deep_compare); }
|
2018-03-12 15:04:32 +00:00
|
|
|
// Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
|
2018-08-08 15:47:59 +00:00
|
|
|
std::vector<std::string> current_different_from_parent_options(const bool deep_compare = false) const
|
|
|
|
{ return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), deep_compare); }
|
2017-10-25 10:53:31 +00:00
|
|
|
|
2019-01-08 09:52:11 +00:00
|
|
|
// Return a sorted list of system preset names.
|
|
|
|
std::vector<std::string> system_preset_names() const;
|
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
// Update the choice UI from the list of presets.
|
2017-11-10 16:27:05 +00:00
|
|
|
// If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.
|
|
|
|
// If an incompatible preset is selected, it is shown as well.
|
2018-04-19 10:08:59 +00:00
|
|
|
size_t update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible);
|
2017-11-10 16:27:05 +00:00
|
|
|
// Update the choice UI from the list of presets.
|
|
|
|
// Only the compatible presets are shown.
|
|
|
|
// If an incompatible preset is selected, it is shown as well.
|
2018-10-09 10:41:05 +00:00
|
|
|
void update_platter_ui(GUI::PresetComboBox *ui);
|
2017-09-19 11:55:48 +00:00
|
|
|
|
2017-10-25 10:53:31 +00:00
|
|
|
// Update a dirty floag of the current preset, update the labels of the UI component accordingly.
|
|
|
|
// Return true if the dirty flag changed.
|
2017-11-10 16:27:05 +00:00
|
|
|
bool update_dirty_ui(wxBitmapComboBox *ui);
|
2017-10-25 10:53:31 +00:00
|
|
|
|
|
|
|
// Select a profile by its name. Return true if the selection changed.
|
|
|
|
// Without force, the selection is only updated if the index changes.
|
|
|
|
// With force, the changes are reverted if the new index is the same as the old index.
|
|
|
|
bool select_preset_by_name(const std::string &name, bool force);
|
|
|
|
|
2017-12-20 10:28:16 +00:00
|
|
|
// Generate a file path from a profile name. Add the ".ini" suffix if it is missing.
|
|
|
|
std::string path_from_name(const std::string &new_name) const;
|
|
|
|
|
2018-04-13 12:49:33 +00:00
|
|
|
protected:
|
|
|
|
// Select a preset, if it exists. If it does not exist, select an invalid (-1) index.
|
|
|
|
// This is a temporary state, which shall be fixed immediately by the following step.
|
|
|
|
bool select_preset_by_name_strict(const std::string &name);
|
|
|
|
|
2018-04-18 11:35:51 +00:00
|
|
|
// Merge one vendor's presets with the other vendor's presets, report duplicates.
|
|
|
|
std::vector<std::string> merge_presets(PresetCollection &&other, const std::set<VendorProfile> &new_vendors);
|
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
private:
|
2017-10-25 10:53:31 +00:00
|
|
|
PresetCollection();
|
|
|
|
PresetCollection(const PresetCollection &other);
|
|
|
|
PresetCollection& operator=(const PresetCollection &other);
|
|
|
|
|
2018-06-28 18:13:01 +00:00
|
|
|
// Find a preset position in the sorted list of presets.
|
2017-12-06 15:47:53 +00:00
|
|
|
// The "-- default -- " preset is always the first, so it needs
|
|
|
|
// to be handled differently.
|
2018-06-28 18:13:01 +00:00
|
|
|
// If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name.
|
2017-12-06 15:47:53 +00:00
|
|
|
std::deque<Preset>::iterator find_preset_internal(const std::string &name)
|
|
|
|
{
|
|
|
|
Preset key(m_type, name);
|
2018-08-01 09:09:51 +00:00
|
|
|
auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key);
|
|
|
|
if (it == m_presets.end() || it->name != name) {
|
|
|
|
// Preset has not been not found in the sorted list of non-default presets. Try the defaults.
|
|
|
|
for (size_t i = 0; i < m_num_default_presets; ++ i)
|
|
|
|
if (m_presets[i].name == name) {
|
|
|
|
it = m_presets.begin() + i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return it;
|
2017-12-06 15:47:53 +00:00
|
|
|
}
|
|
|
|
std::deque<Preset>::const_iterator find_preset_internal(const std::string &name) const
|
|
|
|
{ return const_cast<PresetCollection*>(this)->find_preset_internal(name); }
|
|
|
|
|
2018-12-04 16:56:49 +00:00
|
|
|
size_t update_compatible_internal(const Preset &active_printer, const Preset *active_print, bool unselect_if_incompatible);
|
2018-04-13 12:49:33 +00:00
|
|
|
|
2018-04-18 11:32:21 +00:00
|
|
|
static std::vector<std::string> dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type = false);
|
2018-03-12 15:04:32 +00:00
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
// Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER.
|
|
|
|
Preset::Type m_type;
|
|
|
|
// List of presets, starting with the "- default -" preset.
|
2017-10-25 10:53:31 +00:00
|
|
|
// Use deque to force the container to allocate an object per each entry,
|
|
|
|
// so that the addresses of the presets don't change during resizing of the container.
|
|
|
|
std::deque<Preset> m_presets;
|
|
|
|
// Initially this preset contains a copy of the selected preset. Later on, this copy may be modified by the user.
|
2017-09-19 11:55:48 +00:00
|
|
|
Preset m_edited_preset;
|
|
|
|
// Selected preset.
|
|
|
|
int m_idx_selected;
|
|
|
|
// Is the "- default -" preset suppressed?
|
2018-08-01 09:09:51 +00:00
|
|
|
bool m_default_suppressed = true;
|
|
|
|
size_t m_num_default_presets = 0;
|
2017-10-25 10:53:31 +00:00
|
|
|
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items of a Platter.
|
|
|
|
// These bitmaps are not owned by PresetCollection, but by a PresetBundle.
|
2018-03-12 15:04:32 +00:00
|
|
|
const wxBitmap *m_bitmap_compatible = nullptr;
|
2017-09-19 11:55:48 +00:00
|
|
|
const wxBitmap *m_bitmap_incompatible = nullptr;
|
2018-03-12 15:04:32 +00:00
|
|
|
const wxBitmap *m_bitmap_lock = nullptr;
|
|
|
|
const wxBitmap *m_bitmap_lock_open = nullptr;
|
2017-10-25 10:53:31 +00:00
|
|
|
// Marks placed at the wxBitmapComboBox of a MainFrame.
|
|
|
|
// These bitmaps are owned by PresetCollection.
|
|
|
|
wxBitmap *m_bitmap_main_frame;
|
2017-10-26 15:17:39 +00:00
|
|
|
// Path to the directory to store the config files into.
|
|
|
|
std::string m_dir_path;
|
2018-04-13 12:49:33 +00:00
|
|
|
|
2018-04-19 10:08:59 +00:00
|
|
|
// Caching color bitmaps for the filament combo box.
|
|
|
|
GUI::BitmapCache *m_bitmap_cache = nullptr;
|
2018-04-24 16:15:23 +00:00
|
|
|
|
2018-04-13 12:49:33 +00:00
|
|
|
// to access select_preset_by_name_strict()
|
|
|
|
friend class PresetBundle;
|
2017-09-19 11:55:48 +00:00
|
|
|
};
|
|
|
|
|
2018-10-31 15:22:36 +00:00
|
|
|
// Printer supports the FFF and SLA technologies, with different set of configuration values,
|
|
|
|
// therefore this PresetCollection needs to handle two defaults.
|
|
|
|
class PrinterPresetCollection : public PresetCollection
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PrinterPresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name = "- default -") :
|
|
|
|
PresetCollection(type, keys, defaults, default_name) {}
|
|
|
|
const Preset& default_preset_for(const DynamicPrintConfig &config) const override;
|
|
|
|
};
|
|
|
|
|
2017-09-19 11:55:48 +00:00
|
|
|
} // namespace Slic3r
|
|
|
|
|
|
|
|
#endif /* slic3r_Preset_hpp_ */
|