149{
151 if (opt_key == "host_type" || opt_key == "printhost_authorization_type")
153 if (opt_key == "print_host")
155 if (opt_key == "printhost_port")
157 if (opt_key == "bbl_use_print_host_webui")
159 };
160
161 m_optgroup->append_single_option_line(
"host_type");
162
163 auto create_sizer_with_btn = [](wxWindow* parent, Button** btn, const std::string& icon_name, const wxString& label) {
164 *btn = new Button(parent, label);
166
167 auto sizer = new wxBoxSizer(wxHORIZONTAL);
168 sizer->Add(*btn);
169 return sizer;
170 };
171
172 auto printhost_browse = [=](wxWindow* parent)
173 {
177
178
179
180
181
183 CrealityDiscoveryDialog dialog(this);
184 if (dialog.ShowModal() == wxID_OK && !dialog.selected_ip().empty()) {
185
186
187 wxString new_url = wxString::FromUTF8("http://" + dialog.selected_ip());
188 m_optgroup->set_value(
"print_host", new_url,
true);
189 m_optgroup->get_field(
"print_host")->field_changed();
190 }
191 return;
192 }
193
195 wxBusyCursor wait;
196 std::vector<FlashforgeDiscoveredPrinter> printers;
197 wxString error_msg;
200 return;
201 }
202
203 wxArrayString choices;
204 for (const auto& printer : printers)
205 choices.Add(
from_u8((boost::format(
"%1% (%2%) [%3%]") % printer.name % printer.ip_address % printer.serial_number).str()));
206
207 wxSingleChoiceDialog dialog(
this,
_L(
"Select a Flashforge printer"),
_L(
"Discovered Printers"), choices);
208 if (dialog.ShowModal() == wxID_OK) {
209 const int idx = dialog.GetSelection();
210 if (idx >= 0 && idx < static_cast<int>(printers.size())) {
212 m_optgroup->set_value(
"flashforge_serial_number",
from_u8(printers[idx].serial_number),
true);
213 m_config->opt_string(
"print_host") = printers[idx].ip_address;
214 m_config->opt_string(
"flashforge_serial_number") = printers[idx].serial_number;
216 }
217 }
218 return;
219 }
220
222 if (dialog.show_and_lookup()) {
223 m_optgroup->set_value(
"print_host", dialog.get_selected(),
true);
224 m_optgroup->get_field(
"print_host")->field_changed();
225 }
226 });
227
228 return sizer;
229 };
230
231 auto print_host_test = [=](wxWindow* parent) {
233
236 if (!host) {
237 const wxString text =
_L(
"Could not get a valid Printer Host reference");
239 return;
240 }
241
242 wxString msg;
243 bool result;
244 {
245
246 wxBusyCursor wait;
247 result = host->test(msg);
248
249 if (!result && host->is_cloud()) {
250 if (const auto h = dynamic_cast<SimplyPrint*>(host.get()); h) {
251 OAuthDialog dlg(this, h->get_oauth_params());
252 dlg.ShowModal();
253
254 const auto& r = dlg.get_result();
255 result = r.success;
256 if (r.success) {
257 h->save_oauth_credential(r);
258 } else {
259 msg = r.error_message;
260 }
261 } else if (const auto h = dynamic_cast<C3DPrinterOS*>(host.get()); h) {
262 GUI::MessageDialog dlg(
this,
_L(
"Valid session not detected. Proceed with login to 3DPrinterOS?"),
_L(
"Proceed"),
263 wxICON_INFORMATION | wxYES | wxNO);
264 if (dlg.ShowModal() == wxID_YES) {
265 result = h->login(msg);
266 }
267 } else {
268 PrinterCloudAuthDialog dlg(this->GetParent(), host.get());
269 dlg.ShowModal();
270
271 const auto api_key = dlg.GetApiKey();
272 m_config->opt_string(
"printhost_apikey") = api_key;
273 result = !api_key.empty();
274 }
275 }
276 }
277 if (result)
278 show_info(
this, host->get_test_ok_msg(),
_L(
"Success!"));
279 else
280 show_error(
this, host->get_test_failed_msg(msg));
281
283 });
284
285 return sizer;
286 };
287
288
289 auto ultimaker_generate_creds = [=](wxWindow* parent) {
291
294 if (!host) {
295 const wxString text =
_L(
"Could not get a valid Printer Host reference");
297 return;
298 }
299
300 wxString msg = "generate_auth_creds";
301 bool result;
302 {
303
304 wxBusyCursor wait;
305
306 result = host->test(msg);
307
308
309 show_info(
this,
_L(
"API Key created. Go to the physical printer and hit \"authorize\" on the screen, then run \"Test\" again.") +
"\n" + msg,
_L(
"API Key created."));
310
311
312 }
313 if (result)
314 show_info(
this, host->get_test_ok_msg(),
_L(
"Success!"));
315 else
316 show_error(
this, host->get_test_failed_msg(msg));
317
319 });
320
321 return sizer;
322 };
323
324
325 auto print_host_logout = [&](wxWindow* parent) {
327
330 if (!host) {
331 const wxString text =
_L(
"Could not get a valid Printer Host reference");
333 return;
334 }
335
336 wxString msg_text =
_L(
"Are you sure to log out?");
337 MessageDialog dialog(this, msg_text, "", wxICON_QUESTION | wxYES_NO);
338
339 if (dialog.ShowModal() == wxID_YES) {
340 host->log_out();
342 }
343 });
344
345 return sizer;
346 };
347
348 auto print_host_printers = [this, create_sizer_with_btn](wxWindow* parent) {
349
353 btn->Bind(wxEVT_BUTTON, [
this](wxCommandEvent e) {
update_printers(); });
354 return sizer;
355 };
356
357
358 Option option =
m_optgroup->get_option(
"print_host");
360 Line host_line =
m_optgroup->create_single_option_line(option);
361 host_line.append_widget(printhost_browse);
362 host_line.append_widget(print_host_test);
363 host_line.append_widget(ultimaker_generate_creds);
364 host_line.append_widget(print_host_logout);
366
367 option =
m_optgroup->get_option(
"print_host_webui");
369 m_optgroup->append_single_option_line(option);
370
371 {
372
373 ConfigOptionDef def;
376 def.label =
L(
"View print host webui in Device tab");
377 def.tooltip =
L(
"Replace the BambuLab's device tab with print host webui");
378 def.set_default_value(new ConfigOptionBool(false));
379
380 auto option = Option(def, "bbl_use_print_host_webui");
381 m_optgroup->append_single_option_line(option);
382 }
383
384 m_optgroup->append_single_option_line(
"printhost_authorization_type");
385
386 option =
m_optgroup->get_option(
"printhost_apikey");
388 m_optgroup->append_single_option_line(option);
389
390 option =
m_optgroup->get_option(
"flashforge_serial_number");
392 m_optgroup->append_single_option_line(option);
393
394 option =
m_optgroup->get_option(
"printhost_port");
396 Line port_line =
m_optgroup->create_single_option_line(option);
397 port_line.append_widget(print_host_printers);
399
400 const auto ca_file_hint =
_u8L(
"HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate.");
401
403 option =
m_optgroup->get_option(
"printhost_cafile");
405 Line cafile_line =
m_optgroup->create_single_option_line(option);
406
407 auto printhost_cafile_browse = [=](wxWindow* parent) {
410 static const auto filemasks =
_L(
"Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*");
411 wxFileDialog openFileDialog(
this,
_L(
"Open CA certificate file"),
"",
"", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
412 if (openFileDialog.ShowModal() != wxID_CANCEL) {
413 m_optgroup->set_value(
"printhost_cafile", openFileDialog.GetPath(),
true);
414 m_optgroup->get_field(
"printhost_cafile")->field_changed();
415 }
416 });
417
418 return sizer;
419 };
420
421 cafile_line.append_widget(printhost_cafile_browse);
423
424 Line cafile_hint{ "", "" };
425 cafile_hint.full_width = 1;
426 cafile_hint.widget = [ca_file_hint](wxWindow* parent) {
428 auto sizer = new wxBoxSizer(wxHORIZONTAL);
429 sizer->Add(txt);
430 return sizer;
431 };
433 }
434 else {
435
436 Line line{ "", "" };
437 line.full_width = 1;
438
439 line.widget = [ca_file_hint](wxWindow* parent) {
440 std::string info =
_u8L(
"HTTPS CA File") +
":\n\t" +
441 (boost::format(
_u8L(
"On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.")) % SLIC3R_APP_NAME).str() +
442 "\n\t" +
_u8L(
"To use a custom CA file, please import your CA file into Certificate Store / Keychain.");
443
444
445 auto txt =
new wxStaticText(parent, wxID_ANY,
from_u8((boost::format(
"%1%\n\t%2%") % info % ca_file_hint).str()));
447 auto sizer = new wxBoxSizer(wxHORIZONTAL);
448 sizer->Add(txt, 1, wxEXPAND);
449 return sizer;
450 };
452 }
453
454 for (const std::string& opt_key : std::vector<std::string>{ "printhost_user", "printhost_password" }) {
457 m_optgroup->append_single_option_line(option);
458 }
459
460#ifdef WIN32
461 option =
m_optgroup->get_option(
"printhost_ssl_ignore_revoke");
463 m_optgroup->append_single_option_line(option);
464#endif
465
467
468 Field* printhost_field =
m_optgroup->get_field(
"print_host");
469 if (printhost_field)
470 {
471 wxTextCtrl* temp = dynamic_cast<wxTextCtrl*>(printhost_field->getWindow());
472 if (temp)
473 temp->Bind(wxEVT_TEXT, ([printhost_field, temp](wxEvent& e)
474 {
475#ifndef __WXGTK__
476 e.Skip();
477 temp->GetToolTip()->Enable(true);
478#endif
479
480 std::string trimed_str, str = trimed_str = temp->GetValue().ToStdString();
481 boost::trim(trimed_str);
482 if (trimed_str != str)
483 temp->SetValue(trimed_str);
484
486 if (field)
487 field->propagate_value();
488 }), temp->GetId());
489 }
490
491
492 {
494 choice->set_values(std::vector<std::string>{
m_config->opt_string(
"printhost_port") });
495 choice->set_selection();
496 }
497
499}
wxTextCtrl TextCtrl
Definition TextCtrl.h:14
static bool discover_printers(std::vector< FlashforgeDiscoveredPrinter > &printers, wxString &msg, int timeout_ms=10000, int idle_timeout_ms=1500, int max_retries=3)
Definition Flashforge.cpp:241
static int def_width_wider()
Definition Field.cpp:402
void update_printers()
Definition PhysicalPrinterDialog.cpp:842
void update_webui()
Definition PhysicalPrinterDialog.cpp:537
void update_ports()
Definition PhysicalPrinterDialog.cpp:501
void update_printhost_buttons()
Definition PhysicalPrinterDialog.cpp:561
Button * m_printhost_browse_btn
Definition PhysicalPrinterDialog.hpp:35
Button * m_printhost_generate_creds_btn
Definition PhysicalPrinterDialog.hpp:37
Button * m_printhost_logout_btn
Definition PhysicalPrinterDialog.hpp:38
Button * m_printhost_cafile_browse_btn
Definition PhysicalPrinterDialog.hpp:39
Button * m_printhost_port_browse_btn
Definition PhysicalPrinterDialog.hpp:40
Button * m_printhost_test_btn
Definition PhysicalPrinterDialog.hpp:36
static bool ca_file_supported()
Definition Http.cpp:943
PrinterTechnology printer_technology() const
Definition Preset.hpp:399
static PrintHost * get_print_host(DynamicPrintConfig *config)
Definition PrintHost.cpp:58
static wxString dots("...", wxConvUTF8)
void show_error(wxWindow *parent, const wxString &message, bool has_code_excerpts)
Definition GUI.cpp:296
void show_info(wxWindow *parent, const wxString &message, const wxString &title)
Definition GUI.cpp:316
std::string t_config_option_key
Definition Config.hpp:96
PrintHostType
Definition PrintConfig.hpp:118
@ htCrealityPrint
Definition PrintConfig.hpp:119
@ htFlashforge
Definition PrintConfig.hpp:119
@ coBool
Definition Config.hpp:210