diff --git a/resources/images/create_success.svg b/resources/images/create_success.svg
new file mode 100644
index 0000000000..242dc57327
--- /dev/null
+++ b/resources/images/create_success.svg
@@ -0,0 +1,10 @@
+
diff --git a/resources/images/step_1.svg b/resources/images/step_1.svg
new file mode 100644
index 0000000000..27385f06b1
--- /dev/null
+++ b/resources/images/step_1.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/images/step_2.svg b/resources/images/step_2.svg
new file mode 100644
index 0000000000..7ea460c47d
--- /dev/null
+++ b/resources/images/step_2.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/images/step_2_ready.svg b/resources/images/step_2_ready.svg
new file mode 100644
index 0000000000..8e53610c3a
--- /dev/null
+++ b/resources/images/step_2_ready.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/images/step_is_ok.svg b/resources/images/step_is_ok.svg
new file mode 100644
index 0000000000..04ee5c02ae
--- /dev/null
+++ b/resources/images/step_is_ok.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 121704e9cc..b8a03f205e 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -2065,7 +2065,7 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string
return preset;
}
-bool PresetCollection::clone_presets(std::vector const &presets, std::vector &failures, std::function modifier)
+bool PresetCollection::clone_presets(std::vector const &presets, std::vector &failures, std::function modifier, bool force_rewritten)
{
std::vector new_presets;
for (auto curr_preset : presets) {
@@ -2095,26 +2095,32 @@ bool PresetCollection::clone_presets(std::vector const &presets,
preset.config.option("printer_settings_id", true)->value = preset.name;
preset.updated_time = (long long) Slic3r::Utils::get_current_time_utc();
}
- if (!failures.empty())
+ if (!failures.empty() && !force_rewritten)
return false;
lock();
for (auto preset : new_presets) {
auto it = this->find_preset_internal(preset.name);
- assert(it == m_presets.end() || it->name != preset.name);
- Preset & new_preset = *m_presets.insert(it, preset);
- new_preset.save(nullptr);
+ assert((it == m_presets.end() || it->name != preset.name) || force_rewritten);
+ if (it == m_presets.end() || it->name != preset.name) {
+ Preset &new_preset = *m_presets.insert(it, preset);
+ new_preset.save(nullptr);
+ } else if (force_rewritten) {
+ *it = preset;
+ (*it).save(nullptr);
+ }
}
unlock();
return true;
}
-bool PresetCollection::clone_presets_for_printer(std::vector const &presets, std::vector &failures, std::string const &printer)
+bool PresetCollection::clone_presets_for_printer(std::vector const &presets, std::vector &failures, std::string const &printer, bool force_rewritten)
{
return clone_presets(presets, failures, [printer](Preset &preset) {
preset.name = preset.alias + " @ " + printer;
+ preset.alias = preset.name;
auto *compatible_printers = dynamic_cast(preset.config.option("compatible_printers"));
compatible_printers->values = std::vector{ printer };
- });
+ }, force_rewritten);
}
bool PresetCollection::create_presets_from_template_for_printer(std::vector const &templates, std::vector &failures, std::string const &printer)
@@ -2125,13 +2131,15 @@ bool PresetCollection::create_presets_from_template_for_printer(std::vector const &presets,
std::vector & failures,
std::string const & filament_name,
- std::string const & filament_id)
+ std::string const & filament_id,
+ bool force_rewritten)
{
return clone_presets(presets, failures, [filament_name, filament_id](Preset &preset) {
preset.name = filament_name + " " + preset.name.substr(preset.name.find_last_of('@'));
preset.alias = filament_name;
preset.filament_id = filament_id;
- });
+ },
+ force_rewritten);
}
std::map> PresetCollection::get_filament_presets() const
diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp
index 30b90da66a..74676c845f 100644
--- a/src/libslic3r/Preset.hpp
+++ b/src/libslic3r/Preset.hpp
@@ -449,10 +449,10 @@ public:
Preset& load_preset(const std::string &path, const std::string &name, const DynamicPrintConfig &config, bool select = true, Semver file_version = Semver(), bool is_custom_defined = false);
Preset& load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select = true, Semver file_version = Semver(), bool is_custom_defined = false);
- bool clone_presets(std::vector const &presets, std::vector &failures, std::function modifier);
- bool clone_presets_for_printer(std::vector const &presets, std::vector &failures, std::string const &printer);
+ bool clone_presets(std::vector const &presets, std::vector &failures, std::function modifier, bool force_rewritten = false);
+ bool clone_presets_for_printer(std::vector const &presets, std::vector &failures, std::string const &printer, bool force_rewritten = false);
bool create_presets_from_template_for_printer(std::vector const &templates, std::vector &failures, std::string const &printer);
- bool clone_presets_for_filament(std::vector const &presets, std::vector &failures, std::string const &filament_name, std::string const &filament_id);
+ bool clone_presets_for_filament(std::vector const &presets, std::vector &failures, std::string const &filament_name, std::string const &filament_id, bool force_rewritten = false);
std::map> get_filament_presets() const;
diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp
index 35d2197a7c..3c839937e5 100644
--- a/src/libslic3r/PresetBundle.cpp
+++ b/src/libslic3r/PresetBundle.cpp
@@ -1202,7 +1202,6 @@ VendorProfile PresetBundle::get_custom_vendor_models() const
iter_model = vendor.models.emplace(vendor.models.end(), VendorProfile::PrinterModel{});
iter_model->name = model;
}
- iter_model->variants.push_back(variant);
}
return vendor;
}
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index ed0b0051c8..0da9ee3ef8 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -416,6 +416,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Calibration.cpp
GUI/PrintOptionsDialog.hpp
GUI/PrintOptionsDialog.cpp
+ GUI/CreatePresetsDialog.hpp
+ GUI/CreatePresetsDialog.cpp
Utils/json_diff.hpp
Utils/json_diff.cpp
GUI/KBShortcutsDialog.hpp
diff --git a/src/slic3r/GUI/CreatePresetsDialog.cpp b/src/slic3r/GUI/CreatePresetsDialog.cpp
new file mode 100644
index 0000000000..cff40017ed
--- /dev/null
+++ b/src/slic3r/GUI/CreatePresetsDialog.cpp
@@ -0,0 +1,2677 @@
+#include "CreatePresetsDialog.hpp"
+
+#include
+#include
+#include
+#include "libslic3r/PresetBundle.hpp"
+#include "I18N.hpp"
+#include "GUI_App.hpp"
+#include "MsgDialog.hpp"
+#include "miniz.h"
+#include
+#include
+
+#define NAME_OPTION_COMBOBOX_SIZE wxSize(FromDIP(200), FromDIP(24))
+#define FILAMENT_PRESET_COMBOBOX_SIZE wxSize(FromDIP(300), FromDIP(24))
+#define OPTION_SIZE wxSize(FromDIP(100), FromDIP(24))
+#define PRINTER_LIST_SIZE wxSize(-1, FromDIP(100))
+#define FILAMENT_LIST_SIZE wxSize(FromDIP(560), FromDIP(100))
+#define FILAMENT_OPTION_SIZE wxSize(FromDIP(-1), FromDIP(30))
+#define PRESET_TEMPLATE_SIZE wxSize(FromDIP(-1), FromDIP(100))
+#define PRINTER_SPACE_SIZE wxSize(FromDIP(80), FromDIP(24))
+#define ORIGIN_TEXT_SIZE wxSize(FromDIP(10), FromDIP(24))
+#define PRINTER_PRESET_VENDOR_SIZE wxSize(FromDIP(150), FromDIP(24))
+#define PRINTER_PRESET_MODEL_SIZE wxSize(FromDIP(280), FromDIP(24))
+#define STATIC_TEXT_COLOUR wxColour("#363636")
+#define PRINTER_LIST_COLOUR wxColour("#EEEEEE")
+#define FILAMENT_OPTION_COLOUR wxColour("#D9D9D9")
+#define SELECT_ALL_OPTION_COLOUR wxColour("#00AE42")
+#define DEFAULT_PROMPT_TEXT_COLOUR wxColour("#ACACAC")
+
+namespace Slic3r {
+namespace GUI {
+
+static const std::vector filament_vendors =
+ {"Made for Prusa", "Prusa", "Prusa Polymers", "123-3D", "3DJAKE", "AmazonBasics", "AMOLEN", "Atoraie Filarmetl",
+ "AzureFilm", "BIBO", "ColorFabb", "Creality", "Das Filament", "Devil Design", "E3D", "Eolas Prints",
+ "Esun", "Extrudr", "Fiberlogy", "Filament PM", "Filatech", "Fillamentum", "FormFutura", "Geeetech",
+ "Generic", "Hatchbox", "Infinity3D", "Inland", "KVP", "MakerGear", "MatterHackers", "Overture",
+ "Polymaker", "PrimaSelect", "Print4Taste", "Printed Solid", "Proto-pasta", "ProtoPasta", "Push Plastic", "Real Filament",
+ "SainSmart", "Smartfil", "Snapmaker", "Solutech", "Velleman", "Verbatim", "VOXELPLA"};
+
+static const std::vector filament_types = {"PLA", "PLA+", "PLA Tough", "PETG", "ABS", "ASA", "FLEX", "HIPS", "PA", "PACF",
+ "NYLON", "PVA", "PC", "PCABS", "PCTG", "PCCF", "PP", "PEI", "PET", "PETG",
+ "PETGCF", "PTBA", "PTBA90A", "PEEK", "TPU93A", "TPU75D", "TPU", "TPU92A", "TPU98A", "Misc",
+ "TPE", "GLAZE", "Nylon", "CPE", "METAL", "ABST", "Carbon Fiber"};
+
+static const std::vector system_filament_types = {"PLA", "ABS", "TPU", "PC","ASA", "PA-CF","PET-CF", "PETG", "PETG-CF", "PLA-AERO", "PLA-CF", "PA",
+ "HIPS", "PPS", "PVA"};
+
+static const std::vector printer_vendors = {"AnkerMake", "Anycubic", "Artillery", "BIBO", "BIQU", "Creality ENDER", "Creality CR", "Creality SERMOON",
+ "Elegoo", "FLSun", "gCreate", "Geeetech", "INAT", "Infinity3D", "Jubilee", "LNL3D",
+ "LulzBot", "MakerGear", "Papapiu", "Print4Taste", "RatRig", "Rigid3D", "Snapmaker", "Sovol",
+ "TriLAB", "Trimaker", "Ultimaker", "Voron", "Zonestar"};
+
+static const std::unordered_map> printer_model_map =
+ {{"AnkerMake", {"M5"}},
+ {"Anycubic", {"Kossel Linear Plus", "Kossel Pulley(Linear)", "Mega Zero", "i3 Mega", "i3 Mega S", "4Max Pro 2.0", "Predator"}},
+ {"Artillery", {"sidewinder X1", "Genius", "Hornet"}},
+ {"BIBO", {"BIBO2 Touch"}},
+ {"BIQU", {"BIQU BX"}},
+ {"Creality ENDER", {"Creality Ender-3", "Creality Ender-3 BLTouch", "Creality Ender-3 Pro", "Creality Ender-3 Neo", "Creality Ender-3", "Creality Ender-3 V2",
+ "Creality Ender-3 V2 Neo", "Creality Ender-3 S1", "Creality Ender-3 S1 Pro", "Creality Ender-3 S1 Plus", "Creality Ender-3 Max", "Creality Ender-3 Max Neo",
+ "Creality Ender-4", "Creality Ender-5", "Creality Ender-5 Pro", "Creality Ender-5 Pro", "Creality Ender-5 S1", "Creality Ender-6",
+ "Creality Ender-7", "Creality Ender-2", "Creality Ender-2 Pro"}},
+ {"Creality CR", {"Creality CR-5 Pro", "Creality CR-5 Pro H", "Creality CR-6 SE", "Creality CR-6 Max", "Creality CR-10 SMART", "Creality CR-10 SMART Pro", "Creality CR-10 Mini",
+ "Creality CR-10 Max", "Creality CR-10", "Creality CR-10 v2", "Creality CR-10 v3", "Creality CR-10 S", "Creality CR-10 v2", "Creality CR-10 v2",
+ "Creality CR-10 S Pro", "Creality CR-10 S Pro v2", "Creality CR-10 S4", "Creality CR-10 S5", "Creality CR-20", "Creality CR-20 Pro", "Creality CR-200B",
+ "Creality CR-8"}},
+ {"Creality SERMOON",{"Creality Sermoon-D1", "Creality Sermoon-V1", "Creality Sermoon-V1 Pro"}},
+ {"Elegoo", {"Elegoo Neptune-1", "Elegoo Neptune-2", "Elegoo Neptune-2D", "Elegoo Neptune-2s", "Elegoo Neptune-3", "Elegoo Neptune-3 Max", "Elegoo Neptune-3 Plus",
+ "Elegoo Neptune-3 Pro", "Elegoo Neptune-x"}},
+ {"FLSun", {"FLSun QQs Pro", "FLSun Q5"}},
+ {"gCreate", {"gMax 1.5XT Plus", "gMax 2", "gMax 2 Pro", "gMax 2 Dual 2in1", "gMax 2 Dual Chimera"}},
+ {"Geeetech", {"Geeetech Thunder", "Geeetech Thunder Pro", "Geeetech Mizar s", "Geeetech Mizar Pro", "Geeetech Mizar", "Geeetech Mizar Max",
+ "Geeetech Mizar M", "Geeetech A10 Pro", "Geeetech A10 M", "Geeetech A10 T", "Geeetech A20", "Geeetech A20 M",
+ "Geeetech A20T", "Geeetech A30 Pro", "Geeetech A30 M", "Geeetech A30 T", "Geeetech E180", "Geeetech Me Ducer",
+ "Geeetech Me creator", "Geeetech Me Creator2", "Geeetech GiantArmD200", "Geeetech l3 ProB", "Geeetech l3 Prow", "Geeetech l3 ProC"}},
+ {"INAT", {"INAT Proton X Rail", "INAT Proton x Rod", "INAT Proton XE-750"}},
+ {"Infinity3D", {"Infinity3D DEV-200", "Infinity3D DEV-350"}},
+ {"Jubilee", {"Jubilee"}},
+ {"LNL3D", {"LNL3D D3 v2", "LNL3D D3 Vulcan", "LNL3D D5", "LNL3D D6"}},
+ {"LulzBot", {"Mini Aero", "Taz6 Aero"}},
+ {"MakerGear", {"MakerGear Micro", "MakerGear M2(V4 Hotend)", "MakerGear M2 Dual", "M3 - single Extruder", "M3- Independent Dual Rev.0", "M3 - Independent Dual Rev.0(Duplication Mode)",
+ "M3 - Independent Dual Rev.1", "M3 - Independent Dual Rev.1(Duplication Mode)", "ultra One", "Ultra One (DuplicationMode)"}},
+ {"Papapiu", {"Papapiu N1s"}},
+ {"Print4Taste", {"mycusini 2.0"}},
+ {"RatRig", {"RatRig v-core-3 300mm", "RatRig v-Core-3 400mm", "RatRig V-Core-3 500mm", "RatRig V-Minion"}},
+ {"Rigid3D", {"Rigid3D Zero2", "Rigid3D Zero3"}},
+ {"Snapmaker", {"Snapmaker A250", "Snapmaker A350"}},
+ {"Sovol", {"SV06", "SV06 PLUS", "SV05", "SV04", "SV03 / SV03 BLTOUCH", "SVo2 / SV02 BLTOUCH", "SVo1 / SV01 BLToUCH", "SV01 PRO"}},
+ {"TriLAB", {"AzteQ Industrial", "AzteQ Dynamic", "DeltiQ 2", "DeltiQ 2 Plus", "DeltiQ 2 + FlexPrint 2", "DeltiQ 2 Plus + FlexPrint 2", "DeltiQ 2 +FlexPrint",
+ "DeltiQ 2 Plus + FlexPrint", "DeltiQ M", "DeltiQ L", "DeltiQ XL"}},
+ {"Trimaker", {"Trimaker Nebula cloud", "Trimaker Nebula", "Trimaker Cosmos ll"}},
+ {"Ultimaker", {"Ultimaker 2"}},
+ {"Voron", {"Voron v2 250mm3", "Voron v2 300mm3", "Voron v2 350mm3", "Voron v2 250mm3", "Voron v2 300mm3", "Voron v2 350mm3", "Voron v1 250mm3", "Voron v1 300mm3", "Voron v1 350mm3",
+ "voron Zero 120mm3", "Voron Switchwire"}},
+ {"Zonestar", {"Zonestar Z5", "Zonestar Z6", "Zonestar Z5x", "Zonestar Z8", "Zonestar Z9"}}};
+
+static const std::vector nozzle_diameter = {"0.2","0.25", "0.3","0.35", "0.4", "0.5", "0.6","0.75", "0.8", "1.0", "1.2"};
+
+static std::string get_curr_time()
+{
+ std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
+
+ std::time_t time = std::chrono::system_clock::to_time_t(now);
+
+ std::tm local_time = *std::localtime(&time);
+ std::ostringstream time_stream;
+ time_stream << std::put_time(&local_time, "%Y_%m_%d_%H_%M_%S");
+
+ std::string current_time = time_stream.str();
+ return current_time;
+}
+
+static wxBoxSizer* create_checkbox(wxWindow* parent, Preset* preset, std::string& preset_name, std::vector>& preset_checkbox)
+{
+ wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
+ CheckBox * checkbox = new CheckBox(parent);
+ sizer->Add(checkbox, 0, 0, 0);
+ preset_checkbox.push_back(std::make_pair(checkbox, preset));
+ wxStaticText *preset_name_str = new wxStaticText(parent, wxID_ANY, preset_name);
+ sizer->Add(preset_name_str, 0, wxLEFT, 5);
+ return sizer;
+}
+
+static wxArrayString get_exist_vendor_choices(VendorMap& vendors)
+{
+ wxArrayString choices;
+ PresetBundle temp_preset_bundle;
+ std::pair system_models = temp_preset_bundle.load_system_models_from_json(ForwardCompatibilitySubstitutionRule::EnableSystemSilent);
+ PresetBundle * preset_bundle = wxGetApp().preset_bundle;
+ VendorProfile users_models = preset_bundle->get_custom_vendor_models();
+
+ vendors = temp_preset_bundle.vendors;
+
+ if (!users_models.models.empty()) {
+ vendors[users_models.name] = users_models;
+ }
+
+ for (const pair &vendor : vendors) {
+ if (vendor.second.models.empty() || vendor.second.id.empty()) continue;
+ choices.Add(vendor.first);
+ }
+ return choices;
+}
+
+std::string get_machine_name(const std::string &preset_name)
+{
+ size_t index_at = preset_name.find("@");
+ if (std::string::npos == index_at) {
+ return "";
+ } else {
+ return preset_name.substr(index_at + 1);
+ }
+}
+
+std::string get_filament_name(std::string &preset_name)
+{
+ size_t index_at = preset_name.find("@");
+ if (std::string::npos == index_at) {
+ return preset_name;
+ } else {
+ return preset_name.substr(0, index_at - 1);
+ }
+}
+
+static wxBoxSizer *create_select_filament_preset_checkbox(wxWindow * parent,
+ std::string & machine_name,
+ std::vector presets,
+ std::unordered_map &machine_filament_preset)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer *checkbox_sizer = new wxBoxSizer(wxVERTICAL);
+ CheckBox * checkbox = new CheckBox(parent);
+ checkbox_sizer->Add(checkbox, 0, wxEXPAND | wxRIGHT, 5);
+
+ wxBoxSizer *combobox_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *machine_name_str = new wxStaticText(parent, wxID_ANY, machine_name);
+ ComboBox * combobox = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200, 24), 0, nullptr, wxCB_READONLY);
+ combobox->SetBackgroundColor(PRINTER_LIST_COLOUR);
+ combobox->SetLabel(_L("Select filament preset"));
+ combobox->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ combobox->Bind(wxEVT_COMBOBOX, [combobox, checkbox, presets, &machine_filament_preset](wxCommandEvent &e) {
+ combobox->SetLabelColor(*wxBLACK);
+ std::string preset_name = into_u8(combobox->GetLabel());
+ for (Preset *preset : presets) {
+ if (preset_name == preset->name) {
+ machine_filament_preset[checkbox] = preset;
+ }
+ }
+ e.Skip();
+ });
+ combobox_sizer->Add(machine_name_str, 0, wxEXPAND, 0);
+ combobox_sizer->Add(combobox, 0, wxEXPAND | wxTOP, 5);
+
+ wxArrayString choices;
+ for (Preset *preset : presets) {
+ choices.Add(preset->name);
+ }
+ combobox->Set(choices);
+
+ horizontal_sizer->Add(checkbox_sizer);
+ horizontal_sizer->Add(combobox_sizer);
+ return horizontal_sizer;
+}
+
+static wxString get_curr_radio_type(std::vector> &radio_btns)
+{
+ for (std::pair radio_string : radio_btns) {
+ if (radio_string.first) {
+ return radio_string.second;
+ }
+ }
+ return "";
+}
+
+static std::string calculate_md5(const std::string &input)
+{
+ unsigned char digest[MD5_DIGEST_LENGTH];
+ std::string md5;
+
+ EVP_MD_CTX *mdContext = EVP_MD_CTX_new();
+ EVP_DigestInit(mdContext, EVP_md5());
+ EVP_DigestUpdate(mdContext, input.c_str(), input.length());
+ EVP_DigestFinal(mdContext, digest, nullptr);
+ EVP_MD_CTX_free(mdContext);
+
+ char hexDigest[MD5_DIGEST_LENGTH * 2 + 1];
+ for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) { sprintf(hexDigest + (i * 2), "%02x", digest[i]); }
+ hexDigest[MD5_DIGEST_LENGTH * 2] = '\0';
+
+ md5 = std::string(hexDigest);
+ return md5;
+}
+
+static std::string get_filament_id(std::string vendor_typr_serial)
+{
+ std::string user_filament_id = "P" + calculate_md5(vendor_typr_serial).substr(0, 7);
+
+ std::unordered_map> filament_id_to_filament_name;
+
+ // temp filament presets
+ PresetBundle temp_preset_bundle;
+ temp_preset_bundle.load_system_filaments_json(Slic3r::ForwardCompatibilitySubstitutionRule::EnableSilent);
+ std::string dir_user_presets = wxGetApp().app_config->get("preset_folder");
+ if (dir_user_presets.empty()) {
+ temp_preset_bundle.load_user_presets(DEFAULT_USER_FOLDER_NAME, ForwardCompatibilitySubstitutionRule::EnableSilent);
+ } else {
+ temp_preset_bundle.load_user_presets(dir_user_presets, ForwardCompatibilitySubstitutionRule::EnableSilent);
+ }
+ const std::deque &filament_presets = temp_preset_bundle.filaments.get_presets();
+
+ for (const Preset &preset : filament_presets) {
+ std::string preset_name = preset.name;
+ filament_id_to_filament_name[preset.filament_id].push_back(get_filament_name(preset_name));
+ }
+ // global filament presets
+ PresetBundle * preset_bundle = wxGetApp().preset_bundle;
+ std::map> temp_filament_id_to_presets = preset_bundle->filaments.get_filament_presets();
+ for (std::pair> filament_id_to_presets : temp_filament_id_to_presets) {
+ if (filament_id_to_presets.first.empty()) continue;
+ for (const Preset *preset : filament_id_to_presets.second) {
+ std::string preset_name = preset->name;
+ filament_id_to_filament_name[preset->filament_id].push_back(get_filament_name(preset_name));
+ }
+ }
+ while (filament_id_to_filament_name.find(user_filament_id) != filament_id_to_filament_name.end()) {//find same filament id
+ bool have_same_filament_name = false;
+ for (const std::string &name : filament_id_to_filament_name.find(user_filament_id)->second) {
+ if (name == vendor_typr_serial) {
+ have_same_filament_name = true;
+ break;
+ }
+ }
+ if (have_same_filament_name) {
+ break;
+ }
+ else {
+ user_filament_id = "P" + calculate_md5(vendor_typr_serial + get_curr_time()).substr(0, 7);
+ }
+ }
+
+
+ return user_filament_id;
+}
+
+static json get_config_json(const Preset* preset) {
+ json j;
+ // record the headers
+ j[BBL_JSON_KEY_VERSION] = preset->version.to_string();
+ j[BBL_JSON_KEY_NAME] = preset->name;
+ j[BBL_JSON_KEY_FROM] = "";
+
+ DynamicPrintConfig config = preset->config;
+
+ // record all the key-values
+ for (const std::string &opt_key : config.keys()) {
+ const ConfigOption *opt = config.option(opt_key);
+ if (opt->is_scalar()) {
+ if (opt->type() == coString)
+ // keep \n, \r, \t
+ j[opt_key] = (dynamic_cast(opt))->value;
+ else
+ j[opt_key] = opt->serialize();
+ } else {
+ const ConfigOptionVectorBase *vec = static_cast(opt);
+ std::vector string_values = vec->vserialize();
+
+ json j_array(string_values);
+ j[opt_key] = j_array;
+ }
+ }
+
+ return j;
+}
+
+static char* read_json_file(const std::string &preset_path)
+{
+ FILE *json_file = boost::nowide::fopen(boost::filesystem::path(preset_path).make_preferred().string().c_str(), "rb");
+ if (json_file == NULL) {
+ BOOST_LOG_TRIVIAL(info) << "Failed to open JSON file: " << preset_path;
+ return NULL;
+ }
+ fseek(json_file, 0, SEEK_END); // seek to end
+ long file_size = ftell(json_file); // get file size
+ fseek(json_file, 0, SEEK_SET); // seek to start
+
+ char * json_contents = (char *) malloc(file_size);
+ if (json_contents == NULL) {
+ BOOST_LOG_TRIVIAL(info) << "Failed to allocate memory for JSON file ";
+ fclose(json_file);
+ return NULL;
+ }
+
+ fread(json_contents, 1, file_size, json_file);
+ fclose(json_file);
+
+ return json_contents;
+}
+
+CreateFilamentPresetDialog::CreateFilamentPresetDialog(wxWindow *parent)
+ : DPIDialog(parent ? parent : nullptr, wxID_ANY, _L("Creat Filament"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) {
+
+ m_create_type.base_filament = _L("Create based on current filamet");
+ m_create_type.base_filament_preset = _L("Copy current filament preset ");
+
+ this->SetBackgroundColour(*wxWHITE);
+ this->SetSize(wxSize(FromDIP(600), FromDIP(480)));
+
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
+ wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL);
+ // top line
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
+ m_line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
+ m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
+ m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
+
+ m_main_sizer->Add(create_item(FilamentOptionType::VENDOR), 0, wxEXPAND | wxALL, FromDIP(5));
+ m_main_sizer->Add(create_item(FilamentOptionType::TYPE), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ m_main_sizer->Add(create_item(FilamentOptionType::SERIAL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ m_main_sizer->Add(create_item(FilamentOptionType::FILAMENT_PRESET), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ m_main_sizer->Add(create_item(FilamentOptionType::PRESET_FOR_PRINTER), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ m_main_sizer->Add(create_button_item(), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+
+ get_all_filament_presets();
+ select_curr_radiobox(m_create_type_btns, 0);
+
+ this->SetSizer(m_main_sizer);
+
+ Layout();
+ Fit();
+
+ wxGetApp().UpdateDlgDarkUI(this);
+}
+
+CreateFilamentPresetDialog::~CreateFilamentPresetDialog() {}
+
+void CreateFilamentPresetDialog::on_dpi_changed(const wxRect &suggested_rect) {}
+
+wxBoxSizer *CreateFilamentPresetDialog::create_item(FilamentOptionType option_type)
+{
+
+ wxSizer *item = nullptr;
+ switch (option_type) {
+ case VENDOR: return create_vendor_item();
+ case TYPE: return create_type_item();
+ case SERIAL: return create_serial_item();
+ case FILAMENT_PRESET: return create_filament_preset_item();
+ case PRESET_FOR_PRINTER: return create_filament_preset_for_printer_item();
+ default: return nullptr;
+ }
+}
+wxBoxSizer *CreateFilamentPresetDialog::create_vendor_item()
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_vendor_text = new wxStaticText(this, wxID_ANY, _L("Vendor"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_vendor_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxArrayString choices;
+ for (const wxString &vendor : filament_vendors) {
+ choices.push_back(vendor);
+ }
+ wxString no_vendor_choice = _L("No vendor I want");
+ choices.push_back(no_vendor_choice);
+
+ wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxVERTICAL);
+ m_filament_vendor_combobox = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
+ m_filament_vendor_combobox->SetLabel(_L("Select Vendor"));
+ m_filament_vendor_combobox->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ m_filament_vendor_combobox->Set(choices);
+ comboBoxSizer->Add(m_filament_vendor_combobox, 0, wxEXPAND | wxALL, 0);
+ m_filament_vendor_combobox->Bind(wxEVT_COMBOBOX, [this, no_vendor_choice](wxCommandEvent &e) {
+ m_filament_vendor_combobox->SetLabelColor(*wxBLACK);
+ wxString vendor_name = m_filament_vendor_combobox->GetStringSelection();
+ if (vendor_name == no_vendor_choice) {
+ m_filament_custom_vendor_input->Show();
+ } else {
+ m_filament_custom_vendor_input->Hide();
+ }
+ Layout();
+ Fit();
+ });
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *textInputSizer = new wxBoxSizer(wxVERTICAL);
+ m_filament_custom_vendor_input = new TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, wxTE_PROCESS_ENTER);
+ m_filament_custom_vendor_input->SetSize(NAME_OPTION_COMBOBOX_SIZE);
+ textInputSizer->Add(m_filament_custom_vendor_input, 0, wxEXPAND | wxALL, 0);
+ m_filament_custom_vendor_input->GetTextCtrl()->SetHint(_L("Input custom vendor"));
+ m_filament_custom_vendor_input->Hide();
+ horizontal_sizer->Add(textInputSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+
+}
+
+wxBoxSizer *CreateFilamentPresetDialog::create_type_item()
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(this, wxID_ANY, _L("Type"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxArrayString filament_type;
+ for (const wxString &filament : system_filament_types) {
+ filament_type.Add(filament);
+ }
+
+ wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxVERTICAL);
+ m_filament_type_combobox = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
+ m_filament_type_combobox->SetLabel(_L("Select Type"));
+ m_filament_type_combobox->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ m_filament_type_combobox->Set(filament_type);
+ comboBoxSizer->Add(m_filament_type_combobox, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ m_filament_type_combobox->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) {
+ m_filament_type_combobox->SetLabelColor(*wxBLACK);
+ const wxString &curr_create_type = curr_create_filament_type();
+ clear_filament_preset_map();
+ if (curr_create_type == m_create_type.base_filament) {
+ wxArrayString filament_preset_choice = get_filament_preset_choices();
+ m_filament_preset_combobox->Set(filament_preset_choice);
+ m_filament_preset_combobox->SetLabel(_L("Select Filament Preset"));
+ m_filament_preset_combobox->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+
+ } else if (curr_create_type == m_create_type.base_filament_preset) {
+ get_filament_presets_by_machine();
+ }
+ Layout();
+ Fit();
+ e.Skip();
+ });
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreateFilamentPresetDialog::create_serial_item()
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_serial_text = new wxStaticText(this, wxID_ANY, _L("Serial"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxVERTICAL);
+ m_filament_serial_input = new TextInput(this, "", "", "", wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, wxTE_PROCESS_ENTER);
+ comboBoxSizer->Add(m_filament_serial_input, 0, wxEXPAND | wxALL, 0);
+ wxStaticText *static_eg_text = new wxStaticText(this, wxID_ANY, _L("e.g. Basic, Matte, Silk, Marble"), wxDefaultPosition, wxDefaultSize);
+ static_eg_text->SetForegroundColour(wxColour("#6B6B6B"));
+ static_eg_text->SetFont(::Label::Body_12);
+ comboBoxSizer->Add(static_eg_text, 0, wxEXPAND | wxTOP, FromDIP(5));
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreateFilamentPresetDialog::create_filament_preset_item()
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_filament_preset_text = new wxStaticText(this, wxID_ANY, _L("Filament preset"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_filament_preset_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer * comboBoxSizer = new wxBoxSizer(wxVERTICAL);
+ comboBoxSizer->Add(create_radio_item(m_create_type.base_filament, this, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxALL, 0);
+
+ m_filament_preset_combobox = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, FILAMENT_PRESET_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
+ m_filament_preset_combobox->SetLabel(_L("Select Filament Preset"));
+ m_filament_preset_combobox->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+
+
+ m_filament_preset_combobox->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) {
+ m_filament_preset_combobox->SetLabelColor(*wxBLACK);
+ std::string filament_type = into_u8(m_filament_preset_combobox->GetStringSelection());
+ std::unordered_map>::iterator iter = m_filament_choice_map.find(m_public_name_to_filament_id_map[filament_type]);
+
+ m_filament_preset_panel->Freeze();
+ m_filament_presets_sizer->Clear(true);
+ m_filament_preset_panel->Thaw();
+ m_filament_preset.clear();
+ if (iter != m_filament_choice_map.end()) {
+ for (Preset* preset : iter->second) {
+ std::string preset_name = wxString::FromUTF8(preset->name).ToStdString();
+ size_t index_at = preset_name.find("@");
+ if (std::string::npos != index_at) {
+ std::string machine_name = preset_name.substr(index_at + 1);
+ m_filament_presets_sizer->Add(create_checkbox(m_filament_preset_panel, preset, machine_name, m_filament_preset), 0, wxEXPAND | wxTOP | wxLEFT, FromDIP(5));
+ }
+ }
+ } else {
+
+ }
+
+ Layout();
+ Fit();
+ Refresh();
+
+ e.Skip();
+ });
+
+ comboBoxSizer->Add(m_filament_preset_combobox, 0, wxEXPAND | wxTOP, FromDIP(5));
+
+ comboBoxSizer->Add(create_radio_item(m_create_type.base_filament_preset, this, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
+
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ horizontal_sizer->Add(0, 0, 0, wxLEFT, FromDIP(30));
+
+ return horizontal_sizer;
+
+}
+
+wxBoxSizer *CreateFilamentPresetDialog::create_filament_preset_for_printer_item()
+{
+ wxBoxSizer *vertical_sizer = new wxBoxSizer(wxVERTICAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_filament_preset_text = new wxStaticText(this, wxID_ANY, _L("We could create the filament presets for your following printer:"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_filament_preset_text, 0, wxEXPAND | wxALL, 0);
+
+ m_filament_preset_panel = new wxPanel(this, wxID_ANY);
+ m_filament_preset_panel->SetBackgroundColour(PRINTER_LIST_COLOUR);
+ //m_filament_preset_panel->SetMinSize(PRINTER_LIST_SIZE);
+ m_filament_preset_panel->SetSize(PRINTER_LIST_SIZE);
+ m_filament_presets_sizer = new wxGridSizer(3, FromDIP(5), FromDIP(5));
+ m_filament_preset_panel->SetSizer(m_filament_presets_sizer);
+ optionSizer->Add(m_filament_preset_panel, 0, wxEXPAND | wxTOP | wxALIGN_CENTER_HORIZONTAL, FromDIP(5));
+
+ vertical_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return vertical_sizer;
+}
+
+wxBoxSizer *CreateFilamentPresetDialog::create_button_item()
+{
+ wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL);
+ bSizer_button->Add(0, 0, 1, wxEXPAND, 0);
+
+ StateColor btn_bg_green(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered),
+ std::pair(wxColour(0, 174, 66), StateColor::Normal));
+
+ m_button_create = new Button(this, _L("Create"));
+ m_button_create->SetBackgroundColor(btn_bg_green);
+ m_button_create->SetBorderColor(*wxWHITE);
+ m_button_create->SetTextColor(wxColour(0xFFFFFE));
+ m_button_create->SetFont(Label::Body_12);
+ m_button_create->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_create->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_create->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_create, 0, wxRIGHT, FromDIP(10));
+
+ m_button_create->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ //get vendor name
+ wxString vendor_str = m_filament_vendor_combobox->GetLabel();
+ std::string vendor_name;
+ if (_L("Select Vendor") == vendor_str) {
+ MessageDialog dlg(this, _L("Vendor is not selected, please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ } else if (_L("No vendor I want") == vendor_str) {
+ if (m_filament_custom_vendor_input->GetTextCtrl()->GetValue().empty()) {
+ MessageDialog dlg(this, _L("Custom vendor is not input, please input custom vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ } else {
+ vendor_name = into_u8(m_filament_custom_vendor_input->GetTextCtrl()->GetValue());
+ }
+ } else {
+ vendor_name = into_u8(vendor_str);
+ }
+
+ //get fialment type name
+ wxString type_str = m_filament_type_combobox->GetLabel();
+ std::string type_name;
+ if (_L("Select Type") == type_str) {
+ MessageDialog dlg(this, _L("Filament type is not selected, please reselect type."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ } else {
+ type_name = into_u8(type_str);
+ }
+ //get filament serial
+ wxString serial_str = m_filament_serial_input->GetTextCtrl()->GetValue();
+ std::string serial_name;
+ if (serial_str.empty()) {
+ MessageDialog dlg(this, _L("Filament serial is not inputed, please input serial."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ } else {
+ serial_name = into_u8(serial_str);
+ }
+
+ std::string filament_preset_name = vendor_name + " " + type_name + " " + serial_name;
+ std::string user_filament_id = get_filament_id(filament_preset_name);
+
+ const wxString &curr_create_type = curr_create_filament_type();
+ PresetBundle * preset_bundle = wxGetApp().preset_bundle;
+ std::vector filament_presets;
+ if (curr_create_type == m_create_type.base_filament) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":clone filament create type filament ";
+ for (const std::pair &preset : m_filament_preset) {
+ if (preset.first->GetValue()) {
+ filament_presets.push_back(preset.second);
+ }
+ }
+ if (!filament_presets.empty()) {
+ std::vector failures;
+ bool res = preset_bundle->filaments.clone_presets_for_filament(filament_presets, failures, filament_preset_name, user_filament_id);
+ if (!res) {
+ std::string failure_names;
+ for (std::string &failure : failures) {
+ failure_names += failure + "\n";
+ }
+ MessageDialog dlg(this, _L("Some existing presets have failed to be created, as follows:\n") + failure_names + _L("\nDo you want to rewrite it?"),
+ wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ if (dlg.ShowModal() == wxID_YES) {
+ res = preset_bundle->filaments.clone_presets_for_filament(filament_presets, failures, filament_preset_name, user_filament_id, true);
+ BOOST_LOG_TRIVIAL(info) << "clone filament have failures rewritten is successful? "<< res;
+ } else {
+ std::vector temp_filament_presets;
+ for (const Preset* preset : filament_presets) {
+ for (const std::string &exist_name : failures) {
+ if (exist_name == preset->name) {
+ continue;
+ }
+ temp_filament_presets.push_back(preset);
+ }
+ }
+ preset_bundle->filaments.clone_presets_for_filament(temp_filament_presets, failures, filament_preset_name, user_filament_id);
+ BOOST_LOG_TRIVIAL(info) << "clone filament have failures not rewritten is successful? " << res;
+ }
+ }
+ BOOST_LOG_TRIVIAL(info) << "clone filament no failures is successful? " << res;
+ } else {
+ MessageDialog dlg(this, _L("You have not selected a filament preset, please choose."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+ } else if (curr_create_type == m_create_type.base_filament_preset) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":clone filament presets create type filament preset";
+ for (const std::pair &checkbox_preset : m_machint_filament_preset) {
+ if (checkbox_preset.first->GetValue()) {
+ filament_presets.push_back(checkbox_preset.second);
+ }
+ }
+ if (!filament_presets.empty()) {
+ std::vector failures;
+ bool res = preset_bundle->filaments.clone_presets_for_filament(filament_presets, failures, filament_preset_name, user_filament_id);
+ if (!res) {
+ std::string failure_names;
+ for (std::string &failure : failures) { failure_names += failure + "\n"; }
+ MessageDialog dlg(this, _L("Some existing presets have failed to be created, as follows:\n") + failure_names,
+ wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ if (wxID_YES == dlg.ShowModal()) {
+ res = preset_bundle->filaments.clone_presets_for_filament(filament_presets, failures, filament_preset_name, user_filament_id, true);
+ BOOST_LOG_TRIVIAL(info) << "clone filament presets have failures rewritten is successful? " << res;
+ } else {
+ std::vector temp_filament_presets;
+ for (const Preset *preset : filament_presets) {
+ for (const std::string &exist_name : failures) {
+ if (exist_name == preset->name) { continue; }
+ temp_filament_presets.push_back(preset);
+ }
+ }
+ preset_bundle->filaments.clone_presets_for_filament(temp_filament_presets, failures, filament_preset_name, user_filament_id);
+ BOOST_LOG_TRIVIAL(info) << "clone filament have failures not rewritten is successful? " << res;
+ }
+ }
+ BOOST_LOG_TRIVIAL(info) << "clone filament presets no failures is successful? " << res;
+ } else {
+ MessageDialog dlg(this, _L("You have not selected a filament preset, please choose."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+ }
+
+ EndModal(wxID_OK);
+ });
+
+ StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ m_button_cancel = new Button(this, _L("Cancel"));
+ m_button_cancel->SetBackgroundColor(btn_bg_white);
+ m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
+ m_button_cancel->SetFont(Label::Body_12);
+ m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_cancel, 0, wxRIGHT, FromDIP(10));
+
+ m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ EndModal(wxID_CANCEL);
+ });
+
+ return bSizer_button;
+}
+
+wxArrayString CreateFilamentPresetDialog::get_filament_preset_choices()
+{
+ wxArrayString choices;
+ // get fialment type name
+ wxString type_str = m_filament_type_combobox->GetLabel();
+ std::string type_name;
+ if (_L("Select Type") == type_str) {
+ /*MessageDialog dlg(this, _L("Filament type is not selected, please reselect type."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();*/
+ return choices;
+ } else {
+ type_name = into_u8(type_str);
+ }
+
+ for (std::pair filament_presets : m_all_presets_map) {
+ Preset *preset = filament_presets.second;
+ if (std::string::npos == filament_presets.first.find(type_name)) continue;
+ m_filament_choice_map[preset->filament_id].push_back(preset);
+ }
+
+ int suffix = 0;
+ for (const pair> &preset : m_filament_choice_map) {
+ if (preset.second.empty()) continue;
+ std::set preset_name_set;
+ for (Preset* filament_preset : preset.second) {
+ std::string preset_name = filament_preset->name;
+ size_t index_at = preset_name.find("@");
+ if (std::string::npos != index_at) {
+ std::string cur_preset_name = preset_name.substr(0, index_at - 1);
+ preset_name_set.insert(cur_preset_name);
+ }
+ }
+ assert(1 == preset_name_set.size());
+ for (const std::string& public_name : preset_name_set) {
+ if (m_public_name_to_filament_id_map.find(public_name) != m_public_name_to_filament_id_map.end()) {
+ suffix++;
+ m_public_name_to_filament_id_map[public_name + "_" + std::to_string(suffix)] = preset.first;
+ choices.Add(public_name + "_" + std::to_string(suffix));
+ } else {
+ m_public_name_to_filament_id_map[public_name] = preset.first;
+ choices.Add(public_name);
+ }
+ }
+ }
+
+ return choices;
+}
+
+wxBoxSizer *CreateFilamentPresetDialog::create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+ RadioBox * radiobox = new RadioBox(parent);
+ horizontal_sizer->Add(radiobox, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(5));
+ radiobox_list.push_back(std::make_pair(radiobox, title));
+ int btn_idx = radiobox_list.size() - 1;
+ radiobox->Bind(wxEVT_LEFT_DOWN, [this, &radiobox_list, btn_idx](wxMouseEvent &e) { select_curr_radiobox(radiobox_list, btn_idx); });
+
+ wxStaticText *text = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
+ text->Bind(wxEVT_LEFT_DOWN, [this, &radiobox_list, btn_idx](wxMouseEvent &e) { select_curr_radiobox(radiobox_list, btn_idx); });
+ horizontal_sizer->Add(text, 0, wxEXPAND | wxLEFT, 0);
+
+ radiobox->SetToolTip(tooltip);
+ text->SetToolTip(tooltip);
+ return horizontal_sizer;
+}
+
+void CreateFilamentPresetDialog::select_curr_radiobox(std::vector> &radiobox_list, int btn_idx)
+{
+ int len = radiobox_list.size();
+ for (int i = 0; i < len; ++i) {
+ if (i == btn_idx) {
+ radiobox_list[i].first->SetValue(true);
+ const wxString &curr_selected_type = radiobox_list[i].second;
+ if (curr_selected_type == m_create_type.base_filament) {
+ m_filament_preset_combobox->Show();
+ if (_L("Select Type") != m_filament_type_combobox->GetLabel()) {
+ clear_filament_preset_map();
+ wxArrayString filament_preset_choice = get_filament_preset_choices();
+ m_filament_preset_combobox->Set(filament_preset_choice);
+ m_filament_preset_combobox->SetLabel(_L("Select Filament Preset"));
+ m_filament_preset_combobox->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ }
+ } else if (curr_selected_type == m_create_type.base_filament_preset) {
+ m_filament_preset_combobox->Hide();
+ if (_L("Select Type") != m_filament_type_combobox->GetLabel()) {
+ clear_filament_preset_map();
+ get_filament_presets_by_machine();
+ }
+ }
+ Fit();
+ Layout();
+ Refresh();
+ } else {
+ radiobox_list[i].first->SetValue(false);
+ }
+ }
+}
+
+wxString CreateFilamentPresetDialog::curr_create_filament_type()
+{
+ wxString curr_filament_type;
+ for (const std::pair &printer_radio : m_create_type_btns) {
+ if (printer_radio.first->GetValue()) {
+ curr_filament_type = printer_radio.second;
+ }
+ }
+ return curr_filament_type;
+}
+
+void CreateFilamentPresetDialog::get_filament_presets_by_machine()
+{
+ wxArrayString choices;
+ // get fialment type name
+ wxString type_str = m_filament_type_combobox->GetLabel();
+ std::string type_name;
+ if (_L("Select Type") == type_str) {
+ /*MessageDialog dlg(this, _L("Filament type is not selected, please reselect type."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT |
+ wxCENTRE); dlg.ShowModal();*/
+ return;
+ } else {
+ type_name = into_u8(type_str);
+ }
+
+ std::unordered_map> machine_name_to_presets;
+ for (std::pair filament_preset : m_all_presets_map) {
+ std::string preset_name = filament_preset.first;
+ if (std::string::npos == preset_name.find(type_name)) continue;
+ size_t index_at = preset_name.find("@");
+ if (std::string::npos == index_at) continue;
+ else {
+ std::string machine_name = preset_name.substr(index_at + 1);
+ machine_name_to_presets[machine_name].push_back(filament_preset.second);
+ }
+ }
+
+ for (std::pair> machine_filament_presets : machine_name_to_presets) {
+ std::string machine_name = machine_filament_presets.first;
+ std::vector &presets = machine_filament_presets.second;
+ m_filament_presets_sizer->Add(create_select_filament_preset_checkbox(m_filament_preset_panel, machine_name, presets, m_machint_filament_preset), 0, wxEXPAND | wxALL, FromDIP(5));
+ }
+
+}
+
+void CreateFilamentPresetDialog::get_all_filament_presets()
+{
+ // temp filament presets
+ PresetBundle temp_preset_bundle;
+ //temp_preset_bundle.load_system_filaments_json(Slic3r::ForwardCompatibilitySubstitutionRule::EnableSilent);
+ std::string dir_user_presets = wxGetApp().app_config->get("preset_folder");
+ if (dir_user_presets.empty()) {
+ temp_preset_bundle.load_user_presets(DEFAULT_USER_FOLDER_NAME, ForwardCompatibilitySubstitutionRule::EnableSilent);
+ } else {
+ temp_preset_bundle.load_user_presets(dir_user_presets, ForwardCompatibilitySubstitutionRule::EnableSilent);
+ }
+ const std::deque &filament_presets = temp_preset_bundle.filaments.get_presets();
+
+ for (const Preset &preset : filament_presets) {
+ if (preset.filament_id.empty()) continue; // to do: empty filament id is user preset
+ std::string filament_preset_name = wxString::FromUTF8(preset.name).ToStdString();
+ Preset *filament_preset = new Preset(preset);
+ m_all_presets_map[filament_preset_name] = filament_preset;
+ }
+ // global filament presets
+ PresetBundle * preset_bundle = wxGetApp().preset_bundle;
+ std::map> temp_filament_id_to_presets = preset_bundle->filaments.get_filament_presets();
+ for (std::pair> filament_id_to_presets : temp_filament_id_to_presets) {
+ if (filament_id_to_presets.first.empty()) continue;
+ for (const Preset *preset : filament_id_to_presets.second) {
+ std::string filament_preset_name = wxString::FromUTF8(preset->name).ToStdString();
+ if (!preset->is_visible) continue;
+ Preset *filament_preset = new Preset(*preset);
+ m_all_presets_map[filament_preset_name] = filament_preset;
+ }
+ }
+}
+
+void CreateFilamentPresetDialog::clear_filament_preset_map()
+{
+ m_filament_choice_map.clear();
+ m_filament_preset.clear();
+ m_machint_filament_preset.clear();
+ m_public_name_to_filament_id_map.clear();
+ m_filament_preset_panel->Freeze();
+ m_filament_presets_sizer->Clear(true);
+ m_filament_preset_panel->Thaw();
+}
+
+CreatePrinterPresetDialog::CreatePrinterPresetDialog(wxWindow *parent)
+: DPIDialog(parent ? parent : nullptr, wxID_ANY, _L("Create Printer/Nozzle"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
+{
+ m_create_presets_type = {_L("Create from template"), _L("Create based on current printer")};
+ m_create_printer_type = {_L("Create Printer"), _L("Create Nozzle for existing printer")};
+
+ this->SetBackgroundColour(*wxWHITE);
+ this->SetSize(wxSize(FromDIP(600), FromDIP(600)));
+
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
+ wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL);
+ // top line
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 2), wxTAB_TRAVERSAL);
+ m_line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
+ m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
+ m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
+ m_main_sizer->Add(create_step_switch_item(), 0, wxEXPAND | wxALL, FromDIP(5));
+
+ wxBoxSizer *page_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ m_page1 = new wxWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
+ m_page1->SetBackgroundColour(*wxWHITE);
+ m_page2 = new wxWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
+ m_page2->SetBackgroundColour(*wxWHITE);
+
+ create_printer_page1(m_page1);
+ create_printer_page2(m_page2);
+ m_page2->Hide();
+
+ page_sizer->Add(m_page1, 1, wxEXPAND, 0);
+ page_sizer->Add(m_page2, 1, wxEXPAND, 0);
+ m_main_sizer->Add(page_sizer, 0, wxEXPAND | wxRIGHT, FromDIP(10));
+ select_curr_radiobox(m_create_type_btns, 0);
+ select_curr_radiobox(m_create_presets_btns, 0);
+
+ m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
+
+ this->SetSizer(m_main_sizer);
+
+ Layout();
+ Fit();
+
+ wxGetApp().UpdateDlgDarkUI(this);
+}
+
+CreatePrinterPresetDialog::~CreatePrinterPresetDialog() {}
+
+void CreatePrinterPresetDialog::on_dpi_changed(const wxRect &suggested_rect) {}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_step_switch_item()
+{
+ wxBoxSizer *step_switch_sizer = new wxBoxSizer(wxVERTICAL);
+
+ std::string wiki_url = "https://makerhub-pre.bambu-lab.com";
+ wxHyperlinkCtrl *m_download_hyperlink = new wxHyperlinkCtrl(this, wxID_ANY, _L("wiki"), wiki_url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
+ step_switch_sizer->Add(m_download_hyperlink, 0, wxRIGHT | wxALIGN_RIGHT, FromDIP(5));
+
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+ m_step_1 = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("step_1", nullptr, FromDIP(20)), wxDefaultPosition, wxDefaultSize);
+ horizontal_sizer->Add(m_step_1, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
+ wxStaticText *static_create_printer_text = new wxStaticText(this, wxID_ANY, _L("Create Printer"), wxDefaultPosition, wxDefaultSize);
+ horizontal_sizer->Add(static_create_printer_text, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
+ auto divider_line = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(50), 1));
+ divider_line->SetBackgroundColour(PRINTER_LIST_COLOUR);
+ horizontal_sizer->Add(divider_line, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(3));
+ m_step_2 = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("step_2_ready", nullptr, FromDIP(20)), wxDefaultPosition, wxDefaultSize);
+ horizontal_sizer->Add(m_step_2, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
+ wxStaticText *static_improt_presets_text = new wxStaticText(this, wxID_ANY, _L("Improt Presets"), wxDefaultPosition, wxDefaultSize);
+ horizontal_sizer->Add(static_improt_presets_text, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
+
+ step_switch_sizer->Add(horizontal_sizer, 0, wxBOTTOM | wxALIGN_CENTER_HORIZONTAL, FromDIP(10));
+
+ auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
+ line_top->SetBackgroundColour(PRINTER_LIST_COLOUR);
+
+ step_switch_sizer->Add(line_top, 0, wxEXPAND | wxALL, FromDIP(10));
+
+ return step_switch_sizer;
+}
+
+void CreatePrinterPresetDialog::create_printer_page1(wxWindow *parent)
+{
+ this->SetBackgroundColour(*wxWHITE);
+
+ wxBoxSizer *page1_sizer = new wxBoxSizer(wxVERTICAL);
+
+ page1_sizer->Add(create_type_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_printer_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_nozzle_diameter_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_bed_shape_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_bed_size_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_origin_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_hot_bed_stl_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_hot_bed_svg_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_max_print_height_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page1_sizer->Add(create_page1_btns_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+
+ parent->SetSizer(page1_sizer);
+ Layout();
+
+ wxGetApp().UpdateDlgDarkUI(this);
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_type_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_serial_text = new wxStaticText(parent, wxID_ANY, _L("Create Type"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *radioBoxSizer = new wxBoxSizer(wxVERTICAL);
+
+ radioBoxSizer->Add(create_radio_item(m_create_printer_type[0], parent, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxALL, 0);
+ radioBoxSizer->Add(create_radio_item(m_create_printer_type[1], parent, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
+ horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_printer_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_vendor_text = new wxStaticText(parent, wxID_ANY, _L("Printer"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_vendor_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *vertical_sizer = new wxBoxSizer(wxVERTICAL);
+ wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+ m_select_vendor = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
+ m_select_vendor->SetValue(_L("Select Vendor"));
+ m_select_vendor->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ wxArrayString printer_vendor;
+ for (const std::string &vendor : printer_vendors) {
+ printer_vendor.Add(vendor);
+ }
+ m_select_vendor->Set(printer_vendor);
+ m_select_vendor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent e) {
+ m_select_vendor->SetLabelColor(*wxBLACK);
+ std::string curr_selected_vendor = into_u8(m_select_vendor->GetStringSelection());
+ std::unordered_map>::const_iterator iter = printer_model_map.find(curr_selected_vendor);
+ if (iter != printer_model_map.end())
+ {
+ std::vector vendor_model = iter->second;
+ wxArrayString model_choice;
+ for (const std::string &model : vendor_model) {
+ model_choice.Add(model);
+ }
+ m_select_model->Set(model_choice);
+ if (!model_choice.empty()) {
+ m_select_model->SetSelection(0);
+ m_select_model->SetLabelColor(*wxBLACK);
+ }
+ } else {
+ MessageDialog dlg(this, _L("The model is not fond, place reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ }
+ e.Skip();
+ });
+
+ comboBoxSizer->Add(m_select_vendor, 0, wxEXPAND | wxALL, 0);
+
+ m_select_model = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
+ comboBoxSizer->Add(m_select_model, 0, wxEXPAND | wxLEFT, FromDIP(5));
+ m_select_model->SetValue(_L("Select model"));
+ m_select_model->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ m_select_model->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent e) {
+ m_select_model->SetLabelColor(*wxBLACK);
+ e.Skip();
+ });
+
+ m_select_printer = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
+ comboBoxSizer->Add(m_select_printer, 0, wxEXPAND | wxALL, 0);
+ m_select_printer->SetValue(_L("Select printer"));
+ m_select_printer->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ m_select_printer->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent e) {
+ m_select_printer->SetLabelColor(*wxBLACK);
+ e.Skip();
+ });
+ m_select_printer->Hide();
+
+ vertical_sizer->Add(comboBoxSizer, 0, wxEXPAND, 0);
+
+ wxBoxSizer *checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
+ m_can_not_find_vendor_combox = new CheckBox(parent);
+
+ checkbox_sizer->Add(m_can_not_find_vendor_combox, 0, wxALIGN_CENTER, 0);
+ checkbox_sizer->Add(0, 0, 0, wxEXPAND | wxRIGHT, FromDIP(5));
+
+ m_can_not_find_vendor_text = new wxStaticText(parent, wxID_ANY, _L("Can't find my printer model"), wxDefaultPosition, wxDefaultSize, 0);
+ m_can_not_find_vendor_text->SetFont(::Label::Body_13);
+
+ wxSize size = m_can_not_find_vendor_text->GetTextExtent(_L("Can't find my printer model"));
+ m_can_not_find_vendor_text->SetMinSize(wxSize(size.x + FromDIP(4), -1));
+ m_can_not_find_vendor_text->Wrap(-1);
+ checkbox_sizer->Add(m_can_not_find_vendor_text, 0, wxALIGN_CENTER, 0);
+
+ m_custom_vendor_model = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE);
+ m_custom_vendor_model->SetHint(_L("Input Printer Vendor and Model"));
+ checkbox_sizer->Add(m_custom_vendor_model, 0, wxLEFT | wxALIGN_CENTER, FromDIP(13));
+ m_custom_vendor_model->Hide();
+
+ m_can_not_find_vendor_combox->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent &e) {
+ bool value = m_can_not_find_vendor_combox->GetValue();
+ if (value) {
+ m_can_not_find_vendor_combox->SetValue(true);
+ m_custom_vendor_model->Show();
+ m_select_vendor->Enable(false);
+ m_select_model->Enable(false);
+ } else {
+ m_can_not_find_vendor_combox->SetValue(false);
+ m_custom_vendor_model->Hide();
+ m_select_vendor->Enable(true);
+ m_select_model->Enable(true);
+ }
+ Refresh();
+ Layout();
+ Fit();
+ });
+
+ vertical_sizer->Add(checkbox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
+
+ horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_nozzle_diameter_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Nozzle Diameter"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxVERTICAL);
+ m_nozzle_diameter = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
+ wxArrayString nozzle_diameters;
+ for (const std::string& nozzle : nozzle_diameter) {
+ nozzle_diameters.Add(nozzle + " nozzle");
+ }
+ m_nozzle_diameter->Set(nozzle_diameters);
+ m_nozzle_diameter->SetSelection(0);
+ comboBoxSizer->Add(m_nozzle_diameter, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_bed_shape_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Bed Shape"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer * bed_shape_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_bed_shape_text = new wxStaticText(parent, wxID_ANY, _L("Rectangle"), wxDefaultPosition, wxDefaultSize);
+ bed_shape_sizer->Add(static_bed_shape_text, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(bed_shape_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_bed_size_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Printable Space"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer * length_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_length_text = new wxStaticText(parent, wxID_ANY, _L("X"), wxDefaultPosition, wxDefaultSize);
+ static_length_text->SetMinSize(ORIGIN_TEXT_SIZE);
+ static_length_text->SetSize(ORIGIN_TEXT_SIZE);
+ length_sizer->Add(static_length_text, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ wxBoxSizer *length_input_sizer = new wxBoxSizer(wxVERTICAL);
+ m_bed_size_x_input = new TextInput(parent, wxEmptyString, "mm", wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
+ wxTextValidator validator(wxFILTER_DIGITS);
+ m_bed_size_x_input->GetTextCtrl()->SetValidator(validator);
+ length_input_sizer->Add(m_bed_size_x_input, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(length_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+
+ wxBoxSizer * width_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_width_text = new wxStaticText(parent, wxID_ANY, _L("Y"), wxDefaultPosition, wxDefaultSize);
+ static_width_text->SetMinSize(ORIGIN_TEXT_SIZE);
+ static_width_text->SetSize(ORIGIN_TEXT_SIZE);
+ width_sizer->Add(static_width_text, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ wxBoxSizer *width_input_sizer = new wxBoxSizer(wxVERTICAL);
+ m_bed_size_y_input = new TextInput(parent, wxEmptyString, "mm", wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
+ m_bed_size_y_input->GetTextCtrl()->SetValidator(validator);
+ width_input_sizer->Add(m_bed_size_y_input, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+
+ return horizontal_sizer;
+
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_origin_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Origin"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer * length_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_origin_x_text = new wxStaticText(parent, wxID_ANY, _L("X"), wxDefaultPosition, wxDefaultSize);
+ static_origin_x_text->SetMinSize(ORIGIN_TEXT_SIZE);
+ static_origin_x_text->SetSize(ORIGIN_TEXT_SIZE);
+ length_sizer->Add(static_origin_x_text, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ wxBoxSizer *length_input_sizer = new wxBoxSizer(wxVERTICAL);
+ m_bed_origin_x_input = new TextInput(parent, wxEmptyString, "mm", wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
+ wxTextValidator validator(wxFILTER_DIGITS);
+ m_bed_origin_x_input->GetTextCtrl()->SetValidator(validator);
+ length_input_sizer->Add(m_bed_origin_x_input, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(length_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+
+ wxBoxSizer * width_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_origin_y_text = new wxStaticText(parent, wxID_ANY, _L("Y"), wxDefaultPosition, wxDefaultSize);
+ static_origin_y_text->SetMinSize(ORIGIN_TEXT_SIZE);
+ static_origin_y_text->SetSize(ORIGIN_TEXT_SIZE);
+ width_sizer->Add(static_origin_y_text, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ wxBoxSizer *width_input_sizer = new wxBoxSizer(wxVERTICAL);
+ m_bed_origin_y_input = new TextInput(parent, wxEmptyString, "mm", wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
+ m_bed_origin_y_input->GetTextCtrl()->SetValidator(validator);
+ width_input_sizer->Add(m_bed_origin_y_input, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_hot_bed_stl_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Hot Bed STL"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *hot_bed_stl_sizer = new wxBoxSizer(wxVERTICAL);
+
+ StateColor flush_bg_col(std::pair(wxColour(219, 253, 231), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(wxColour(238, 238, 238), StateColor::Normal));
+
+ StateColor flush_bd_col(std::pair(wxColour(0, 174, 66), StateColor::Pressed), std::pair(wxColour(0, 174, 66), StateColor::Hovered),
+ std::pair(wxColour(172, 172, 172), StateColor::Normal));
+
+ m_button_bed_stl = new Button(parent, _L("Upload"));
+ m_button_bed_stl->SetFont(Label::Body_10);
+
+ m_button_bed_stl->SetPaddingSize(wxSize(FromDIP(30), FromDIP(8)));
+ m_button_bed_stl->SetFont(Label::Body_13);
+ m_button_bed_stl->SetCornerRadius(FromDIP(8));
+ m_button_bed_stl->SetBackgroundColor(flush_bg_col);
+ m_button_bed_stl->SetBorderColor(flush_bd_col);
+ hot_bed_stl_sizer->Add(m_button_bed_stl, 0, wxEXPAND | wxALL, 0);
+
+ horizontal_sizer->Add(hot_bed_stl_sizer, 0, wxEXPAND | wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_hot_bed_svg_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Hot Bed SVG"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *hot_bed_stl_sizer = new wxBoxSizer(wxVERTICAL);
+
+ StateColor flush_bg_col(std::pair(wxColour(219, 253, 231), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(wxColour(238, 238, 238), StateColor::Normal));
+
+ StateColor flush_bd_col(std::pair(wxColour(0, 174, 66), StateColor::Pressed), std::pair(wxColour(0, 174, 66), StateColor::Hovered),
+ std::pair(wxColour(172, 172, 172), StateColor::Normal));
+
+ m_button_bed_svg = new Button(parent, _L("Upload"));
+ m_button_bed_svg->SetFont(Label::Body_10);
+
+ m_button_bed_svg->SetPaddingSize(wxSize(FromDIP(30), FromDIP(8)));
+ m_button_bed_svg->SetFont(Label::Body_13);
+ m_button_bed_svg->SetCornerRadius(FromDIP(8));
+ m_button_bed_svg->SetBackgroundColor(flush_bg_col);
+ m_button_bed_svg->SetBorderColor(flush_bd_col);
+ hot_bed_stl_sizer->Add(m_button_bed_svg, 0, wxEXPAND | wxALL, 0);
+
+ horizontal_sizer->Add(hot_bed_stl_sizer, 0, wxEXPAND | wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_max_print_height_item(wxWindow *parent)
+{
+ wxBoxSizer * horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Max print height"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *hight_input_sizer = new wxBoxSizer(wxVERTICAL);
+ m_print_height_input = new TextInput(parent, wxEmptyString, "mm", wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
+ wxTextValidator validator(wxFILTER_DIGITS);
+ m_print_height_input->GetTextCtrl()->SetValidator(validator);
+ hight_input_sizer->Add(m_print_height_input, 0, wxEXPAND | wxLEFT, FromDIP(5));
+ horizontal_sizer->Add(hight_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_page1_btns_item(wxWindow *parent)
+{
+ wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL);
+ bSizer_button->Add(0, 0, 1, wxEXPAND, 0);
+
+ StateColor btn_bg_green(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered),
+ std::pair(wxColour(0, 174, 66), StateColor::Normal));
+
+ m_button_OK = new Button(parent, _L("OK"));
+ m_button_OK->SetBackgroundColor(btn_bg_green);
+ m_button_OK->SetBorderColor(*wxWHITE);
+ m_button_OK->SetTextColor(wxColour(0xFFFFFE));
+ m_button_OK->SetFont(Label::Body_12);
+ m_button_OK->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_OK->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_OK->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_OK, 0, wxRIGHT, FromDIP(10));
+
+ m_button_OK->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ data_init();
+ show_page2();
+ });
+
+ StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ m_button_page1_cancel = new Button(parent, _L("Cancel"));
+ m_button_page1_cancel->SetBackgroundColor(btn_bg_white);
+ m_button_page1_cancel->SetBorderColor(wxColour(38, 46, 48));
+ m_button_page1_cancel->SetFont(Label::Body_12);
+ m_button_page1_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_page1_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_page1_cancel->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_page1_cancel, 0, wxRIGHT, FromDIP(10));
+
+ m_button_page1_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { EndModal(wxID_CANCEL); });
+
+ return bSizer_button;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+ RadioBox * radiobox = new RadioBox(parent);
+ horizontal_sizer->Add(radiobox, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(5));
+ radiobox_list.push_back(std::make_pair(radiobox,title));
+ int btn_idx = radiobox_list.size() - 1;
+ radiobox->Bind(wxEVT_LEFT_DOWN, [this, &radiobox_list, btn_idx](wxMouseEvent &e) {
+ select_curr_radiobox(radiobox_list, btn_idx);
+ });
+
+ wxStaticText *text = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
+ text->Bind(wxEVT_LEFT_DOWN, [this, &radiobox_list, btn_idx](wxMouseEvent &e) {
+ select_curr_radiobox(radiobox_list, btn_idx);
+ });
+ horizontal_sizer->Add(text, 0, wxEXPAND | wxLEFT, 0);
+
+ radiobox->SetToolTip(tooltip);
+ text->SetToolTip(tooltip);
+ return horizontal_sizer;
+
+}
+
+void CreatePrinterPresetDialog::select_curr_radiobox(std::vector> &radiobox_list, int btn_idx)
+{
+ int len = radiobox_list.size();
+ for (int i = 0; i < len; ++i) {
+ if (i == btn_idx) {
+ radiobox_list[i].first->SetValue(true);
+ wxString curr_selected_type = radiobox_list[i].second;
+ if (curr_selected_type == m_create_presets_type[0]) {
+ m_filament_preset_template_sizer->Clear(true);
+ m_filament_preset.clear();
+ m_process_preset_template_sizer->Clear(true);
+ m_process_preset.clear();
+ } else if (curr_selected_type == m_create_presets_type[1]) {
+ if (into_u8(m_printer_model->GetLabel()) == _L("Select model")) {
+ m_filament_preset_template_sizer->Clear(true);
+ m_filament_preset.clear();
+ m_process_preset_template_sizer->Clear(true);
+ m_process_preset.clear();
+ } else {
+ update_presets_list();
+ }
+ } else if (curr_selected_type == m_create_printer_type[0]) {
+ m_select_printer->Hide();
+ m_select_vendor->Show();
+ m_select_model->Show();
+ m_can_not_find_vendor_combox->Show();
+ m_can_not_find_vendor_text->Show();
+ if (m_can_not_find_vendor_combox->GetValue()) {
+ m_custom_vendor_model->Show();
+ }
+ } else if (curr_selected_type == m_create_printer_type[1]) {
+ m_select_vendor->Hide();
+ m_select_model->Hide();
+ m_can_not_find_vendor_combox->Hide();
+ m_can_not_find_vendor_text->Hide();
+ m_custom_vendor_model->Hide();
+ m_select_printer->Show();
+ }
+ Layout();
+ Fit();
+ Refresh();
+ } else {
+ radiobox_list[i].first->SetValue(false);
+ }
+ }
+}
+
+void CreatePrinterPresetDialog::create_printer_page2(wxWindow *parent)
+{
+ this->SetBackgroundColour(*wxWHITE);
+
+ wxBoxSizer* page2_sizer = new wxBoxSizer(wxVERTICAL);
+
+ page2_sizer->Add(create_printer_preset_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page2_sizer->Add(create_presets_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page2_sizer->Add(create_presets_template_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ page2_sizer->Add(create_page2_btns_item(parent), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+
+ parent->SetSizer(page2_sizer);
+ Layout();
+ Fit();
+
+ wxGetApp().UpdateDlgDarkUI(this);
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_printer_preset_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_vendor_text = new wxStaticText(parent, wxID_ANY, _L("Printer preset"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_vendor_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer * vertical_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *combobox_title = new wxStaticText(parent, wxID_ANY, _L("Create based on current printer"), wxDefaultPosition, wxDefaultSize, 0);
+ combobox_title->SetFont(::Label::Body_13);
+ auto size = combobox_title->GetTextExtent(_L("Create based on current printer"));
+ combobox_title->SetMinSize(wxSize(size.x + FromDIP(4), -1));
+ combobox_title->Wrap(-1);
+ vertical_sizer->Add(combobox_title, 0, wxEXPAND | wxALL, 0);
+
+ wxBoxSizer *comboBox_sizer = new wxBoxSizer(wxHORIZONTAL);
+ m_printer_vendor = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, PRINTER_PRESET_VENDOR_SIZE, 0, nullptr, wxCB_READONLY);
+ m_printer_vendor->SetValue(_L("Select vendor"));
+ m_printer_vendor->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ comboBox_sizer->Add(m_printer_vendor, 0, wxEXPAND, 0);
+ m_printer_model = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, PRINTER_PRESET_MODEL_SIZE, 0, nullptr, wxCB_READONLY);
+ m_printer_model->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
+ m_printer_model->SetValue(_L("Select model"));
+
+ comboBox_sizer->Add(m_printer_model, 0, wxEXPAND | wxLEFT, FromDIP(10));
+ vertical_sizer->Add(comboBox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
+
+ horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_presets_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_serial_text = new wxStaticText(parent, wxID_ANY, _L("Presets"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *radioBoxSizer = new wxBoxSizer(wxVERTICAL);
+
+ radioBoxSizer->Add(create_radio_item(m_create_presets_type[0], parent, wxEmptyString, m_create_presets_btns), 0, wxEXPAND | wxALL, 0);
+ radioBoxSizer->Add(create_radio_item(m_create_presets_type[1], parent, wxEmptyString, m_create_presets_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
+ horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_presets_template_item(wxWindow *parent)
+{
+ wxBoxSizer *vertical_sizer = new wxBoxSizer(wxVERTICAL);
+
+ m_preset_template_panel = new wxScrolledWindow(parent);
+ m_preset_template_panel->SetSize(wxSize(-1, -1));
+ m_preset_template_panel->SetBackgroundColour(PRINTER_LIST_COLOUR);
+ //m_filament_preset_panel->SetMinSize(PRESET_TEMPLATE_SIZE);
+ wxBoxSizer * filament_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_filament_preset_text = new wxStaticText(m_preset_template_panel, wxID_ANY, _L("Filament preset template"), wxDefaultPosition, wxDefaultSize);
+ filament_sizer->Add(static_filament_preset_text, 0, wxEXPAND | wxALL, FromDIP(5));
+ m_filament_preset_panel = new wxPanel(m_preset_template_panel);
+ m_filament_preset_template_sizer = new wxGridSizer(3, FromDIP(5), FromDIP(5));
+ m_filament_preset_panel->SetSize(PRESET_TEMPLATE_SIZE);
+ m_filament_preset_panel->SetSizer(m_filament_preset_template_sizer);
+ filament_sizer->Add(m_filament_preset_panel, 0, wxEXPAND | wxALL, FromDIP(5));
+
+ wxBoxSizer *hori_filament_btn_sizer = new wxBoxSizer(wxHORIZONTAL);
+ wxPanel * filament_btn_panel = new wxPanel(m_preset_template_panel);
+ filament_btn_panel->SetBackgroundColour(FILAMENT_OPTION_COLOUR);
+ wxStaticText *filament_sel_all_text = new wxStaticText(filament_btn_panel, wxID_ANY, _L("Select All"), wxDefaultPosition, wxDefaultSize);
+ filament_sel_all_text->SetForegroundColour(SELECT_ALL_OPTION_COLOUR);
+ filament_sel_all_text->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ select_all_preset_template(m_filament_preset);
+ e.Skip();
+ });
+ wxStaticText *filament_desel_all_text = new wxStaticText(filament_btn_panel, wxID_ANY, _L("Deselect All"), wxDefaultPosition, wxDefaultSize);
+ filament_desel_all_text->SetForegroundColour(SELECT_ALL_OPTION_COLOUR);
+ filament_desel_all_text->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ deselect_all_preset_template(m_filament_preset);
+ e.Skip();
+ });
+ hori_filament_btn_sizer->Add(filament_sel_all_text, 0, wxEXPAND | wxALL, FromDIP(5));
+ hori_filament_btn_sizer->Add(filament_desel_all_text, 0, wxEXPAND | wxALL, FromDIP(5));
+ filament_btn_panel->SetSizer(hori_filament_btn_sizer);
+ filament_sizer->Add(filament_btn_panel, 0, wxEXPAND, 0);
+
+ wxPanel *split_panel = new wxPanel(m_preset_template_panel, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(10)));
+ split_panel->SetBackgroundColour(wxColour(*wxWHITE));
+ filament_sizer->Add(split_panel, 0, wxEXPAND, 0);
+
+ wxStaticText *static_process_preset_text = new wxStaticText(m_preset_template_panel, wxID_ANY, _L("Process preset template"), wxDefaultPosition, wxDefaultSize);
+ filament_sizer->Add(static_process_preset_text, 0, wxEXPAND | wxALL, FromDIP(5));
+ m_process_preset_panel = new wxPanel(m_preset_template_panel);
+ m_process_preset_panel->SetSize(PRESET_TEMPLATE_SIZE);
+ m_process_preset_template_sizer = new wxGridSizer(3, FromDIP(5), FromDIP(5));
+ m_process_preset_panel->SetSizer(m_process_preset_template_sizer);
+ filament_sizer->Add(m_process_preset_panel, 0, wxEXPAND | wxALL, FromDIP(5));
+
+
+ wxBoxSizer *hori_process_btn_sizer = new wxBoxSizer(wxHORIZONTAL);
+ wxPanel * process_btn_panel = new wxPanel(m_preset_template_panel);
+ process_btn_panel->SetBackgroundColour(FILAMENT_OPTION_COLOUR);
+ wxStaticText *process_sel_all_text = new wxStaticText(process_btn_panel, wxID_ANY, _L("Select All"), wxDefaultPosition, wxDefaultSize);
+ process_sel_all_text->SetForegroundColour(SELECT_ALL_OPTION_COLOUR);
+ process_sel_all_text->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ select_all_preset_template(m_process_preset);
+ e.Skip();
+ });
+ wxStaticText *process_desel_all_text = new wxStaticText(process_btn_panel, wxID_ANY, _L("Deselect All"), wxDefaultPosition, wxDefaultSize);
+ process_desel_all_text->SetForegroundColour(SELECT_ALL_OPTION_COLOUR);
+ process_desel_all_text->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ deselect_all_preset_template(m_process_preset);
+ e.Skip();
+ });
+ hori_process_btn_sizer->Add(process_sel_all_text, 0, wxEXPAND | wxALL, FromDIP(5));
+ hori_process_btn_sizer->Add(process_desel_all_text, 0, wxEXPAND | wxALL, FromDIP(5));
+ process_btn_panel->SetSizer(hori_process_btn_sizer);
+ filament_sizer->Add(process_btn_panel, 0, wxEXPAND, 0);
+
+ m_preset_template_panel->SetSizer(filament_sizer);
+ vertical_sizer->Add(m_preset_template_panel, 0, wxEXPAND | wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return vertical_sizer;
+}
+
+wxBoxSizer *CreatePrinterPresetDialog::create_page2_btns_item(wxWindow *parent)
+{
+ wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL);
+ bSizer_button->Add(0, 0, 1, wxEXPAND, 0);
+
+ StateColor btn_bg_green(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered),
+ std::pair(wxColour(0, 174, 66), StateColor::Normal));
+
+ StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ m_button_page2_back = new Button(parent, _L("Back"));
+ m_button_page2_back->SetBackgroundColor(btn_bg_white);
+ m_button_page2_back->SetBorderColor(wxColour(38, 46, 48));
+ m_button_page2_back->SetFont(Label::Body_12);
+ m_button_page2_back->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_page2_back->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_page2_back->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_page2_back, 0, wxRIGHT, FromDIP(10));
+
+ m_button_page2_back->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { show_page1(); });
+
+ m_button_create = new Button(parent, _L("Create"));
+ m_button_create->SetBackgroundColor(btn_bg_green);
+ m_button_create->SetBorderColor(*wxWHITE);
+ m_button_create->SetTextColor(wxColour(0xFFFFFE));
+ m_button_create->SetFont(Label::Body_12);
+ m_button_create->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_create->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_create->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_create, 0, wxRIGHT, FromDIP(10));
+
+ m_button_create->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ if (!validate_input_valid()) return;
+ PresetBundle *preset_bundle = wxGetApp().preset_bundle;
+ wxString curr_selected_printer_type = curr_create_printer_type();
+ wxString curr_selected_preset_type = curr_create_preset_type();
+ if (curr_selected_preset_type == m_create_presets_type[0]) {
+
+ } else if (curr_selected_printer_type == m_create_printer_type[0] && curr_selected_preset_type == m_create_presets_type[1]) {//create printer and based on printer
+ /****************************** clone printer preset ********************************/
+ //create preset name
+ std::string printer_preset_name;
+ std::string nozzle_diameter = into_u8(m_nozzle_diameter->GetStringSelection());
+ if (m_can_not_find_vendor_combox->GetValue()) {
+ std::string vendor_model = into_u8(m_custom_vendor_model->GetLabel());
+ if (vendor_model.empty()) {
+ MessageDialog dlg(this, _L("The custom printer and model are not inputed, place return page 1 to input."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ show_page1();
+ return;
+ }
+ printer_preset_name = vendor_model + " " + nozzle_diameter;
+ } else {
+ std::string vender_name = into_u8(m_select_vendor->GetStringSelection());
+ std::string model_name = into_u8(m_select_model->GetStringSelection());
+ if (vender_name.empty() || model_name.empty()) {
+ MessageDialog dlg(this, _L("The printer and model are not selected, place return page 1 to select."),
+ wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ show_page1();
+ return;
+ }
+ printer_preset_name = vender_name + " " + model_name + " " + nozzle_diameter;
+ }
+
+ //Confirm if the printer preset exists
+ if (!m_printer_preset) {
+ MessageDialog dlg(this, _L("You have not yet chosen which printer preset to create based on. Please choose the vendor and model of the printer"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ show_page1();
+ }
+ // Confirm if the printer preset has a duplicate name
+ if (!rewritten && preset_bundle->printers.find_preset(printer_preset_name)) {
+ MessageDialog dlg(this,
+ _L("The preset you created already has a preset with the same name. Do you want to overwrite it?\n\tYes: Overwrite the printer preset with the "
+ "same name, and filament and process presets with the same preset name will not be recreated.\n\tCancel: Do not create a preset, return to the creation interface."),
+ wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxCANCEL | wxYES_DEFAULT | wxCENTRE);
+ int res = dlg.ShowModal();
+ if (res == wxID_YES) {
+ rewritten = true;
+ } else {
+ return;
+ }
+ }
+
+ //Confirm if the filament preset is exist
+ bool filament_preset_is_exist = false;
+ std::vector selected_filament_presets;
+ for (std::pair filament_preset : m_filament_preset) {
+ if (filament_preset.first->GetValue()) {
+ selected_filament_presets.push_back(filament_preset.second);
+ }
+ if (!filament_preset_is_exist && preset_bundle->filaments.find_preset(filament_preset.second->alias + " @ " + printer_preset_name) != nullptr) {
+ filament_preset_is_exist = true;
+ }
+ }
+ if (selected_filament_presets.empty() && !filament_preset_is_exist) {
+ MessageDialog dlg(this, _L("You need to select at least one filling preset."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+
+ // Confirm if the process preset is exist
+ bool process_preset_is_exist = false;
+ std::vector selected_process_presets;
+ for (std::pair process_preset : m_process_preset) {
+ if (process_preset.first->GetValue()) {
+ selected_process_presets.push_back(process_preset.second);
+ }
+ if (!process_preset_is_exist && preset_bundle->prints.find_preset(process_preset.second->alias + " @ " + printer_preset_name) != nullptr) {
+ process_preset_is_exist = true;
+ }
+ }
+ if (selected_process_presets.empty() && !process_preset_is_exist) {
+ MessageDialog dlg(this, _L("You need to select at least one process preset."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":creater printer ";
+ /****************************** clone filament preset ********************************/
+ std::vector failures;
+ if (!selected_filament_presets.empty()) {
+ bool create_preset_result = preset_bundle->filaments.clone_presets_for_printer(selected_filament_presets, failures, printer_preset_name, rewritten);
+ if (!create_preset_result) {
+ std::string message;
+ for (const std::string& failure : failures) {
+ message += "\t" + failure + "\n";
+ }
+ MessageDialog dlg(this, _L("Create filament presets failed. As follows:\n") + message, wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ }
+ }
+
+ /****************************** clone process preset ********************************/
+ failures.clear();
+ if (!selected_process_presets.empty()) {
+ bool create_preset_result = preset_bundle->prints.clone_presets_for_printer(selected_process_presets, failures, printer_preset_name, rewritten);
+ if (!create_preset_result) {
+ std::string message;
+ for (const std::string& failure : failures) {
+ message += "\t" + failure + "\n";
+ }
+ MessageDialog dlg(this, _L("Create process presets failed. As follows:\n") + message, wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ }
+ }
+ save_preset_config(m_printer_preset);
+ preset_bundle->printers.save_current_preset(printer_preset_name, true, false, m_printer_preset);
+ preset_bundle->update_compatible(PresetSelectCompatibleType::Always);
+ }
+ EndModal(wxID_OK);
+ });
+
+ m_button_page2_cancel = new Button(parent, _L("Cancel"));
+ m_button_page2_cancel->SetBackgroundColor(btn_bg_white);
+ m_button_page2_cancel->SetBorderColor(wxColour(38, 46, 48));
+ m_button_page2_cancel->SetFont(Label::Body_12);
+ m_button_page2_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_page2_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_page2_cancel->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_page2_cancel, 0, wxRIGHT, FromDIP(10));
+
+ m_button_page2_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { EndModal(wxID_CANCEL); });
+
+ return bSizer_button;
+}
+
+void CreatePrinterPresetDialog::show_page1()
+{
+ m_step_1->SetBitmap(create_scaled_bitmap("step_1", nullptr, FromDIP(20)));
+ m_step_2->SetBitmap(create_scaled_bitmap("step_2_ready", nullptr, FromDIP(20)));
+ m_page1->Show();
+ m_page2->Hide();
+ Refresh();
+ Layout();
+ Fit();
+}
+
+void CreatePrinterPresetDialog::show_page2()
+{
+ m_step_1->SetBitmap(create_scaled_bitmap("step_is_ok", nullptr, FromDIP(20)));
+ m_step_2->SetBitmap(create_scaled_bitmap("step_2", nullptr, FromDIP(20)));
+ m_page2->Show();
+ m_page1->Hide();
+ Refresh();
+ Layout();
+ Fit();
+}
+
+bool CreatePrinterPresetDialog::data_init()
+{
+ std::string nozzle_type = into_u8(m_nozzle_diameter->GetStringSelection());
+ size_t index_nozzle = nozzle_type.find(" nozzle");
+ nozzle_type = nozzle_type.substr(0, index_nozzle);
+ float nozzle = std::stof(nozzle_type);
+
+ VendorMap vendors;
+ wxArrayString exist_vendor_choice = get_exist_vendor_choices(vendors);
+ m_printer_vendor->Set(exist_vendor_choice);
+
+ m_printer_model->Bind(wxEVT_COMBOBOX, &CreatePrinterPresetDialog::on_preset_model_value_change, this);
+
+ m_printer_vendor->Bind(wxEVT_COMBOBOX, [this, vendors, nozzle](wxCommandEvent e) {
+ m_printer_vendor->SetLabelColor(*wxBLACK);
+
+ std::string curr_selected_vendor = into_u8(m_printer_vendor->GetStringSelection());
+ auto iterator = vendors.find(curr_selected_vendor);
+ if (iterator != vendors.end()) {
+ m_printer_preset_vendor_selected = iterator->second;
+ } else {
+ MessageDialog dlg(this, _L("Vendor is not find, please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+
+ wxArrayString printer_preset_model = printer_preset_sort_with_nozzle_diameter(m_printer_preset_vendor_selected, nozzle);
+ if (printer_preset_model.size() == 0) {
+ MessageDialog dlg(this, _L("Current vendor has no models, please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+ m_printer_model->Set(printer_preset_model);
+ if (!printer_preset_model.empty()) {
+ m_printer_model->SetSelection(0);
+ wxCommandEvent e;
+ on_preset_model_value_change(e);
+ }
+ rewritten = false;
+ e.Skip();
+
+ });
+ return true;
+
+}
+
+wxArrayString CreatePrinterPresetDialog::printer_preset_sort_with_nozzle_diameter(const VendorProfile &vendor_profile, float nozzle_diameter)
+{
+ std::vector> preset_sort;
+
+ for (const Slic3r::VendorProfile::PrinterModel &model : vendor_profile.models) {
+ std::string model_name = model.name;
+ for (const Slic3r::VendorProfile::PrinterVariant &variant : model.variants) {
+ try {
+ float variant_diameter = std::stof(variant.name);
+ preset_sort.push_back(std::make_pair(variant_diameter, model_name + " @ " + variant.name + " nozzle"));
+ }
+ catch (...) {
+ continue;
+ }
+ }
+ }
+
+ std::sort(preset_sort.begin(), preset_sort.end(), [](const std::pair &a, const std::pair &b) { return a.first < b.first; });
+
+ int index_nearest_nozzle = -1;
+ float nozzle_diameter_diff = 1;
+ for (int i = 0; i < preset_sort.size(); ++i) {
+ float curr_nozzle_diameter_diff = std::abs(nozzle_diameter - preset_sort[i].first);
+ if (curr_nozzle_diameter_diff < nozzle_diameter_diff) {
+ index_nearest_nozzle = i;
+ nozzle_diameter_diff = curr_nozzle_diameter_diff;
+ if (curr_nozzle_diameter_diff == 0) break;
+ }
+ }
+ wxArrayString printer_preset_model_selection;
+ int right_index = index_nearest_nozzle + 1;
+ while (index_nearest_nozzle >= 0 || right_index < preset_sort.size()) {
+ if (index_nearest_nozzle >= 0 && right_index < preset_sort.size()) {
+ float left_nozzle_diff = std::abs(nozzle_diameter - preset_sort[index_nearest_nozzle].first);
+ float right_nozzle_diff = std::abs(nozzle_diameter - preset_sort[right_index].first);
+ bool left_is_little = left_nozzle_diff < right_nozzle_diff;
+ if (left_is_little) {
+ printer_preset_model_selection.Add(preset_sort[index_nearest_nozzle].second);
+ index_nearest_nozzle--;
+ } else {
+ printer_preset_model_selection.Add(preset_sort[right_index].second);
+ right_index++;
+ }
+ } else if (index_nearest_nozzle >= 0) {
+ printer_preset_model_selection.Add(preset_sort[index_nearest_nozzle].second);
+ index_nearest_nozzle--;
+ } else if (right_index < preset_sort.size()) {
+ printer_preset_model_selection.Add(preset_sort[right_index].second);
+ right_index++;
+ }
+ }
+ return printer_preset_model_selection;
+}
+/*
+wxBoxSizer *CreatePrinterPresetDialog::create_checkbox(wxWindow *parent, Preset *preset, std::vector> &preset_checkbox)
+{
+ wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
+ CheckBox* checkbox = new CheckBox(parent);
+ sizer->Add(checkbox, 0, 0, 0);
+ preset_checkbox.push_back(std::make_pair(checkbox, preset));
+ wxStaticText *preset_name = new wxStaticText(parent, wxID_ANY, preset->name);
+ sizer->Add(preset_name, 0, wxLEFT, 5);
+ return sizer;
+}
+*/
+void CreatePrinterPresetDialog::select_all_preset_template(std::vector> &preset_templates)
+{
+ for (std::pair < CheckBox *, Preset const * > filament_preset : preset_templates) {
+ filament_preset.first->SetValue(true);
+ }
+}
+
+void CreatePrinterPresetDialog::deselect_all_preset_template(std::vector> &preset_templates)
+{
+ for (std::pair filament_preset : preset_templates) {
+ filament_preset.first->SetValue(false);
+ }
+}
+
+void CreatePrinterPresetDialog::update_presets_list()
+{
+ std::string curr_selected_model = into_u8(m_printer_model->GetStringSelection());
+ int nozzle_index = curr_selected_model.find_first_of("@");
+ std::string select_model = curr_selected_model.substr(0, nozzle_index - 1);
+ for (const Slic3r::VendorProfile::PrinterModel &model : m_printer_preset_vendor_selected.models) {
+ if (model.name == select_model) {
+ m_printer_preset_model_selected = model;
+ break;
+ }
+ }
+
+ PresetBundle temp_preset_bundle;
+ std::string preset_path;
+ if (boost::filesystem::exists(boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR / m_printer_preset_vendor_selected.id)) {
+ preset_path = (boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR).string();
+ } else if (boost::filesystem::exists(boost::filesystem::path(Slic3r::resources_dir()) / "profiles" / m_printer_preset_vendor_selected.id)) {
+ preset_path = (boost::filesystem::path(Slic3r::resources_dir()) / "profiles").string();
+ }
+
+ if (preset_path.empty()) {
+ MessageDialog dlg(this, _L("Preset path is not find, please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+
+ temp_preset_bundle.load_vendor_configs_from_json(preset_path, m_printer_preset_vendor_selected.id, PresetBundle::LoadConfigBundleAttribute::LoadSystem,
+ ForwardCompatibilitySubstitutionRule::EnableSilent);
+
+ std::string dir_user_presets = wxGetApp().app_config->get("preset_folder");
+ if (dir_user_presets.empty()) {
+ temp_preset_bundle.load_user_presets(DEFAULT_USER_FOLDER_NAME, ForwardCompatibilitySubstitutionRule::EnableSilent);
+ } else {
+ temp_preset_bundle.load_user_presets(dir_user_presets, ForwardCompatibilitySubstitutionRule::EnableSilent);
+ }
+
+ std::string model_varient = into_u8(m_printer_model->GetStringSelection());
+ size_t index_at = model_varient.find(" @ ");
+ size_t index_nozzle = model_varient.find("nozzle");
+ std::string varient;
+ if (index_at != std::string::npos && index_nozzle != std::string::npos) {
+ varient = model_varient.substr(index_at + 3, index_nozzle - index_at - 4);
+ }
+ else {
+ MessageDialog dlg(this, _L("The nozzle_diameter is not fond, place reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+
+ const Preset* temp_printer_preset = temp_preset_bundle.printers.find_system_preset_by_model_and_variant(m_printer_preset_model_selected.id, varient);
+
+ if (temp_printer_preset) {
+ temp_preset_bundle.printers.select_preset_by_name(temp_printer_preset->name, true);
+ m_printer_preset = new Preset(*temp_printer_preset);
+ }
+ else {
+ MessageDialog dlg(this, _L("The printer preset is not fond, place reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ return;
+ }
+
+ temp_preset_bundle.update_compatible(PresetSelectCompatibleType::Always);
+
+ const std::deque &filament_presets = temp_preset_bundle.filaments.get_presets();
+ const std::deque &process_presets = temp_preset_bundle.prints.get_presets();
+
+ // clear filament preset window sizer
+ clear_preset_combobox();
+
+ // update filament preset window sizer
+ for (const Preset &filament_preset : filament_presets) {
+ if (filament_preset.is_compatible) {
+ Preset *temp_filament = new Preset(filament_preset);
+ m_filament_preset_template_sizer->Add(create_checkbox(m_filament_preset_panel, temp_filament, temp_filament->name, m_filament_preset), 0, wxEXPAND, FromDIP(5));
+ }
+ }
+
+ for (const Preset &process_preset : process_presets) {
+ if (process_preset.is_compatible) {
+ Preset *temp_process = new Preset(process_preset);
+ m_process_preset_template_sizer->Add(create_checkbox(m_process_preset_panel, temp_process, temp_process->name, m_process_preset), 0, wxEXPAND, FromDIP(5));
+ }
+ }
+}
+
+void CreatePrinterPresetDialog::clear_preset_combobox()
+{
+ for (std::pair preset : m_filament_preset) {
+ if (preset.second) {
+ delete preset.second;
+ preset.second = nullptr;
+ }
+ }
+ m_filament_preset.clear();
+ m_filament_preset_template_sizer->Clear(true);
+
+ for (std::pair preset : m_process_preset) {
+ if (preset.second) {
+ delete preset.second;
+ preset.second = nullptr;
+ }
+ }
+ m_process_preset.clear();
+ m_process_preset_template_sizer->Clear(true);
+}
+
+void CreatePrinterPresetDialog::save_preset_config(Preset* preset)
+{
+ DynamicPrintConfig &config = preset->config;
+
+ double prnite_area_x = 0;
+ m_bed_size_x_input->GetTextCtrl()->GetValue().ToDouble(&prnite_area_x);
+ double prnite_area_y = 0;
+ m_bed_size_y_input->GetTextCtrl()->GetValue().ToDouble(&prnite_area_y);
+ std::vector points = {{0, 0}, {prnite_area_x, 0}, {prnite_area_x, prnite_area_y}, {0, prnite_area_y}};
+ config.set_key_value("printable_area", new ConfigOptionPoints(points));
+
+ double max_print_height = 0;
+ m_print_height_input->GetTextCtrl()->GetValue().ToDouble(&max_print_height);
+ config.set("printable_height", max_print_height);
+}
+
+bool CreatePrinterPresetDialog::validate_input_valid()
+{
+ if (m_bed_size_x_input->GetTextCtrl()->GetValue().empty() || m_bed_size_y_input->GetTextCtrl()->GetValue().empty()) {
+ MessageDialog dlg(this, _L("You did not entered in the printable area of the printer. Please return to page 1 to input."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ show_page1();
+ return false;
+ }
+
+ if (m_print_height_input->GetTextCtrl()->GetValue().empty()) {
+ MessageDialog dlg(this, _L("You have not entered the maximum printing height of the printer. Please return to page 1 for input."),
+ wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ dlg.ShowModal();
+ show_page1();
+ return false;
+ }
+
+ return true;
+}
+
+void CreatePrinterPresetDialog::on_preset_model_value_change(wxCommandEvent &e)
+{
+ m_printer_model->SetLabelColor(*wxBLACK);
+ if (m_printer_preset_vendor_selected.models.empty()) return;
+
+ wxString curr_selected_preset_type = curr_create_preset_type();
+ if (curr_selected_preset_type == m_create_presets_type[1]) {
+ update_presets_list();
+ } else if (curr_selected_preset_type == m_create_presets_type[0]) {
+ m_filament_preset_template_sizer->Clear(true);
+ m_filament_preset.clear();
+ m_process_preset_template_sizer->Clear(true);
+ m_process_preset.clear();
+ }
+ rewritten = false;
+
+ Layout();
+ Fit();
+ Refresh();
+ e.Skip();
+}
+
+wxString CreatePrinterPresetDialog::curr_create_preset_type()
+{
+ wxString curr_selected_preset_type;
+ for (const std::pair &presets_radio : m_create_presets_btns) {
+ if (presets_radio.first->GetValue()) {
+ curr_selected_preset_type = presets_radio.second;
+ }
+ }
+ return curr_selected_preset_type;
+}
+
+wxString CreatePrinterPresetDialog::curr_create_printer_type()
+{
+ wxString curr_selected_printer_type;
+ for (const std::pair &printer_radio : m_create_type_btns) {
+ if (printer_radio.first->GetValue()) { curr_selected_printer_type = printer_radio.second; }
+ }
+ return curr_selected_printer_type;
+}
+
+CreatePresetSuccessfulDialog::CreatePresetSuccessfulDialog(wxWindow *parent, const SuccessType &create_success_type)
+ : DPIDialog(parent ? parent : nullptr, wxID_ANY, _L("Create Printer/Filament Successful"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
+{
+ this->SetBackgroundColour(*wxWHITE);
+ this->SetSize(wxSize(FromDIP(450), FromDIP(200)));
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
+ wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL);
+ // top line
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
+ m_line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
+ m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
+ m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
+
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+ horizontal_sizer->Add(0, 0, 0, wxLEFT, FromDIP(30));
+
+ wxBoxSizer *success_bitmap_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticBitmap *success_bitmap = new wxStaticBitmap(this,wxID_ANY, create_scaled_bitmap("create_success", nullptr, FromDIP(24)));
+ success_bitmap_sizer->Add(success_bitmap, 0, wxEXPAND, 0);
+ horizontal_sizer->Add(success_bitmap_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
+
+ wxBoxSizer *success_text_sizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *success_text;
+ wxStaticText *next_step_text;
+ switch (create_success_type) {
+ case PRINTER:
+ success_text = new wxStaticText(this, wxID_ANY, _L("Printer Created"));
+ next_step_text = new wxStaticText(this, wxID_ANY, _L("Please go to printer settings to edit your presets"));
+ break;
+ case FILAMENT:
+ success_text = new wxStaticText(this, wxID_ANY, _L("Filament Created"));
+ next_step_text = new wxStaticText(this, wxID_ANY, _L("Please go to filament setting to edit your presets if you need"));
+ break;
+ }
+ success_text->SetFont(Label::Head_18);
+ next_step_text->SetFont(Label::Body_16);
+ success_text_sizer->Add(success_text, 0, wxEXPAND, 0);
+ success_text_sizer->Add(next_step_text, 0, wxEXPAND | wxTOP, FromDIP(5));
+ horizontal_sizer->Add(success_text_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
+ horizontal_sizer->Add(0, 0, 0, wxLEFT, FromDIP(60));
+
+ m_main_sizer->Add(horizontal_sizer, 0, wxALL, FromDIP(5));
+
+ wxBoxSizer *btn_sizer = new wxBoxSizer(wxHORIZONTAL);
+ btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
+ switch (create_success_type) {
+ case PRINTER:
+ m_button_ok = new Button(this, _L("Printer Setting"));
+ break;
+ case FILAMENT:
+ m_button_ok = new Button(this, _L("OK"));
+ break;
+ }
+ StateColor btn_bg_green(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered),
+ std::pair(wxColour(0, 174, 66), StateColor::Normal));
+
+ StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+ m_button_ok->SetBackgroundColor(btn_bg_green);
+ m_button_ok->SetBorderColor(wxColour(*wxWHITE));
+ m_button_ok->SetTextColor(wxColour(*wxWHITE));
+ m_button_ok->SetFont(Label::Body_12);
+ m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_ok->SetCornerRadius(FromDIP(12));
+ btn_sizer->Add(m_button_ok, 0, wxRIGHT, FromDIP(10));
+
+ m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { EndModal(wxID_OK); });
+
+ m_button_cancel = new Button(this, _L("Cancle"));
+ m_button_cancel->SetBackgroundColor(btn_bg_white);
+ m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
+ m_button_cancel->SetTextColor(wxColour(38, 46, 48));
+ m_button_cancel->SetFont(Label::Body_12);
+ m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetCornerRadius(FromDIP(12));
+ btn_sizer->Add(m_button_cancel, 0, wxRIGHT, FromDIP(10));
+
+ m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { EndModal(wxID_CANCEL); });
+
+ m_main_sizer->Add(btn_sizer, 0, wxEXPAND | wxALL, FromDIP(15));
+ m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
+
+ SetSizer(m_main_sizer);
+ Layout();
+ Fit();
+ wxGetApp().UpdateDlgDarkUI(this);
+}
+
+CreatePresetSuccessfulDialog::~CreatePresetSuccessfulDialog() {}
+
+void CreatePresetSuccessfulDialog::on_dpi_changed(const wxRect &suggested_rect) {}
+
+ExportConfigsDialog::ExportConfigsDialog(wxWindow *parent)
+ : DPIDialog(parent ? parent : nullptr, wxID_ANY, _L("Export Configs"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
+{
+ m_exprot_type.preset_bundle = _L("Printer config bundle(.bundle)");
+ m_exprot_type.printer_preset = _L("Printer presets(.json)");
+ m_exprot_type.filament_preset = _L("Filament presets(.json)");
+ m_exprot_type.process_preset = _L("Process presets(.json)");
+
+ this->SetBackgroundColour(*wxWHITE);
+ this->SetSize(wxSize(FromDIP(600), FromDIP(600)));
+
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
+ wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL);
+ // top line
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
+ m_line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
+ m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
+ m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
+
+ m_main_sizer->Add(create_txport_config_item(this), 0, wxEXPAND | wxALL, FromDIP(5));
+ m_main_sizer->Add(create_select_printer(this), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+ m_main_sizer->Add(create_button_item(this), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5));
+
+ data_init();
+
+ this->SetSizer(m_main_sizer);
+
+ this->Layout();
+ this->Fit();
+
+ wxGetApp().UpdateDlgDarkUI(this);
+
+}
+
+ExportConfigsDialog::~ExportConfigsDialog() {}
+
+void ExportConfigsDialog::on_dpi_changed(const wxRect &suggested_rect) {}
+
+wxBoxSizer *ExportConfigsDialog::create_txport_config_item(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_serial_text = new wxStaticText(parent, wxID_ANY, _L("Presets"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ wxBoxSizer *radioBoxSizer = new wxBoxSizer(wxVERTICAL);
+
+ radioBoxSizer->Add(create_radio_item(m_exprot_type.preset_bundle, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxALL, 0);
+ radioBoxSizer->Add(0, 0, 0, wxTOP, FromDIP(6));
+ wxStaticText *static_text = new wxStaticText(parent, wxID_ANY, _L("Printer and all the filament&process presets that belongs to the printer. \nCan be share in makerworld."), wxDefaultPosition, wxDefaultSize);
+ static_text->SetFont(Label::Body_12);
+ static_text->SetForegroundColour(wxColour("#6B6B6B"));
+ radioBoxSizer->Add(static_text, 0, wxEXPAND | wxLEFT, FromDIP(22));
+ radioBoxSizer->Add(create_radio_item(m_exprot_type.printer_preset, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
+ radioBoxSizer->Add(create_radio_item(m_exprot_type.filament_preset, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
+ radioBoxSizer->Add(create_radio_item(m_exprot_type.process_preset, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
+ horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+wxBoxSizer *ExportConfigsDialog::create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
+ RadioBox * radiobox = new RadioBox(parent);
+ horizontal_sizer->Add(radiobox, 0, wxEXPAND | wxALL, 0);
+ horizontal_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(5));
+ radiobox_list.push_back(std::make_pair(radiobox, title));
+ int btn_idx = radiobox_list.size() - 1;
+ radiobox->Bind(wxEVT_LEFT_DOWN, [this, &radiobox_list, btn_idx](wxMouseEvent &e) {
+ select_curr_radiobox(radiobox_list, btn_idx);
+ });
+
+ wxStaticText *text = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
+ text->Bind(wxEVT_LEFT_DOWN, [this, &radiobox_list, btn_idx](wxMouseEvent &e) {
+ select_curr_radiobox(radiobox_list, btn_idx);
+ });
+ horizontal_sizer->Add(text, 0, wxEXPAND | wxLEFT, 0);
+
+ radiobox->SetToolTip(tooltip);
+ text->SetToolTip(tooltip);
+ return horizontal_sizer;
+}
+
+void ExportConfigsDialog::select_curr_radiobox(std::vector> &radiobox_list, int btn_idx)
+{
+ int len = radiobox_list.size();
+ for (int i = 0; i < len; ++i) {
+ if (i == btn_idx) {
+ radiobox_list[i].first->SetValue(true);
+ const wxString &export_type = radiobox_list[i].second;
+ m_preset_sizer->Clear(true);
+ if (export_type == m_exprot_type.preset_bundle) {
+ for (std::pair preset : m_printer_presets) {
+ m_preset_sizer->Add(create_checkbox(m_presets_window, preset.second, preset.first, m_preset), 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(5));
+ }
+ } else if (export_type == m_exprot_type.printer_preset) {
+ for (std::pair preset : m_printer_presets) {
+ m_preset_sizer->Add(create_checkbox(m_presets_window, preset.second, preset.first, m_preset), 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(5));
+ }
+ } else if (export_type == m_exprot_type.filament_preset) {
+ PresetBundle & preset_bundle = *wxGetApp().preset_bundle;
+ const Preset & curr_selected_printer_preset = preset_bundle.printers.get_selected_preset();
+ std::string preset_name = wxString::FromUTF8(curr_selected_printer_preset.name).ToStdString();
+ std::unordered_map>::iterator iter = m_filament_presets.find(preset_name);
+ if (m_filament_presets.end() != iter) {
+ for (Preset *preset : iter->second) {
+ m_preset_sizer->Add(create_checkbox(m_presets_window, preset, preset->name, m_preset), 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(5));
+ }
+ }
+ } else if (export_type == m_exprot_type.process_preset) {
+ PresetBundle & preset_bundle = *wxGetApp().preset_bundle;
+ const Preset & curr_selected_printer_preset = preset_bundle.printers.get_selected_preset();
+ std::string preset_name = wxString::FromUTF8(curr_selected_printer_preset.name).ToStdString();
+ std::unordered_map>::iterator iter = m_process_presets.find(preset_name);
+ if (m_process_presets.end() != iter) {
+ for (Preset *preset : iter->second) {
+ m_preset_sizer->Add(create_checkbox(m_presets_window, preset, preset->name, m_preset), 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(5));
+ }
+ }
+ }
+ Layout();
+ Fit();
+ } else {
+ radiobox_list[i].first->SetValue(false);
+ }
+ }
+}
+
+ExportConfigsDialog::ExportCase ExportConfigsDialog::archive_preset_bundle_to_file(const wxString &path)
+{
+ std::string export_path = into_u8(path);
+ boost::filesystem::path printer_export_path = (boost::filesystem::path(export_path) / "Printer config bundle").make_preferred();
+ if (boost::filesystem::exists(printer_export_path)) {
+ MessageDialog dlg(this,
+ _L("The 'Printer config bundle' folder already exists in the current directory. Do you want to clear it and rebuild it.\nIf not, a time suffix will be "
+ "added, and you can modify the name after creation."),
+ wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
+ int res = dlg.ShowModal();
+ if (wxID_YES == res) {
+ boost::filesystem::remove_all(printer_export_path);
+ boost::filesystem::create_directories(printer_export_path);
+ export_path = printer_export_path.string();
+ } else {
+ export_path = printer_export_path.string();
+ std::string export_path_with_time;
+ boost::filesystem::path *printer_export_path_with_time = nullptr;
+ do {
+ if (printer_export_path_with_time) {
+ delete printer_export_path_with_time;
+ printer_export_path_with_time = nullptr;
+ }
+ export_path_with_time = export_path + " " + get_curr_time();
+ printer_export_path_with_time = new boost::filesystem::path(export_path_with_time);
+ } while (boost::filesystem::exists(*printer_export_path_with_time));
+ export_path = export_path_with_time;
+ boost::filesystem::create_directories(*printer_export_path_with_time);
+ if (printer_export_path_with_time) {
+ delete printer_export_path_with_time;
+ printer_export_path_with_time = nullptr;
+ }
+ }
+ } else {
+ boost::filesystem::create_directories(printer_export_path);
+ export_path = printer_export_path.string();
+ }
+
+ for (std::pair checkbox_preset : m_preset) {
+ if (checkbox_preset.first->GetValue()) {
+ mz_zip_archive zip_archive;
+ mz_zip_zero_struct(&zip_archive);
+ mz_bool status;
+
+ // Initialize the ZIP file to write to the structure, using memory storage
+ status = mz_zip_writer_init_heap(&zip_archive, 0, 1024);
+ if (MZ_FALSE == status) {
+ BOOST_LOG_TRIVIAL(info) << "Failed to initialize ZIP archive";
+ return ExportCase::INITIALIZE_FAIL;
+ }
+ Preset * printer_preset = checkbox_preset.second;
+ std::string preset_path = boost::filesystem::path(printer_preset->file).make_preferred().string();
+ if (preset_path.empty()) continue;
+ char * json_contents = read_json_file(preset_path);
+ if (!json_contents) continue;
+
+ // Add a file to the ZIP file
+ status = mz_zip_writer_add_file(&zip_archive, ("printer/" + printer_preset->name + ".json").c_str(), preset_path.c_str(), NULL, 0, MZ_DEFAULT_COMPRESSION);
+ //status = mz_zip_writer_add_mem(&zip_archive, ("printer/" + printer_preset->name + ".json").c_str(), json_contents, strlen(json_contents), MZ_DEFAULT_COMPRESSION);
+ if (MZ_FALSE == status) {
+ BOOST_LOG_TRIVIAL(info) << printer_preset->name << " Failed to add file to ZIP archive";
+ mz_zip_writer_end(&zip_archive);
+ return ExportCase::ADD_FILE_FAIL;
+ }
+ BOOST_LOG_TRIVIAL(info) << "Printer preset json add successful: " << printer_preset->name;
+ free(json_contents);
+
+ const std::string printer_preset_name = printer_preset->name;
+ std::unordered_map>::iterator iter = m_filament_presets.find(printer_preset_name);
+ if (m_filament_presets.end() != iter) {
+ for (Preset *preset : iter->second) {
+ std::string filament_preset_path = boost::filesystem::path(preset->file).make_preferred().string();
+ if (filament_preset_path.empty()) continue;
+ json_contents = read_json_file(filament_preset_path);
+ status = mz_zip_writer_add_file(&zip_archive, ("filament/" + preset->name + ".json").c_str(), filament_preset_path.c_str(), NULL, 0, MZ_DEFAULT_COMPRESSION);
+ if (MZ_FALSE == status) {
+ BOOST_LOG_TRIVIAL(info) << preset->name << " Failed to add file to ZIP archive";
+ mz_zip_writer_end(&zip_archive);
+ return ExportCase::ADD_FILE_FAIL;
+ }
+ BOOST_LOG_TRIVIAL(info) << "Filament preset json add successful: ";
+ free(json_contents);
+ }
+ }
+
+ iter = m_process_presets.find(printer_preset_name);
+ if (m_process_presets.end() != iter) {
+ for (Preset *preset : iter->second) {
+ std::string process_preset_path = boost::filesystem::path(preset->file).make_preferred().string();
+ if (process_preset_path.empty()) continue;
+ json_contents = read_json_file(process_preset_path);
+ status = mz_zip_writer_add_file(&zip_archive, ("process/" + preset->name + ".json").c_str(), process_preset_path.c_str(), NULL, 0, MZ_DEFAULT_COMPRESSION);
+ if (MZ_FALSE == status) {
+ BOOST_LOG_TRIVIAL(info) << preset->name << " Failed to add file to ZIP archive";
+ mz_zip_writer_end(&zip_archive);
+ return ExportCase::ADD_FILE_FAIL;
+ }
+ BOOST_LOG_TRIVIAL(info) << "Process preset json add successful: ";
+ free(json_contents);
+ }
+ }
+
+ // Complete writing of ZIP file
+ void * pZipData;
+ size_t zipSize;
+ status = mz_zip_writer_finalize_heap_archive(&zip_archive, &pZipData, &zipSize);
+ if (MZ_FALSE == status) {
+ BOOST_LOG_TRIVIAL(info) << "Failed to finalize ZIP archive";
+ mz_zip_writer_end(&zip_archive);
+ return ExportCase::FINALIZE_FAIL;
+ }
+
+ // Save ZIP file data to disk
+ std::string print_export_dir = boost::filesystem::path(export_path + "/" + printer_preset->name + ".bbscfg").make_preferred().string();
+ FILE * zipFile = boost::nowide::fopen(print_export_dir.c_str(), "wb");
+ if (zipFile == NULL) {
+ BOOST_LOG_TRIVIAL(info) << "Failed to open ZIP file for writing";
+ mz_zip_writer_end(&zip_archive);
+ return ExportCase::OPEN_ZIP_WRITTEN_FILE;
+ }
+
+ fwrite(pZipData, 1, zipSize, zipFile);
+ fclose(zipFile);
+
+ // Release ZIP file to write structure and related resources
+ mz_zip_writer_end(&zip_archive);
+ }
+ }
+ BOOST_LOG_TRIVIAL(info) << "ZIP archive created successfully";
+
+ return ExportCase::EXPORT_SUCCESS;
+}
+
+ExportConfigsDialog::ExportCase ExportConfigsDialog::archive_printer_preset_to_file(const wxString &path)
+{
+ return ExportCase::EXPORT_SUCCESS;
+
+}
+
+ExportConfigsDialog::ExportCase ExportConfigsDialog::archive_filament_preset_to_file(const wxString &path)
+{
+ return ExportCase::EXPORT_SUCCESS;
+
+}
+
+ExportConfigsDialog::ExportCase ExportConfigsDialog::archive_process_preset_to_file(const wxString &path)
+{
+ return ExportCase::EXPORT_SUCCESS;
+
+}
+
+wxBoxSizer *ExportConfigsDialog::create_button_item(wxWindow* parent)
+{
+ wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL);
+ bSizer_button->Add(0, 0, 1, wxEXPAND, 0);
+
+ StateColor btn_bg_green(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered),
+ std::pair(wxColour(0, 174, 66), StateColor::Normal));
+
+ m_button_ok = new Button(this, _L("OK"));
+ m_button_ok->SetBackgroundColor(btn_bg_green);
+ m_button_ok->SetBorderColor(*wxWHITE);
+ m_button_ok->SetTextColor(wxColour(0xFFFFFE));
+ m_button_ok->SetFont(Label::Body_12);
+ m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_ok->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_ok, 0, wxRIGHT, FromDIP(10));
+
+ m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
+ wxDirDialog dlg(this, _L("Choose a directory"), from_u8(wxGetApp().app_config->get_last_dir()), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
+ wxString path;
+ if (dlg.ShowModal() == wxID_OK) path = dlg.GetPath();
+ if (!path.IsEmpty()) {
+ const wxString curr_radio_type = get_curr_radio_type(m_export_type_btns);
+
+ if (curr_radio_type == m_exprot_type.preset_bundle) {
+ ExportCase export_case = archive_preset_bundle_to_file(path);
+ MessageDialog *msg_dlg;
+ switch (export_case) {
+ case ExportCase::INITIALIZE_FAIL:
+ msg_dlg = new MessageDialog(this, _L("initialize fail"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+ wxYES |
+ wxYES_DEFAULT | wxCENTRE);
+ msg_dlg->ShowModal();
+ return;
+ case ExportCase::ADD_FILE_FAIL:
+ msg_dlg = new MessageDialog(this, _L("add file fail"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ msg_dlg->ShowModal();
+ return;
+ case ExportCase::FINALIZE_FAIL:
+ msg_dlg = new MessageDialog(this, _L("finalize fail"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ msg_dlg->ShowModal();
+ return;
+ case ExportCase::OPEN_ZIP_WRITTEN_FILE:
+ msg_dlg = new MessageDialog(this, _L("open zip written fail"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ msg_dlg->ShowModal();
+ return;
+ case ExportCase::EXPORT_SUCCESS:
+ msg_dlg = new MessageDialog(this, _L("Export successful"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
+ msg_dlg->ShowModal();
+ break;
+ }
+ } else if (curr_radio_type == m_exprot_type.printer_preset) {
+ archive_printer_preset_to_file(path);
+ } else if (curr_radio_type == m_exprot_type.filament_preset) {
+ archive_filament_preset_to_file(path);
+ } else if (curr_radio_type == m_exprot_type.process_preset) {
+ archive_process_preset_to_file(path);
+ }
+ } else {
+ return;
+ }
+
+ EndModal(wxID_OK);
+ });
+
+ StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ m_button_cancel = new Button(this, _L("Cancel"));
+ m_button_cancel->SetBackgroundColor(btn_bg_white);
+ m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
+ m_button_cancel->SetFont(Label::Body_12);
+ m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetCornerRadius(FromDIP(12));
+ bSizer_button->Add(m_button_cancel, 0, wxRIGHT, FromDIP(10));
+
+ m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { EndModal(wxID_CANCEL); });
+
+ return bSizer_button;
+}
+
+wxBoxSizer *ExportConfigsDialog::create_select_printer(wxWindow *parent)
+{
+ wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxVERTICAL);
+
+ wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
+ wxStaticText *static_serial_text = new wxStaticText(parent, wxID_ANY, _L("Select Printer"), wxDefaultPosition, wxDefaultSize);
+ optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
+ optionSizer->SetMinSize(OPTION_SIZE);
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+
+ m_presets_window = new wxWindow(parent, wxID_ANY);
+ m_presets_window->SetBackgroundColour(PRINTER_LIST_COLOUR);
+ wxBoxSizer *select_printer_sizer = new wxBoxSizer(wxVERTICAL);
+
+ m_preset_sizer = new wxGridSizer(3, FromDIP(5), FromDIP(5));
+ select_printer_sizer->Add(m_preset_sizer, 0, wxEXPAND, FromDIP(5));
+ m_presets_window->SetSizer(select_printer_sizer);
+
+ horizontal_sizer->Add(m_presets_window, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(10));
+
+ return horizontal_sizer;
+}
+
+void ExportConfigsDialog::data_init()
+{
+ PresetBundle &preset_bundle(*wxGetApp().preset_bundle);
+
+ const std::deque & printer_presets = preset_bundle.printers.get_presets();
+ for (const Preset &printer_preset : printer_presets) {
+
+ std::string preset_name = wxString::FromUTF8(printer_preset.name).ToStdString();
+ if ("Default Printer" == preset_name) continue;
+ if (preset_bundle.printers.select_preset_by_name(preset_name, true)) {
+ Preset *new_printer_preset = new Preset(printer_preset);
+ m_printer_presets[preset_name] = new_printer_preset;
+ preset_bundle.update_compatible(PresetSelectCompatibleType::Never);
+
+ const std::deque &filament_presets = preset_bundle.filaments.get_presets();
+ for (const Preset &filament_preset : filament_presets) {
+ if ("Default Filament" == filament_preset.name) continue;
+ if (filament_preset.is_compatible) {
+ Preset *new_filament_preset = new Preset(filament_preset);
+ m_filament_presets[preset_name].push_back(new_filament_preset);
+ }
+ }
+
+ const std::deque &process_presets = preset_bundle.prints.get_presets();
+ for (const Preset &process_preset : process_presets) {
+ if ("Default Setting" == process_preset.name) continue;
+ if (process_preset.is_compatible) {
+ Preset *new_prpcess_preset = new Preset(process_preset);
+ m_process_presets[preset_name].push_back(new_prpcess_preset);
+ }
+ }
+ }
+ }
+}
+
+}} //Slic3r
+
+
diff --git a/src/slic3r/GUI/CreatePresetsDialog.hpp b/src/slic3r/GUI/CreatePresetsDialog.hpp
new file mode 100644
index 0000000000..6ed2dac164
--- /dev/null
+++ b/src/slic3r/GUI/CreatePresetsDialog.hpp
@@ -0,0 +1,248 @@
+#ifndef slic3r_CreatePresetsDialog_hpp_
+#define slic3r_CreatePresetsDialog_hpp_
+
+#include "libslic3r/Preset.hpp"
+#include "wxExtensions.hpp"
+#include "GUI_Utils.hpp"
+#include "Widgets/Label.hpp"
+#include "Widgets/TextInput.hpp"
+#include "Widgets/Button.hpp"
+#include "Widgets/RadioBox.hpp"
+#include "Widgets/CheckBox.hpp"
+#include "Widgets/ComboBox.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+class CreateFilamentPresetDialog : public DPIDialog
+{
+public:
+ CreateFilamentPresetDialog(wxWindow *parent);
+ ~CreateFilamentPresetDialog();
+
+protected:
+ enum FilamentOptionType {
+ VENDOR = 0,
+ TYPE,
+ SERIAL,
+ FILAMENT_PRESET,
+ PRESET_FOR_PRINTER,
+ FILAMENT_NAME_COUNT
+ };
+
+protected:
+ void on_dpi_changed(const wxRect &suggested_rect) override;
+ wxBoxSizer *create_item(FilamentOptionType option_type);
+ wxBoxSizer *create_vendor_item();
+ wxBoxSizer *create_type_item();
+ wxBoxSizer *create_serial_item();
+ wxBoxSizer *create_filament_preset_item();
+ wxBoxSizer *create_filament_preset_for_printer_item();
+ wxBoxSizer *create_button_item();
+
+private:
+ void clear_filament_preset_map();
+ wxArrayString get_filament_preset_choices();
+ wxBoxSizer * create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list);
+ void select_curr_radiobox(std::vector> &radiobox_list, int btn_idx);
+ wxString curr_create_filament_type();
+ void get_filament_presets_by_machine();
+ void get_all_filament_presets();
+
+private:
+ struct CreateType
+ {
+ wxString base_filament;
+ wxString base_filament_preset;
+ };
+
+private:
+ std::vector> m_create_type_btns;
+ std::vector> m_filament_preset;
+ std::unordered_map m_machint_filament_preset;
+ std::unordered_map> m_filament_choice_map;
+ std::unordered_map m_public_name_to_filament_id_map;
+ std::unordered_map m_all_presets_map;
+ CreateType m_create_type;
+ Button * m_button_create = nullptr;
+ Button * m_button_cancel = nullptr;
+ ComboBox * m_filament_vendor_combobox = nullptr;
+ ComboBox * m_filament_type_combobox = nullptr;
+ ComboBox * m_exist_vendor_combobox = nullptr;
+ ComboBox * m_filament_preset_combobox = nullptr;
+ TextInput * m_filament_custom_vendor_input = nullptr;
+ wxGridSizer * m_filament_presets_sizer = nullptr;
+ wxPanel * m_filament_preset_panel = nullptr;
+ TextInput * m_filament_serial_input = nullptr;
+
+};
+
+class CreatePrinterPresetDialog : public DPIDialog
+{
+public:
+ CreatePrinterPresetDialog(wxWindow *parent);
+ ~CreatePrinterPresetDialog();
+
+protected:
+ void on_dpi_changed(const wxRect &suggested_rect) override;
+
+/******************************************************** Control Construction *****************************************************/
+ wxBoxSizer *create_step_switch_item();
+ //Create Printer Page1
+ void create_printer_page1(wxWindow *parent);
+ wxBoxSizer *create_type_item(wxWindow *parent);
+ wxBoxSizer *create_printer_item(wxWindow *parent);
+ wxBoxSizer *create_nozzle_diameter_item(wxWindow *parent);
+ wxBoxSizer *create_bed_shape_item(wxWindow *parent);
+ wxBoxSizer *create_bed_size_item(wxWindow *parent);
+ wxBoxSizer *create_origin_item(wxWindow *parent);
+ wxBoxSizer *create_hot_bed_stl_item(wxWindow *parent);
+ wxBoxSizer *create_hot_bed_svg_item(wxWindow *parent);
+ wxBoxSizer *create_max_print_height_item(wxWindow *parent);
+ wxBoxSizer *create_page1_btns_item(wxWindow *parent);
+
+
+ //Improt Presets Page2
+ void create_printer_page2(wxWindow *parent);
+ wxBoxSizer *create_printer_preset_item(wxWindow *parent);
+ wxBoxSizer *create_presets_item(wxWindow *parent);
+ wxBoxSizer *create_presets_template_item(wxWindow *parent);
+ wxBoxSizer *create_page2_btns_item(wxWindow *parent);
+
+ void show_page1();
+ void show_page2();
+
+/********************************************************** Data Interaction *******************************************************/
+ bool data_init();
+ void select_curr_radiobox(std::vector> &radiobox_list, int btn_idx);
+ void select_all_preset_template(std::vector> &preset_templates);
+ void deselect_all_preset_template(std::vector> &preset_templates);
+ void update_presets_list();
+ void on_preset_model_value_change(wxCommandEvent &e);
+ void clear_preset_combobox();
+ void save_preset_config(Preset *preset);
+ bool validate_input_valid();
+ wxArrayString printer_preset_sort_with_nozzle_diameter(const VendorProfile &vendor_profile, float nozzle_diameter);
+
+ wxBoxSizer *create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list);
+
+ wxString curr_create_preset_type();
+ wxString curr_create_printer_type();
+
+private:
+ std::vector> m_create_type_btns;
+ std::vector> m_create_presets_btns;
+ std::vector> m_filament_preset;
+ std::vector> m_process_preset;
+ std::vector m_create_printer_type;
+ std::vector m_create_presets_type;
+ VendorProfile m_printer_preset_vendor_selected;
+ Slic3r::VendorProfile::PrinterModel m_printer_preset_model_selected;
+ bool rewritten = false;
+ Preset * m_printer_preset = nullptr;
+ wxStaticBitmap * m_step_1 = nullptr;
+ wxStaticBitmap * m_step_2 = nullptr;
+ Button * m_button_OK = nullptr;
+ Button * m_button_create = nullptr;
+ Button * m_button_page1_cancel = nullptr;
+ Button * m_button_page2_cancel = nullptr;
+ Button * m_button_page2_back = nullptr;
+ Button * m_button_bed_stl = nullptr;
+ Button * m_button_bed_svg = nullptr;
+ wxWindow * m_page1 = nullptr;
+ wxWindow * m_page2 = nullptr;
+ ComboBox * m_select_vendor = nullptr;
+ ComboBox * m_select_model = nullptr;
+ ComboBox * m_select_printer = nullptr;
+ CheckBox * m_can_not_find_vendor_combox = nullptr;
+ wxStaticText * m_can_not_find_vendor_text = nullptr;
+ wxTextCtrl * m_custom_vendor_model = nullptr;
+ ComboBox * m_nozzle_diameter = nullptr;
+ ComboBox * m_printer_vendor = nullptr;
+ ComboBox * m_printer_model = nullptr;
+ TextInput * m_bed_size_x_input = nullptr;
+ TextInput * m_bed_size_y_input = nullptr;
+ TextInput * m_bed_origin_x_input = nullptr;
+ TextInput * m_bed_origin_y_input = nullptr;
+ TextInput * m_print_height_input = nullptr;
+ wxGridSizer * m_filament_preset_template_sizer = nullptr;
+ wxGridSizer * m_process_preset_template_sizer = nullptr;
+ wxPanel * m_filament_preset_panel = nullptr;
+ wxPanel * m_process_preset_panel = nullptr;
+ wxPanel * m_preset_template_panel = nullptr;
+
+};
+
+enum SuccessType {
+ PRINTER = 0,
+ FILAMENT
+};
+
+class CreatePresetSuccessfulDialog : public DPIDialog
+{
+public:
+ CreatePresetSuccessfulDialog(wxWindow *parent, const SuccessType &create_success_type);
+ ~CreatePresetSuccessfulDialog();
+
+protected:
+ void on_dpi_changed(const wxRect &suggested_rect) override;
+
+private:
+ Button *m_button_ok = nullptr;
+ Button *m_button_cancel = nullptr;
+};
+
+class ExportConfigsDialog : public DPIDialog
+{
+public:
+ ExportConfigsDialog(wxWindow *parent);
+ ~ExportConfigsDialog();//to do: delete preset
+
+protected:
+ void on_dpi_changed(const wxRect &suggested_rect) override;
+ wxBoxSizer *create_txport_config_item(wxWindow* parent);
+ wxBoxSizer *create_button_item(wxWindow *parent);
+ wxBoxSizer *create_select_printer(wxWindow *parent);
+
+ wxBoxSizer *create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list);
+
+ struct ExportType
+ {
+ wxString preset_bundle;
+ wxString printer_preset;
+ wxString filament_preset;
+ wxString process_preset;
+ };
+
+ enum ExportCase {
+ INITIALIZE_FAIL = 0,
+ ADD_FILE_FAIL,
+ FINALIZE_FAIL,
+ OPEN_ZIP_WRITTEN_FILE,
+ EXPORT_SUCCESS,
+ };
+
+private:
+ void data_init();
+ void select_curr_radiobox(std::vector> &radiobox_list, int btn_idx);
+ ExportCase archive_preset_bundle_to_file(const wxString &path);
+ ExportCase archive_printer_preset_to_file(const wxString &path);
+ ExportCase archive_filament_preset_to_file(const wxString &path);
+ ExportCase archive_process_preset_to_file(const wxString &path);
+
+private:
+ std::vector> m_export_type_btns;
+ std::vector> m_preset;
+ std::unordered_map m_printer_presets;
+ std::unordered_map> m_filament_presets;
+ std::unordered_map> m_process_presets;
+ ExportType m_exprot_type;
+ wxGridSizer * m_preset_sizer = nullptr;
+ wxWindow * m_presets_window = nullptr;
+ Button * m_button_ok = nullptr;
+ Button * m_button_cancel = nullptr;
+};
+
+}
+}
+#endif
\ No newline at end of file
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 2d620b2298..4526aac4ce 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -3128,6 +3128,10 @@ struct ConfigsOverwriteConfirmDialog : MessageDialog
void MainFrame::export_config()
{
+ ExportConfigsDialog export_configs_dlg(nullptr);
+ export_configs_dlg.ShowModal();
+ return;
+
// Generate a cummulative configuration for the selected print, filaments and printer.
wxDirDialog dlg(this, _L("Choose a directory"),
from_u8(!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir()), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index be58cd7d2e..a8f64b722f 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -564,10 +564,45 @@ Sidebar::Sidebar(Plater *parent)
wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS);
});
+ StateColor create_printer_bg_col(std::pair(wxColour(219, 253, 231), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(wxColour(238, 238, 238), StateColor::Normal));
+
+ StateColor create_printer_fg_col(std::pair(wxColour(107, 107, 106), StateColor::Pressed),
+ std::pair(wxColour(107, 107, 106), StateColor::Hovered),
+ std::pair(wxColour(107, 107, 106), StateColor::Normal));
+
+ StateColor create_printer_bd_col(std::pair(wxColour(0, 174, 66), StateColor::Pressed), std::pair(wxColour(0, 174, 66), StateColor::Hovered),
+ std::pair(wxColour(172, 172, 172), StateColor::Normal));
+
+ auto create_printer_preset_btn = new Button(p->m_panel_printer_title, _L("Create Printer"));
+ create_printer_preset_btn->SetFont(Label::Body_10);
+ create_printer_preset_btn->SetPaddingSize(wxSize(FromDIP(8), FromDIP(3)));
+ create_printer_preset_btn->SetCornerRadius(FromDIP(8));
+ create_printer_preset_btn->SetBackgroundColor(create_printer_bg_col);
+ create_printer_preset_btn->SetBorderColor(create_printer_bd_col);
+ create_printer_preset_btn->SetTextColor(create_printer_fg_col);
+ create_printer_preset_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
+ //CreateFilamentPresetDialog dlg(p->m_panel_printer_title);
+ CreatePrinterPresetDialog dlg(p->m_panel_printer_title);
+ int res = dlg.ShowModal();
+ if (wxID_OK == res) {
+ wxGetApp().mainframe->update_side_preset_ui();
+ update_all_preset_comboboxes();
+ CreatePresetSuccessfulDialog success_dlg(p->m_panel_filament_title, SuccessType::PRINTER);
+ int res = success_dlg.ShowModal();
+ if (res == wxID_OK) {
+ p->editing_filament = -1;
+ if (p->combo_printer->switch_to_tab())
+ p->editing_filament = 0;
+ }
+ }
+ });
+
wxBoxSizer* h_sizer_title = new wxBoxSizer(wxHORIZONTAL);
h_sizer_title->Add(p->m_printer_icon, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, em);
h_sizer_title->Add(p->m_text_printer_settings, 0, wxALIGN_CENTER);
h_sizer_title->AddStretchSpacer();
+ h_sizer_title->Add(create_printer_preset_btn, 0, wxRIGHT | wxALIGN_CENTER, FromDIP(10));
h_sizer_title->Add(p->m_printer_setting, 0, wxALIGN_CENTER);
h_sizer_title->Add(15 * em / 10, 0, 0, 0, 0);
h_sizer_title->SetMinSize(-1, 3 * em);
@@ -788,6 +823,31 @@ Sidebar::Sidebar(Plater *parent)
wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent));
}
}));
+ auto create_filament_preset_btn = new Button(p->m_panel_filament_title, _L("Create Filament"));
+ create_filament_preset_btn->SetFont(Label::Body_10);
+ create_filament_preset_btn->SetPaddingSize(wxSize(FromDIP(8), FromDIP(3)));
+ create_filament_preset_btn->SetCornerRadius(FromDIP(8));
+ create_filament_preset_btn->SetBackgroundColor(flush_bg_col);
+ create_filament_preset_btn->SetBorderColor(flush_bd_col);
+ create_filament_preset_btn->SetTextColor(flush_fg_col);
+ create_filament_preset_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
+ CreateFilamentPresetDialog dlg(p->m_panel_filament_title);
+ //CreatePrinterPresetDialog dlg(p->m_panel_filament_title);
+ int res = dlg.ShowModal();
+ if (wxID_OK == res) {
+ wxGetApp().mainframe->update_side_preset_ui();
+ update_ui_from_settings();
+ update_all_preset_comboboxes();
+ CreatePresetSuccessfulDialog success_dlg(p->m_panel_filament_title, SuccessType::FILAMENT);
+ int res = success_dlg.ShowModal();
+ /*if (res == wxID_OK) {
+ p->editing_filament = 0;
+ p->combos_filament[0]->switch_to_tab();
+ }*/
+ }
+ });
+
+ bSizer39->Add(create_filament_preset_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5));
bSizer39->Add(p->m_flushing_volume_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5));
bSizer39->Hide(p->m_flushing_volume_btn);
bSizer39->Add(FromDIP(10), 0, 0, 0, 0 );
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index c30eb5a059..e6b30559ab 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -25,6 +25,7 @@
#include "libslic3r/PrintBase.hpp"
#include "libslic3r/Calib.hpp"
#include "libslic3r/FlushVolCalc.hpp"
+#include "CreatePresetsDialog.hpp"
#define FILAMENT_SYSTEM_COLORS_NUM 16
diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp
index e8192c8741..5f00159cfa 100644
--- a/src/slic3r/GUI/SelectMachine.cpp
+++ b/src/slic3r/GUI/SelectMachine.cpp
@@ -3682,7 +3682,7 @@ void SelectMachineDialog::set_default_normal()
auto dialogSize = this->GetSize();
#ifdef __WINDOWS__
- if (screenSize.y < dialogSize.y) {
+ if (screenSize.GetHeight() < dialogSize.GetHeight()) {
m_need_adaptation_screen = true;
m_scrollable_view->SetScrollRate(0, 5);
m_scrollable_view->SetSize(wxSize(-1, FromDIP(220)));
@@ -3843,7 +3843,7 @@ void SelectMachineDialog::set_default_from_sdcard()
auto dialogSize = this->GetSize();
#ifdef __WINDOWS__
- if (screenSize.y < dialogSize.y) {
+ if (screenSize.GetHeight() < dialogSize.GetHeight()) {
m_need_adaptation_screen = true;
m_scrollable_view->SetScrollRate(0, 5);
m_scrollable_view->SetSize(wxSize(-1, FromDIP(220)));