Files
QIDIStudio/src/slic3r/GUI/SendToPrinter.cpp

2170 lines
82 KiB
C++
Raw Normal View History

2024-09-03 09:34:33 +08:00
#include "SendToPrinter.hpp"
#include "I18N.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Thread.hpp"
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "GUI_Preview.hpp"
#include "MainFrame.hpp"
#include "format.hpp"
#include "Widgets/ProgressDialog.hpp"
2025-05-08 15:05:30 +08:00
#include "ReleaseNote.hpp"
2024-09-03 09:34:33 +08:00
#include "Widgets/RoundedRectangle.hpp"
#include "Widgets/StaticBox.hpp"
#include "ConnectPrinter.hpp"
#include <wx/progdlg.h>
#include <wx/clipbrd.h>
#include <wx/dcgraph.h>
#include <miniz.h>
#include <algorithm>
#include "BitmapCache.hpp"
namespace Slic3r {
namespace GUI {
#define INITIAL_NUMBER_OF_MACHINES 0
#define LIST_REFRESH_INTERVAL 200
#define MACHINE_LIST_REFRESH_INTERVAL 2000
2025-05-08 15:05:30 +08:00
#define EMMC_STORAGE "emmc"
constexpr int timeout_period = 15000; // ms
2024-09-03 09:34:33 +08:00
wxDEFINE_EVENT(EVT_UPDATE_USER_MACHINE_LIST, wxCommandEvent);
wxDEFINE_EVENT(EVT_PRINT_JOB_CANCEL, wxCommandEvent);
wxDEFINE_EVENT(EVT_SEND_JOB_SUCCESS, wxCommandEvent);
wxDEFINE_EVENT(EVT_CLEAR_IPADDRESS, wxCommandEvent);
void SendToPrinterDialog::stripWhiteSpace(std::string& str)
{
if (str == "") { return; }
string::iterator cur_it;
cur_it = str.begin();
while (cur_it != str.end()) {
if ((*cur_it) == '\n' || (*cur_it) == ' ') {
cur_it = str.erase(cur_it);
}
else {
cur_it++;
}
}
}
wxString SendToPrinterDialog::format_text(wxString &m_msg)
{
if (wxGetApp().app_config->get("language") != "zh_CN") { return m_msg; }
wxString out_txt = m_msg;
wxString count_txt = "";
int new_line_pos = 0;
for (int i = 0; i < m_msg.length(); i++) {
auto text_size = m_statictext_printer_msg->GetTextExtent(count_txt);
if (text_size.x < (FromDIP(400))) {
count_txt += m_msg[i];
}
else {
out_txt.insert(i - 1, '\n');
count_txt = "";
}
}
return out_txt;
}
void SendToPrinterDialog::check_focus(wxWindow* window)
{
if (window == m_rename_input || window == m_rename_input->GetTextCtrl()) {
on_rename_enter();
}
}
void SendToPrinterDialog::check_fcous_state(wxWindow* window)
{
check_focus(window);
auto children = window->GetChildren();
for (auto child : children) {
check_fcous_state(child);
}
}
void SendToPrinterDialog::on_rename_click(wxCommandEvent& event)
{
m_is_rename_mode = true;
m_rename_input->GetTextCtrl()->SetValue(m_current_project_name);
m_rename_switch_panel->SetSelection(1);
m_rename_input->GetTextCtrl()->SetFocus();
m_rename_input->GetTextCtrl()->SetInsertionPointEnd();
}
void SendToPrinterDialog::on_rename_enter()
{
if (m_is_rename_mode == false) {
return;
}
else {
m_is_rename_mode = false;
}
auto new_file_name = m_rename_input->GetTextCtrl()->GetValue();
wxString temp;
int num = 0;
for (auto t : new_file_name) {
if (t == wxString::FromUTF8("\x20")) {
num++;
if (num == 1) temp += t;
} else {
num = 0;
temp += t;
}
}
new_file_name = temp;
auto m_valid_type = Valid;
wxString info_line;
2025-01-03 15:03:32 +08:00
//y51
const char* unusable_symbols = "<>[]:\\|?*\"";
2024-09-03 09:34:33 +08:00
const std::string unusable_suffix = PresetCollection::get_suffix_modified(); //"(modified)";
for (size_t i = 0; i < std::strlen(unusable_symbols); i++) {
if (new_file_name.find_first_of(unusable_symbols[i]) != std::string::npos) {
info_line = _L("Name is invalid;") + "\n" + _L("illegal characters:") + " " + unusable_symbols;
m_valid_type = NoValid;
break;
}
}
if (m_valid_type == Valid && new_file_name.find(unusable_suffix) != std::string::npos) {
info_line = _L("Name is invalid;") + "\n" + _L("illegal suffix:") + "\n\t" + from_u8(PresetCollection::get_suffix_modified());
m_valid_type = NoValid;
}
if (m_valid_type == Valid && new_file_name.empty()) {
info_line = _L("The name is not allowed to be empty.");
m_valid_type = NoValid;
}
if (m_valid_type == Valid && new_file_name.find_first_of(' ') == 0) {
info_line = _L("The name is not allowed to start with space character.");
m_valid_type = NoValid;
}
if (m_valid_type == Valid && new_file_name.find_last_of(' ') == new_file_name.length() - 1) {
info_line = _L("The name is not allowed to end with space character.");
m_valid_type = NoValid;
}
2025-05-08 15:05:30 +08:00
if (m_valid_type == Valid && new_file_name.size() >= 100) {
info_line = _L("The name length exceeds the limit.");
m_valid_type = NoValid;
}
2024-09-03 09:34:33 +08:00
if (m_valid_type != Valid) {
MessageDialog msg_wingow(nullptr, info_line, "", wxICON_WARNING | wxOK);
if (msg_wingow.ShowModal() == wxID_OK) {
m_rename_switch_panel->SetSelection(0);
m_rename_text->SetLabel(m_current_project_name);
m_rename_normal_panel->Layout();
return;
}
}
m_current_project_name = new_file_name;
m_rename_switch_panel->SetSelection(0);
m_rename_text->SetLabel(m_current_project_name);
m_rename_normal_panel->Layout();
}
SendToPrinterDialog::SendToPrinterDialog(Plater *plater)
2025-05-08 15:05:30 +08:00
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Send to Printer storage"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
2024-09-03 09:34:33 +08:00
, m_plater(plater), m_export_3mf_cancel(false)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
#endif //__WINDOWS__
2025-05-08 15:05:30 +08:00
//y24
m_isNetMode = wxGetApp().app_config->get("machine_list_net") == "1";
PresetBundle& preset_bundle = *wxGetApp().preset_bundle;
preset_typename = preset_bundle.printers.get_edited_preset().get_printer_type(&preset_bundle);
preset_typename_normalized = NormalizeVendor(preset_typename);
2024-09-03 09:34:33 +08:00
// bind
Bind(wxEVT_CLOSE_WINDOW, &SendToPrinterDialog::on_cancel, this);
// font
SetFont(wxGetApp().normal_font());
// icon
std::string icon_path = (boost::format("%1%/images/QIDIStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
Freeze();
SetBackgroundColour(m_colour_def_color);
m_sizer_main = new wxBoxSizer(wxVERTICAL);
m_sizer_main->SetMinSize(wxSize(0, -1));
m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_scrollable_region = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
2025-05-08 15:05:30 +08:00
m_sizer_scrollable_region = new wxBoxSizer(wxVERTICAL);
2024-09-03 09:34:33 +08:00
m_panel_image = new wxPanel(m_scrollable_region, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_panel_image->SetBackgroundColour(m_colour_def_color);
sizer_thumbnail = new wxBoxSizer(wxVERTICAL);
m_thumbnailPanel = new ThumbnailPanel(m_panel_image);
m_thumbnailPanel->SetSize(wxSize(FromDIP(256), FromDIP(256)));
m_thumbnailPanel->SetMinSize(wxSize(FromDIP(256), FromDIP(256)));
m_thumbnailPanel->SetMaxSize(wxSize(FromDIP(256), FromDIP(256)));
sizer_thumbnail->Add(m_thumbnailPanel, 0, wxEXPAND, 0);
m_panel_image->SetSizer(sizer_thumbnail);
m_panel_image->Layout();
wxBoxSizer *m_sizer_basic = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizer_basic_weight = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizer_basic_time = new wxBoxSizer(wxHORIZONTAL);
auto timeimg = new wxStaticBitmap(m_scrollable_region, wxID_ANY, create_scaled_bitmap("print-time", this, 18), wxDefaultPosition, wxSize(FromDIP(18), FromDIP(18)), 0);
m_sizer_basic_weight->Add(timeimg, 1, wxEXPAND | wxALL, FromDIP(5));
m_stext_time = new wxStaticText(m_scrollable_region, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
m_sizer_basic_weight->Add(m_stext_time, 0, wxALL, FromDIP(5));
m_sizer_basic->Add(m_sizer_basic_weight, 0, wxALIGN_CENTER, 0);
m_sizer_basic->Add(0, 0, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30));
auto weightimg = new wxStaticBitmap(m_scrollable_region, wxID_ANY, create_scaled_bitmap("print-weight", this, 18), wxDefaultPosition, wxSize(FromDIP(18), FromDIP(18)), 0);
m_sizer_basic_time->Add(weightimg, 1, wxEXPAND | wxALL, FromDIP(5));
m_stext_weight = new wxStaticText(m_scrollable_region, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
m_sizer_basic_time->Add(m_stext_weight, 0, wxALL, FromDIP(5));
m_sizer_basic->Add(m_sizer_basic_time, 0, wxALIGN_CENTER, 0);
m_line_materia = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line_materia->SetForegroundColour(wxColour(238, 238, 238));
m_line_materia->SetBackgroundColour(wxColour(238, 238, 238));
wxBoxSizer *m_sizer_printer = new wxBoxSizer(wxHORIZONTAL);
m_stext_printer_title = new wxStaticText(this, wxID_ANY, _L("Printer"), wxDefaultPosition, wxSize(-1, -1), 0);
m_stext_printer_title->SetFont(::Label::Head_14);
m_stext_printer_title->Wrap(-1);
m_stext_printer_title->SetForegroundColour(m_colour_bold_color);
m_stext_printer_title->SetBackgroundColour(m_colour_def_color);
m_sizer_printer->Add(m_stext_printer_title, 0, wxALL | wxLEFT, FromDIP(5));
m_sizer_printer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(12));
m_comboBox_printer = new ::ComboBox(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(250), -1), 0, nullptr, wxCB_READONLY);
m_comboBox_printer->Bind(wxEVT_COMBOBOX, &SendToPrinterDialog::on_selection_changed, this);
m_sizer_printer->Add(m_comboBox_printer, 1, wxEXPAND | wxRIGHT, FromDIP(5));
// y96
btn_bg_enable = StateColor(std::pair<wxColour, int>(wxColour(95, 82, 253), StateColor::Pressed), std::pair<wxColour, int>(wxColour(129, 150, 255), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(68, 121, 251), StateColor::Normal));
m_button_refresh = new Button(this, _L("Refresh"));
m_button_refresh->SetBackgroundColor(btn_bg_enable);
m_button_refresh->SetBorderColor(btn_bg_enable);
m_button_refresh->SetTextColor(StateColor::darkModeColorFor("#FFFFFE"));
m_button_refresh->SetSize(SELECT_MACHINE_DIALOG_BUTTON_SIZE);
m_button_refresh->SetMinSize(SELECT_MACHINE_DIALOG_BUTTON_SIZE);
m_button_refresh->SetCornerRadius(FromDIP(10));
m_button_refresh->Bind(wxEVT_BUTTON, &SendToPrinterDialog::on_refresh, this);
m_sizer_printer->Add(m_button_refresh, 0, wxALL | wxLEFT, FromDIP(5));
2025-05-08 15:05:30 +08:00
// y21
wxPanel* switch_button_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxTAB_TRAVERSAL | wxBU_RIGHT);
wxBoxSizer* printer_sizer = new wxBoxSizer(wxHORIZONTAL);
switch_button_panel->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#FFFFFF")));
m_switch_button = new SwitchButton(switch_button_panel);
m_switch_button->SetMaxSize(wxSize(100, 100));
m_switch_button->SetLabels(_L("Local"), _L("Link"));
m_switch_button->SetValue(m_isNetMode);
m_switch_button->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) {
bool is_checked = evt.GetInt();
m_switch_button->SetValue(is_checked);
m_isNetMode = is_checked;
m_comboBox_printer->SetValue("");
m_comboBox_printer->Clear();
if (!m_isNetMode)
{
for (auto machine : machine_list_local)
{
//y24
m_comboBox_printer->Append(from_u8(machine.display_name));
if (m_comboBox_printer->GetValue().empty() && preset_typename_normalized.find(NormalizeVendor(machine.type)) != std::string::npos)
{
m_comboBox_printer->SetStringSelection(from_u8(machine.display_name));
wxCommandEvent event(wxEVT_COMBOBOX, m_comboBox_printer->GetId());
event.SetEventObject(m_comboBox_printer);
event.SetString(m_comboBox_printer->GetValue());
m_comboBox_printer->GetEventHandler()->ProcessEvent(event);
}
}
}
else
{
#if QDT_RELEASE_TO_PUBLIC
for (auto machine : machine_list_link)
{
//y24
m_comboBox_printer->Append(from_u8(machine.display_name));
if (m_comboBox_printer->GetValue().empty() && preset_typename_normalized.find(NormalizeVendor(machine.type)) != std::string::npos)
{
m_comboBox_printer->SetStringSelection(from_u8(machine.display_name));
wxCommandEvent event(wxEVT_COMBOBOX, m_comboBox_printer->GetId());
event.SetEventObject(m_comboBox_printer);
event.SetString(m_comboBox_printer->GetValue());
m_comboBox_printer->GetEventHandler()->ProcessEvent(event);
}
}
#endif
}
// y27
if (m_comboBox_printer->GetValue().empty())
{
m_button_ensure->Disable();
m_button_ensure->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
m_button_ensure->SetBorderColor(wxColour(0x90, 0x90, 0x90));
}
});
m_isSwitch = new wxCheckBox(switch_button_panel, wxID_ANY, _L("Switch to Device tab"), wxDefaultPosition);
m_isSwitch->SetValue((wxGetApp().app_config->get("switch to device tab after upload") == "true") ? true : false);
m_isSwitch->SetForegroundColour(StateColor::darkModeColorFor(wxColour(0, 0, 0)));
wxToolTip* switch_tips = new wxToolTip(_L("Switch to Device tab after upload."));
m_isSwitch->SetToolTip(switch_tips);
printer_sizer->Add(m_switch_button, 0, wxALIGN_CENTER);
printer_sizer->AddSpacer(20);
printer_sizer->Add(m_isSwitch, 1, wxALIGN_CENTER);
switch_button_panel->SetSizer(printer_sizer);
switch_button_panel->Layout();
/*select storage*/
m_storage_panel = new wxPanel(this);
m_storage_panel->SetBackgroundColour(*wxWHITE);
m_storage_sizer = new wxBoxSizer(wxHORIZONTAL);
m_storage_panel->SetSizer(m_storage_sizer);
m_storage_panel->Layout();
2024-09-03 09:34:33 +08:00
m_statictext_printer_msg = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
m_statictext_printer_msg->SetFont(::Label::Body_13);
m_statictext_printer_msg->SetForegroundColour(*wxBLACK);
m_statictext_printer_msg->Hide();
// line schedule
m_line_schedule = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_schedule->SetBackgroundColour(wxColour(238, 238, 238));
m_simplebook = new wxSimplebook(this, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_DIALOG_SIMBOOK_SIZE, 0);
// perpare mode
m_panel_prepare = new wxPanel(m_simplebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_panel_prepare->SetBackgroundColour(m_colour_def_color);
// m_panel_prepare->SetBackgroundColour(wxColour(135,206,250));
wxBoxSizer *m_sizer_prepare = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_sizer_pcont = new wxBoxSizer(wxHORIZONTAL);
m_sizer_prepare->Add(0, 0, 1, wxTOP, FromDIP(22));
2025-05-08 15:05:30 +08:00
auto hyperlink_sizer = new wxBoxSizer(wxHORIZONTAL);
//y36
std::string language = wxGetApp().app_config->get("language");
wxString region = L"en";
if (language.find("zh") == 0)
region = L"zh";
wxString hyperlink_2 = wxString::Format(L"https://wiki.qidi3d.com/%s/software/qidi-studio/troubleshooting/connect-send-problem", region);
m_hyperlink = new wxHyperlinkCtrl(m_panel_prepare, wxID_ANY, _L("Click here if you failed to send the print job"), hyperlink_2, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
hyperlink_sizer->Add(m_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
m_sizer_prepare->Add(hyperlink_sizer, 0, wxALIGN_CENTER | wxALL, 5);
2024-09-03 09:34:33 +08:00
m_button_ensure = new Button(m_panel_prepare, _L("Send"));
m_button_ensure->SetBackgroundColor(btn_bg_enable);
m_button_ensure->SetBorderColor(btn_bg_enable);
m_button_ensure->SetTextColor(StateColor::darkModeColorFor("#FFFFFE"));
m_button_ensure->SetSize(SELECT_MACHINE_DIALOG_BUTTON_SIZE);
m_button_ensure->SetMinSize(SELECT_MACHINE_DIALOG_BUTTON_SIZE);
2025-05-08 15:05:30 +08:00
m_button_ensure->SetCornerRadius(12);
2024-09-03 09:34:33 +08:00
m_button_ensure->Bind(wxEVT_BUTTON, &SendToPrinterDialog::on_ok, this);
2025-05-08 15:05:30 +08:00
m_sizer_pcont->Add(0, 0, 1, wxEXPAND, 0);
m_sizer_pcont->Add(m_button_ensure, 0, wxRIGHT, 0);
2024-09-03 09:34:33 +08:00
m_sizer_prepare->Add(m_sizer_pcont, 0, wxEXPAND, 0);
m_panel_prepare->SetSizer(m_sizer_prepare);
m_panel_prepare->Layout();
m_simplebook->AddPage(m_panel_prepare, wxEmptyString, true);
// sending mode
m_status_bar = std::make_shared<QDTStatusBarSend>(m_simplebook);
m_panel_sending = m_status_bar->get_panel();
m_simplebook->AddPage(m_panel_sending, wxEmptyString, false);
// finish mode
m_panel_finish = new wxPanel(m_simplebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_panel_finish->SetBackgroundColour(wxColour(135, 206, 250));
wxBoxSizer *m_sizer_finish = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizer_finish_v = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_sizer_finish_h = new wxBoxSizer(wxHORIZONTAL);
auto imgsize = FromDIP(25);
auto completedimg = new wxStaticBitmap(m_panel_finish, wxID_ANY, create_scaled_bitmap("completed", m_panel_finish, 25), wxDefaultPosition, wxSize(imgsize, imgsize), 0);
m_sizer_finish_h->Add(completedimg, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
m_statictext_finish = new wxStaticText(m_panel_finish, wxID_ANY, L("send completed"), wxDefaultPosition, wxDefaultSize, 0);
m_statictext_finish->Wrap(-1);
// y96
m_statictext_finish->SetForegroundColour(wxColour(68, 121, 251));
m_sizer_finish_h->Add(m_statictext_finish, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
m_sizer_finish_v->Add(m_sizer_finish_h, 1, wxALIGN_CENTER, 0);
m_sizer_finish->Add(m_sizer_finish_v, 1, wxALIGN_CENTER, 0);
m_panel_finish->SetSizer(m_sizer_finish);
m_panel_finish->Layout();
m_sizer_finish->Fit(m_panel_finish);
m_simplebook->AddPage(m_panel_finish, wxEmptyString, false);
//show bind failed info
m_sw_print_failed_info = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(380), FromDIP(125)), wxVSCROLL);
m_sw_print_failed_info->SetBackgroundColour(*wxWHITE);
m_sw_print_failed_info->SetScrollRate(0, 5);
m_sw_print_failed_info->SetMinSize(wxSize(FromDIP(380), FromDIP(125)));
m_sw_print_failed_info->SetMaxSize(wxSize(FromDIP(380), FromDIP(125)));
wxBoxSizer* sizer_print_failed_info = new wxBoxSizer(wxVERTICAL);
m_sw_print_failed_info->SetSizer(sizer_print_failed_info);
wxBoxSizer* sizer_error_code = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_error_desc = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_extra_info = new wxBoxSizer(wxHORIZONTAL);
auto st_title_error_code = new wxStaticText(m_sw_print_failed_info, wxID_ANY, _L("Error code"));
auto st_title_error_code_doc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, ": ");
m_st_txt_error_code = new Label(m_sw_print_failed_info, wxEmptyString);
st_title_error_code->SetForegroundColour(0x909090);
st_title_error_code_doc->SetForegroundColour(0x909090);
m_st_txt_error_code->SetForegroundColour(0x909090);
st_title_error_code->SetFont(::Label::Body_13);
st_title_error_code_doc->SetFont(::Label::Body_13);
m_st_txt_error_code->SetFont(::Label::Body_13);
st_title_error_code->SetMinSize(wxSize(FromDIP(74), -1));
st_title_error_code->SetMaxSize(wxSize(FromDIP(74), -1));
m_st_txt_error_code->SetMinSize(wxSize(FromDIP(260), -1));
m_st_txt_error_code->SetMaxSize(wxSize(FromDIP(260), -1));
sizer_error_code->Add(st_title_error_code, 0, wxALL, 0);
sizer_error_code->Add(st_title_error_code_doc, 0, wxALL, 0);
sizer_error_code->Add(m_st_txt_error_code, 0, wxALL, 0);
auto st_title_error_desc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, wxT("Error desc"));
auto st_title_error_desc_doc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, ": ");
m_st_txt_error_desc = new Label(m_sw_print_failed_info, wxEmptyString);
st_title_error_desc->SetForegroundColour(0x909090);
st_title_error_desc_doc->SetForegroundColour(0x909090);
m_st_txt_error_desc->SetForegroundColour(0x909090);
st_title_error_desc->SetFont(::Label::Body_13);
st_title_error_desc_doc->SetFont(::Label::Body_13);
m_st_txt_error_desc->SetFont(::Label::Body_13);
st_title_error_desc->SetMinSize(wxSize(FromDIP(74), -1));
st_title_error_desc->SetMaxSize(wxSize(FromDIP(74), -1));
m_st_txt_error_desc->SetMinSize(wxSize(FromDIP(260), -1));
m_st_txt_error_desc->SetMaxSize(wxSize(FromDIP(260), -1));
sizer_error_desc->Add(st_title_error_desc, 0, wxALL, 0);
sizer_error_desc->Add(st_title_error_desc_doc, 0, wxALL, 0);
sizer_error_desc->Add(m_st_txt_error_desc, 0, wxALL, 0);
auto st_title_extra_info = new wxStaticText(m_sw_print_failed_info, wxID_ANY, wxT("Extra info"));
auto st_title_extra_info_doc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, ": ");
m_st_txt_extra_info = new Label(m_sw_print_failed_info, wxEmptyString);
st_title_extra_info->SetForegroundColour(0x909090);
st_title_extra_info_doc->SetForegroundColour(0x909090);
m_st_txt_extra_info->SetForegroundColour(0x909090);
st_title_extra_info->SetFont(::Label::Body_13);
st_title_extra_info_doc->SetFont(::Label::Body_13);
m_st_txt_extra_info->SetFont(::Label::Body_13);
st_title_extra_info->SetMinSize(wxSize(FromDIP(74), -1));
st_title_extra_info->SetMaxSize(wxSize(FromDIP(74), -1));
m_st_txt_extra_info->SetMinSize(wxSize(FromDIP(260), -1));
m_st_txt_extra_info->SetMaxSize(wxSize(FromDIP(260), -1));
sizer_extra_info->Add(st_title_extra_info, 0, wxALL, 0);
sizer_extra_info->Add(st_title_extra_info_doc, 0, wxALL, 0);
sizer_extra_info->Add(m_st_txt_extra_info, 0, wxALL, 0);
m_link_network_state = new wxHyperlinkCtrl(m_sw_print_failed_info, wxID_ANY,_L("Check the status of current system services"),"");
m_link_network_state->SetFont(::Label::Body_12);
m_link_network_state->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_network_check(); });
m_link_network_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_HAND); });
m_link_network_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_ARROW); });
sizer_print_failed_info->Add(m_link_network_state, 0, wxLEFT, 5);
sizer_print_failed_info->Add(sizer_error_code, 0, wxLEFT, 5);
sizer_print_failed_info->Add(0, 0, 0, wxTOP, FromDIP(3));
sizer_print_failed_info->Add(sizer_error_desc, 0, wxLEFT, 5);
sizer_print_failed_info->Add(0, 0, 0, wxTOP, FromDIP(3));
sizer_print_failed_info->Add(sizer_extra_info, 0, wxLEFT, 5);
// bind
2025-05-08 15:05:30 +08:00
Bind(EVT_SHOW_ERROR_INFO_SEND, [this](auto& e) {
2024-09-03 09:34:33 +08:00
show_print_failed_info(true);
});
// bind
Bind(EVT_UPDATE_USER_MACHINE_LIST, &SendToPrinterDialog::update_printer_combobox, this);
Bind(EVT_PRINT_JOB_CANCEL, &SendToPrinterDialog::on_print_job_cancel, this);
m_sizer_scrollable_region->Add(m_panel_image, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_sizer_scrollable_region->Add(0, 0, 0, wxTOP, FromDIP(10));
m_sizer_scrollable_region->Add(m_sizer_basic, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_scrollable_region->SetSizer(m_sizer_scrollable_region);
m_scrollable_region->Layout();
//file name
//rename normal
m_rename_switch_panel = new wxSimplebook(this);
m_rename_switch_panel->SetSize(wxSize(FromDIP(420), FromDIP(25)));
m_rename_switch_panel->SetMinSize(wxSize(FromDIP(420), FromDIP(25)));
m_rename_switch_panel->SetMaxSize(wxSize(FromDIP(420), FromDIP(25)));
m_rename_normal_panel = new wxPanel(m_rename_switch_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_rename_normal_panel->SetBackgroundColour(*wxWHITE);
rename_sizer_v = new wxBoxSizer(wxVERTICAL);
rename_sizer_h = new wxBoxSizer(wxHORIZONTAL);
m_rename_text = new wxStaticText(m_rename_normal_panel, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
m_rename_text->SetForegroundColour(*wxBLACK);
m_rename_text->SetFont(::Label::Body_13);
m_rename_text->SetMaxSize(wxSize(FromDIP(390), -1));
m_rename_button = new Button(m_rename_normal_panel, "", "ams_editable", wxBORDER_NONE, FromDIP(10));
m_rename_button->SetBackgroundColor(*wxWHITE);
m_rename_button->SetBackgroundColour(*wxWHITE);
rename_sizer_h->Add(m_rename_text, 0, wxALIGN_CENTER, 0);
rename_sizer_h->Add(m_rename_button, 0, wxALIGN_CENTER, 0);
rename_sizer_v->Add(rename_sizer_h, 1, wxALIGN_CENTER, 0);
m_rename_normal_panel->SetSizer(rename_sizer_v);
m_rename_normal_panel->Layout();
rename_sizer_v->Fit(m_rename_normal_panel);
//rename edit
auto m_rename_edit_panel = new wxPanel(m_rename_switch_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_rename_edit_panel->SetBackgroundColour(*wxWHITE);
auto rename_edit_sizer_v = new wxBoxSizer(wxVERTICAL);
m_rename_input = new ::TextInput(m_rename_edit_panel, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
m_rename_input->GetTextCtrl()->SetFont(::Label::Body_13);
m_rename_input->SetSize(wxSize(FromDIP(380), FromDIP(24)));
m_rename_input->SetMinSize(wxSize(FromDIP(380), FromDIP(24)));
m_rename_input->SetMaxSize(wxSize(FromDIP(380), FromDIP(24)));
m_rename_input->Bind(wxEVT_TEXT_ENTER, [this](auto& e) {on_rename_enter();});
m_rename_input->Bind(wxEVT_KILL_FOCUS, [this](auto& e) {
if (!m_rename_input->HasFocus() && !m_rename_text->HasFocus())
on_rename_enter();
else
e.Skip(); });
rename_edit_sizer_v->Add(m_rename_input, 1, wxALIGN_CENTER, 0);
m_rename_edit_panel->SetSizer(rename_edit_sizer_v);
m_rename_edit_panel->Layout();
rename_edit_sizer_v->Fit(m_rename_edit_panel);
m_rename_button->Bind(wxEVT_BUTTON, &SendToPrinterDialog::on_rename_click, this);
m_rename_switch_panel->AddPage(m_rename_normal_panel, wxEmptyString, true);
m_rename_switch_panel->AddPage(m_rename_edit_panel, wxEmptyString, false);
Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent& e) {
if (e.GetKeyCode() == WXK_ESCAPE) {
if (m_rename_switch_panel->GetSelection() == 0) {
e.Skip();
}
else {
m_rename_switch_panel->SetSelection(0);
m_rename_text->SetLabel(m_current_project_name);
m_rename_normal_panel->Layout();
}
}
else {
e.Skip();
}
});
m_panel_prepare->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
check_fcous_state(this);
e.Skip();
});
m_scrollable_region->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
check_fcous_state(this);
e.Skip();
});
Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
check_fcous_state(this);
e.Skip();
});
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(10));
m_sizer_main->Add(m_scrollable_region, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(6));
m_sizer_main->Add(m_rename_switch_panel, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(6));
m_sizer_main->Add(m_line_materia, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30));
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(12));
2025-05-08 15:05:30 +08:00
m_sizer_main->Add(switch_button_panel, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30));
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(12));
2024-09-03 09:34:33 +08:00
m_sizer_main->Add(m_sizer_printer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30));
2025-05-08 15:05:30 +08:00
m_sizer_main->Add(m_storage_panel, 0, wxALIGN_CENTER | wxTOP, FromDIP(8));
2024-09-03 09:34:33 +08:00
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(11));
m_sizer_main->Add(m_statictext_printer_msg, 0, wxALIGN_CENTER_HORIZONTAL, 0);
2025-05-08 15:05:30 +08:00
m_sizer_main->Add(0, 1, 0, wxTOP, FromDIP(10));
2024-09-03 09:34:33 +08:00
m_sizer_main->Add(m_line_schedule, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30));
m_sizer_main->Add(m_simplebook, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_sizer_main->Add(m_sw_print_failed_info, 0, wxALIGN_CENTER, 0);
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(13));
show_print_failed_info(false);
2025-05-08 15:05:30 +08:00
//y58
update_user_printer();
2024-09-03 09:34:33 +08:00
SetSizer(m_sizer_main);
Layout();
Fit();
Thaw();
init_bind();
init_timer();
// CenterOnParent();
Centre(wxBOTH);
wxGetApp().UpdateDlgDarkUI(this);
}
2025-05-08 15:05:30 +08:00
std::string SendToPrinterDialog::get_storage_selected()
{
for (const auto& radio : m_storage_radioBox) {
if (radio->GetValue()) {
return radio->GetLabel().ToStdString();
}
}
return "";
}
void SendToPrinterDialog::update_storage_list(const std::vector<std::string>& storages)
{
m_storage_sizer->Clear();
m_storage_radioBox.clear();
m_storage_panel->DestroyChildren();
for (int i=0; i < storages.size(); i++) {
if (storages[i] == EMMC_STORAGE) continue;
RadioBox* radiobox = new RadioBox(m_storage_panel);
Label* storage_text = new Label(m_storage_panel, storages[i]);
radiobox->SetLabel(storages[i]);
radiobox->Bind(wxEVT_LEFT_DOWN, [this, radiobox](auto& e) {
for (const auto& radio : m_storage_radioBox) {
radio->SetValue(false);
}
radiobox->SetValue(true);
});
m_storage_sizer->Add(radiobox, 0, wxALIGN_CENTER, 0);
m_storage_sizer->Add(0, 0, 0, wxEXPAND|wxLEFT, FromDIP(6));
m_storage_sizer->Add(storage_text, 0, wxALIGN_CENTER,0);
m_storage_radioBox.push_back(radiobox);
}
if (m_storage_radioBox.size() > 0) {
m_storage_sizer->Add(0, 0, 0, wxEXPAND, FromDIP(6));
auto radio = m_storage_radioBox.front();
radio->SetValue(true);
}
m_storage_panel->Layout();
m_storage_panel->Fit();
Layout();
Fit();
}
2024-09-03 09:34:33 +08:00
void SendToPrinterDialog::update_print_error_info(int code, std::string msg, std::string extra)
{
m_print_error_code = code;
m_print_error_msg = msg;
m_print_error_extra = extra;
}
void SendToPrinterDialog::show_print_failed_info(bool show, int code, wxString description, wxString extra)
{
if (show) {
if (!m_sw_print_failed_info->IsShown()) {
m_sw_print_failed_info->Show(true);
m_st_txt_error_code->SetLabelText(wxString::Format("%d", m_print_error_code));
m_st_txt_error_desc->SetLabelText( wxGetApp().filter_string(m_print_error_msg));
m_st_txt_extra_info->SetLabelText( wxGetApp().filter_string(m_print_error_extra));
m_st_txt_error_code->Wrap(FromDIP(260));
m_st_txt_error_desc->Wrap(FromDIP(260));
m_st_txt_extra_info->Wrap(FromDIP(260));
}
else {
m_sw_print_failed_info->Show(false);
}
Layout();
Fit();
}
else {
if (!m_sw_print_failed_info->IsShown()) { return; }
m_sw_print_failed_info->Show(false);
m_st_txt_error_code->SetLabelText(wxEmptyString);
m_st_txt_error_desc->SetLabelText(wxEmptyString);
m_st_txt_extra_info->SetLabelText(wxEmptyString);
Layout();
Fit();
}
}
void SendToPrinterDialog::prepare_mode()
{
m_is_in_sending_mode = false;
m_comboBox_printer->Enable();
if (m_send_job) {
m_send_job->join();
}
if (wxIsBusy())
wxEndBusyCursor();
Enable_Send_Button(true);
show_print_failed_info(false);
m_status_bar->reset();
if (m_simplebook->GetSelection() != 0) {
m_simplebook->SetSelection(0);
}
}
void SendToPrinterDialog::sending_mode()
{
m_is_in_sending_mode = true;
m_comboBox_printer->Disable();
if (m_simplebook->GetSelection() != 1){
m_simplebook->SetSelection(1);
Layout();
Fit();
}
}
void SendToPrinterDialog::prepare(int print_plate_idx)
{
m_print_plate_idx = print_plate_idx;
}
2025-05-08 15:05:30 +08:00
void SendToPrinterDialog::update_priner_status_msg(wxString msg, bool is_warning)
2024-09-03 09:34:33 +08:00
{
auto colour = is_warning ? wxColour(0xFF, 0x6F, 0x00) : wxColour(0x6B, 0x6B, 0x6B);
m_statictext_printer_msg->SetForegroundColour(colour);
if (msg.empty()) {
if (!m_statictext_printer_msg->GetLabel().empty()) {
m_statictext_printer_msg->SetLabel(wxEmptyString);
m_statictext_printer_msg->Hide();
Layout();
Fit();
}
} else {
msg = format_text(msg);
auto str_new = msg.ToStdString();
stripWhiteSpace(str_new);
auto str_old = m_statictext_printer_msg->GetLabel().ToStdString();
stripWhiteSpace(str_old);
if (str_new != str_old) {
if (m_statictext_printer_msg->GetLabel() != msg) {
m_statictext_printer_msg->SetLabel(msg);
m_statictext_printer_msg->SetMinSize(wxSize(FromDIP(400), -1));
m_statictext_printer_msg->SetMaxSize(wxSize(FromDIP(400), -1));
m_statictext_printer_msg->Wrap(FromDIP(400));
m_statictext_printer_msg->Show();
Layout();
Fit();
}
}
}
}
void SendToPrinterDialog::update_print_status_msg(wxString msg, bool is_warning, bool is_printer_msg)
{
if (is_printer_msg) {
update_priner_status_msg(msg, is_warning);
} else {
update_priner_status_msg(wxEmptyString, false);
}
}
void SendToPrinterDialog::init_bind()
{
Bind(wxEVT_TIMER, &SendToPrinterDialog::on_timer, this);
Bind(EVT_CLEAR_IPADDRESS, &SendToPrinterDialog::clear_ip_address_config, this);
}
void SendToPrinterDialog::init_timer()
{
m_refresh_timer = new wxTimer();
m_refresh_timer->SetOwner(this);
}
void SendToPrinterDialog::on_cancel(wxCloseEvent &event)
{
if (m_send_job) {
if (m_send_job->is_running()) {
m_send_job->cancel();
m_send_job->join();
}
}
2025-05-08 15:05:30 +08:00
#if !QDT_RELEASE_TO_PUBLIC
if (m_file_sys) {
m_file_sys->CancelUploadTask();
if (m_task_timer && m_task_timer->IsRunning()) {
m_task_timer->Stop();
m_task_timer.reset();
}
}
#endif
2024-09-03 09:34:33 +08:00
this->EndModal(wxID_CANCEL);
}
2025-05-08 15:05:30 +08:00
2024-09-03 09:34:33 +08:00
void SendToPrinterDialog::on_ok(wxCommandEvent &event)
{
2025-05-08 15:05:30 +08:00
bool isSwitch = m_isSwitch->GetValue();
if (isSwitch)
wxGetApp().app_config->set_bool("switch to device tab after upload", true);
else
wxGetApp().app_config->set_bool("switch to device tab after upload", false);
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
// y16
machine_name = into_u8(m_comboBox_printer->GetValue());
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
//y24
if (!m_isNetMode)
{
for (auto machine : machine_list_local)
{
if (machine.display_name == machine_name)
{
machine_url = machine.url;
machine_ip = machine.ip;
machine_apikey = machine.apikey;
break;
}
}
}
else
{
#if QDT_RELEASE_TO_PUBLIC
for (auto machine : machine_list_link)
{
if (machine.display_name == machine_name)
{
machine_url = machine.url;
machine_ip = machine.ip;
machine_apikey = "";
machine_link_url = machine.link_url;
machine_is_special = machine.is_special;
break;
}
}
#endif
2024-09-03 09:34:33 +08:00
}
2025-05-08 15:05:30 +08:00
//y58
bool qidi_3mf = wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_bool("is_support_3mf");
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
Enable_Send_Button(false);
m_is_canceled = false;
fs::path output_path(m_plater->model().get_backup_path());
2024-09-03 09:34:33 +08:00
show_status(PrintDialogStatus::PrintStatusSending);
2025-05-08 15:05:30 +08:00
output_path += "/temp_file";
std::string upload_file_name = into_u8(m_current_project_name);
2024-09-03 09:34:33 +08:00
m_status_bar->reset();
m_status_bar->set_prog_block();
m_status_bar->set_cancel_callback_fina([this]() {
m_is_canceled = true;
wxCommandEvent* event = new wxCommandEvent(EVT_PRINT_JOB_CANCEL);
wxQueueEvent(this, event);
2025-05-08 15:05:30 +08:00
});
2024-09-03 09:34:33 +08:00
if (m_is_canceled) {
BOOST_LOG_TRIVIAL(info) << "send_job: m_is_canceled";
//m_status_bar->set_status_text(task_canceled_text);
return;
}
sending_mode();
2025-05-08 15:05:30 +08:00
wxString msg = _L("Preparing print job");
m_status_bar->update_status(msg, m_is_canceled, 0, true);
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
if (qidi_3mf) {
if (boost::iends_with(output_path.string(), ".gcode")) {
std::wstring temp_path = output_path.wstring();
temp_path = temp_path.substr(0, temp_path.size() - 6);
output_path = temp_path + L".gcode.3mf";
}
else if (boost::iends_with(output_path.string(), ".gcode.gcode.3mf")) {//for mac
std::wstring temp_path = output_path.wstring();
temp_path = temp_path.substr(0, temp_path.size() - 16);
output_path = temp_path + L".gcode.3mf";
2024-09-03 09:34:33 +08:00
}
2025-05-08 15:05:30 +08:00
else if (!boost::iends_with(output_path.string(), ".gcode.3mf")) {
output_path = output_path.replace_extension(".gcode.3mf");
}
upload_file_name += ".gcode.3mf";
int result = m_plater->export_3mf(output_path, SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithGcode | SaveStrategy::SkipModel, m_print_plate_idx);
2024-09-03 09:34:33 +08:00
}
2025-05-08 15:05:30 +08:00
else {
if (!boost::iends_with(output_path.string(), ".gcode"))
{
output_path += ".gcode";
}
upload_file_name += ".gcode";
m_plater->export_gcode(output_path);
2024-09-03 09:34:33 +08:00
}
2025-05-08 15:05:30 +08:00
msg = _L("Test the network");
m_status_bar->update_status(msg, m_is_canceled, 10, true);
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
if (m_isNetMode)
{
PrintHostJob upload_job(machine_url, machine_ip);
upload_job.upload_data.upload_path = upload_file_name;
upload_job.upload_data.post_action = PrintHostPostUploadAction::None;
upload_job.upload_data.source_path = output_path.string();
upload_job.is_3mf = qidi_3mf;
start_to_send(std::move(upload_job));
}
else
{
DynamicPrintConfig cfg_t;
cfg_t.set_key_value("print_host", new ConfigOptionString(machine_url));
cfg_t.set_key_value("host_type", new ConfigOptionString("ptfff"));
cfg_t.set_key_value("printhost_apikey", new ConfigOptionString(machine_apikey));
PrintHostJob upload_job(&cfg_t);
upload_job.upload_data.upload_path = upload_file_name;
upload_job.upload_data.post_action = PrintHostPostUploadAction::None;
upload_job.upload_data.source_path = output_path.string();
upload_job.is_3mf = qidi_3mf;
start_to_send(std::move(upload_job));
}
// BOOST_LOG_TRIVIAL(info) << "print_job: on_ok to send";
// m_is_canceled = false;
// Enable_Send_Button(false);
// if (m_is_in_sending_mode)
// return;
// int result = 0;
// if (m_printer_last_select.empty()) {
// return;
// }
// DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
// if (!dev) return;
// MachineObject *obj_ = dev->get_selected_machine();
// if (obj_ == nullptr) {
// m_printer_last_select = "";
// m_comboBox_printer->SetTextLabel("");
// return;
// }
// assert(obj_->dev_id == m_printer_last_select);
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", print_job: for send task, current printer id = " << m_printer_last_select << std::endl;
// show_status(PrintDialogStatus::PrintStatusSending);
// m_status_bar->reset();
// m_status_bar->set_prog_block();
// m_status_bar->set_cancel_callback_fina([this]() {
// BOOST_LOG_TRIVIAL(info) << "print_job: enter canceled";
// if (m_send_job) {
// if (m_send_job->is_running()) {
// BOOST_LOG_TRIVIAL(info) << "send_job: canceled";
// m_send_job->cancel();
// }
// m_send_job->join();
// }
// #if !QDT_RELEASE_TO_PUBLIC
// if (m_file_sys) {
// m_file_sys->CancelUploadTask();
// if (m_task_timer && m_task_timer->IsRunning()) {
// m_task_timer->Stop();
// m_task_timer.reset();
// }
// }
// #endif
// m_is_canceled = true;
// wxCommandEvent* event = new wxCommandEvent(EVT_PRINT_JOB_CANCEL);
// wxQueueEvent(this, event);
// });
// if (m_is_canceled) {
// BOOST_LOG_TRIVIAL(info) << "send_job: m_is_canceled";
// //m_status_bar->set_status_text(task_canceled_text);
// return;
// }
// // enter sending mode
// sending_mode();
// result = m_plater->send_gcode(m_print_plate_idx, [this](int export_stage, int current, int total, bool &cancel) {
// if (this->m_is_canceled) return;
// bool cancelled = false;
// wxString msg = _L("Preparing print job");
// m_status_bar->update_status(msg, cancelled, 10, true);
// m_export_3mf_cancel = cancel = cancelled;
// });
// if (m_is_canceled || m_export_3mf_cancel) {
// BOOST_LOG_TRIVIAL(info) << "send_job: m_export_3mf_cancel or m_is_canceled";
// //m_status_bar->set_status_text(task_canceled_text);
// return;
// }
// if (result < 0) {
// wxString msg = _L("Abnormal print file data. Please slice again");
// m_status_bar->set_status_text(msg);
// return;
// }
// // export config 3mf if needed
// if (!obj_->is_lan_mode_printer()) {
// result = m_plater->export_config_3mf(m_print_plate_idx);
// if (result < 0) {
// BOOST_LOG_TRIVIAL(info) << "export_config_3mf failed, result = " << result;
// return;
// }
// }
// if (m_is_canceled || m_export_3mf_cancel) {
// BOOST_LOG_TRIVIAL(info) << "send_job: m_export_3mf_cancel or m_is_canceled";
// //m_status_bar->set_status_text(task_canceled_text);
// return;
// }
// /* std::string file_name = "";
// auto default_output_file = wxGetApp().plater()->get_export_gcode_filename(".3mf");
// if (!default_output_file.empty()) {
// fs::path default_output_file_path = boost::filesystem::path(default_output_file.c_str());
// file_name = default_output_file_path.filename().string();
// }*/
// #if !QDT_RELEASE_TO_PUBLIC
// if (!obj_->is_lan_mode_printer()) {
// update_print_status_msg(wxEmptyString, false, false);
// if (m_file_sys) {
// PrintPrepareData print_data;
// m_plater->get_print_job_data(&print_data);
// std::string project_name = m_current_project_name.utf8_string() + ".3mf";
// std::string _3mf_path = print_data._3mf_path.string();
// std::string storage;
// auto it = std::find_if(m_ability_list.begin(), m_ability_list.end(), [](const std::string& s) {
// return s != EMMC_STORAGE;
// });
// if (it != m_ability_list.end())
// m_file_sys->SetUploadFile(_3mf_path, project_name, *it);
// else {
// BOOST_LOG_TRIVIAL(info) << "SendToPrinter::send job: The printer media capability set is incorrect.";
// }
// m_file_sys->RequestUploadFile();
// // time out
// if (m_task_timer && m_task_timer->IsRunning())
// m_task_timer->Stop();
// m_task_timer.reset(new wxTimer());
// m_task_timer->SetOwner(this);
// this->Bind(
// wxEVT_TIMER,
// [this, wfs = boost::weak_ptr(m_file_sys)](auto e) {
// show_status(PrintDialogStatus::PrintStatusPublicUploadFiled);
// boost::shared_ptr fs(wfs.lock());
// if (!fs) return;
// fs->CancelUploadTask(false);
// update_print_status_msg(_L("Upload file timeout, please check if the firmware version supports it."), false, true);
// },
// m_task_timer->GetId());
// m_task_timer->StartOnce(timeout_period);
// }
// } else {
// #endif
// m_send_job = std::make_shared<SendJob>(m_status_bar, m_plater, m_printer_last_select);
// m_send_job->m_dev_ip = obj_->dev_ip;
// m_send_job->m_access_code = obj_->get_access_code();
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
BOOST_LOG_TRIVIAL(info) << "send_job: send print job";
}
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
//y58
void SendToPrinterDialog::start_to_send(PrintHostJob upload_job) {
bool success = upload_job.printhost->upload(std::move(upload_job.upload_data),
[this](Http::Progress progress, bool& cancel) {
cancel = m_is_canceled;
int gui_progress = progress.ultotal > 0 ? 100 * progress.ulnow / progress.ultotal : 0;
OctoPrint::progress_percentage = gui_progress / 100.f;
wxString msg = _L("Sending...");
bool is_undisplay = false;
m_status_bar->update_status(msg, is_undisplay, std::floor(10 + gui_progress * 0.9), true);
},
[this](wxString error) {
show_status(PrintDialogStatus::PrintStatusPublicUploadFiled);
update_print_status_msg(error, false, true);
}
);
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
if (success)
{
bool is_switch_to_device = wxGetApp().app_config->get("switch to device tab after upload") == "true" ? true : false;
if (is_switch_to_device) {
for(int i = 3; i > 0; i--){
if(m_is_canceled)
return;
wxString msg = wxString::Format(_L("Successfully sent. Will automatically jump to the device page in %s s."), std::to_string(i));
m_status_bar->update_status(msg, m_is_canceled, 100, true);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
wxString msg = _L("Switch to device tab...");
m_status_bar->update_status(msg, m_is_canceled, 100, true);
if (m_isNetMode) {
wxGetApp().mainframe->m_printer_view->FormatNetUrl(machine_link_url, machine_ip, machine_is_special);
wxGetApp().mainframe->m_printer_view->SetToggleBar(m_isNetMode);
wxGetApp().app_config->set("machine_list_net", "1");
wxGetApp().mainframe->m_printer_view->ShowNetPrinterButton();
}
else {
wxGetApp().mainframe->m_printer_view->FormatUrl(machine_url);
wxGetApp().mainframe->m_printer_view->SetToggleBar(m_isNetMode);
wxGetApp().app_config->set("machine_list_net", "0");
wxGetApp().mainframe->m_printer_view->ShowLocalPrinterButton();
}
wxGetApp().mainframe->select_tab(size_t(3));
}
else{
for(int i = 3; i > 0; i--){
if(m_is_canceled)
return;
wxString msg = wxString::Format(_L("Successfully sent. Close current page in %s s."), std::to_string(i));
m_status_bar->update_status(msg, m_is_canceled, 100, true);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
EndDialog(wxID_CLOSE);
2024-09-03 09:34:33 +08:00
}
}
void SendToPrinterDialog::clear_ip_address_config(wxCommandEvent& e)
{
enable_prepare_mode = true;
prepare_mode();
}
void SendToPrinterDialog::update_user_machine_list()
{
NetworkAgent* m_agent = wxGetApp().getAgent();
if (m_agent && m_agent->is_user_login()) {
//B
2025-05-08 15:05:30 +08:00
// boost::thread get_print_info_thread = Slic3r::create_thread([this, token = std::weak_ptr<int>(m_token)] {
2024-09-03 09:34:33 +08:00
// NetworkAgent* agent = wxGetApp().getAgent();
// unsigned int http_code;
// std::string body;
// int result = agent->get_user_print_info(&http_code, &body);
// CallAfter([token, this, result, body] {
// if (token.expired()) {return;}
// if (result == 0) {
// m_print_info = body;
// }
// else {
// m_print_info = "";
// }
// wxCommandEvent event(EVT_UPDATE_USER_MACHINE_LIST);
// event.SetEventObject(this);
// wxPostEvent(this, event);
// });
// });
} else {
wxCommandEvent event(EVT_UPDATE_USER_MACHINE_LIST);
event.SetEventObject(this);
wxPostEvent(this, event);
}
}
void SendToPrinterDialog::on_refresh(wxCommandEvent &event)
{
BOOST_LOG_TRIVIAL(info) << "m_printer_last_select: on_refresh";
2025-05-08 15:05:30 +08:00
show_status(PrintDialogStatus::PrintStatusRefreshingMachineList);
update_user_machine_list();
/*todo refresh*/
/*if (m_file_sys) { m_file_sys->Retry(); }*/
2024-09-03 09:34:33 +08:00
}
void SendToPrinterDialog::on_print_job_cancel(wxCommandEvent &evt)
{
BOOST_LOG_TRIVIAL(info) << "print_job: canceled";
show_status(PrintDialogStatus::PrintStatusSendingCanceled);
// enter prepare mode
prepare_mode();
2025-05-08 15:05:30 +08:00
m_is_canceled = true;
2024-09-03 09:34:33 +08:00
}
std::vector<std::string> SendToPrinterDialog::sort_string(std::vector<std::string> strArray)
{
std::vector<std::string> outputArray;
std::sort(strArray.begin(), strArray.end());
std::vector<std::string>::iterator st;
for (st = strArray.begin(); st != strArray.end(); st++) { outputArray.push_back(*st); }
return outputArray;
}
bool SendToPrinterDialog::is_timeout()
{
if (timeout_count > 15 * 1000 / LIST_REFRESH_INTERVAL) {
return true;
}
return false;
}
void SendToPrinterDialog::reset_timeout()
{
timeout_count = 0;
}
void SendToPrinterDialog::update_user_printer()
{
2025-05-08 15:05:30 +08:00
// Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
// if (!dev) return;
// // update user print info
// if (!m_print_info.empty()) {
// dev->parse_user_print_info(m_print_info);
// m_print_info = "";
// }
// // clear machine list
// m_list.clear();
// m_comboBox_printer->Clear();
// std::vector<std::string> machine_list;
// wxArrayString machine_list_name;
// std::map<std::string, MachineObject*> option_list;
// option_list = dev->get_my_machine_list();
// // same machine only appear once
// for (auto it = option_list.begin(); it != option_list.end(); it++) {
// if (it->second && (it->second->is_online() || it->second->is_connected())) {
// machine_list.push_back(it->second->dev_name);
// }
// }
// machine_list = sort_string(machine_list);
// for (auto tt = machine_list.begin(); tt != machine_list.end(); tt++) {
// for (auto it = option_list.begin(); it != option_list.end(); it++) {
// if (it->second->dev_name == *tt) {
// m_list.push_back(it->second);
// wxString dev_name_text = from_u8(it->second->dev_name);
// if (it->second->is_lan_mode_printer()) {
// dev_name_text += "(LAN)";
// }
// machine_list_name.Add(dev_name_text);
// break;
// }
// }
// }
// m_comboBox_printer->Set(machine_list_name);
// MachineObject* obj = dev->get_selected_machine();
// if (obj) {
// m_printer_last_select = obj->dev_id;
// } else {
// m_printer_last_select = "";
// }
// if (m_list.size() > 0) {
// // select a default machine
// if (m_printer_last_select.empty()) {
// m_printer_last_select = m_list[0]->dev_id;
// m_comboBox_printer->SetSelection(0);
// wxCommandEvent event(wxEVT_COMBOBOX);
// event.SetEventObject(m_comboBox_printer);
// wxPostEvent(m_comboBox_printer, event);
// }
// for (auto i = 0; i < m_list.size(); i++) {
// if (m_list[i]->dev_id == m_printer_last_select) {
// m_comboBox_printer->SetSelection(i);
// wxCommandEvent event(wxEVT_COMBOBOX);
// event.SetEventObject(m_comboBox_printer);
// wxPostEvent(m_comboBox_printer, event);
// }
// }
// }
// else {
// m_printer_last_select = "";
// m_comboBox_printer->SetTextLabel("");
// }
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "for send task, current printer id = " << m_printer_last_select << std::endl;
// y16
2024-09-03 09:34:33 +08:00
m_comboBox_printer->Clear();
2025-05-08 15:05:30 +08:00
machine_list_local.clear();
machine_list_link.clear();
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
PresetBundle& preset_bundle = *wxGetApp().preset_bundle;
const std::deque<PhysicalPrinter>& ph_printers = preset_bundle.physical_printers();
for (size_t i = 0; i < ph_printers.size(); i++)
{
//y24
Machine_info machine;
const PhysicalPrinter& py_printer = ph_printers[i];
machine.name = py_printer.name;
machine.url = py_printer.config.opt_string("print_host");
machine.ip = py_printer.config.opt_string("print_host");
machine.type = py_printer.config.opt_string("preset_name");
machine.display_name = machine.name + " (" + machine.ip + ")";
machine.apikey = py_printer.config.opt_string("printhost_apikey");
machine_list_local.push_back(machine);
}
#if QDT_RELEASE_TO_PUBLIC
if (wxGetApp().app_config->get("user_token") != "")
{
auto m_devices = wxGetApp().get_devices();
for (const auto& device : m_devices) {
//y24
Machine_info machine;
machine.name = device.device_name;
machine.url = device.url;
machine.ip = device.local_ip;
machine.type = device.machine_type;
if (machine.type.empty())
{
std::size_t found = device.device_name.find('@');
if (found != std::string::npos)
{
machine.type = device.device_name.substr(found + 1);
2024-09-03 09:34:33 +08:00
}
}
2025-05-08 15:05:30 +08:00
machine.display_name = machine.name + " (" + machine.ip + ")";
machine.link_url = device.link_url;
machine.is_special = device.isSpecialMachine;
machine_list_link.push_back(machine);
2024-09-03 09:34:33 +08:00
}
}
2025-05-08 15:05:30 +08:00
#endif
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
//y58
show_status(PrintDialogStatus::PrintStatusInit);
2024-09-03 09:34:33 +08:00
2025-05-08 15:05:30 +08:00
m_switch_button->SetValue(m_isNetMode);
wxCommandEvent event(wxEVT_TOGGLEBUTTON, m_switch_button->GetId());
event.SetEventObject(m_switch_button);
event.SetInt(m_switch_button->GetValue());
m_switch_button->GetEventHandler()->ProcessEvent(event);
2024-09-03 09:34:33 +08:00
}
void SendToPrinterDialog::update_printer_combobox(wxCommandEvent &event)
{
show_status(PrintDialogStatus::PrintStatusInit);
update_user_printer();
}
void SendToPrinterDialog::on_timer(wxTimerEvent &event)
{
update_show_status();
}
void SendToPrinterDialog::on_selection_changed(wxCommandEvent &event)
{
2025-05-08 15:05:30 +08:00
// /* reset timeout and reading printer info */
// //m_status_bar->reset();
// timeout_count = 0;
// auto selection = m_comboBox_printer->GetSelection();
// DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
// if (!dev) return;
// MachineObject* obj = nullptr;
// for (int i = 0; i < m_list.size(); i++) {
// if (i == selection) {
// m_printer_last_select = m_list[i]->dev_id;
// obj = m_list[i];
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "for send task, current printer id = " << m_printer_last_select << std::endl;
// break;
// }
// }
// if (obj && !obj->get_lan_mode_connection_state()) {
// obj->command_get_version();
// obj->command_request_push_all();
// if (!dev->get_selected_machine()) {
// dev->set_selected_machine(m_printer_last_select, true);
// #if !QDT_RELEASE_TO_PUBLIC
// if (m_file_sys) m_file_sys.reset();
// #endif
// }else if (dev->get_selected_machine()->dev_id != m_printer_last_select) {
// m_ability_list.clear();
// //update_storage_list(std::vector<std::string>());
// dev->set_selected_machine(m_printer_last_select, true);
// #if !QDT_RELEASE_TO_PUBLIC
// if (m_file_sys) m_file_sys.reset();
// #endif
// }
// }
// else {
// BOOST_LOG_TRIVIAL(error) << "on_selection_changed dev_id not found";
// return;
// }
// update_show_status();
//y24
std::string selection_name = into_u8(m_comboBox_printer->GetValue());
if (!selection_name.empty())
{
if (!m_isNetMode)
{
for (auto machine : machine_list_local)
{
if (machine.display_name != selection_name)
continue;
else if (preset_typename_normalized.find(NormalizeVendor(machine.type)) != std::string::npos)
{
Enable_Send_Button(true);
update_print_status_msg(wxEmptyString, false, false);
break;
}
else
{
Enable_Send_Button(false);
wxString msg_text = wxString::Format(_L("The selected printer (%s) is incompatible with the chosen printer profile in the slicer (%s)."), machine.type, preset_typename);
update_print_status_msg(msg_text, true, true);
break;
}
}
2024-09-03 09:34:33 +08:00
}
2025-05-08 15:05:30 +08:00
else
{
for (auto machine : machine_list_link)
{
if (machine.display_name != selection_name)
continue;
else if (preset_typename_normalized.find(NormalizeVendor(machine.type)) != std::string::npos)
{
Enable_Send_Button(true);
update_print_status_msg(wxEmptyString, false, false);
break;
}
else
{
Enable_Send_Button(false);
wxString msg_text = wxString::Format(_L("The selected printer (%s) is incompatible with the chosen printer profile in the slicer (%s)."), machine.type, preset_typename);
update_print_status_msg(msg_text, true, true);
break;
}
}
2024-09-03 09:34:33 +08:00
}
}
2025-05-08 15:05:30 +08:00
else
Enable_Send_Button(false);
2024-09-03 09:34:33 +08:00
}
void SendToPrinterDialog::update_show_status()
{
NetworkAgent* agent = Slic3r::GUI::wxGetApp().getAgent();
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!agent) return;
if (!dev) return;
MachineObject* obj_ = dev->get_my_machine(m_printer_last_select);
if (!obj_) {
if (agent) {
if (agent->is_user_login()) {
show_status(PrintDialogStatus::PrintStatusInvalidPrinter);
}
else {
show_status(PrintDialogStatus::PrintStatusNoUserLogin);
}
}
return;
}
/* check cloud machine connections */
if (!obj_->is_lan_mode_printer()) {
if (!agent->is_server_connected()) {
show_status(PrintDialogStatus::PrintStatusConnectingServer);
reset_timeout();
return;
}
}
if (!obj_->is_info_ready()) {
if (is_timeout()) {
show_status(PrintDialogStatus::PrintStatusReadingTimeout);
return;
}
else {
timeout_count++;
show_status(PrintDialogStatus::PrintStatusReading);
return;
}
return;
}
reset_timeout();
// reading done
if (is_blocking_printing(obj_)) {
show_status(PrintDialogStatus::PrintStatusUnsupportedPrinter);
return;
}
else if (obj_->is_in_upgrading()) {
show_status(PrintDialogStatus::PrintStatusInUpgrading);
return;
}
else if (obj_->is_system_printing()) {
show_status(PrintDialogStatus::PrintStatusInSystemPrinting);
return;
}
// check sdcard when if lan mode printer
/* if (obj_->is_lan_mode_printer()) {
}*/
if (obj_->get_sdcard_state() == MachineObject::SdcardState::NO_SDCARD) {
show_status(PrintDialogStatus::PrintStatusNoSdcard);
return;
}
if (!obj_->is_support_send_to_sdcard) {
show_status(PrintDialogStatus::PrintStatusNotSupportedSendToSDCard);
return;
}
if (!m_is_in_sending_mode) {
2025-05-08 15:05:30 +08:00
#if QDT_RELEASE_TO_PUBLIC
2024-09-03 09:34:33 +08:00
show_status(PrintDialogStatus::PrintStatusReadingFinished);
return;
}
2025-05-08 15:05:30 +08:00
#else
if (obj_->connection_type() == "lan") {
show_status(PrintDialogStatus::PrintStatusReadingFinished);
return;
} else if (obj_->connection_type() == "cloud") {
Enable(obj_ && obj_->is_connected() && obj_->m_push_count > 0);
std::string dev_id = obj_->dev_ip;
if (m_file_sys) {
if (dev_id == m_device_select) {
if ((m_waiting_enable && IsEnabled()) || (m_waiting_support && obj_->get_file_remote()))
m_file_sys->Retry();
return;
} else {
m_file_sys->Stop(true);
}
}
m_device_select.swap(dev_id);
m_file_sys = boost::make_shared<PrinterFileSystem>();
m_file_sys->Attached();
m_file_sys->Bind(EVT_STATUS_CHANGED, [this, wfs = boost::weak_ptr(m_file_sys)](auto e) {
e.Skip();
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
wxString msg;
int status = e.GetInt();
int extra = e.GetExtraLong();
switch (status) {
case PrinterFileSystem::Initializing:
case PrinterFileSystem::Connecting: show_status(PrintDialogStatus::PrintStatusReading); break;
case PrinterFileSystem::ListSyncing: {
show_status(PrintDialogStatus::PrintStatusReading);
boost::uint32_t seq = fs->RequestMediaAbility(3);
if (m_task_timer && m_task_timer->IsRunning())
m_task_timer->Stop();
m_task_timer.reset(new wxTimer());
m_task_timer->SetOwner(this);
this->Bind(wxEVT_TIMER, [this, wfs_1 = boost::weak_ptr(fs), seq](auto e) {
show_status(PrintDialogStatus::PrintStatusPublicUploadFiled);
boost::shared_ptr fs_1(wfs_1.lock());
if (!fs_1) return;
fs_1->CancelUploadTask(false);
update_print_status_msg(_L("Media capability acquisition timeout, please check if the firmware version supports it."), false, true);
}, m_task_timer->GetId());
m_task_timer->StartOnce(timeout_period);
break;
}
case PrinterFileSystem::Failed: msg = _L("Please check the network and try again, You can restart or update the printer if the issue persists."); break;
}
if (!msg.empty()) {
show_status(PrintDialogStatus::PrintStatusPublicInitFailed);
update_print_status_msg(msg, false, true);
}
if (e.GetInt() == PrinterFileSystem::Initializing) {
CallAfter([=] {
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
fetchUrl(boost::weak_ptr(fs));
});
}
});
m_file_sys->Bind(EVT_MEDIA_ABILITY_CHANGED, [this, wfs = boost::weak_ptr(m_file_sys)](auto e) {
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
if (m_task_timer && m_task_timer->IsRunning()) {
m_task_timer->Stop();
m_task_timer.reset();
}
m_ability_list = fs->GetMediaAbilityList();
if (e.GetInt() == PrinterFileSystem::RequestMediaAbilityStatus::S_SUCCESS) {
//update_storage_list(m_ability_list);
show_status(PrintDialogStatus::PrintStatusReadingFinished);
} else {
show_status(PrintDialogStatus::PrintStatusPublicInitFailed);
update_print_status_msg(e.GetString(), false, true);
}
});
m_file_sys->Bind(EVT_UPLOADING, [this, wfs = boost::weak_ptr(m_file_sys)](auto e) {
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
int progress = e.GetInt();
bool cancelled = false;
wxString msg = _L("Sending...");
m_status_bar->update_status(msg, cancelled, 10 + std::floor(progress * 0.9), true);
if (m_task_timer && m_task_timer->IsRunning()) m_task_timer->Stop();
if (progress == 99) {
m_task_timer.reset(new wxTimer());
m_task_timer->SetOwner(this);
this->Bind(
wxEVT_TIMER,
[this, wfs = boost::weak_ptr(m_file_sys)](auto e) {
show_status(PrintDialogStatus::PrintStatusPublicUploadFiled);
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
fs->CancelUploadTask(false);
update_print_status_msg(_L("File upload timed out. Please check if the firmware version supports this operation or verify if the printer is functioning properly."), false, true);
},
m_task_timer->GetId());
m_task_timer->StartOnce(timeout_period);
}
});
m_file_sys->Bind(EVT_UPLOAD_CHANGED, [this, wfs = boost::weak_ptr(m_file_sys)](auto e) {
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
if (m_task_timer && m_task_timer->IsRunning()) m_task_timer->Stop();
if (e.GetInt() == PrinterFileSystem::FF_UPLOADDONE) {
show_status(PrintDialogStatus::PrintStatusReadingFinished);
wxCommandEvent *evt = new wxCommandEvent(m_plater->get_send_finished_event());
evt->SetString(from_u8(m_current_project_name.utf8_string()));
wxQueueEvent(m_plater, evt);
} else if (e.GetInt() == PrinterFileSystem::FF_UPLOADCANCEL) {
show_status(PrintDialogStatus::PrintStatusPublicUploadFiled);
wxString err_msg = e.GetString();
if (err_msg.IsEmpty())
err_msg = _L("Sending failed, please try again!");
update_print_status_msg(err_msg, false, true);
}
});
m_file_sys->Start();
}
}
#endif
2024-09-03 09:34:33 +08:00
}
bool SendToPrinterDialog::is_blocking_printing(MachineObject* obj_)
{
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return true;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
auto source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
auto target_model = obj_->printer_type;
if (source_model != target_model) {
std::vector<std::string> compatible_machine = dev->get_compatible_machine(target_model);
vector<std::string>::iterator it = find(compatible_machine.begin(), compatible_machine.end(), source_model);
if (it == compatible_machine.end()) {
return true;
}
}
return false;
}
void SendToPrinterDialog::Enable_Refresh_Button(bool en)
{
if (!en) {
if (m_button_refresh->IsEnabled()) {
m_button_refresh->Disable();
m_button_refresh->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
m_button_refresh->SetBorderColor(wxColour(0x90, 0x90, 0x90));
}
} else {
if (!m_button_refresh->IsEnabled()) {
m_button_refresh->Enable();
m_button_refresh->SetBackgroundColor(btn_bg_enable);
m_button_refresh->SetBorderColor(btn_bg_enable);
}
}
}
void SendToPrinterDialog::show_status(PrintDialogStatus status, std::vector<wxString> params)
{
if (m_print_status != status)
BOOST_LOG_TRIVIAL(info) << "select_machine_dialog: show_status = " << status;
m_print_status = status;
// m_comboBox_printer
if (status == PrintDialogStatus::PrintStatusRefreshingMachineList)
m_comboBox_printer->Disable();
else
m_comboBox_printer->Enable();
// m_panel_warn m_simplebook
if (status == PrintDialogStatus::PrintStatusSending) {
sending_mode();
}
// other
if (status == PrintDialogStatus::PrintStatusInit) {
update_print_status_msg(wxEmptyString, false, false);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusNoUserLogin) {
wxString msg_text = _L("No login account, only printers in LAN mode are displayed");
update_print_status_msg(msg_text, false, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusInvalidPrinter) {
update_print_status_msg(wxEmptyString, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusConnectingServer) {
wxString msg_text = _L("Connecting to server");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(true);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusReading) {
wxString msg_text = _L("Synchronizing device information");
update_print_status_msg(msg_text, false, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusReadingFinished) {
update_print_status_msg(wxEmptyString, false, true);
Enable_Send_Button(true);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusReadingTimeout) {
wxString msg_text = _L("Synchronizing device information time out");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(true);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusInUpgrading) {
wxString msg_text = _L("Cannot send the print task when the upgrade is in progress");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusUnsupportedPrinter) {
wxString msg_text = _L("The selected printer is incompatible with the chosen printer presets.");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusRefreshingMachineList) {
update_print_status_msg(wxEmptyString, false, true);
Enable_Send_Button(false);
Enable_Refresh_Button(false);
}
else if (status == PrintDialogStatus::PrintStatusSending) {
Enable_Send_Button(false);
Enable_Refresh_Button(false);
}
else if (status == PrintDialogStatus::PrintStatusSendingCanceled) {
Enable_Send_Button(true);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusNoSdcard) {
2025-05-08 15:05:30 +08:00
wxString msg_text = _L("Storage needs to be inserted before send to printer.");
2024-09-03 09:34:33 +08:00
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusNotOnTheSameLAN) {
wxString msg_text = _L("The printer is required to be in the same LAN as QIDI Studio.");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
else if (status == PrintDialogStatus::PrintStatusNotSupportedSendToSDCard) {
2025-05-08 15:05:30 +08:00
wxString msg_text = _L("The printer does not support sending to printer storage.");
2024-09-03 09:34:33 +08:00
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
2025-05-08 15:05:30 +08:00
} else if (status == PrintDialogStatus::PrintStatusPublicInitFailed) {
Enable_Send_Button(false);
Enable_Refresh_Button(true);
} else if (status == PrintDialogStatus::PrintStatusPublicUploadFiled) {
prepare_mode();
Enable_Send_Button(true);
Enable_Refresh_Button(true);
2024-09-03 09:34:33 +08:00
}
else {
Enable_Send_Button(true);
Enable_Refresh_Button(true);
}
}
void SendToPrinterDialog::Enable_Send_Button(bool en)
{
if (!en) {
if (m_button_ensure->IsEnabled()) {
m_button_ensure->Disable();
m_button_ensure->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
m_button_ensure->SetBorderColor(wxColour(0x90, 0x90, 0x90));
2025-05-08 15:05:30 +08:00
m_storage_panel->Hide();
2024-09-03 09:34:33 +08:00
}
} else {
if (!m_button_ensure->IsEnabled()) {
m_button_ensure->Enable();
m_button_ensure->SetBackgroundColor(btn_bg_enable);
m_button_ensure->SetBorderColor(btn_bg_enable);
2025-05-08 15:05:30 +08:00
m_storage_panel->Show();
2024-09-03 09:34:33 +08:00
}
}
}
void SendToPrinterDialog::on_dpi_changed(const wxRect &suggested_rect)
{
m_button_refresh->SetMinSize(SELECT_MACHINE_DIALOG_BUTTON_SIZE);
m_button_refresh->SetCornerRadius(FromDIP(12));
m_button_ensure->SetMinSize(SELECT_MACHINE_DIALOG_BUTTON_SIZE);
m_button_ensure->SetCornerRadius(FromDIP(12));
m_status_bar->msw_rescale();
Fit();
Refresh();
}
void SendToPrinterDialog::set_default()
{
//project name
m_rename_switch_panel->SetSelection(0);
2025-05-08 15:05:30 +08:00
//y61
wxString filename = "";
if (wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_string("filename_format") == "{input_filename_base}.gcode"){
try{
filename = m_plater->get_export_gcode_filename("", true, m_print_plate_idx == PLATE_ALL_IDX ? true : false);
}
catch (const Slic3r::PlaceholderParserError& ex) {
// Show the error with monospaced font.
show_error(this, ex.what(), true);
}
catch (const std::exception& ex) {
show_error(this, ex.what(), false);
}
}
2025-05-09 20:39:27 +08:00
else{
try{
filename = m_plater->get_output_filename();
}
catch (const Slic3r::PlaceholderParserError& ex) {
// Show the error with monospaced font.
show_error(this, ex.what(), true);
}
catch (const std::exception &ex) {
show_error(this, ex.what(), false);
}
}
2024-09-03 09:34:33 +08:00
if (m_print_plate_idx == PLATE_ALL_IDX && filename.empty()) {
filename = _L("Untitled");
}
if (filename.empty()) {
filename = m_plater->get_export_gcode_filename("", true);
if (filename.empty()) filename = _L("Untitled");
}
fs::path filename_path(filename.c_str());
2025-05-08 15:05:30 +08:00
//y52
wxString file_name = from_u8(filename_path.filename().string());
if (file_name.find(_L("Untitled")) != wxString::npos) {
PartPlate* part_plate = m_plater->get_partplate_list().get_plate(m_print_plate_idx);
if (part_plate) {
if (std::vector<ModelObject*> objects = part_plate->get_objects_on_this_plate(); objects.size() > 0) {
file_name = from_u8(objects[0]->name);
for (int i = 1; i < objects.size(); i++) {
file_name += " + " + from_u8(objects[i]->name);
}
}
}
}
if (file_name.size() > 80) {
file_name = file_name.substr(0, 80) + "...";
}
m_current_project_name = file_name;
if(m_current_project_name.find(".gcode") != wxString::npos)
m_current_project_name = m_current_project_name.substr(0, m_current_project_name.size() - 6);
2024-09-03 09:34:33 +08:00
//unsupported character filter
2025-01-03 15:03:32 +08:00
//y51
m_current_project_name = from_u8(filter_characters(m_current_project_name.ToUTF8().data(), "<>[]:\\|?*\""));
2024-09-03 09:34:33 +08:00
m_rename_text->SetLabelText(m_current_project_name);
m_rename_normal_panel->Layout();
enable_prepare_mode = true;
prepare_mode();
//clear combobox
m_list.clear();
m_comboBox_printer->Clear();
m_printer_last_select = "";
m_print_info = "";
m_comboBox_printer->SetValue(wxEmptyString);
m_comboBox_printer->Enable();
// rset status bar
m_status_bar->reset();
2025-05-08 15:05:30 +08:00
2024-09-03 09:34:33 +08:00
NetworkAgent* agent = wxGetApp().getAgent();
if (agent) {
if (agent->is_user_login()) {
show_status(PrintDialogStatus::PrintStatusInit);
} else {
show_status(PrintDialogStatus::PrintStatusNoUserLogin);
}
}
// thumbmail
//wxBitmap bitmap;
ThumbnailData &data = m_plater->get_partplate_list().get_curr_plate()->thumbnail_data;
if (data.is_valid()) {
wxImage image(data.width, data.height);
image.InitAlpha();
for (unsigned int r = 0; r < data.height; ++r) {
unsigned int rr = (data.height - 1 - r) * data.width;
for (unsigned int c = 0; c < data.width; ++c) {
unsigned char *px = (unsigned char *) data.pixels.data() + 4 * (rr + c);
image.SetRGB((int) c, (int) r, px[0], px[1], px[2]);
image.SetAlpha((int) c, (int) r, px[3]);
}
}
image = image.Rescale(FromDIP(256), FromDIP(256));
m_thumbnailPanel->set_thumbnail(image);
}
2025-05-08 15:05:30 +08:00
2024-09-03 09:34:33 +08:00
std::vector<std::string> materials;
std::vector<std::string> display_materials;
{
auto preset_bundle = wxGetApp().preset_bundle;
for (auto filament_name : preset_bundle->filament_presets) {
for (auto iter = preset_bundle->filaments.lbegin(); iter != preset_bundle->filaments.end(); iter++) {
if (filament_name.compare(iter->name) == 0) {
std::string display_filament_type;
std::string filament_type = iter->config.get_filament_type(display_filament_type);
display_materials.push_back(display_filament_type);
materials.push_back(filament_type);
}
}
}
}
m_scrollable_region->Layout();
m_scrollable_region->Fit();
Layout();
Fit();
2025-05-08 15:05:30 +08:00
2024-09-03 09:34:33 +08:00
wxSize screenSize = wxGetDisplaySize();
auto dialogSize = this->GetSize();
// basic info
auto aprint_stats = m_plater->get_partplate_list().get_current_fff_print().print_statistics();
wxString time;
PartPlate *plate = m_plater->get_partplate_list().get_curr_plate();
if (plate) {
if (plate->get_slice_result()) { time = wxString::Format("%s", short_time(get_time_dhms(plate->get_slice_result()->print_statistics.modes[0].time))); }
}
char weight[64];
if (wxGetApp().app_config->get("use_inches") == "1") {
::sprintf(weight, " %.2f oz", aprint_stats.total_weight*0.035274);
}else{
::sprintf(weight, " %.2f g", aprint_stats.total_weight);
}
m_stext_time->SetLabel(time);
m_stext_weight->SetLabel(weight);
}
bool SendToPrinterDialog::Show(bool show)
{
show_status(PrintDialogStatus::PrintStatusInit);
// set default value when show this dialog
if (show) {
2025-05-08 15:05:30 +08:00
m_ability_list.clear();
//update_storage_list(std::vector<std::string>());
2024-09-03 09:34:33 +08:00
set_default();
update_user_machine_list();
}
if (show) {
m_refresh_timer->Start(LIST_REFRESH_INTERVAL);
} else {
m_refresh_timer->Stop();
}
Layout();
Fit();
if (show) { CenterOnParent(); }
2025-05-08 15:05:30 +08:00
#if !QDT_RELEASE_TO_PUBLIC
if (m_file_sys && !show) {
m_file_sys->Stop(true);
m_waiting_enable = false;
m_waiting_support = false;
m_file_sys.reset();
}
#endif
2024-09-03 09:34:33 +08:00
return DPIDialog::Show(show);
}
2025-05-08 15:05:30 +08:00
extern wxString hide_passwd(wxString url, std::vector<wxString> const &passwords);
extern void refresh_agora_url(char const *device, char const *dev_ver, char const *channel, void *context, void (*callback)(void *context, char const *url));
void SendToPrinterDialog::fetchUrl(boost::weak_ptr<PrinterFileSystem> wfs)
{
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
if (!IsEnabled()) {
m_waiting_enable = true;
fs->SetUrl("0");
return;
}
m_waiting_enable = false;
DeviceManager *dm = GUI::wxGetApp().getDeviceManager();
MachineObject *obj = dm->get_selected_machine();
std::string dev_ver = obj->get_ota_version();
std::string dev_id = obj->dev_id;
int remote_proto = obj->get_file_remote();
if (!remote_proto) {
m_waiting_support = true;
fs->SetUrl("0");
return;
}
if (obj->is_camera_busy_off()) {
fs->SetUrl("0");
return;
}
m_waiting_support = false;
NetworkAgent *agent = wxGetApp().getAgent();
std::string agent_version = agent ? agent->get_version() : "";
if (agent) {
std::string protocols[] = {"", "\"tutk\"", "\"agora\"", "\"tutk\",\"agora\""};
agent->get_camera_url(obj->dev_id + "|" + dev_ver + "|" + protocols[remote_proto],
[this, wfs, m = dev_id, v = agent->get_version(), dv = dev_ver](std::string url) {
if (boost::algorithm::starts_with(url, "qidi:///")) {
url += "&device=" + m;
url += "&net_ver=" + v;
url += "&dev_ver=" + dv;
url += "&refresh_url=" + boost::lexical_cast<std::string>(&refresh_agora_url);
url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid");
url += "&cli_ver=" + std::string(SLIC3R_VERSION);
}
BOOST_LOG_TRIVIAL(info) << "SendToPrinter::fetchUrl: camera_url: " << hide_passwd(url, {"?uid=", "authkey=", "passwd="});
std::cout << "SendToPrinter::fetchUrl: camera_url: " << hide_passwd(url, {"?uid=", "authkey=", "passwd="});
CallAfter([=] {
boost::shared_ptr fs(wfs.lock());
if (!fs) return;
if (boost::algorithm::starts_with(url, "qidi:///")) {
fs->SetUrl(url);
} else {
fs->SetUrl("3");
}
});
});
}
return;
}
2024-09-03 09:34:33 +08:00
SendToPrinterDialog::~SendToPrinterDialog()
{
delete m_refresh_timer;
2025-05-08 15:05:30 +08:00
if (m_task_timer && m_task_timer->IsRunning())
m_task_timer->Stop();
}
//y24
std::string SendToPrinterDialog::NormalizeVendor(const std::string& str)
{
std::string normalized;
for (char c : str) {
if (std::isalnum(c)) {
normalized += std::tolower(c);
}
}
return normalized;
2024-09-03 09:34:33 +08:00
}
}
}