diff --git a/resources/custom_gcodes/before_layer_gcode b/resources/custom_gcodes/before_layer_gcode
new file mode 100644
index 0000000000..3e00992c4d
--- /dev/null
+++ b/resources/custom_gcodes/before_layer_gcode
@@ -0,0 +1,4 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:08 UTC
+layer_num = 2
+layer_z = 1
+max_layer_z = 1
diff --git a/resources/custom_gcodes/end_filament_gcode b/resources/custom_gcodes/end_filament_gcode
new file mode 100644
index 0000000000..6cd107ae83
--- /dev/null
+++ b/resources/custom_gcodes/end_filament_gcode
@@ -0,0 +1,5 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC
+filament_extruder_id = 2
+layer_num = 2
+layer_z = 1
+max_layer_z = 1
diff --git a/resources/custom_gcodes/end_gcode b/resources/custom_gcodes/end_gcode
new file mode 100644
index 0000000000..6cd107ae83
--- /dev/null
+++ b/resources/custom_gcodes/end_gcode
@@ -0,0 +1,5 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC
+filament_extruder_id = 2
+layer_num = 2
+layer_z = 1
+max_layer_z = 1
diff --git a/resources/custom_gcodes/layer_gcode b/resources/custom_gcodes/layer_gcode
new file mode 100644
index 0000000000..9bebff5d45
--- /dev/null
+++ b/resources/custom_gcodes/layer_gcode
@@ -0,0 +1,4 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC
+layer_num = 2
+layer_z = 1
+max_layer_z = 1
diff --git a/resources/custom_gcodes/rw_slicing_state b/resources/custom_gcodes/rw_slicing_state
new file mode 100644
index 0000000000..e269a084ab
--- /dev/null
+++ b/resources/custom_gcodes/rw_slicing_state
@@ -0,0 +1,4 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC
+e_restart_extra = 16385
+e_retracted = 16385
+position = 16385
diff --git a/resources/custom_gcodes/start_filament_gcode b/resources/custom_gcodes/start_filament_gcode
new file mode 100644
index 0000000000..6cd107ae83
--- /dev/null
+++ b/resources/custom_gcodes/start_filament_gcode
@@ -0,0 +1,5 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC
+filament_extruder_id = 2
+layer_num = 2
+layer_z = 1
+max_layer_z = 1
diff --git a/resources/custom_gcodes/tcr_rotated_gcode b/resources/custom_gcodes/tcr_rotated_gcode
new file mode 100644
index 0000000000..b616714f57
--- /dev/null
+++ b/resources/custom_gcodes/tcr_rotated_gcode
@@ -0,0 +1,3 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-14 at 11:40:58 UTC
+deretraction_from_wipe_tower_generator = 3
+toolchange_gcode = 3
diff --git a/resources/custom_gcodes/toolchange_gcode b/resources/custom_gcodes/toolchange_gcode
new file mode 100644
index 0000000000..a254e530b3
--- /dev/null
+++ b/resources/custom_gcodes/toolchange_gcode
@@ -0,0 +1,7 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-14 at 11:40:58 UTC
+layer_num = 2
+layer_z = 1
+max_layer_z = 1
+next_extruder = 2
+previous_extruder = 2
+toolchange_z = 1
diff --git a/resources/custom_gcodes/universal b/resources/custom_gcodes/universal
new file mode 100644
index 0000000000..511a9c9b59
--- /dev/null
+++ b/resources/custom_gcodes/universal
@@ -0,0 +1,39 @@
+# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC
+current_extruder = 2
+current_object_idx = 2
+day = 2
+extruded_volume = 16385
+extruded_volume_total = 1
+extruded_weight = 16385
+extruded_weight_total = 1
+filament_preset = 16387
+first_layer_print_convex_hull = 16390
+first_layer_print_max = 16385
+first_layer_print_min = 16385
+first_layer_print_size = 16385
+has_single_extruder_multi_material_priming = 8
+has_wipe_tower = 8
+hour = 2
+initial_extruder = 2
+initial_tool = 2
+input_filename = 3
+input_filename_base = 3
+is_extruder_used = 16392
+minute = 2
+month = 2
+num_extruders = 2
+num_instances = 2
+num_objects = 2
+physical_printer_preset = 3
+print_bed_max = 16385
+print_bed_min = 16385
+print_bed_size = 16385
+print_preset = 3
+printer_preset = 3
+scale = 16387
+second = 2
+timestamp = 3
+total_layer_count = 2
+total_toolchanges = 2
+year = 2
+zhop = 1
diff --git a/resources/icons/scalar_param.svg b/resources/icons/scalar_param.svg
new file mode 100644
index 0000000000..f9386ab70e
--- /dev/null
+++ b/resources/icons/scalar_param.svg
@@ -0,0 +1,21 @@
+
+
+
diff --git a/resources/icons/vector_filament_param.svg b/resources/icons/vector_filament_param.svg
new file mode 100644
index 0000000000..a3404cfd88
--- /dev/null
+++ b/resources/icons/vector_filament_param.svg
@@ -0,0 +1,28 @@
+
+
+
diff --git a/resources/icons/vector_param.svg b/resources/icons/vector_param.svg
new file mode 100644
index 0000000000..a5c8affc7f
--- /dev/null
+++ b/resources/icons/vector_param.svg
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp
index 0d627aa837..4b2aaed18d 100644
--- a/src/PrusaSlicer.cpp
+++ b/src/PrusaSlicer.cpp
@@ -763,6 +763,7 @@ bool CLI::setup(int argc, char **argv)
set_var_dir((path_resources / "icons").string());
set_local_dir((path_resources / "localization").string());
set_sys_shapes_dir((path_resources / "shapes").string());
+ set_custom_gcodes_dir((path_resources / "custom_gcodes").string());
// Parse all command line options into a DynamicConfig.
// If any option is unsupported, print usage and abort immediately.
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index debe3e63b9..5ae7cd0dd0 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1504,6 +1504,12 @@ std::string GCodeGenerator::placeholder_parser_process(
unsigned int current_extruder_id,
const DynamicConfig *config_override)
{
+#if GET_CUSTOM_GCODE_PLACEHOLDERS
+ if (config_override &&
+ g_code_placeholders_map.find(name) == g_code_placeholders_map.end())
+ g_code_placeholders_map[name] = *config_override;
+#endif
+
PlaceholderParserIntegration &ppi = m_placeholder_parser_integration;
try {
ppi.update_from_gcodewriter(m_writer);
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index 1c92874922..888055cc9a 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -72,6 +72,8 @@ struct LayerResult {
};
class GCodeGenerator {
+#define GET_CUSTOM_GCODE_PLACEHOLDERS 1
+
public:
GCodeGenerator() :
m_origin(Vec2d::Zero()),
@@ -97,6 +99,13 @@ public:
{}
~GCodeGenerator() = default;
+#if GET_CUSTOM_GCODE_PLACEHOLDERS
+ std::map g_code_placeholders_map;
+ const std::map& get_g_code_placeholders_map() { return g_code_placeholders_map; }
+ const DynamicConfig& get_placeholder_parser_config() const { return m_placeholder_parser_integration.parser.config(); }
+ const DynamicConfig& get_placeholder_output_config() const { return m_placeholder_parser_integration.output_config; }
+#endif
+
// throws std::runtime_exception on error,
// throws CanceledException through print->throw_if_canceled().
void do_export(Print* print, const char* path, GCodeProcessorResult* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr);
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 1ee545606c..c63b3b1a95 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -1014,6 +1014,46 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor
std::unique_ptr gcode(new GCodeGenerator);
gcode->do_export(this, path.c_str(), result, thumbnail_cb);
+
+#if GET_CUSTOM_GCODE_PLACEHOLDERS
+
+ const std::string dir = custom_gcodes_dir() +
+#ifdef _WIN32
+ "\\";
+#else
+ "/";
+#endif
+
+ auto save_placeholders = [dir](const std::string& file_name, const DynamicConfig& config) {
+ try {
+ boost::nowide::ofstream c;
+ c.open(dir + file_name, std::ios::out | std::ios::trunc);
+ c << "# " << header_slic3r_generated() << std::endl;
+ auto keys = config.keys();
+ for (const std::string& opt_key : keys) {
+ const std::string type = std::to_string(int(config.optptr(opt_key)->type()));
+ c << opt_key << " = " << type << std::endl;
+ }
+ c.close();
+ }
+ catch (const std::ofstream::failure& err) {
+ throw RuntimeError(format("The %1% cannot be loaded:\n\tReason: %2%", file_name, err.what()));
+ }
+ };
+
+ // save specific placeholders
+ const auto& gcode_placeholders = gcode->get_g_code_placeholders_map();
+ for (const auto& [gcode_name, config] : gcode_placeholders)
+ save_placeholders(gcode_name, config);
+
+ // save universal placeholders
+ save_placeholders("universal", gcode->get_placeholder_parser_config());
+
+ // save placeholders for "rw_slicing_state" slicing state
+ save_placeholders("rw_slicing_state", gcode->get_placeholder_output_config());
+
+#endif
+
if (m_conflict_result.has_value())
result->conflict_result = *m_conflict_result;
diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp
index 9cc81b241f..201cbcc88d 100644
--- a/src/libslic3r/Utils.hpp
+++ b/src/libslic3r/Utils.hpp
@@ -53,6 +53,11 @@ const std::string& sys_shapes_dir();
// Return a full path to the custom shapes gallery directory.
std::string custom_shapes_dir();
+// Set a path with shapes gallery files.
+void set_custom_gcodes_dir(const std::string &path);
+// Return a full path to the system shapes gallery directory.
+const std::string& custom_gcodes_dir();
+
// Set a path with preset files.
void set_data_dir(const std::string &path);
// Return a full path to the GUI resource files.
diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp
index d934819bfe..161a24e0a6 100644
--- a/src/libslic3r/utils.cpp
+++ b/src/libslic3r/utils.cpp
@@ -193,6 +193,18 @@ const std::string& sys_shapes_dir()
return g_sys_shapes_dir;
}
+static std::string g_custom_gcodes_dir;
+
+void set_custom_gcodes_dir(const std::string &dir)
+{
+ g_custom_gcodes_dir = dir;
+}
+
+const std::string& custom_gcodes_dir()
+{
+ return g_custom_gcodes_dir;
+}
+
// Translate function callback, to call wxWidgets translate function to convert non-localized UTF8 string to a localized one.
Slic3r::I18N::translate_fn_type Slic3r::I18N::translate_fn = nullptr;
diff --git a/src/slic3r/GUI/EditGCodeDialog.cpp b/src/slic3r/GUI/EditGCodeDialog.cpp
index ea80d95351..2875ffe7e3 100644
--- a/src/slic3r/GUI/EditGCodeDialog.cpp
+++ b/src/slic3r/GUI/EditGCodeDialog.cpp
@@ -20,30 +20,104 @@
#include "MsgDialog.hpp"
#include "Plater.hpp"
+#include "libslic3r/PlaceholderParser.hpp"
#include "libslic3r/Preset.hpp"
+#include "libslic3r/Print.hpp"
namespace Slic3r {
namespace GUI {
-
-static std::vector get_specific_params(const std::string& custom_gcode)
+
+ConfigOption* get_new_option(const ConfigOptionType type)
{
- if (custom_gcode == "start_filament_gcode" || custom_gcode == "end_filament_gcode")
- return{ "max_layer_z",
- "layer_num",
- "layer_z",
- "filament_extruder_id" };
- if (custom_gcode == "end_gcode" || custom_gcode == "before_layer_gcode" || custom_gcode == "layer_gcode")
- return{ "max_layer_z",
- "layer_num",
- "layer_z" };
- if (custom_gcode == "toolchange_gcode")
- return{ "next_extruder",
- "previous_extruder",
- "toolchange_z",
- "max_layer_z",
- "layer_num",
- "layer_z" };
- return {};
+ switch (type) {
+ case coFloat:
+ return new ConfigOptionFloat(0.);
+ case coFloats:
+ return new ConfigOptionFloats({ 0. });
+ case coInt:
+ return new ConfigOptionInt(0);
+ case coInts:
+ return new ConfigOptionInts({ 0 });
+ case coString:
+ return new ConfigOptionString("");
+ case coStrings:
+ return new ConfigOptionStrings({ ""});
+ case coPercent:
+ return new ConfigOptionPercent(0);
+ case coPercents:
+ return new ConfigOptionPercents({ 0});
+ case coFloatOrPercent:
+ return new ConfigOptionFloatOrPercent();
+ case coFloatsOrPercents:
+ return new ConfigOptionFloatsOrPercents();
+ case coPoint:
+ return new ConfigOptionPoint(Vec2d(100, 100));
+ case coPoints:
+ return new ConfigOptionPoints({ Vec2d(100,100) });
+ case coPoint3:
+ return new ConfigOptionPoint3();
+ case coBool:
+ return new ConfigOptionBool(true);
+ case coBools:
+ return new ConfigOptionBools({ true });
+ case coEnum:
+ return new ConfigOptionEnum();
+ default:
+ return nullptr;
+ }
+}
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+static std::vector get_params_from_file(const std::string& file_name, DynamicConfig& out_config)
+{
+ const fs::path file_path = fs::path(custom_gcodes_dir() +
+#ifdef _WIN32
+ "\\"
+#else
+ "/"
+#endif
+ + file_name);
+
+ if (!fs::exists(file_path))
+ return {};
+
+ const std::string file = file_path.string();
+
+ // Load the preset file, apply preset values on top of defaults.
+ try {
+ DynamicConfig config;
+
+ try {
+ pt::ptree tree;
+ boost::nowide::ifstream ifs(file);
+ pt::read_ini(ifs, tree);
+ for (const pt::ptree::value_type& v : tree) {
+ try {
+ t_config_option_key opt_key = v.first;
+ const std::string type_str = v.second.get_value();
+ const ConfigOptionType type = ConfigOptionType(std::atoi(type_str.c_str()));
+ if (ConfigOption* opt = get_new_option(type))
+ config.set_key_value(opt_key, std::move(opt));
+ }
+ catch (UnknownOptionException& err) {
+ throw RuntimeError(format("Some option from %1% cannot be loaded:\n\tReason: %2%", file, err.what()));
+ }
+ }
+ }
+ catch (const ConfigurationError& e) {
+ throw ConfigurationError(format("Failed loading configuration file \"%1%\": \n\t%2%", file, e.what()));
+ }
+
+ out_config += config;
+ return config.keys();
+ }
+ catch (const std::ifstream::failure& err) {
+ throw RuntimeError(format("The %1% cannot be loaded:\n\tReason: %2%", file, err.what()));
+ }
+ catch (const std::runtime_error& err) {
+ throw RuntimeError(format("Failed loading the custom_gcode_placeholders file: \"%1%\"\n\tReason: %2%", file , err.what()));
+ }
}
//------------------------------------------
@@ -120,97 +194,106 @@ std::string EditGCodeDialog::get_edited_gcode() const
void EditGCodeDialog::init_params_list(const std::string& custom_gcode_name)
{
- wxDataViewItem group = m_params_list->AppendGroup(_L("Slicing State"), "re_slice");
+ const std::vector universal_params = get_params_from_file("universal", m_universal_config);
+
+ auto get_type = [](const std::string& opt_key, const DynamicConfig& config) {
+ return config.optptr(opt_key)->is_scalar() ? ParamType::Scalar : ParamType::Vector;
+ };
+
+ // Add slicing states placeholders
+
+ std::vector read_only_opts = { "zhop" };
+ wxDataViewItem group = m_params_list->AppendGroup(_L("Slicing State"), "re_slice");
{
- wxDataViewItem read_only = m_params_list->AppendSubGroup(group, _L("Read Only"), "lock_closed");
- m_params_list->AppendParam(read_only, ParamType::Scalar, "zhop");
- }
- {
- wxDataViewItem read_write = m_params_list->AppendSubGroup(group, _L("Read Write"), "lock_open");
- for (const auto& opt_name : { "position", "e_position"})
- m_params_list->AppendParam(read_write, ParamType::Vector, opt_name);
- for (const auto& opt_name : { "e_retracted", "e_restart_extra"})
- m_params_list->AppendParam(read_write, ParamType::FilamentVector, opt_name);
+ wxDataViewItem read_only = m_params_list->AppendSubGroup(group, _L("Read Only"), "lock_closed");
+ for (const auto& opt_key : read_only_opts)
+ m_params_list->AppendParam(read_only, get_type(opt_key, m_universal_config), opt_key);
}
- group = m_params_list->AppendGroup(_L("Universal"), "equal");
- {
- wxDataViewItem time_stamp = m_params_list->AppendSubGroup(group, _L("Time Stamp"), "time");
- for (const auto& opt_name : { "day",
- "hour",
- "minute",
- "month",
- "second",
- "year",
- "timestamp" })
- m_params_list->AppendParam(time_stamp, ParamType::Scalar, opt_name);
-
- for (const auto& opt_name : { "current_extruder",
- "current_object_idx",
- "filament_preset",
- "first_layer_print_convex_hull",
- "first_layer_print_max",
- "first_layer_print_min",
- "first_layer_print_size",
- "has_single_extruder_multi_material_priming",
- "has_wipe_tower",
- "initial_extruder",
- "initial_tool",
- "input_filename",
- "input_filename_base",
- "is_extruder_used",
- "num_instances",
- "num_objects",
- "physical_printer_preset",
- "print_bed_max",
- "print_bed_min",
- "print_bed_size",
- "print_preset",
- "printer_preset",
- "scale",
- "total_layer_count",
- "total_toolchanges" })
- m_params_list->AppendParam(group, ParamType::Scalar, opt_name);
+ const std::vector read_write_params = get_params_from_file("rw_slicing_state", m_read_write_config);
+ if (!read_write_params.empty()) {
+ wxDataViewItem read_write = m_params_list->AppendSubGroup(group, _L("Read Write"), "lock_open");
+ for (const auto& opt_key : read_write_params)
+ m_params_list->AppendParam(read_write, get_type(opt_key, m_read_write_config), opt_key);
}
- std::vector specific_params = get_specific_params(custom_gcode_name);
+ // Add universal placeholders
+
+ if (!universal_params.empty()) {
+ group = m_params_list->AppendGroup(_L("Universal"), "equal");
+
+ // Add print statistics subgroup
+
+ m_print_statistics_config = PrintStatistics::placeholders();
+ if (!m_print_statistics_config.empty()) {
+ wxDataViewItem statistics = m_params_list->AppendSubGroup(group, _L("Print Statistics"), "info");
+ const std::vector statistics_params = m_print_statistics_config.keys();
+ for (const auto& opt_key : statistics_params)
+ m_params_list->AppendParam(statistics, get_type(opt_key, m_print_statistics_config), opt_key);
+ }
+
+ // Add timestamp subgroup
+
+ PlaceholderParser parser;
+ parser.update_timestamp();
+ const DynamicConfig& ts_config = parser.config();
+ wxDataViewItem time_stamp = ts_config.empty() ? group : m_params_list->AppendSubGroup(group, _L("Timestamps"), "time");
+
+ // Add un-grouped params
+
+ wxDataViewItem other = m_params_list->AppendSubGroup(group, _L("Other"), "add_gcode");
+ for (const auto& opt_key : universal_params) {
+ if (m_print_statistics_config.has(opt_key) || std::find(read_only_opts.begin(), read_only_opts.end(), opt_key) != read_only_opts.end())
+ continue;
+ m_params_list->AppendParam( ts_config.has(opt_key) ? time_stamp : other, get_type(opt_key, m_universal_config), opt_key);
+ }
+ }
+
+ // Add specific placeholders
+
+ const std::vector specific_params = get_params_from_file(custom_gcode_name, m_specific_config);
if (!specific_params.empty()) {
group = m_params_list->AppendGroup(format_wxstr(_L("Specific for %1%"), custom_gcode_name), "not_equal");
- for (const auto& opt_name : specific_params)
- m_params_list->AppendParam(group, ParamType::Scalar, opt_name);
+ for (const auto& opt_key : specific_params)
+ m_params_list->AppendParam(group, get_type(opt_key, m_specific_config), opt_key);
+
+ m_params_list->Expand(group);
}
- auto get_set_from_vec = [](const std::vector& vec) {
+ // Add placeholders from presets
+
+ add_presets_placeholders();
+}
+
+void EditGCodeDialog::add_presets_placeholders()
+{
+ auto get_set_from_vec = [](const std::vector&vec) {
return std::set(vec.begin(), vec.end());
};
- const bool is_fff = wxGetApp().plater()->printer_technology() == ptFFF;
+
+ const bool is_fff = wxGetApp().plater()->printer_technology() == ptFFF;
const std::set print_options = get_set_from_vec(is_fff ? Preset::print_options() : Preset::sla_print_options());
const std::set material_options = get_set_from_vec(is_fff ? Preset::filament_options() : Preset::sla_material_options());
const std::set printer_options = get_set_from_vec(is_fff ? Preset::printer_options() : Preset::sla_printer_options());
- const auto& full_config = wxGetApp().preset_bundle->full_config();
+ const auto&full_config = wxGetApp().preset_bundle->full_config();
- const auto& def = full_config.def()->get("")->label;
+ wxDataViewItem group = m_params_list->AppendGroup(_L("Presets"), "cog");
+ wxDataViewItem print = m_params_list->AppendSubGroup(group, _L("Print settings"), "cog");
+ for (const auto&opt : print_options)
+ if (const ConfigOption *optptr = full_config.optptr(opt))
+ m_params_list->AppendParam(print, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt);
+
+ wxDataViewItem material = m_params_list->AppendSubGroup(group, _(is_fff ? L("Filament settings") : L("SLA Materials settings")), is_fff ? "spool" : "resin");
+ for (const auto&opt : material_options)
+ if (const ConfigOption *optptr = full_config.optptr(opt))
+ m_params_list->AppendParam(material, optptr->is_scalar() ? ParamType::Scalar : ParamType::FilamentVector, opt);
- group = m_params_list->AppendGroup(_L("Presets"), "cog");
- {
- wxDataViewItem print = m_params_list->AppendSubGroup(group, _L("Print settings"), "cog");
- for (const auto& opt : print_options)
- if (const ConfigOption *optptr = full_config.optptr(opt))
- m_params_list->AppendParam(print, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt);
-
- wxDataViewItem material = m_params_list->AppendSubGroup(group, _(is_fff ? L("Filament settings") : L("SLA Materials settings")), is_fff ? "spool" : "resin");
- for (const auto& opt : material_options)
- if (const ConfigOption *optptr = full_config.optptr(opt))
- m_params_list->AppendParam(material, optptr->is_scalar() ? ParamType::Scalar : ParamType::FilamentVector, opt);
-
- wxDataViewItem printer = m_params_list->AppendSubGroup(group, _L("Printer settings"), is_fff ? "printer" : "sla_printer");
- for (const auto& opt : printer_options)
- if (const ConfigOption *optptr = full_config.optptr(opt))
- m_params_list->AppendParam(printer, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt);
-
- }
+ wxDataViewItem printer = m_params_list->AppendSubGroup(group, _L("Printer settings"), is_fff ? "printer" : "sla_printer");
+ for (const auto&opt : printer_options)
+ if (const ConfigOption *optptr = full_config.optptr(opt))
+ m_params_list->AppendParam(printer, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt);
}
void EditGCodeDialog::add_selected_value_to_gcode()
@@ -227,28 +310,43 @@ void EditGCodeDialog::bind_list_and_button()
const std::string opt_key = m_params_list->GetSelectedParamKey();
if (!opt_key.empty()) {
+ const ConfigOptionDef* cod { nullptr };
+ const ConfigOption* optptr { nullptr };
+
const auto& full_config = wxGetApp().preset_bundle->full_config();
- if (const ConfigDef* def = full_config.def();
- def && def->has(opt_key)) {
- const ConfigOptionDef* cod = def->get(opt_key);
- const ConfigOption* optptr = full_config.optptr(opt_key);
- const ConfigOptionType type = optptr->type();
+ if (const ConfigDef* def = full_config.def(); def && def->has(opt_key)) {
+ cod = def->get(opt_key);
+ optptr = full_config.optptr(opt_key);
+ }
+ else {
+ for (const DynamicConfig* config: { &m_read_write_config, &m_universal_config, &m_specific_config, &m_print_statistics_config }) {
+ optptr = config->optptr(opt_key);
+ if (optptr)
+ break;
+ }
+ }
- wxString type_str = type == coNone ? "none" :
- type == coFloat || type == coFloats ? "float" :
- type == coInt || type == coInts ? "integer" :
- type == coString || type == coStrings ? "string" :
- type == coPercent || type == coPercents ? "percent" :
- type == coFloatOrPercent || type == coFloatsOrPercents ? "float ar percent" :
- type == coPoint || type == coPoints || type == coPoint3 ? "point" :
- type == coBool || type == coBools ? "bool" :
- type == coEnum ? "enum" : "undef";
+ if (optptr) {
+ const ConfigOptionType scalar_type = optptr->is_scalar() ? optptr->type() : static_cast(optptr->type() - coVectorType);
+ wxString type_str = scalar_type == coNone ? "none" :
+ scalar_type == coFloat ? "float" :
+ scalar_type == coInt ? "integer" :
+ scalar_type == coString ? "string" :
+ scalar_type == coPercent ? "percent" :
+ scalar_type == coFloatOrPercent ? "float or percent" :
+ scalar_type == coPoint ? "point" :
+ scalar_type == coBool ? "bool" :
+ scalar_type == coEnum ? "enum" : "undef";
+ if (!optptr->is_scalar())
+ type_str += "[]";
- label = ( cod->full_label.empty() && cod->label.empty() ) ? format_wxstr("Undef Label\n(%1%)", type_str) :
+ label = (!cod || (cod->full_label.empty() && cod->label.empty()) ) ? format_wxstr("%1%\n(%2%)", opt_key, type_str) :
(!cod->full_label.empty() && !cod->label.empty() ) ?
format_wxstr("%1% > %2%\n(%3%)", _(cod->full_label), _(cod->label), type_str) :
format_wxstr("%1%\n(%2%)", cod->label.empty() ? _(cod->full_label) : _(cod->label), type_str);
}
+ else
+ label = "Undef optptr";
}
m_param_label->SetLabel(label);
@@ -461,7 +559,7 @@ void ParamsModel::GetValue(wxVariant& variant, const wxDataViewItem& item, unsig
assert(item.IsOk());
ParamsNode* node = static_cast(item.GetID());
- if (col == unsigned int(0))
+ if (col == (unsigned int)0)
#ifdef __linux__
variant << wxDataViewIconText(node->text, get_bmp_bundle(node->icon_name)->GetIconFor(m_ctrl->GetParent()));
#else
@@ -476,11 +574,11 @@ bool ParamsModel::SetValue(const wxVariant& variant, const wxDataViewItem& item,
assert(item.IsOk());
ParamsNode* node = static_cast(item.GetID());
- if (col == unsigned int(0)) {
+ if (col == (unsigned int)0) {
#ifdef __linux__
wxDataViewIconText data;
data << variant;
- node->m_icon = data.GetIcon();
+ node->icon = data.GetIcon();
#else
DataViewBitmapText data;
data << variant;
@@ -559,7 +657,7 @@ ParamsViewCtrl::ParamsViewCtrl(wxWindow *parent, wxSize size)
#ifdef SUPPORTS_MARKUP
rd->EnableMarkup(true);
#endif
- wxDataViewColumn* column = new wxDataViewColumn("", rd, 0, width * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT);
+ wxDataViewColumn* column = new wxDataViewColumn("", rd, 0, 20 * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT);
#else
wxDataViewColumn* column = new wxDataViewColumn("", new BitmapTextRenderer(true, wxDATAVIEW_CELL_INERT), 0, 20 * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE);
#endif //__linux__
diff --git a/src/slic3r/GUI/EditGCodeDialog.hpp b/src/slic3r/GUI/EditGCodeDialog.hpp
index be7746b413..f255190f98 100644
--- a/src/slic3r/GUI/EditGCodeDialog.hpp
+++ b/src/slic3r/GUI/EditGCodeDialog.hpp
@@ -30,6 +30,11 @@ class EditGCodeDialog : public DPIDialog
wxTextCtrl* m_gcode_editor {nullptr};
wxStaticText* m_param_label {nullptr};
+ DynamicConfig m_read_write_config;
+ DynamicConfig m_universal_config;
+ DynamicConfig m_specific_config;
+ DynamicConfig m_print_statistics_config;
+
public:
EditGCodeDialog(wxWindow*parent, const std::string&key, const std::string&value);
~EditGCodeDialog() {}
@@ -37,6 +42,8 @@ public:
std::string get_edited_gcode() const;
void init_params_list(const std::string& custom_gcode_name);
+ void add_presets_placeholders();
+
void add_selected_value_to_gcode();
void bind_list_and_button();