diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4e79d3cc4..3cd467492 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2745,7 +2745,6 @@ void GCode::append_full_config(const Print &print, std::string &str) "print_host", "printhost_apikey", "printhost_cafile", - "repetier_group", "repetier_slug" }; assert(std::is_sorted(banned_keys.begin(), banned_keys.end())); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index da06a1dd8..f0de4e798 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -154,13 +154,6 @@ void PrintConfigDef::init_common_params() def->tooltip = L("Name of the Repetier printer"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); - - def = this->add("repetier_group", coString); - def->label = L("Repetier Group"); - def->tooltip = L("Name of the Repetier group that the G-code file will be sent to."); - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionString("")); - def = this->add("printhost_cafile", coString); def->label = L("HTTPS CA File"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e66f3ee58..df003e816 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1278,7 +1278,6 @@ public: ConfigOptionString printhost_apikey; ConfigOptionString printhost_cafile; ConfigOptionString repetier_slug; - ConfigOptionString repetier_group; ConfigOptionString serial_port; ConfigOptionInt serial_speed; @@ -1290,7 +1289,6 @@ protected: OPT_PTR(printhost_apikey); OPT_PTR(printhost_cafile); OPT_PTR(repetier_slug); - OPT_PTR(repetier_group); OPT_PTR(serial_port); OPT_PTR(serial_speed); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f8882bb1d..66547ebf7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2066,7 +2066,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) "complete_objects_one_skirt", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance", "skirt_height", "brim_width", "variable_layer_height", "serial_port", "serial_speed", "host_type", "print_host", - "printhost_apikey", "printhost_cafile", "repetier_slug", "repetier_group", "nozzle_diameter", "single_extruder_multi_material", + "printhost_apikey", "printhost_cafile", "repetier_slug", "nozzle_diameter", "single_extruder_multi_material", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim", "extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology", // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor. @@ -5295,10 +5295,14 @@ void Plater::send_gcode() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); - PrintHostSendDialog dlg(default_output_file, upload_job.printhost->can_start_print()); + wxArrayString groups; + upload_job.printhost->get_groups(groups); + + PrintHostSendDialog dlg(default_output_file, upload_job.printhost->can_start_print(), groups); if (dlg.ShowModal() == wxID_OK) { upload_job.upload_data.upload_path = dlg.filename(); upload_job.upload_data.start_print = dlg.start_print(); + upload_job.upload_data.group = dlg.group(); p->export_gcode(fs::path(), false, std::move(upload_job)); } diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 83288454c..0af064746 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -613,7 +613,7 @@ const std::vector& Preset::printer_options() "bed_shape", "bed_custom_texture", "bed_custom_model", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height", "min_length", - "host_type", "print_host", "printhost_apikey", "printhost_cafile", "repetier_slug", "repetier_group", + "host_type", "print_host", "printhost_apikey", "printhost_cafile", "repetier_slug", "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode", "feature_gcode", "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction", @@ -751,7 +751,7 @@ const std::vector& Preset::sla_printer_options() "gamma_correction", "min_exposure_time", "max_exposure_time", "min_initial_exposure_time", "max_initial_exposure_time", - "print_host", "printhost_apikey", "printhost_cafile", "repetier_slug", "repetier_group", + "print_host", "printhost_apikey", "printhost_cafile", "repetier_slug", "printer_notes", "inherits", "thumbnails", @@ -892,20 +892,17 @@ static ProfileHostParams profile_host_params_same_or_anonymized(const DynamicPri auto opt_printhost_apikey_old = cfg_old.option("printhost_apikey"); auto opt_printhost_cafile_old = cfg_old.option("printhost_cafile"); auto opt_repetier_slug_old = cfg_old.option("repetier_slug"); - auto opt_repetier_group_old = cfg_old.option("repetier_group"); auto opt_print_host_new = cfg_new.option("print_host"); auto opt_printhost_apikey_new = cfg_new.option("printhost_apikey"); auto opt_printhost_cafile_new = cfg_new.option("printhost_cafile"); auto opt_repetier_slug_new = cfg_new.option("repetier_slug"); - auto opt_repetier_group_new = cfg_new.option("repetier_group"); // If the new print host data is undefined, use the old data. bool new_print_host_undefined = (opt_print_host_new == nullptr || opt_print_host_new ->empty()) && (opt_printhost_apikey_new == nullptr || opt_printhost_apikey_new ->empty()) && (opt_printhost_cafile_new == nullptr || opt_printhost_cafile_new ->empty()) && - (opt_repetier_slug_new == nullptr || opt_repetier_slug_new ->empty()) && - (opt_repetier_group_new == nullptr || opt_repetier_group_new ->empty()); + (opt_repetier_slug_new == nullptr || opt_repetier_slug_new ->empty()); if (new_print_host_undefined) return ProfileHostParams::Anonymized; @@ -914,8 +911,8 @@ static ProfileHostParams profile_host_params_same_or_anonymized(const DynamicPri (l != nullptr && r != nullptr && l->value == r->value); }; return (opt_same(opt_print_host_old, opt_print_host_new) && opt_same(opt_printhost_apikey_old, opt_printhost_apikey_new) && - opt_same(opt_printhost_cafile_old, opt_printhost_cafile_new) && opt_same(opt_repetier_slug_old, opt_repetier_slug_new) && - opt_same(opt_repetier_group_old, opt_repetier_group_new)) ? ProfileHostParams::Same : ProfileHostParams::Different; + opt_same(opt_printhost_cafile_old, opt_printhost_cafile_new) && opt_same(opt_repetier_slug_old, opt_repetier_slug_new)) + ? ProfileHostParams::Same : ProfileHostParams::Different; } static bool profile_print_params_same(const DynamicPrintConfig &cfg_old, const DynamicPrintConfig &cfg_new) @@ -927,7 +924,7 @@ static bool profile_print_params_same(const DynamicPrintConfig &cfg_old, const D "compatible_printers", "compatible_printers_condition", "inherits", "print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id", "printer_model", "printer_variant", "default_print_profile", "default_filament_profile", "default_sla_print_profile", "default_sla_material_profile", - "print_host", "printhost_apikey", "repetier_slug", "repetier_group", "printhost_cafile" }) + "print_host", "printhost_apikey", "repetier_slug", "printhost_cafile" }) diff.erase(std::remove(diff.begin(), diff.end(), key), diff.end()); // Preset with the same name as stored inside the config exists. return diff.empty() && profile_host_params_same_or_anonymized(cfg_old, cfg_new) != ProfileHostParams::Different; @@ -978,7 +975,6 @@ Preset& PresetCollection::load_external_preset( opt_update("printhost_apikey"); opt_update("printhost_cafile"); opt_update("repetier_slug"); - opt_update("repetier_group"); } } // Update the "inherits" field. diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 9f7ab713a..233953f27 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -527,7 +527,6 @@ DynamicPrintConfig PresetBundle::full_config_secure() const config.erase("print_host"); config.erase("printhost_apikey"); config.erase("repetier_slug"); - config.erase("repetier_group"); config.erase("printhost_cafile"); return config; } diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp index bae60e47f..eee907a60 100644 --- a/src/slic3r/GUI/PrintHostDialogs.cpp +++ b/src/slic3r/GUI/PrintHostDialogs.cpp @@ -28,11 +28,13 @@ namespace GUI { static const char *CONFIG_KEY_PATH = "printhost_path"; static const char *CONFIG_KEY_PRINT = "printhost_print"; +static const char *CONFIG_KEY_GROUP = "repetier_group"; -PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_print) +PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_print, wxArrayString& groups) : MsgDialog(nullptr, _(L("Send G-Code to printer host")), _(L("Upload to Printer Host with the following filename:")), wxID_NONE) , txt_filename(new wxTextCtrl(this, wxID_ANY)) , box_print(can_start_print ? new wxCheckBox(this, wxID_ANY, _(L("Start printing after upload"))) : nullptr) + , combo_groups(!groups.IsEmpty() ? new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, groups, wxCB_READONLY) : nullptr) { #ifdef __APPLE__ txt_filename->OSXDisableAllSmartSubstitutions(); @@ -49,6 +51,18 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr content_sizer->Add(box_print, 0, wxBOTTOM, 2*VERT_SPACING); box_print->SetValue(app_config->get("recent", CONFIG_KEY_PRINT) == "1"); } + + if (combo_groups != nullptr) { + auto *label_group = new wxStaticText(this, wxID_ANY, _(L("Group"))); + content_sizer->Add(label_group); + + content_sizer->Add(combo_groups, 0, wxBOTTOM, 2*VERT_SPACING); + + wxString recent_group = from_u8(app_config->get("recent", CONFIG_KEY_GROUP)); + if (recent_group.Length() > 0) { + combo_groups->SetValue(recent_group); + } + } btn_sizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL)); @@ -64,7 +78,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr txt_filename->SetValue(recent_path); txt_filename->SetFocus(); - + Fit(); Bind(wxEVT_SHOW, [=](const wxShowEvent &) { @@ -86,6 +100,16 @@ bool PrintHostSendDialog::start_print() const return box_print != nullptr ? box_print->GetValue() : false; } +std::string PrintHostSendDialog::group() const +{ + if (combo_groups == nullptr) { + return ""; + } else { + wxString group = combo_groups->GetValue(); + return into_u8(group); + } +} + void PrintHostSendDialog::EndModal(int ret) { if (ret == wxID_OK) { @@ -96,9 +120,15 @@ void PrintHostSendDialog::EndModal(int ret) path.clear(); else path = path.SubString(0, last_slash); + AppConfig *app_config = wxGetApp().app_config; app_config->set("recent", CONFIG_KEY_PATH, into_u8(path)); app_config->set("recent", CONFIG_KEY_PRINT, start_print() ? "1" : "0"); + + if (combo_groups != nullptr) { + wxString group = combo_groups->GetValue(); + app_config->set("recent", CONFIG_KEY_GROUP, into_u8(group)); + } } MsgDialog::EndModal(ret); diff --git a/src/slic3r/GUI/PrintHostDialogs.hpp b/src/slic3r/GUI/PrintHostDialogs.hpp index e5f96f2b6..54eeaceae 100644 --- a/src/slic3r/GUI/PrintHostDialogs.hpp +++ b/src/slic3r/GUI/PrintHostDialogs.hpp @@ -29,14 +29,16 @@ namespace GUI { class PrintHostSendDialog : public GUI::MsgDialog { public: - PrintHostSendDialog(const boost::filesystem::path &path, bool can_start_print); + PrintHostSendDialog(const boost::filesystem::path &path, bool can_start_print, wxArrayString& groups); boost::filesystem::path filename() const; bool start_print() const; + std::string group() const; virtual void EndModal(int ret) override; private: wxTextCtrl *txt_filename; wxCheckBox *box_print; + wxComboBox *combo_groups; }; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 4504c8934..132ee9eca 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1991,6 +1991,26 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) return sizer; }; + + auto repetier_slug_browse = [=](wxWindow* parent) { + add_scaled_button(parent, &m_repetier_slug_browse_btn, "printers", _(L("Printers")) + " "+ dots, wxBU_LEFT | wxBU_EXACTFIT); + ScalableButton* btn = m_repetier_slug_browse_btn; + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn); + + btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { + BonjourDialog dialog(parent, tech); + if (dialog.show_and_lookup()) { + optgroup->set_value("repetier_slug", std::move(dialog.get_selected()), true); + optgroup->get_field("repetier_slug")->field_changed(); + } + }); + + return sizer; + }; + // Set a wider width for a better alignment Option option = optgroup->get_option("print_host"); @@ -2002,13 +2022,11 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) option = optgroup->get_option("printhost_apikey"); option.opt.width = Field::def_width_wider(); optgroup->append_single_option_line(option); + option = optgroup->get_option("repetier_slug"); option.opt.width = Field::def_width_wider(); optgroup->append_single_option_line(option); - option = optgroup->get_option("repetier_group"); - option.opt.width = Field::def_width_wider(); - optgroup->append_single_option_line(option); - + const auto ca_file_hint = _utf8(L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate.")); if (Http::ca_file_supported()) { @@ -2614,13 +2632,10 @@ void TabPrinter::update_fff() bool is_repetier = m_config->option>("host_type")->value == htRepetier; { Field *rs = get_field("repetier_slug"); - Field *rg = get_field("repetier_group"); if (is_repetier) { rs->enable(); - rg->enable(); } else { rs->disable(); - rg->disable(); } } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 1122fbdfb..777c6043e 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -392,6 +392,7 @@ public: wxButton* m_serial_test_btn = nullptr; ScalableButton* m_print_host_test_btn = nullptr; ScalableButton* m_printhost_browse_btn = nullptr; + ScalableButton* m_repetier_slug_browse_btn = nullptr; ScalableButton* m_reset_to_filament_color = nullptr; size_t m_extruders_count; diff --git a/src/slic3r/Utils/AstroBox.hpp b/src/slic3r/Utils/AstroBox.hpp index 38542275c..362857546 100644 --- a/src/slic3r/Utils/AstroBox.hpp +++ b/src/slic3r/Utils/AstroBox.hpp @@ -28,7 +28,8 @@ public: bool can_test() const override { return true; } bool can_start_print() const override { return true; } std::string get_host() const override { return host; } - + bool get_groups(wxArrayString& groups) const override { return false; } + protected: bool validate_version_text(const boost::optional &version_text) const; diff --git a/src/slic3r/Utils/Duet.hpp b/src/slic3r/Utils/Duet.hpp index 702efbddb..5d403d647 100644 --- a/src/slic3r/Utils/Duet.hpp +++ b/src/slic3r/Utils/Duet.hpp @@ -27,7 +27,8 @@ public: bool can_test() const override { return true; } bool can_start_print() const override { return true; } std::string get_host() const override { return host; } - + bool get_groups(wxArrayString& groups) const override { return false; } + private: std::string host; std::string password; diff --git a/src/slic3r/Utils/FlashAir.hpp b/src/slic3r/Utils/FlashAir.hpp index 40af48da1..013941b0d 100644 --- a/src/slic3r/Utils/FlashAir.hpp +++ b/src/slic3r/Utils/FlashAir.hpp @@ -28,7 +28,8 @@ public: bool can_test() const override { return true; } bool can_start_print() const override { return false; } std::string get_host() const override { return host; } - + bool get_groups(wxArrayString& groups) const override { return false; } + private: std::string host; diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index 965019d85..ceed69cbb 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -29,6 +29,7 @@ public: bool can_test() const override { return true; } bool can_start_print() const override { return true; } std::string get_host() const override { return host; } + bool get_groups(wxArrayString& groups) const override { return false; } protected: virtual bool validate_version_text(const boost::optional &version_text) const; diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp index e0aeb463c..daa34966d 100644 --- a/src/slic3r/Utils/PrintHost.hpp +++ b/src/slic3r/Utils/PrintHost.hpp @@ -20,6 +20,9 @@ struct PrintHostUpload { boost::filesystem::path source_path; boost::filesystem::path upload_path; + + std::string group; + bool start_print = false; }; @@ -42,6 +45,7 @@ public: virtual bool can_test() const = 0; virtual bool can_start_print() const = 0; virtual std::string get_host() const = 0; + virtual bool get_groups(wxArrayString& groups) const = 0; static PrintHost* get_print_host(DynamicPrintConfig *config); diff --git a/src/slic3r/Utils/Repetier.cpp b/src/slic3r/Utils/Repetier.cpp index 7e9560933..0b2f6eeba 100644 --- a/src/slic3r/Utils/Repetier.cpp +++ b/src/slic3r/Utils/Repetier.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -27,8 +28,7 @@ Repetier::Repetier(DynamicPrintConfig *config) : host(config->opt_string("print_host")), apikey(config->opt_string("printhost_apikey")), cafile(config->opt_string("printhost_cafile")), - slug(config->opt_string("repetier_slug")), - group(config->opt_string("repetier_group")) + slug(config->opt_string("repetier_slug")) {} const char* Repetier::get_name() const { return "Repetier"; } @@ -106,19 +106,20 @@ bool Repetier::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Error auto url = make_url((boost::format("printer/model/%1%") % slug).str()); - BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%") + BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%, group: %7%") % name % upload_data.source_path % url % upload_filename.string() % upload_parent_path.string() - % upload_data.start_print; + % upload_data.start_print + % upload_data.group; auto http = Http::post(std::move(url)); set_auth(http); - if (! group.empty()) { - http.form_add("group", group); + if (! upload_data.group.empty() && upload_data.group != _utf8(L("Default"))) { + http.form_add("group", upload_data.group); } http.form_add("a", "upload") @@ -171,4 +172,45 @@ std::string Repetier::make_url(const std::string &path) const } } +bool Repetier::get_groups(wxArrayString& groups) const +{ + bool res = true; + + const char *name = get_name(); + auto url = make_url((boost::format("printer/api/%1%") % slug).str()); + + BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get groups at: %2%") % name % url; + + auto http = Http::get(std::move(url)); + set_auth(http); + http.form_add("a", "listModelGroups"); + http.on_error([&](std::string body, std::string error, unsigned status) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; + }) + .on_complete([&, this](std::string body, unsigned) { + BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got groups: %2%") % name % body; + + try { + std::stringstream ss(body); + pt::ptree ptree; + pt::read_json(ss, ptree); + + BOOST_FOREACH(boost::property_tree::ptree::value_type &v, ptree.get_child("groupNames.")) { + if (v.second.data() == "#") { + groups.push_back(_utf8(L("Default"))); + } else { + groups.push_back(v.second.data()); + } + } + } + catch (const std::exception &) { + //msg = "Could not parse server response"; + res = false; + } + }) + .perform_sync(); + + return res; +} + } diff --git a/src/slic3r/Utils/Repetier.hpp b/src/slic3r/Utils/Repetier.hpp index 512c74468..442415526 100644 --- a/src/slic3r/Utils/Repetier.hpp +++ b/src/slic3r/Utils/Repetier.hpp @@ -29,6 +29,7 @@ public: bool can_test() const override { return true; } bool can_start_print() const override { return false; } std::string get_host() const override { return host; } + bool get_groups(wxArrayString& groups) const override; protected: virtual bool validate_version_text(const boost::optional &version_text) const; @@ -38,7 +39,6 @@ private: std::string apikey; std::string cafile; std::string slug; - std::string group; void set_auth(Http &http) const; std::string make_url(const std::string &path) const;