diff --git a/resources/printers/BL-P001.json b/resources/printers/BL-P001.json index fbdea5d750f..0004806aaac 100644 --- a/resources/printers/BL-P001.json +++ b/resources/printers/BL-P001.json @@ -6,10 +6,10 @@ "resolution_supported": [ "720p", "1080p" ], "virtual_camera": "enabled", "liveview": { - "remote": "enabled" + "remote": "tutk" }, "file": { - "remote": "enabled", + "remote": "tutk", "model_download": "enabled" } }, diff --git a/resources/printers/BL-P002.json b/resources/printers/BL-P002.json index 286e552716f..3c2e7ed049b 100644 --- a/resources/printers/BL-P002.json +++ b/resources/printers/BL-P002.json @@ -6,10 +6,10 @@ "resolution_supported": [ "720p", "1080p" ], "virtual_camera": "enabled", "liveview": { - "remote": "enabled" + "remote": "tutk" }, "file": { - "remote": "enabled", + "remote": "tutk", "model_download": "enabled" } }, diff --git a/resources/printers/C11.json b/resources/printers/C11.json index 5fb53b3f0f6..a2cbbb078a5 100644 --- a/resources/printers/C11.json +++ b/resources/printers/C11.json @@ -58,7 +58,7 @@ "print": { "ipcam": { "liveview": { - "remote": "enabled" + "remote": "tutk" } } } @@ -79,7 +79,7 @@ "print": { "ipcam": { "file": { - "remote": "enabled" + "remote": "tutk" } }, "support_user_preset":true diff --git a/resources/printers/C12.json b/resources/printers/C12.json index d3a6c6d995a..5cc12a1a66f 100644 --- a/resources/printers/C12.json +++ b/resources/printers/C12.json @@ -60,7 +60,7 @@ "print": { "ipcam": { "liveview": { - "remote": "enabled" + "remote": "tutk" } }, "support_mqtt_alive":true, @@ -71,7 +71,7 @@ "print": { "ipcam": { "file": { - "remote": "enabled" + "remote": "tutk" } }, "support_user_preset":true diff --git a/resources/printers/C13.json b/resources/printers/C13.json index c8bce2ad6a5..44c4ecda299 100644 --- a/resources/printers/C13.json +++ b/resources/printers/C13.json @@ -6,10 +6,10 @@ "resolution_supported": [ "720p", "1080p" ], "virtual_camera": "enabled", "liveview": { - "remote": "enabled" + "remote": "tutk" }, "file": { - "remote": "enabled", + "remote": "tutk", "model_download": "enabled" } }, diff --git a/resources/printers/N1.json b/resources/printers/N1.json index 8bcd035a5ef..ac161ed7bed 100644 --- a/resources/printers/N1.json +++ b/resources/printers/N1.json @@ -6,7 +6,7 @@ "resolution_supported": [ "720p" ], "liveview": { "local": "local", - "remote": "enabled" + "remote": "tutk" } }, "support_motor_noise_cali":true, @@ -53,7 +53,7 @@ "print": { "ipcam": { "file": { - "remote": "enabled" + "remote": "tutk" } }, "support_user_preset":true diff --git a/resources/printers/N2S.json b/resources/printers/N2S.json index 2857bb17ebe..a87b08d08b9 100644 --- a/resources/printers/N2S.json +++ b/resources/printers/N2S.json @@ -6,7 +6,7 @@ "resolution_supported": [ "720p" ], "liveview": { "local": "local", - "remote": "enabled" + "remote": "tutk" } }, "support_motor_noise_cali":true, @@ -53,7 +53,7 @@ "print": { "ipcam": { "file": { - "remote": "enabled" + "remote": "tutk" } } } diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 039930c3872..9f7facf922a 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -1983,6 +1983,11 @@ void PresetBundle::set_calibrate_printer(std::string name) std::set PresetBundle::get_printer_names_by_printer_type_and_nozzle(const std::string &printer_type, std::string nozzle_diameter_str) { std::set printer_names; + + /* unknown or empty printer type */ + if (printer_type.empty()) + return printer_names; + if ("0.0" == nozzle_diameter_str || nozzle_diameter_str.empty()) { nozzle_diameter_str = "0.4"; } diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 1ce29c28a35..2142eae5260 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -1431,6 +1431,9 @@ void MachineObject::parse_status(int flag) sdcard_state = MachineObject::SdcardState((flag >> 8) & 0x11); network_wired = ((flag >> 18) & 0x1) != 0; + is_support_agora = ((flag >> 30) & 0x1) != 0; + if (is_support_agora) + is_support_tunnel_mqtt = false; } PrintingSpeedLevel MachineObject::_parse_printing_speed_lvl(int lvl) @@ -2617,29 +2620,29 @@ bool MachineObject::is_camera_busy_off() return false; } -int MachineObject::publish_json(std::string json_str, int qos) +int MachineObject::publish_json(std::string json_str, int qos, int flag) { if (is_lan_mode_printer()) { - return local_publish_json(json_str, qos); + return local_publish_json(json_str, qos, flag); } else { - return cloud_publish_json(json_str, qos); + return cloud_publish_json(json_str, qos, flag); } } -int MachineObject::cloud_publish_json(std::string json_str, int qos) +int MachineObject::cloud_publish_json(std::string json_str, int qos, int flag) { int result = -1; if (m_agent) - result = m_agent->send_message(dev_id, json_str, qos); + result = m_agent->send_message(dev_id, json_str, qos, flag); return result; } -int MachineObject::local_publish_json(std::string json_str, int qos) +int MachineObject::local_publish_json(std::string json_str, int qos, int flag) { int result = -1; if (m_agent) { - result = m_agent->send_message_to_printer(dev_id, json_str, qos); + result = m_agent->send_message_to_printer(dev_id, json_str, qos, flag); } return result; } @@ -2902,7 +2905,7 @@ int MachineObject::parse_json(std::string payload, bool key_field_only) } if (!key_field_only) { - if (!DeviceManager::EnableMultiMachine) { + if (!DeviceManager::EnableMultiMachine && !is_support_agora) { if (jj.contains("support_tunnel_mqtt")) { if (jj["support_tunnel_mqtt"].is_boolean()) { is_support_tunnel_mqtt = jj["support_tunnel_mqtt"].get(); @@ -3687,11 +3690,18 @@ int MachineObject::parse_json(std::string payload, bool key_field_only) if (ipcam.contains("liveview")) { char const *local_protos[] = {"none", "disabled", "local", "rtsps", "rtsp"}; liveview_local = enum_index_of(ipcam["liveview"].value("local", "none").c_str(), local_protos, 5, LiveviewLocal::LVL_None); - liveview_remote = ipcam["liveview"].value("remote", "disabled") == "enabled"; + char const *remote_protos[] = {"none", "tutk", "agora", "tutk_agaro"}; + liveview_remote = enum_index_of(ipcam["liveview"].value("remote", "none").c_str(), remote_protos, 4, LiveviewRemote::LVR_None); + if (is_support_agora) + liveview_remote = liveview_remote == LVR_None ? LVR_Agora : liveview_remote == LVR_Tutk ? LVR_TutkAgora : liveview_remote; } if (ipcam.contains("file")) { - file_local = ipcam["file"].value("local", "disabled") == "enabled"; - file_remote = ipcam["file"].value("remote", "disabled") == "enabled"; + char const *local_protos[] = {"none", "local"}; + file_local = enum_index_of(ipcam["file"].value("local", "none").c_str(), local_protos, 2, FileLocal::FL_None); + char const *remote_protos[] = {"none", "tutk", "agora", "tutk_agaro"}; + file_remote = enum_index_of(ipcam["file"].value("remote", "none").c_str(), remote_protos, 4, FileRemote::FR_None); + if (is_support_agora) + file_remote = file_remote == FR_None ? FR_Agora : file_remote == FR_Tutk ? FR_TutkAgora : file_remote; file_model_download = ipcam["file"].value("model_download", "disabled") == "enabled"; } virtual_camera = ipcam.value("virtual_camera", "disabled") == "enabled"; @@ -5265,8 +5275,6 @@ void DeviceManager::on_machine_alive(std::string json_str) Slic3r::GUI::wxGetApp().app_config->set_str("ip_address", obj->dev_id, obj->dev_ip); Slic3r::GUI::wxGetApp().app_config->save(); }*/ - - BOOST_LOG_TRIVIAL(info) << "SsdpDiscovery::New Machine, ip = " << Slic3r::GUI::wxGetApp().format_IP(dev_ip) << ", printer_name= " << dev_name << ", printer_type = " << printer_type_str << ", signal = " << printer_signal; } } @@ -5275,6 +5283,21 @@ void DeviceManager::on_machine_alive(std::string json_str) } } +MachineObject* DeviceManager::insert_local_device(std::string dev_name, std::string dev_id, std::string dev_ip, std::string connection_type, std::string bind_state, std::string version, std::string access_code) +{ + MachineObject* obj; + obj = new MachineObject(m_agent, dev_name, dev_id, dev_ip); + obj->printer_type = MachineObject::parse_printer_type("C11"); + obj->dev_connection_type = connection_type; + obj->bind_state = bind_state; + obj->bind_sec_link = "secure"; + obj->bind_ssdp_version = version; + obj->m_is_online = true; + obj->set_access_code(access_code, false); + obj->set_user_access_code(access_code, false); + return obj; +} + void DeviceManager::disconnect_all() { @@ -5458,13 +5481,13 @@ bool DeviceManager::set_selected_machine(std::string dev_id, bool need_disconnec } } else { BOOST_LOG_TRIVIAL(info) << "static: set_selected_machine: same dev_id = empty"; - m_agent->set_user_selected_machine(""); it->second->reset(); #if !BBL_RELEASE_TO_PUBLIC it->second->connect(false, Slic3r::GUI::wxGetApp().app_config->get("enable_ssl_for_mqtt") == "true" ? true : false); #else it->second->connect(false, it->second->local_use_ssl_for_mqtt); #endif + m_agent->set_user_selected_machine(dev_id); it->second->set_lan_mode_connection_state(true); } } diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index be177bba5a6..8928e5a9a36 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -708,9 +708,22 @@ class MachineObject LVL_Rtsps, LVL_Rtsp } liveview_local{ LVL_None }; - bool liveview_remote{false}; - bool file_local{false}; - bool file_remote{false}; + enum LiveviewRemote { + LVR_None, + LVR_Tutk, + LVR_Agora, + LVR_TutkAgora + } liveview_remote{ LVR_None }; + enum FileLocal { + FL_None, + FL_Local + } file_local{ FL_None }; + enum FileRemote { + FR_None, + FR_Tutk, + FR_Agora, + FR_TutkAgora + } file_remote{ FR_None }; bool file_model_download{false}; bool virtual_camera{false}; @@ -762,6 +775,8 @@ class MachineObject bool is_support_p1s_plus{false}; bool is_support_nozzle_blob_detection{false}; bool is_support_air_print_detection{false}; + bool is_support_filament_setting_inprinting{false}; + bool is_support_agora{false}; int nozzle_max_temperature = -1; int bed_temperature_limit = -1; @@ -940,9 +955,9 @@ class MachineObject /* Msg for display MsgFn */ typedef std::function MsgFn; - int publish_json(std::string json_str, int qos = 0); - int cloud_publish_json(std::string json_str, int qos = 0); - int local_publish_json(std::string json_str, int qos = 0); + int publish_json(std::string json_str, int qos = 0, int flag = 0); + int cloud_publish_json(std::string json_str, int qos = 0, int flag = 0); + int local_publish_json(std::string json_str, int qos = 0, int flag = 0); int parse_json(std::string payload, bool key_filed_only = false); int publish_gcode(std::string gcode_str); @@ -1006,7 +1021,7 @@ class DeviceManager /* create machine or update machine properties */ void on_machine_alive(std::string json_str); - + MachineObject* insert_local_device(std::string dev_name, std::string dev_id, std::string dev_ip, std::string connection_type, std::string bind_state, std::string version, std::string access_code); /* disconnect all machine connections */ void disconnect_all(); int query_bind_status(std::string &msg); diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 234340dc6b6..49ac8d66f9f 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -32,6 +32,7 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_PRINT_SELECT, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER_ALL, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_PRINT_MULTI_MACHINE, SimpleEvent); +wxDEFINE_EVENT(EVT_GLTOOLBAR_SEND_BAMBU_CONNECT, SimpleEvent); wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent); diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 85413edc66d..402d60c5525 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -32,6 +32,7 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_PRINT_SELECT, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER_ALL, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_PRINT_MULTI_MACHINE, SimpleEvent); +wxDECLARE_EVENT(EVT_GLTOOLBAR_SEND_BAMBU_CONNECT, SimpleEvent); wxDECLARE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 2cbbd216832..050a3f1cc16 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -976,6 +976,8 @@ void GUI_App::post_init() // this->check_privacy_version(0); request_user_handle(0); } + + this->check_cert(); }); } @@ -1024,9 +1026,11 @@ void GUI_App::post_init() for (auto& it : boost::filesystem::directory_iterator(log_folder)) { auto temp_path = it.path(); try { - std::time_t lw_t = boost::filesystem::last_write_time(temp_path) ; - files_vec.push_back({ lw_t, temp_path.filename().string() }); - } catch (const std::exception &) { + if (it.status().type() == boost::filesystem::regular_file) { + std::time_t lw_t = boost::filesystem::last_write_time(temp_path) ; + files_vec.push_back({ lw_t, temp_path.filename().string() }); + } + } catch (const std::exception &ex) { } } std::sort(files_vec.begin(), files_vec.end(), []( @@ -1569,6 +1573,17 @@ void GUI_App::init_networking_callbacks() // GUI::wxGetApp().request_user_handle(online_login); // }); + m_agent->set_server_callback([this](std::string url, int status) { + if (!m_server_error_dialog) { + m_server_error_dialog = new NetworkErrorDialog(mainframe); + } + + if (!m_server_error_dialog->IsShown()) { + m_server_error_dialog->ShowModal(); + } + }); + + m_agent->set_on_server_connected_fn([this](int return_code, int reason_code) { if (m_is_closing) { return; @@ -1623,6 +1638,8 @@ void GUI_App::init_networking_callbacks() obj->command_get_version(); obj->erase_user_access_code(); obj->command_get_access_code(); + if (m_agent) + m_agent->install_device_cert(obj->dev_id, obj->is_lan_mode_printer()); if (!is_enable_multi_machine()) { GUI::wxGetApp().sidebar().load_ams_list(obj->dev_id, obj); } @@ -1721,6 +1738,8 @@ void GUI_App::init_networking_callbacks() CallAfter([this, dev_id, msg] { if (m_is_closing) return; + this->process_network_msg(dev_id, msg); + MachineObject* obj = this->m_device_manager->get_user_machine(dev_id); if (obj) { obj->is_ams_need_update = false; @@ -1773,6 +1792,7 @@ void GUI_App::init_networking_callbacks() if (m_is_closing) return; + this->process_network_msg(dev_id, msg); MachineObject* obj = m_device_manager->get_my_machine(dev_id); if (!obj || !obj->is_lan_mode_printer()) { obj = m_device_manager->get_local_machine(dev_id); @@ -3225,6 +3245,23 @@ void GUI_App::link_to_network_check() wxLaunchDefaultBrowser(url); } +void GUI_App::link_to_lan_only_wiki() +{ + std::string url; + std::string country_code = app_config->get_country_code(); + + if (country_code == "US") { + url = "https://wiki.bambulab.com/en/knowledge-sharing/enable-lan-mode"; + } + else if (country_code == "CN") { + url = "https://wiki.bambulab.com/zh/knowledge-sharing/enable-lan-mode"; + } + else { + url = "https://wiki.bambulab.com/en/knowledge-sharing/enable-lan-mode"; + } + wxLaunchDefaultBrowser(url); +} + bool GUI_App::tabs_as_menu() const { return false; @@ -3684,7 +3721,7 @@ void GUI_App::request_user_logout() { if (m_agent && m_agent->is_user_login()) { // Update data first before showing dialogs - m_agent->user_logout(); + m_agent->user_logout(true); m_agent->set_user_selected_machine(""); /* delete old user settings */ bool transfer_preset_changes = false; @@ -4018,7 +4055,15 @@ void GUI_App::on_http_error(wxCommandEvent &evt) MessageDialog msg_dlg(nullptr, _L("The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally"), "", wxAPPLY | wxOK); if (msg_dlg.ShowModal() == wxOK) { } - + } + else if (status == 400 && code == HttpErrorCertRevoked) { + if (!m_show_error_msgdlg) { + MessageDialog msg_dlg(nullptr, _L("Your software certificate has been revoked, please update Orca Slicer software."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + return; + } } // request login @@ -4026,15 +4071,12 @@ void GUI_App::on_http_error(wxCommandEvent &evt) if (m_agent) { if (m_agent->is_user_login()) { this->request_user_logout(); - - if (!m_show_http_errpr_msgdlg) { + if (!m_show_error_msgdlg) { MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK); - m_show_http_errpr_msgdlg = true; + m_show_error_msgdlg = true; auto modal_result = msg_dlg.ShowModal(); - if (modal_result == wxOK || modal_result == wxCLOSE) { - m_show_http_errpr_msgdlg = false; - return; - } + m_show_error_msgdlg = false; + return; } } } @@ -4338,6 +4380,89 @@ void GUI_App::check_new_version_sf(bool show_tips, int by_user) .perform(); } +void GUI_App::check_cert() +{ + m_check_cert_thread = Slic3r::create_thread( + [this]{ + if (m_agent) + m_agent->check_cert(); + }); + BOOST_LOG_TRIVIAL(info) << "check_cert"; +} + +void GUI_App::process_network_msg(std::string dev_id, std::string msg) +{ + if (dev_id.empty()) { + if (msg == "wait_info") { + BOOST_LOG_TRIVIAL(info) << "process_network_msg, wait_info"; + Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) + return; + MachineObject* obj = dev->get_selected_machine(); + if (obj) + m_agent->install_device_cert(obj->dev_id, obj->is_lan_mode_printer()); + if (!m_show_error_msgdlg) { + MessageDialog msg_dlg(nullptr, _L("Retrieving printer information, please try again later."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + } + } + else if (msg == "update_studio") { + BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_studio"; + if (!m_show_error_msgdlg) { + MessageDialog msg_dlg(nullptr, _L("Please try updating Orca Slicer and then try again."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + } + } + else if (msg == "update_fixed_studio") { + BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_fixed_studio"; + if (!m_show_error_msgdlg) { + MessageDialog msg_dlg(nullptr, _L("Please try updating Orca Slicer and then try again."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + } + } + else if (msg == "cert_expired") { + BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_expired"; + if (!m_show_error_msgdlg) { + MessageDialog msg_dlg(nullptr, _L("The certificate has expired. Please check the time settings or update Orca Slicer and try again."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + } + } + else if (msg == "cert_revoked") { + BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_revoked"; + if (!m_show_error_msgdlg) { + MessageDialog msg_dlg(nullptr, _L("The certificate has been revoked. Please check the time settings or update Orca Slicer and try again."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + } + } + else if (msg == "update_firmware_studio") { + BOOST_LOG_TRIVIAL(info) << "process_network_msg, firmware internal error"; + if (!m_show_error_msgdlg) { + MessageDialog msg_dlg(nullptr, _L("Internal error. Please try upgrading the firmware and Slicer version. If the issue persists, contact customer support."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + } + } + else if (msg == "unsigned_studio") { + BOOST_LOG_TRIVIAL(info) << "process_network_msg, unsigned_studio"; + MessageDialog msg_dlg(nullptr, _L("Your software is not signed, and some printing functions have been restricted. Please use the officially signed software version."), "", wxAPPLY | wxOK); + m_show_error_msgdlg = true; + auto modal_result = msg_dlg.ShowModal(); + m_show_error_msgdlg = false; + } + } +} + //BBS pop up a dialog and download files void GUI_App::request_new_version(int by_user) { diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index e4d735448ce..fa4ab1ce7b0 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -81,6 +81,7 @@ class ParamsDialog; class HMSQuery; class ModelMallDialog; class PingCodeBindDialog; +class NetworkErrorDialog; enum FileType @@ -304,13 +305,14 @@ class GUI_App : public wxApp bool m_is_dark_mode{ false }; bool m_adding_script_handler { false }; bool m_side_popup_status{false}; - bool m_show_http_errpr_msgdlg{false}; + bool m_show_error_msgdlg{false}; wxString m_info_dialog_content; HttpServer m_http_server; bool m_show_gcode_window{true}; boost::thread m_check_network_thread; - public: - //try again when subscription fails + boost::thread m_check_cert_thread; +public: + //try again when subscription fails void on_start_subscribe_again(std::string dev_id); void check_filaments_in_blacklist(std::string tag_supplier, std::string tag_material, bool& in_blacklist, std::string& action, std::string& info); std::string get_local_models_path(); @@ -394,8 +396,9 @@ class GUI_App : public wxApp void set_side_menu_popup_status(bool status); void link_to_network_check(); + void link_to_lan_only_wiki(); - const wxColour& get_label_clr_modified(){ return m_color_label_modified; } + const wxColour& get_label_clr_modified() { return m_color_label_modified; } const wxColour& get_label_clr_sys() { return m_color_label_sys; } const wxColour& get_label_clr_default() { return m_color_label_default; } const wxColour& get_window_default_clr(){ return m_color_window_default; } @@ -472,6 +475,9 @@ class GUI_App : public wxApp void check_update(bool show_tips, int by_user); void check_new_version(bool show_tips = false, int by_user = 0); void check_new_version_sf(bool show_tips = false, int by_user = 0); + void check_cert(); + void process_network_msg(std::string dev_id, std::string msg); + void check_beta_version(); void request_new_version(int by_user); void enter_force_upgrade(); void set_skip_version(bool skip = true); @@ -574,6 +580,8 @@ class GUI_App : public wxApp ModelMallDialog* m_mall_publish_dialog{ nullptr }; PingCodeBindDialog* m_ping_code_binding_dialog{ nullptr }; + NetworkErrorDialog* m_server_error_dialog { nullptr }; + void set_download_model_url(std::string url) {m_mall_model_download_url = url;} void set_download_model_name(std::string name) {m_mall_model_download_name = name;} std::string get_download_model_url() {return m_mall_model_download_url;} diff --git a/src/slic3r/GUI/Jobs/PrintJob.cpp b/src/slic3r/GUI/Jobs/PrintJob.cpp index bb21337e6b7..b8b5fc01a78 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.cpp +++ b/src/slic3r/GUI/Jobs/PrintJob.cpp @@ -21,6 +21,7 @@ static auto file_over_size_str = _u8L("The print file exceeds the maximum allowa static auto print_canceled_str = _u8L("Task canceled."); static auto send_print_failed_str = _u8L("Failed to send the print job. Please try again."); static auto upload_ftp_failed_str = _u8L("Failed to upload file to ftp. Please try again."); +static auto print_signed_str = _u8L("Your software is not signed, and some printing functions have been restricted. Please use the officially signed software version."); static auto desc_network_error = _u8L("Check the current status of the bambu server by clicking on the link above."); static auto desc_file_too_large = _u8L("The size of the print file is too large. Please adjust the file size and try again."); @@ -123,7 +124,7 @@ wxString PrintJob::get_http_error_msg(unsigned int status, std::string body) ; } return wxEmptyString; -} +} void PrintJob::process(Ctl &ctl) { @@ -264,8 +265,8 @@ void PrintJob::process(Ctl &ctl) params.preset_name = profile_name->second; } catch (...) {} - } - + } + auto model_name = model_info->metadata_items.find(BBL_DESIGNER_MODEL_TITLE_TAG); if (model_name != model_info->metadata_items.end()) { try { @@ -341,9 +342,9 @@ void PrintJob::process(Ctl &ctl) auto update_fn = [this, &ctl, &is_try_lan_mode, &is_try_lan_mode_failed, - &msg, - &error_str, - &curr_percent, + &msg, + &error_str, + &curr_percent, &error_text, StagePercentPoint ](int stage, int code, std::string info) { @@ -406,7 +407,7 @@ void PrintJob::process(Ctl &ctl) } } - //get errors + //get errors if (code > 100 || code < 0 || stage == BBL::SendingPrintJobStage::PrintingStageERROR) { if (code == BAMBU_NETWORK_ERR_PRINT_WR_FILE_OVER_SIZE || code == BAMBU_NETWORK_ERR_PRINT_SP_FILE_OVER_SIZE) { m_plater->update_print_error_info(code, desc_file_too_large, info); @@ -427,7 +428,7 @@ void PrintJob::process(Ctl &ctl) return ctl.was_canceled(); }; - + DeviceManager* dev = wxGetApp().getDeviceManager(); MachineObject* obj = dev->get_selected_machine(); @@ -545,7 +546,7 @@ void PrintJob::process(Ctl &ctl) ctl.update_status(curr_percent, _u8L("Sending print job through cloud service")); result = m_agent->start_print(params, update_fn, cancel_fn, wait_fn); } - } + } } else { if (this->has_sdcard) { ctl.update_status(curr_percent, _u8L("Sending print job over LAN")); @@ -558,8 +559,10 @@ void PrintJob::process(Ctl &ctl) if (result < 0) { curr_percent = -1; - - if (result == BAMBU_NETWORK_ERR_PRINT_WR_FILE_NOT_EXIST || result == BAMBU_NETWORK_ERR_PRINT_SP_FILE_NOT_EXIST) { + if (result == BAMBU_NETOWRK_ERR_PRINT_SP_ENC_FLAG_NOT_READY) { + msg_text = _u8L("Retrieving printer information, please try again later."); + } + else if (result == BAMBU_NETWORK_ERR_PRINT_WR_FILE_NOT_EXIST || result == BAMBU_NETWORK_ERR_PRINT_SP_FILE_NOT_EXIST) { msg_text = file_is_not_exists_str; } else if (result == BAMBU_NETWORK_ERR_PRINT_SP_FILE_OVER_SIZE || result == BAMBU_NETWORK_ERR_PRINT_WR_FILE_OVER_SIZE) { msg_text = file_over_size_str; @@ -572,6 +575,8 @@ void PrintJob::process(Ctl &ctl) } else if (result == BAMBU_NETWORK_ERR_CANCELED) { msg_text = print_canceled_str; ctl.update_status(0, msg_text); + } else if (result == BAMBU_NETWORK_SIGNED_ERROR) { + msg_text = print_signed_str; } else { msg_text = send_print_failed_str; } @@ -579,7 +584,7 @@ void PrintJob::process(Ctl &ctl) if (result != BAMBU_NETWORK_ERR_CANCELED) { ctl.show_error_info(msg_text, 0, "", ""); } - + BOOST_LOG_TRIVIAL(error) << "print_job: failed, result = " << result; } else { // wait for printer mqtt ready the same job id diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 945e8b493e3..dd9220f830e 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -12,7 +12,7 @@ //#include #include #include -#include +#include #include #include @@ -184,7 +184,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ set_miniaturizable(GetHandle()); #endif - if (!wxGetApp().app_config->has("user_mode")) { + if (!wxGetApp().app_config->has("user_mode")) { wxGetApp().app_config->set("user_mode", "simple"); wxGetApp().app_config->set_bool("developer_mode", false); wxGetApp().app_config->save(); @@ -496,7 +496,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); event.Skip(); }); -#endif +#endif update_ui_from_settings(); // FIXME (?) @@ -562,12 +562,12 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ return; } else if (evt.CmdDown() && evt.GetKeyCode() == 'G') { if (can_export_gcode()) { wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE)); } evt.Skip(); return; } - if (evt.CmdDown() && evt.GetKeyCode() == 'J') { m_printhost_queue_dlg->Show(); return; } + if (evt.CmdDown() && evt.GetKeyCode() == 'J') { m_printhost_queue_dlg->Show(); return; } if (evt.CmdDown() && evt.GetKeyCode() == 'N') { m_plater->new_project(); return;} if (evt.CmdDown() && evt.GetKeyCode() == 'O') { m_plater->load_project(); return;} if (evt.CmdDown() && evt.ShiftDown() && evt.GetKeyCode() == 'S') { if (can_save_as()) m_plater->save_project(true); return;} else if (evt.CmdDown() && evt.GetKeyCode() == 'S') { if (can_save()) m_plater->save_project(); return;} - if (evt.CmdDown() && evt.GetKeyCode() == 'F') { + if (evt.CmdDown() && evt.GetKeyCode() == 'F') { if (m_plater && (m_tabpanel->GetSelection() == TabPosition::tp3DEditor || m_tabpanel->GetSelection() == TabPosition::tpPreview)) { m_plater->sidebar().can_search(); } @@ -1639,6 +1639,8 @@ wxBoxSizer* MainFrame::create_side_tools() wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SEND_TO_PRINTER)); else if (m_print_select == eSendToPrinterAll) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SEND_TO_PRINTER_ALL)); + else if (m_print_select == eSendBambuConnect) + wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SEND_BAMBU_CONNECT)); /* else if (m_print_select == ePrintMultiMachine) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_PRINT_MULTI_MACHINE));*/ }); @@ -1818,6 +1820,7 @@ wxBoxSizer* MainFrame::create_side_tools() }); p->append_button(print_multi_machine_btn); } + p->append_button(export_sliced_file_btn); p->append_button(export_all_sliced_file_btn); SideButton* export_gcode_btn = new SideButton(p, _L("Export G-code file"), ""); @@ -1831,6 +1834,18 @@ wxBoxSizer* MainFrame::create_side_tools() p->Dismiss(); }); p->append_button(export_gcode_btn); + + SideButton *send_to_bambu_connect_btn = new SideButton(p, _L("Send to Bambu Connect"), ""); + send_to_bambu_connect_btn->SetCornerRadius(0); + send_to_bambu_connect_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent &) { + m_print_btn->SetLabel(_L("Send to BC")); + m_print_select = eSendBambuConnect; + m_print_enable = get_enable_print_status(); + m_print_btn->Enable(m_print_enable); + this->Layout(); + p->Dismiss(); + }); + p->append_button(send_to_bambu_connect_btn); } p->Popup(m_print_btn); @@ -1979,6 +1994,11 @@ bool MainFrame::get_enable_print_status() enable = false; } enable = enable && !is_all_plates; + }else if (m_print_select == eSendBambuConnect) { + if (!current_plate->is_slice_result_ready_for_print()) { + enable = false; + } + enable = enable && !is_all_plates; } BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": m_print_select %1%, enable= %2% ")%m_print_select %enable; @@ -1998,7 +2018,7 @@ void MainFrame::update_side_button_style() m_slice_btn->SetExtraSize(wxSize(FromDIP(38), FromDIP(10))); m_slice_btn->SetBottomColour(wxColour(0x3B4446));*/ StateColor m_btn_bg_enable = StateColor( - std::pair(wxColour(0, 137, 123), StateColor::Pressed), + std::pair(wxColour(0, 137, 123), StateColor::Pressed), std::pair(wxColour(48, 221, 112), StateColor::Hovered), std::pair(wxColour(0, 150, 136), StateColor::Normal) ); @@ -2566,7 +2586,7 @@ void MainFrame::init_menubar_as_editor() #if 0 // BBS Delete selected append_menu_item(editMenu, wxID_ANY, _L("Delete selected") + "\tBackSpace", - _L("Deletes the current selection"),[this](wxCommandEvent&) { + _L("Deletes the current selection"),[this](wxCommandEvent&) { m_plater->remove_selected(); }, "", nullptr, [this](){return can_delete(); }, this); @@ -2609,7 +2629,7 @@ void MainFrame::init_menubar_as_editor() // BBS Select All append_menu_item(editMenu, wxID_ANY, _L("Select all") + "\t" + ctrl + "A", - _L("Selects all objects"), [this, handle_key_event](wxCommandEvent&) { + _L("Selects all objects"), [this, handle_key_event](wxCommandEvent&) { wxKeyEvent e; e.SetEventType(wxEVT_KEY_DOWN); e.SetControlDown(true); @@ -2936,7 +2956,7 @@ void MainFrame::init_menubar_as_editor() m_retraction_calib_dlg->ShowModal(); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); - + append_menu_item(m_topbar->GetCalibMenu(), wxID_ANY, _L("Orca Tolerance Test"), _L("Orca Tolerance Test"), [this](wxCommandEvent&) { m_plater->new_project(); @@ -2967,7 +2987,7 @@ void MainFrame::init_menubar_as_editor() [this]() {return m_plater->is_view3D_shown();; }, this); m_topbar->GetCalibMenu()->AppendSubMenu(advance_menu, _L("More...")); - // help + // help append_menu_item(m_topbar->GetCalibMenu(), wxID_ANY, _L("Tutorial"), _L("Calibration help"), [this](wxCommandEvent&) { std::string url = "https://github.com/SoftFever/OrcaSlicer/wiki/Calibration"; @@ -2999,7 +3019,7 @@ void MainFrame::init_menubar_as_editor() m_temp_calib_dlg->ShowModal(); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); - + // Flowrate auto flowrate_menu = new wxMenu(); append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 1"), _L("Flow rate test - Pass 1"), @@ -3048,28 +3068,28 @@ void MainFrame::init_menubar_as_editor() auto advance_menu = new wxMenu(); append_menu_item( advance_menu, wxID_ANY, _L("Max flowrate"), _L("Max flowrate"), - [this](wxCommandEvent&) { + [this](wxCommandEvent&) { if (!m_vol_test_dlg) m_vol_test_dlg = new MaxVolumetricSpeed_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); - m_vol_test_dlg->ShowModal(); + m_vol_test_dlg->ShowModal(); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); append_menu_item( advance_menu, wxID_ANY, _L("VFA"), _L("VFA"), - [this](wxCommandEvent&) { + [this](wxCommandEvent&) { if (!m_vfa_test_dlg) m_vfa_test_dlg = new VFA_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); m_vfa_test_dlg->ShowModal(); }, "", nullptr, - [this]() {return m_plater->is_view3D_shown();; }, this); - + [this]() {return m_plater->is_view3D_shown();; }, this); + append_submenu(calib_menu, advance_menu, wxID_ANY, _L("More..."), _L("More calibrations"), "", [this]() {return m_plater->is_view3D_shown();; }); // help append_menu_item(calib_menu, wxID_ANY, _L("Tutorial"), _L("Calibration help"), [this](wxCommandEvent&) { wxLaunchDefaultBrowser("https://github.com/SoftFever/OrcaSlicer/wiki/Calibration", wxBROWSER_NEW_WINDOW); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); - + m_menubar->Append(calib_menu,wxString::Format("&%s", _L("Calibration"))); if (helpMenu) m_menubar->Append(helpMenu, wxString::Format("&%s", _L("Help"))); @@ -3232,7 +3252,7 @@ void MainFrame::export_config() { ExportConfigsDialog export_configs_dlg(nullptr); export_configs_dlg.ShowModal(); - return; + return; // Generate a cummulative configuration for the selected print, filaments and printer. wxDirDialog dlg(this, _L("Choose a directory"), diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 18682a20712..7aea10ed9f8 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -239,7 +239,8 @@ class MainFrame : public DPIFrame eSendToPrinterAll = 6, eUploadGcode = 7, eExportAllSlicedFile = 8, - ePrintMultiMachine = 9 + ePrintMultiMachine = 9, + eSendBambuConnect = 10 }; void update_layout(); @@ -382,7 +383,7 @@ class MainFrame : public DPIFrame wxWindow* m_plater_page{ nullptr }; PrintHostQueueDialog* m_printhost_queue_dlg; - + mutable int m_print_select{ ePrintAll }; mutable int m_slice_select{ eSliceAll }; // Button* m_publish_btn{ nullptr }; diff --git a/src/slic3r/GUI/MediaFilePanel.cpp b/src/slic3r/GUI/MediaFilePanel.cpp index 672ea696b6b..de9b3951c9e 100644 --- a/src/slic3r/GUI/MediaFilePanel.cpp +++ b/src/slic3r/GUI/MediaFilePanel.cpp @@ -219,10 +219,10 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj) m_lan_ip = obj->dev_ip; m_lan_passwd = obj->get_access_code(); m_dev_ver = obj->get_ota_version(); - m_device_busy = obj->is_camera_busy_off(); + m_device_busy = obj->is_camera_busy_off(); m_sdcard_exist = obj->has_sdcard(); - m_local_support = obj->file_local; - m_remote_support = obj->file_remote; + m_local_proto = obj->file_local; + m_remote_proto = obj->file_remote; m_model_download_support = obj->file_model_download; } else { m_lan_mode = false; @@ -231,13 +231,13 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj) m_dev_ver.clear(); m_sdcard_exist = false; m_device_busy = false; - m_local_support = false; - m_remote_support = false; + m_local_proto = 0; + m_remote_proto = 0; m_model_download_support = false; } Enable(obj && obj->is_connected() && obj->m_push_count > 0); if (machine == m_machine) { - if ((m_waiting_enable && IsEnabled()) || (m_waiting_support && (m_local_support || m_remote_support))) { + if ((m_waiting_enable && IsEnabled()) || (m_waiting_support && (m_local_proto || m_remote_proto))) { auto fs = m_image_grid->GetFileSystem(); if (fs) fs->Retry(); } @@ -433,7 +433,7 @@ void MediaFilePanel::fetchUrl(boost::weak_ptr wfs) return; } m_waiting_enable = false; - if (!m_local_support && !m_remote_support) { + if (!m_local_proto && !m_remote_proto) { m_waiting_support = true; m_image_grid->SetStatus(m_bmp_failed, _L("Browsing file in SD card is not supported in current firmware. Please update the printer firmware.")); fs->SetUrl("0"); @@ -452,7 +452,7 @@ void MediaFilePanel::fetchUrl(boost::weak_ptr wfs) m_waiting_support = false; NetworkAgent *agent = wxGetApp().getAgent(); std::string agent_version = agent ? agent->get_version() : ""; - if ((m_lan_mode || !m_remote_support) && m_local_support && !m_lan_ip.empty()) { + if ((m_lan_mode || !m_remote_proto) && m_local_proto && !m_lan_ip.empty()) { std::string url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd; url += "&device=" + m_machine; url += "&net_ver=" + agent_version; @@ -462,7 +462,7 @@ void MediaFilePanel::fetchUrl(boost::weak_ptr wfs) fs->SetUrl(url); return; } - if (!m_remote_support && m_local_support) { // not support tutk + if (!m_remote_proto && m_local_proto) { // not support tutk m_image_grid->SetStatus(m_bmp_failed, _L("Please enter the IP of printer to connect.")); fs->SetUrl("0"); fs.reset(); @@ -478,12 +478,14 @@ void MediaFilePanel::fetchUrl(boost::weak_ptr wfs) return; } if (agent) { - agent->get_camera_url(m_machine, - [this, wfs, m = m_machine, v = agent->get_version(), dv = m_dev_ver](std::string url) { + std::string protocols[] = {"", "\"tutk\"", "\"agora\"", "\"tutk\",\"agora\""}; + agent->get_camera_url(m_machine + "|" + m_dev_ver + "|" + protocols[m_remote_proto], + [this, wfs, m = m_machine, v = agent->get_version(), dv = m_dev_ver, agent](std::string url) { if (boost::algorithm::starts_with(url, "bambu:///")) { url += "&device=" + m; url += "&net_ver=" + v; url += "&dev_ver=" + dv; + url += "&network_agent=" + boost::lexical_cast(agent->get_network_agent()); url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid"); url += "&cli_ver=" + std::string(SLIC3R_VERSION); } diff --git a/src/slic3r/GUI/MediaFilePanel.h b/src/slic3r/GUI/MediaFilePanel.h index 0b64cdb5d60..c22639304be 100644 --- a/src/slic3r/GUI/MediaFilePanel.h +++ b/src/slic3r/GUI/MediaFilePanel.h @@ -83,8 +83,8 @@ class MediaFilePanel : public wxPanel std::string m_dev_ver; bool m_lan_mode = false; bool m_sdcard_exist = false; - bool m_local_support = false; - bool m_remote_support = false; + int m_local_proto = false; + int m_remote_proto = false; bool m_model_download_support = false; bool m_device_busy = false; bool m_waiting_enable = false; diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp index 208182b9a19..3c5d291ee2e 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.cpp +++ b/src/slic3r/GUI/MediaPlayCtrl.cpp @@ -150,7 +150,7 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj) m_dev_ver = obj->get_ota_version(); m_lan_mode = obj->is_lan_mode_printer(); m_lan_proto = obj->liveview_local; - m_remote_support = obj->liveview_remote; + m_remote_proto = obj->liveview_remote; m_lan_ip = obj->dev_ip; m_lan_passwd = obj->get_access_code(); m_device_busy = obj->is_camera_busy_off(); @@ -163,20 +163,13 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj) m_lan_passwd.clear(); m_dev_ver.clear(); m_tutk_state.clear(); - m_remote_support = true; + m_remote_proto = 0; m_device_busy = false; } Enable(obj && obj->is_connected() && obj->m_push_count > 0); if (machine == m_machine) { if (m_last_state == MEDIASTATE_IDLE && IsEnabled()) Play(); - else if (m_last_state == MEDIASTATE_LOADING && m_tutk_state == "disable" - && m_last_user_play + wxTimeSpan::Seconds(3) < wxDateTime::Now()) { - // resend ttcode to printer - if (auto agent = wxGetApp().getAgent()) - agent->get_camera_url(machine, [](auto) {}); - m_last_user_play = wxDateTime::Now(); - } return; } m_machine = machine; @@ -262,8 +255,8 @@ void MediaPlayCtrl::Play() m_button_play->SetIcon("media_stop"); NetworkAgent *agent = wxGetApp().getAgent(); std::string agent_version = agent ? agent->get_version() : ""; - if (m_lan_proto > MachineObject::LVL_Disable && (m_lan_mode || !m_remote_support) && !m_disable_lan && !m_lan_ip.empty()) { - m_disable_lan = m_remote_support && !m_lan_mode; // try remote next time + if (m_lan_proto > MachineObject::LVL_Disable && (m_lan_mode || !m_remote_proto) && !m_disable_lan && !m_lan_ip.empty()) { + m_disable_lan = m_remote_proto && !m_lan_mode; // try remote next time std::string url; if (m_lan_proto == MachineObject::LVL_Local) url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd; @@ -285,12 +278,12 @@ void MediaPlayCtrl::Play() // m_lan_mode && m_lan_proto > LVL_Disable (use local tunnel) // m_lan_mode && m_lan_proto == LVL_Disable (*) // m_lan_mode && m_lan_proto == LVL_None (x) - // !m_lan_mode && m_remote_support (go on) - // !m_lan_mode && !m_remote_support && m_lan_proto > LVL_None (use local tunnel) - // !m_lan_mode && !m_remote_support && m_lan_proto == LVL_Disable (*) - // !m_lan_mode && !m_remote_support && m_lan_proto == LVL_None (x) + // !m_lan_mode && m_remote_proto (go on) + // !m_lan_mode && !m_remote_proto && m_lan_proto > LVL_None (use local tunnel) + // !m_lan_mode && !m_remote_proto && m_lan_proto == LVL_Disable (*) + // !m_lan_mode && !m_remote_proto && m_lan_proto == LVL_None (x) - if (m_lan_proto <= MachineObject::LVL_Disable && (m_lan_mode || !m_remote_support)) { + if (m_lan_proto <= MachineObject::LVL_Disable && (m_lan_mode || !m_remote_proto)) { Stop(m_lan_proto == MachineObject::LVL_None ? _L("Problem occurred. Please update the printer firmware and try again.") : _L("LAN Only Liveview is off. Please turn on the liveview on printer screen.")); @@ -301,7 +294,7 @@ void MediaPlayCtrl::Play() m_failed_code = 0; m_last_state = MEDIASTATE_INITIALIZING; - if (!m_remote_support) { // not support tutk + if (!m_remote_proto) { // not support tutk m_failed_code = -1; m_url = "bambu:///local/"; Stop(_L("Please enter the IP of printer to connect.")); @@ -312,12 +305,14 @@ void MediaPlayCtrl::Play() SetStatus(_L("Initializing...")); if (agent) { - agent->get_camera_url(m_machine, - [this, m = m_machine, v = agent_version, dv = m_dev_ver](std::string url) { + std::string protocols[] = {"", "\"tutk\"", "\"agora\"", "\"tutk\",\"agora\""}; + agent->get_camera_url(m_machine + "|" + m_dev_ver + "|" + protocols[m_remote_proto], + [this, m = m_machine, v = agent_version, dv = m_dev_ver, agent](std::string url) { if (boost::algorithm::starts_with(url, "bambu:///")) { url += "&device=" + into_u8(m); url += "&net_ver=" + v; url += "&dev_ver=" + dv; + url += "&network_agent=" + boost::lexical_cast(agent->get_network_agent()); url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid"); url += "&cli_ver=" + std::string(SLIC3R_VERSION); } @@ -331,7 +326,7 @@ void MediaPlayCtrl::Play() if (m_last_state == MEDIASTATE_INITIALIZING) { if (url.empty() || !boost::algorithm::starts_with(url, "bambu:///")) { m_failed_code = 3; - Stop(_L("Connection Failed. Please check the network and try again")); + Stop(_L("Connection Failed. Please check the network and try again"), from_u8(url)); } else { m_url = url; load(); @@ -346,7 +341,7 @@ void MediaPlayCtrl::Play() void start_ping_test(); -void MediaPlayCtrl::Stop(wxString const &msg) +void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2) { int last_state = m_last_state; @@ -493,7 +488,7 @@ void MediaPlayCtrl::ToggleStream() wxGetApp().app_config->set("not_show_vcamera_stop_prev", "1"); if (res == wxID_CANCEL) return; } - if (m_lan_proto > MachineObject::LVL_Disable && (m_lan_mode || !m_remote_support) && !m_disable_lan && !m_lan_ip.empty()) { + if (m_lan_proto > MachineObject::LVL_Disable && (m_lan_mode || !m_remote_proto) && !m_disable_lan && !m_lan_ip.empty()) { std::string url; if (m_lan_proto == MachineObject::LVL_Local) url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd; @@ -514,11 +509,12 @@ void MediaPlayCtrl::ToggleStream() } NetworkAgent *agent = wxGetApp().getAgent(); if (!agent) return; - agent->get_camera_url(m_machine, [this, m = m_machine, v = agent->get_version(), dv = m_dev_ver](std::string url) { + agent->get_camera_url(m_machine, [this, m = m_machine, v = agent->get_version(), dv = m_dev_ver, agent](std::string url) { if (boost::algorithm::starts_with(url, "bambu:///")) { url += "&device=" + m; url += "&net_ver=" + v; url += "&dev_ver=" + dv; + url += "&network_agent=" + boost::lexical_cast(agent->get_network_agent()); url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid"); url += "&cli_ver=" + std::string(SLIC3R_VERSION); } diff --git a/src/slic3r/GUI/MediaPlayCtrl.h b/src/slic3r/GUI/MediaPlayCtrl.h index f6e8d0dbeca..d8c29b729f8 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.h +++ b/src/slic3r/GUI/MediaPlayCtrl.h @@ -49,7 +49,7 @@ class MediaPlayCtrl : public wxPanel void Play(); - void Stop(wxString const &msg = {}); + void Stop(wxString const &msg = {}, wxString const &msg2 = {}); void TogglePlay(); @@ -83,7 +83,7 @@ class MediaPlayCtrl : public wxPanel std::string m_tutk_state; bool m_camera_exists = false; bool m_lan_mode = false; - bool m_remote_support = false; + int m_remote_proto = 0; bool m_device_busy = false; bool m_disable_lan = false; wxString m_url; diff --git a/src/slic3r/GUI/Monitor.cpp b/src/slic3r/GUI/Monitor.cpp index 333f4d3de00..1813a1bffe7 100644 --- a/src/slic3r/GUI/Monitor.cpp +++ b/src/slic3r/GUI/Monitor.cpp @@ -359,6 +359,8 @@ void MonitorPanel::update_all() ; } } + if (obj) + m_agent->install_device_cert(obj->dev_id, obj->is_lan_mode_printer()); if (obj) { wxGetApp().reset_to_active(); diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index 3d67c5c2e52..7be96c48d68 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -660,6 +660,93 @@ wxBoxSizer *Newer3mfVersionDialog::get_btn_sizer() return horizontal_sizer; } +NetworkErrorDialog::NetworkErrorDialog(wxWindow* parent) + : DPIDialog(parent ? parent : nullptr, wxID_ANY, _L("Server Exception"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) +{ + this->SetBackgroundColour(*wxWHITE); + std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str(); + SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); + + wxBoxSizer* sizer_main = new wxBoxSizer(wxVERTICAL); + + auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL); + m_line_top->SetBackgroundColour(wxColour(166, 169, 170)); + + wxBoxSizer* sizer_bacis_text = new wxBoxSizer(wxVERTICAL); + + m_text_basic = new Label(this, _L("The server is unable to respond. Please click the link below to check the server status.")); + m_text_basic->SetForegroundColour(0x323A3C); + m_text_basic->SetMinSize(wxSize(FromDIP(450), -1)); + m_text_basic->SetMaxSize(wxSize(FromDIP(450), -1)); + m_text_basic->Wrap(FromDIP(450)); + m_text_basic->SetFont(::Label::Body_14); + sizer_bacis_text->Add(m_text_basic, 0, wxALL, 0); + + + wxBoxSizer* sizer_link = new wxBoxSizer(wxVERTICAL); + + m_link_server_state = new wxHyperlinkCtrl(this, wxID_ANY, _L("Check the status of current system services"), ""); + m_link_server_state->SetFont(::Label::Body_13); + m_link_server_state->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_network_check(); }); + m_link_server_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); }); + m_link_server_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); }); + + sizer_link->Add(m_link_server_state, 0, wxALL, 0); + + + wxBoxSizer* sizer_help = new wxBoxSizer(wxVERTICAL); + + m_text_proposal = new Label(this, _L("If the server is in a fault state, you can temporarily use offline printing or local network printing.")); + m_text_proposal->SetMinSize(wxSize(FromDIP(450), -1)); + m_text_proposal->SetMaxSize(wxSize(FromDIP(450), -1)); + m_text_proposal->Wrap(FromDIP(450)); + m_text_proposal->SetFont(::Label::Body_14); + m_text_proposal->SetForegroundColour(0x323A3C); + + m_text_wiki = new wxHyperlinkCtrl(this, wxID_ANY, _L("How to use LAN only mode"), ""); + m_text_wiki->SetFont(::Label::Body_13); + m_text_wiki->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_lan_only_wiki(); }); + m_text_wiki->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); }); + m_text_wiki->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); }); + + sizer_help->Add(m_text_proposal, 0, wxEXPAND, 0); + sizer_main->Add(0, 0, 0, wxTOP, 6); + sizer_help->Add(m_text_wiki, 0, wxALL, 0); + + wxBoxSizer* sizer_button = new wxBoxSizer(wxHORIZONTAL); + sizer_button->Add(0, 0, 1, wxEXPAND, 5); + + auto bt_enable = StateColor(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered), + std::pair(wxColour(0, 174, 66), StateColor::Normal)); + + m_button_confirm = new Button(this, _L("Confirm")); + m_button_confirm->SetBackgroundColor(bt_enable); + m_button_confirm->SetBorderColor(bt_enable); + m_button_confirm->SetTextColor(StateColor::darkModeColorFor("#FFFFFE")); + m_button_confirm->SetMinSize(wxSize(FromDIP(68), FromDIP(23))); + m_button_confirm->SetMinSize(wxSize(FromDIP(68), FromDIP(23))); + m_button_confirm->SetCornerRadius(12); + m_button_confirm->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {EndModal(wxCLOSE);}); + + sizer_button->Add(m_button_confirm, 0, wxALL, 5); + + sizer_main->Add(m_line_top, 0, wxEXPAND, 0); + sizer_main->Add(0, 0, 0, wxTOP, 20); + sizer_main->Add(sizer_bacis_text, 0, wxEXPAND | wxLEFT | wxRIGHT, 15); + sizer_main->Add(0, 0, 0, wxTOP, 6); + sizer_main->Add(sizer_link, 0, wxLEFT | wxRIGHT, 15); + sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, 8); + sizer_main->Add(sizer_help, 1, wxLEFT | wxRIGHT, 15); + sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, 8); + sizer_main->Add(sizer_button, 1, wxEXPAND | wxLEFT | wxRIGHT, 15); + sizer_main->Add(0, 0, 0, wxTOP, 18); + + SetSizer(sizer_main); + Layout(); + sizer_main->Fit(this); + Centre(wxBOTH); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index e62251af7d5..592eeb7345d 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -410,6 +410,22 @@ class Newer3mfVersionDialog : public DPIDialog wxStaticText *m_msg_text = nullptr; }; + +class NetworkErrorDialog : public DPIDialog +{ +public: + NetworkErrorDialog(wxWindow* parent); + ~NetworkErrorDialog() {}; + virtual void on_dpi_changed(const wxRect& suggested_rect) {}; + +private: + Label* m_text_basic; + wxHyperlinkCtrl* m_link_server_state; + Label* m_text_proposal; + wxHyperlinkCtrl* m_text_wiki; + Button* m_button_confirm; +}; + } } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 589a18aaa77..41ef02047a5 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2686,6 +2686,7 @@ struct Plater::priv //BBS: add popup object table logic bool PopupObjectTable(int object_id, int volume_id, const wxPoint& position); void on_action_send_to_printer(bool isall = false); + void on_action_send_bamcu_conect(SimpleEvent&); void on_action_send_to_multi_machine(SimpleEvent&); int update_print_required_data(Slic3r::DynamicPrintConfig config, Slic3r::Model model, Slic3r::PlateDataPtrs plate_data_list, std::string file_name, std::string file_path); private: @@ -3116,6 +3117,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) q->Bind(EVT_GLTOOLBAR_SEND_TO_PRINTER, &priv::on_action_export_to_sdcard, this); q->Bind(EVT_GLTOOLBAR_SEND_TO_PRINTER_ALL, &priv::on_action_export_to_sdcard_all, this); q->Bind(EVT_GLTOOLBAR_PRINT_MULTI_MACHINE, &priv::on_action_send_to_multi_machine, this); + q->Bind(EVT_GLTOOLBAR_SEND_BAMBU_CONNECT, &priv::on_action_send_bamcu_conect, this); q->Bind(EVT_GLCANVAS_PLATE_SELECT, &priv::on_plate_selected, this); q->Bind(EVT_DOWNLOAD_PROJECT, &priv::on_action_download_project, this); q->Bind(EVT_IMPORT_MODEL_ID, &priv::on_action_request_model_id, this); @@ -3248,14 +3250,14 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) wxGetApp().mainframe->Raise(); this->q->load_files(input_files); }); - + this->q->Bind(EVT_START_DOWNLOAD_OTHER_INSTANCE, [](StartDownloadOtherInstanceEvent& evt) { BOOST_LOG_TRIVIAL(trace) << "Received url from other instance event."; wxGetApp().mainframe->Raise(); for (size_t i = 0; i < evt.data.size(); ++i) { wxGetApp().start_download(evt.data[i]); } - + }); this->q->Bind(EVT_INSTANCE_GO_TO_FRONT, [this](InstanceGoToFrontEvent &) { bring_instance_forward(); @@ -3425,7 +3427,7 @@ void Plater::priv::select_view_3D(const std::string& name, bool no_slice) void Plater::priv::select_next_view_3D() { - + if (current_panel == view3D) wxGetApp().mainframe->select_tab(size_t(MainFrame::tpPreview)); else if (current_panel == preview) @@ -3624,7 +3626,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ int current_width, current_depth, current_height; if (input_files.empty()) { return std::vector(); } - + // SoftFever: ugly fix so we can exist pa calib mode background_process.fff_print()->calib_mode() = CalibMode::Calib_None; @@ -3823,7 +3825,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ // // Is there any modifier or advanced config data? // for (ModelVolume *model_volume : model_object->volumes) model_volume->config.reset(); // } - // } + // } else if (load_config && (file_version > app_version)) { if (config_substitutions.unrecogized_keys.size() > 0) { wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Found following keys unrecognized:"), @@ -3855,7 +3857,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ show_info(q, text, _L("Newer 3mf version")); } } - } + } else if (!load_config) { // reset config except color for (ModelObject *model_object : model.objects) { @@ -4118,14 +4120,14 @@ std::vector Plater::priv::load_files(const std::vector& input_ std::vector project_presets; bool is_xxx; Semver file_version; - + //ObjImportColorFn obj_color_fun=nullptr; auto obj_color_fun = [this, &path](std::vector &input_colors, bool is_single_color, std::vector &filament_ids, unsigned char &first_extruder_id) { if (!boost::iends_with(path.string(), ".obj")) { return; } const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); ObjColorDialog color_dlg(nullptr, input_colors, is_single_color, extruder_colours, filament_ids, first_extruder_id); - if (color_dlg.ShowModal() != wxID_OK) { + if (color_dlg.ShowModal() != wxID_OK) { filament_ids.clear(); } }; @@ -7202,6 +7204,38 @@ void Plater::priv::on_action_send_to_multi_machine(SimpleEvent&) m_send_multi_dlg->ShowModal(); } + +void Plater::priv::on_action_send_bamcu_conect(SimpleEvent&) +{ + auto gcodeResult = q->send_gcode(partplate_list.get_curr_plate_index(), [this](int export_stage, int current, int total, bool &cancel) {}); + + if (gcodeResult != 0) { + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":send_gcode failed\n"; + return; + } + + PrintPrepareData data; + q->get_print_job_data(&data); + + if (data._3mf_path.empty()) { + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":3mf path is empty\n"; + return; + } + + wxString filename = q->get_export_gcode_filename("", true, partplate_list.get_curr_plate_index() == PLATE_ALL_IDX ? true : false); + wxString filepath = wxString::FromUTF8(data._3mf_path.string()); + filepath.Replace("\\", "/"); + std::string filePath = "?version=v1.0.0&path=" + filepath.ToStdString() + "&name=" + filename.utf8_string(); + wxString url = "bambu-connect://import-file?path=" + Http::url_encode(filePath); + if (!wxLaunchDefaultBrowser(url)) { + GUI::MessageDialog msgdialog(nullptr, _L("Failed to start Bambu Farm Manager Client."), "", wxAPPLY | wxOK); + msgdialog.ShowModal(); + } + + return; +} + + void Plater::priv::on_action_print_plate_from_sdcard(SimpleEvent&) { if (q != nullptr) { @@ -7562,7 +7596,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt) const GLVolume* gl_volume = selection.get_first_volume(); const ModelVolume *model_volume = get_model_volume(*gl_volume, selection.get_model()->objects); menu = (model_volume != nullptr && model_volume->is_text()) ? menus.text_part_menu() : - (model_volume != nullptr && model_volume->is_svg()) ? menus.svg_part_menu() : + (model_volume != nullptr && model_volume->is_svg()) ? menus.svg_part_menu() : menus.part_menu(); } else menu = menus.multi_selection_menu(); @@ -7775,8 +7809,8 @@ void Plater::priv::update_title_dirty_status() wxGetApp().mainframe->topbar()->SetTitle(title); #else wxGetApp().mainframe->SetTitle(title); - wxGetApp().mainframe->update_title_colour_after_set_title(); -#endif + wxGetApp().mainframe->update_title_colour_after_set_title(); +#endif } void Plater::priv::set_project_filename(const wxString& filename) @@ -9464,8 +9498,8 @@ void Plater::_calib_pa_pattern(const Calib_Params& params) print_config.set_key_value( "internal_solid_infill_acceleration", new ConfigOptionFloatOrPercent(accel, false)); print_config.set_key_value( "top_surface_acceleration", new ConfigOptionFloat(accel)); print_config.set_key_value( "travel_acceleration", new ConfigOptionFloat(accel)); - - + + //Orca: find jerk value to use in the test if(print_config.option("default_jerk")->value > 0){ // we have set a jerk value auto jerk = print_config.option("outer_wall_jerk")->value; // get outer wall jerk @@ -9473,7 +9507,7 @@ void Plater::_calib_pa_pattern(const Calib_Params& params) jerk = print_config.option("inner_wall_jerk")->value; if (jerk == 0) // if inner wall jerk is not defined, get the default jerk jerk = print_config.option("default_jerk")->value; - + //Orca: Set jerk values. Again first layer jerk should not matter as it is reset to the travel jerk before the // first PA pattern is printed. print_config.set_key_value( "default_jerk", new ConfigOptionFloat(jerk)); @@ -9483,7 +9517,7 @@ void Plater::_calib_pa_pattern(const Calib_Params& params) print_config.set_key_value( "infill_jerk", new ConfigOptionFloat(jerk)); print_config.set_key_value( "travel_jerk", new ConfigOptionFloat(jerk)); } - + for (const auto& opt : SuggestedConfigCalibPAPattern().float_pairs) { print_config.set_key_value( opt.first, @@ -9688,7 +9722,7 @@ auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config // only enlarge if (xyScale > 1.2) { for (auto _obj : objects) - _obj->scale(xyScale, xyScale, zscale); + _obj->scale(xyScale, xyScale, zscale); } else { for (auto _obj : objects) @@ -9816,7 +9850,7 @@ void Plater::calib_temp(const Calib_Params& params) { wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); if (params.mode != CalibMode::Calib_Temp_Tower) return; - + add_model(false, Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.stl"); auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; auto start_temp = lround(params.start); @@ -9844,7 +9878,7 @@ void Plater::calib_temp(const Calib_Params& params) { cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepLower); } } - + // cut bottom obj_bb = model().objects[0]->bounding_box_exact(); block_count = lround((350 - params.start) / 5); @@ -9854,7 +9888,7 @@ void Plater::calib_temp(const Calib_Params& params) { cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepUpper); } } - + p->background_process.fff_print()->set_calib_params(params); } @@ -9892,7 +9926,7 @@ void Plater::calib_max_vol_speed(const Calib_Params& params) filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 }); filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{0.0}); - + obj_cfg.set_key_value("enable_overhang_speed", new ConfigOptionBool { false }); obj_cfg.set_key_value("wall_loops", new ConfigOptionInt(1)); obj_cfg.set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); @@ -11613,7 +11647,7 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st csgmesh.reserve(2 * mo.volumes.size()); bool has_splitable_volume = csg::model_to_csgmesh(mo, Transform3d::Identity(), std::back_inserter(csgmesh), csg::mpartsPositive | csg::mpartsNegative); - + std::string fail_msg = _u8L("Unable to perform boolean operation on model meshes. " "Only positive parts will be kept. You may fix the meshes and try again."); if (auto fail_reason_name = csg::check_csgmesh_booleans(Range{ std::begin(csgmesh), std::end(csgmesh) }); std::get<0>(fail_reason_name) != csg::BooleanFailReason::OK) { @@ -11936,7 +11970,7 @@ std::string create_unique_3mf_filepath(const std::string &file, const SvgFiles s is_unique = false; break; } - } + } } while (!is_unique); return path_in_3mf; } @@ -11989,7 +12023,7 @@ void publish(Model &model, SaveStrategy strategy) { "If you hit 'NO', all SVGs in the project will not be editable any more."), _L("Private protection"), wxYES_NO | wxICON_QUESTION); if (dialog.ShowModal() == wxID_NO){ - for (ModelObject *object : model.objects) + for (ModelObject *object : model.objects) for (ModelVolume *volume : object->volumes) if (volume->emboss_shape.has_value()) volume->emboss_shape.reset(); @@ -12008,7 +12042,7 @@ void publish(Model &model, SaveStrategy strategy) { // check whether original filename is already in: filename = get_file_name(svgfile->path); } - svgfile->path_in_3mf = create_unique_3mf_filepath(filename, svgfiles); + svgfile->path_in_3mf = create_unique_3mf_filepath(filename, svgfiles); } } } @@ -12312,7 +12346,7 @@ void Plater::reslice() // and notify user that he should leave it first. if (get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) return; - + // Stop the running (and queued) UI jobs and only proceed if they actually // get stopped. unsigned timeout_ms = 10000; @@ -13305,7 +13339,7 @@ void Plater::changed_object(ModelObject &object){ // update print p->schedule_background_process(); - + // Check outside bed get_current_canvas3D()->requires_check_outside_state(); } diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index a2a805a39f2..5cbf475ae8a 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -1437,7 +1437,7 @@ void ConfirmBeforeSendDialog::rescale() } InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent) - :DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("LAN Connection Failed (Sending print file)"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) + :DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("Connect the printer using IP and access code"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) { std::string icon_path = (boost::format("%1%/images/OrcaSlicerTitle.ico") % resources_dir()).str(); SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); @@ -1527,7 +1527,7 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent) StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered), std::pair(*wxWHITE, StateColor::Normal)); - m_button_ok = new Button(this, _L("Test")); + m_button_ok = new Button(this, _L("Connect")); m_button_ok->SetBackgroundColor(btn_bg_green); m_button_ok->SetBorderColor(*wxWHITE); m_button_ok->SetTextColor(wxColour(0xFFFFFE)); @@ -1552,7 +1552,7 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent) }); m_sizer_button->AddStretchSpacer(); - //m_sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5)); + m_sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5)); m_sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5)); m_sizer_button->Layout(); @@ -1632,12 +1632,12 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent) m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(4)); m_sizer_main_right->Add(m_input_area, 0, wxRIGHT|wxEXPAND, FromDIP(18)); m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(4)); - m_sizer_main_right->Add(m_button_ok, 0, wxRIGHT, FromDIP(18)); + //m_sizer_main_right->Add(m_button_ok, 0, wxRIGHT, FromDIP(18)); m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(4)); m_sizer_main_right->Add(m_test_right_msg, 0, wxRIGHT|wxEXPAND, FromDIP(18)); m_sizer_main_right->Add(m_test_wrong_msg, 0, wxRIGHT|wxEXPAND, FromDIP(18)); - m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(16)); + m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(4)); m_sizer_main_right->Add(m_status_bar->get_panel(), 0,wxRIGHT|wxEXPAND, FromDIP(18)); m_sizer_main_right->Layout(); @@ -1646,8 +1646,8 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent) m_sizer_main->Layout(); m_sizer_body->Add(m_line_top, 0, wxEXPAND, 0); - m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20)); - m_sizer_body->Add(m_sizer_main, 0, wxEXPAND, 0); + m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(4)); + m_sizer_body->Add(m_sizer_main, 0, wxRIGHT, FromDIP(10)); m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(4)); m_sizer_body->Add(m_sizer_msg, 0, wxLEFT|wxEXPAND, FromDIP(18)); m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(4)); @@ -1655,6 +1655,7 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent) m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(8)); m_sizer_body->Add(m_sizer_button, 0, wxRIGHT | wxEXPAND, FromDIP(25)); + m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(10)); m_sizer_body->Layout(); SetSizer(m_sizer_body); @@ -1665,24 +1666,33 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent) Move(wxPoint(GetScreenPosition().x, GetScreenPosition().y - FromDIP(50))); wxGetApp().UpdateDlgDarkUI(this); + closeTimer = new wxTimer(); + closeTimer->SetOwner(this); + Bind(wxEVT_TIMER, &InputIpAddressDialog::OnTimer, this); + Bind(EVT_CHECK_IP_ADDRESS_FAILED, &InputIpAddressDialog::on_check_ip_address_failed, this); Bind(EVT_CLOSE_IPADDRESS_DLG, [this](auto& e) { m_status_bar->reset(); EndModal(wxID_YES); }); - Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) {on_cancel();}); + Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) { + on_cancel(); + closeTimer->Stop(); + }); } void InputIpAddressDialog::on_cancel() { - m_worker->cancel_all(); - if (m_result == 0){ - this->EndModal(wxID_YES); - }else { - this->EndModal(wxID_CANCEL); + if (m_thread) { + m_thread->interrupt(); + m_thread->join(); + delete m_thread; + m_thread = nullptr; } + + EndModal(wxID_CANCEL); } @@ -1739,9 +1749,7 @@ void InputIpAddressDialog::update_test_msg(wxString msg,bool connected) m_test_wrong_msg->SetLabelText(msg); m_test_wrong_msg->SetMinSize(wxSize(FromDIP(352), -1)); m_test_wrong_msg->SetMaxSize(wxSize(FromDIP(352), -1)); - } - - + } } Layout(); @@ -1771,13 +1779,11 @@ void InputIpAddressDialog::on_ok(wxMouseEvent& evt) m_img_step3->Hide(); m_tip4->Hide(); m_trouble_shoot->Hide(); - Layout(); - Fit(); - wxString ip = m_input_ip->GetTextCtrl()->GetValue(); - wxString str_access_code = m_input_access_code->GetTextCtrl()->GetValue(); + std::string str_ip = m_input_ip->GetTextCtrl()->GetValue().ToStdString(); + std::string str_access_code = m_input_access_code->GetTextCtrl()->GetValue().ToStdString(); //check support function - if (!m_obj) return; + /*if (!m_obj) return; if (!m_obj->is_support_send_to_sdcard) { wxString input_str = wxString::Format("%s|%s", ip, str_access_code); auto event = wxCommandEvent(EVT_ENTER_IP_ADDRESS); @@ -1789,58 +1795,84 @@ void InputIpAddressDialog::on_ok(wxMouseEvent& evt) event_close.SetEventObject(this); wxPostEvent(this, event_close); return; - } + }*/ m_button_ok->Enable(false); m_button_ok->SetBackgroundColor(wxColour(0x90, 0x90, 0x90)); m_button_ok->SetBorderColor(wxColour(0x90, 0x90, 0x90)); - m_worker->wait_for_idle(); + Refresh(); + Layout(); + Fit(); - 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"; - m_worker->cancel_all(); - }); + m_thread = new boost::thread(boost::bind(&InputIpAddressDialog::workerThreadFunc, this, str_ip, str_access_code)); +} +void InputIpAddressDialog::workerThreadFunc(std::string str_ip, std::string str_access_code) +{ + update_test_msg(_L("connecting..."), true); + detectResult detectData; + auto result = wxGetApp().getAgent()->bind_detect(str_ip, "secure", detectData); + + if (result < 0) { + update_test_msg(wxEmptyString, true); + if (result == -1) { + update_test_msg(_L("Failed to connect to printer."), false); + } + else if (result == -2) { + update_test_msg(_L("Failed to publish login request."), false); + } + else if (result == -3) { + update_test_msg(_L("The device does not support using IP and Access Code for connection."), false); + } + Layout(); + Fit(); + return; + } - auto m_send_job = std::make_unique(m_obj->dev_id); - m_send_job->m_dev_ip = ip.ToStdString(); - m_send_job->m_access_code = str_access_code.ToStdString(); + if (detectData.bind_state == "occupied") { + update_test_msg(_L("The printer has already been bound."), false); + Layout(); + Fit(); + return; + } + if (detectData.connect_type == "cloud") { + update_test_msg(_L("The printer mode is incorrect, please switch to LAN Only."), false); + Layout(); + Fit(); + return; + } -#if !BBL_RELEASE_TO_PUBLIC - m_send_job->m_local_use_ssl_for_mqtt = wxGetApp().app_config->get("enable_ssl_for_mqtt") == "true" ? true : false; - m_send_job->m_local_use_ssl_for_ftp = wxGetApp().app_config->get("enable_ssl_for_ftp") == "true" ? true : false; -#else - m_send_job->m_local_use_ssl_for_mqtt = m_obj->local_use_ssl_for_mqtt; - m_send_job->m_local_use_ssl_for_ftp = m_obj->local_use_ssl_for_ftp; -#endif + DeviceManager* dev = wxGetApp().getDeviceManager(); + m_obj = dev->insert_local_device(detectData.dev_name, detectData.dev_id, str_ip, detectData.connect_type, detectData.bind_state, detectData.version, str_access_code); - m_send_job->connection_type = m_obj->connection_type(); - m_send_job->cloud_print_only = true; - m_send_job->has_sdcard = m_obj->has_sdcard(); - m_send_job->set_check_mode(); - m_send_job->set_project_name("verify_job"); - m_send_job->on_check_ip_address_fail([this](int result) { - this->check_ip_address_failed(result); - }); + if (m_obj) { + m_obj->set_user_access_code(str_access_code); + wxGetApp().getDeviceManager()->set_selected_machine(m_obj->dev_id); + } - m_send_job->on_check_ip_address_success([this, ip, str_access_code]() { - wxString input_str = wxString::Format("%s|%s", ip, str_access_code); - auto event = wxCommandEvent(EVT_ENTER_IP_ADDRESS); - event.SetString(input_str); - event.SetEventObject(this); - wxPostEvent(this, event); - m_result = 0; - - update_test_msg(_L("IP and Access Code Verified! You may close the window"), true); - - }); - replace_job(*m_worker, std::move(m_send_job)); + closeCount = 3; + update_test_msg(wxEmptyString, true); + update_test_msg(wxString::Format(_L("Printer binding successful. The dialog will close in %d seconds"), closeCount), true); + closeTimer->Start(1000); + + Layout(); + Fit(); +} + +void InputIpAddressDialog::OnTimer(wxTimerEvent& event) { + if (closeCount > 0) { + closeCount--; + update_test_msg(wxString::Format(_L("Printer binding successful. The dialog will close in %d seconds"), closeCount), true); + Refresh(); + } + else { + closeTimer->Stop(); + EndModal(wxID_CLOSE); + } } void InputIpAddressDialog::check_ip_address_failed(int result) @@ -1876,8 +1908,16 @@ void InputIpAddressDialog::on_text(wxCommandEvent& evt) { auto str_ip = m_input_ip->GetTextCtrl()->GetValue(); auto str_access_code = m_input_access_code->GetTextCtrl()->GetValue(); + bool invalid_access_code = true; - if (isIp(str_ip.ToStdString()) && str_access_code.Length() == 8) { + for (char c : str_access_code) { + if (!('0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z')) { + invalid_access_code = false; + return; + } + } + + if (isIp(str_ip.ToStdString()) && str_access_code.Length() == 8 && invalid_access_code) { m_button_ok->Enable(true); StateColor btn_bg_green(std::pair(wxColour(0, 137, 123), StateColor::Pressed), std::pair(wxColour(38, 166, 154), StateColor::Hovered), std::pair(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); diff --git a/src/slic3r/GUI/ReleaseNote.hpp b/src/slic3r/GUI/ReleaseNote.hpp index d8ad66644c8..1ed68c6740f 100644 --- a/src/slic3r/GUI/ReleaseNote.hpp +++ b/src/slic3r/GUI/ReleaseNote.hpp @@ -277,6 +277,8 @@ class InputIpAddressDialog : public DPIDialog wxString comfirm_before_enter_text; wxString comfirm_after_enter_text; + boost::thread* m_thread{nullptr}; + std::string m_ip; Label* m_tip1{ nullptr }; Label* m_tip2{ nullptr }; @@ -298,6 +300,8 @@ class InputIpAddressDialog : public DPIDialog wxStaticBitmap* m_img_step2{ nullptr }; wxStaticBitmap* m_img_step3{ nullptr }; wxHyperlinkCtrl* m_trouble_shoot{ nullptr }; + wxTimer* closeTimer{ nullptr }; + int closeCount{3}; bool m_show_access_code{ false }; int m_result; std::shared_ptr m_status_bar; @@ -311,6 +315,8 @@ class InputIpAddressDialog : public DPIDialog void check_ip_address_failed(int result); void on_check_ip_address_failed(wxCommandEvent& evt); void on_ok(wxMouseEvent& evt); + void workerThreadFunc(std::string str_ip, std::string str_access_code); + void OnTimer(wxTimerEvent& event); void on_text(wxCommandEvent& evt); void on_dpi_changed(const wxRect& suggested_rect) override; }; diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index e6b2ac81c57..49b07e86a31 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -400,11 +400,13 @@ SelectMachinePopup::SelectMachinePopup(wxWindow *parent) m_sizer_other_devices = new wxBoxSizer(wxVERTICAL); - m_panel_ping_code = new PinCodePanel(m_scrolledWindow, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_ITEM_SIZE); + m_panel_ping_code = new PinCodePanel(m_scrolledWindow, 0, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_ITEM_SIZE); + m_panel_direct_connection = new PinCodePanel(m_scrolledWindow, 1, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_ITEM_SIZE); m_sizxer_scrolledWindow->Add(own_title, 0, wxEXPAND | wxLEFT, FromDIP(15)); m_sizxer_scrolledWindow->Add(m_sizer_my_devices, 0, wxEXPAND, 0); m_sizxer_scrolledWindow->Add(m_panel_ping_code, 0, wxEXPAND, 0); + m_sizxer_scrolledWindow->Add(m_panel_direct_connection, 0, wxEXPAND, 0); m_sizxer_scrolledWindow->Add(other_title, 0, wxEXPAND | wxLEFT, FromDIP(15)); m_sizxer_scrolledWindow->Add(m_sizer_other_devices, 0, wxEXPAND, 0); @@ -879,14 +881,16 @@ void SelectMachinePopup::OnLeftUp(wxMouseEvent &event) //pin code auto pc_rect = m_panel_ping_code->ClientToScreen(wxPoint(0, 0)); if (mouse_pos.x > pc_rect.x && mouse_pos.y > pc_rect.y && mouse_pos.x < (pc_rect.x + m_panel_ping_code->GetSize().x) && mouse_pos.y < (pc_rect.y + m_panel_ping_code->GetSize().y)) { - /*wxMouseEvent event(wxEVT_LEFT_UP); - auto tag_pos = m_panel_ping_code->ScreenToClient(mouse_pos); - event.SetPosition(tag_pos); - event.SetEventObject(m_panel_ping_code); - wxPostEvent(m_panel_ping_code, event);*/ wxGetApp().popup_ping_bind_dialog(); } + //bind with access code + auto dc_rect = m_panel_direct_connection->ClientToScreen(wxPoint(0, 0)); + if (mouse_pos.x > dc_rect.x && mouse_pos.y > dc_rect.y && mouse_pos.x < (dc_rect.x + m_panel_direct_connection->GetSize().x) && mouse_pos.y < (dc_rect.y + m_panel_direct_connection->GetSize().y)) { + InputIpAddressDialog dlgo; + dlgo.ShowModal(); + } + //hyper link auto h_rect = m_hyperlink->ClientToScreen(wxPoint(0, 0)); if (mouse_pos.x > h_rect.x && mouse_pos.y > h_rect.y && mouse_pos.x < (h_rect.x + m_hyperlink->GetSize().x) && mouse_pos.y < (h_rect.y + m_hyperlink->GetSize().y)) { @@ -1450,30 +1454,6 @@ void SelectMachineDialog::init_bind() m_comboBox_printer->SetValue(obj->dev_name + "(LAN)"); } } - /*else if (e.GetInt() == 1 && (m_print_type == PrintFromType::FROM_SDCARD_VIEW)) { - on_send_print(); - } - else if (e.GetInt() == -2 && (m_print_type == PrintFromType::FROM_SDCARD_VIEW)) { - show_status(PrintDialogStatus::PrintStatusInit); - prepare_mode(); - MessageDialog msg_wingow(nullptr, _L("Printer local connection failed, please try again."), "", wxAPPLY | wxOK); - msg_wingow.ShowModal(); - } - else if (e.GetInt() == 5 && (m_print_type == PrintFromType::FROM_SDCARD_VIEW)) { - show_status(PrintDialogStatus::PrintStatusInit); - prepare_mode(); - - DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); - if (!dev) return; - ConnectPrinterDialog dlg(wxGetApp().mainframe, wxID_ANY, _L("Input access code")); - dlg.go_connect_printer(false); - if (dev->get_selected_machine()) { - dlg.set_machine_object(dev->get_selected_machine()); - if (dlg.ShowModal() == wxID_OK) { - this->connect_printer_mqtt(); - } - } - }*/ }); m_bitmap_last_plate->Bind(wxEVT_LEFT_DOWN, [this](auto& e) { @@ -3412,6 +3392,7 @@ void SelectMachineDialog::update_show_status() } if (!dev) return; dev->check_pushing(); + PartPlate* plate = m_plater->get_partplate_list().get_curr_plate(); // blank plate has no valid gcode file @@ -3434,6 +3415,7 @@ void SelectMachineDialog::update_show_status() } return; } + agent->install_device_cert(obj_->dev_id, obj_->is_lan_mode_printer()); /* check cloud machine connections */ if (!obj_->is_lan_mode_printer()) { @@ -4854,7 +4836,7 @@ void EditDevNameDialog::on_edit_name(wxCommandEvent &e) ThumbnailPanel::~ThumbnailPanel() {} - PinCodePanel::PinCodePanel(wxWindow* parent, wxWindowID winid /*= wxID_ANY*/, const wxPoint& pos /*= wxDefaultPosition*/, const wxSize& size /*= wxDefaultSize*/) + PinCodePanel::PinCodePanel(wxWindow* parent, int type, wxWindowID winid /*= wxID_ANY*/, const wxPoint& pos /*= wxDefaultPosition*/, const wxSize& size /*= wxDefaultSize*/) { wxPanel::Create(parent, winid, pos, SELECT_MACHINE_ITEM_SIZE); Bind(wxEVT_PAINT, &PinCodePanel::OnPaint, this); @@ -4862,6 +4844,7 @@ void EditDevNameDialog::on_edit_name(wxCommandEvent &e) SetMaxSize(SELECT_MACHINE_ITEM_SIZE); SetMinSize(SELECT_MACHINE_ITEM_SIZE); + m_type = type; m_bitmap = ScalableBitmap(this, "bind_device_ping_code",10); this->Bind(wxEVT_ENTER_WINDOW, &PinCodePanel::on_mouse_enter, this); @@ -4899,12 +4882,15 @@ void EditDevNameDialog::on_edit_name(wxCommandEvent &e) void PinCodePanel::doRender(wxDC& dc) { auto size = GetSize(); - dc.DrawBitmap(m_bitmap.bmp(), wxPoint(FromDIP(20), (size.y - m_bitmap.GetBmpSize().y) / 2)); + dc.DrawBitmap(m_bitmap.bmp(), wxPoint(FromDIP(12), (size.y - m_bitmap.GetBmpSize().y) / 2)); dc.SetFont(::Label::Head_13); - dc.SetTextForeground(StateColor::darkModeColorFor(wxColour("#262E30"))); // ORCA fix text not visible on dark theme - wxString txt = _L("Bind with Pin Code"); + dc.SetTextForeground(wxColour(38, 46, 48)); + wxString txt; + if (m_type == 0) { txt = _L("Bind with Pin Code"); } + else if (m_type == 1) { txt = _L("Bind with Access Code"); } + auto txt_size = dc.GetTextExtent(txt); - dc.DrawText(txt, wxPoint(FromDIP(40), (size.y - txt_size.y) / 2)); + dc.DrawText(txt, wxPoint(FromDIP(28), (size.y - txt_size.y) / 2)); if (m_hover) { dc.SetPen(SELECT_MACHINE_BRAND); @@ -4927,7 +4913,13 @@ void EditDevNameDialog::on_edit_name(wxCommandEvent &e) void PinCodePanel::on_mouse_left_up(wxMouseEvent& evt) { - wxGetApp().popup_ping_bind_dialog(); + if (m_type == 0) { + wxGetApp().popup_ping_bind_dialog(); + } + else if (m_type == 1) { + InputIpAddressDialog dlgo; + dlgo.ShowModal(); + } } }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp index 16da5e05d57..6752e2a8691 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -195,7 +195,7 @@ class MachineObjectPanel : public wxPanel #define SELECT_MACHINE_POPUP_SIZE wxSize(FromDIP(216), FromDIP(364)) #define SELECT_MACHINE_LIST_SIZE wxSize(FromDIP(212), FromDIP(360)) -#define SELECT_MACHINE_ITEM_SIZE wxSize(FromDIP(182), FromDIP(35)) +#define SELECT_MACHINE_ITEM_SIZE wxSize(FromDIP(190), FromDIP(35)) #define SELECT_MACHINE_GREY900 wxColour(38, 46, 48) #define SELECT_MACHINE_GREY600 wxColour(144,144,144) #define SELECT_MACHINE_GREY400 wxColour(206, 206, 206) @@ -214,6 +214,7 @@ class PinCodePanel : public wxPanel { public: PinCodePanel(wxWindow* parent, + int type, wxWindowID winid = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); @@ -221,6 +222,7 @@ class PinCodePanel : public wxPanel ScalableBitmap m_bitmap; bool m_hover{false}; + int m_type{0}; void OnPaint(wxPaintEvent& event); void render(wxDC& dc); @@ -254,6 +256,7 @@ class SelectMachinePopup : public PopupWindow int m_my_devices_count{0}; int m_other_devices_count{0}; PinCodePanel* m_panel_ping_code{nullptr}; + PinCodePanel* m_panel_direct_connection{nullptr}; wxWindow* m_placeholder_panel{nullptr}; wxHyperlinkCtrl* m_hyperlink{nullptr}; Label* m_ping_code_text{nullptr}; diff --git a/src/slic3r/Utils/Http.hpp b/src/slic3r/Utils/Http.hpp index 872ec6cbdfb..545af22e650 100644 --- a/src/slic3r/Utils/Http.hpp +++ b/src/slic3r/Utils/Http.hpp @@ -30,6 +30,7 @@ enum HttpErrorCode HttpErrorTimeout = 13, HttpErrorResourcesExhaust = 14, HttpErrorVersionLimited = 15, + HttpErrorCertRevoked = 101, }; /// Represetns a Http request diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp index 1ffdf0464e4..d4d4ac98fe9 100644 --- a/src/slic3r/Utils/NetworkAgent.cpp +++ b/src/slic3r/Utils/NetworkAgent.cpp @@ -62,6 +62,8 @@ func_send_message NetworkAgent::send_message_ptr = nullptr; func_connect_printer NetworkAgent::connect_printer_ptr = nullptr; func_disconnect_printer NetworkAgent::disconnect_printer_ptr = nullptr; func_send_message_to_printer NetworkAgent::send_message_to_printer_ptr = nullptr; +func_check_cert NetworkAgent::check_cert_ptr = nullptr; +func_install_device_cert NetworkAgent::install_device_cert_ptr = nullptr; func_start_discovery NetworkAgent::start_discovery_ptr = nullptr; func_change_user NetworkAgent::change_user_ptr = nullptr; func_is_user_login NetworkAgent::is_user_login_ptr = nullptr; @@ -75,6 +77,8 @@ func_build_logout_cmd NetworkAgent::build_logout_cmd_ptr = nullptr func_build_login_info NetworkAgent::build_login_info_ptr = nullptr; func_get_model_id_from_desgin_id NetworkAgent::get_model_id_from_desgin_id_ptr = nullptr; func_ping_bind NetworkAgent::ping_bind_ptr = nullptr; +func_bind_detect NetworkAgent::bind_detect_ptr = nullptr; +func_set_server_callback NetworkAgent::set_server_callback_ptr = nullptr; func_bind NetworkAgent::bind_ptr = nullptr; func_unbind NetworkAgent::unbind_ptr = nullptr; func_get_bambulab_host NetworkAgent::get_bambulab_host_ptr = nullptr; @@ -145,6 +149,31 @@ NetworkAgent::~NetworkAgent() BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", this %1%, network_agent=%2%, destroy_agent_ptr=%3%, ret %4%")%this %network_agent %destroy_agent_ptr %ret; } +std::string NetworkAgent::get_libpath_in_current_directory(std::string library_name) +{ + std::string lib_path; +#if defined(_MSC_VER) || defined(_WIN32) + wchar_t file_name[512]; + DWORD ret = GetModuleFileNameW(NULL, file_name, 512); + if (!ret) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", GetModuleFileNameW return error, can not Load Library for %1%") % library_name; + return lib_path; + } + int size_needed = ::WideCharToMultiByte(0, 0, file_name, wcslen(file_name), nullptr, 0, nullptr, nullptr); + std::string file_name_string(size_needed, 0); + ::WideCharToMultiByte(0, 0, file_name, wcslen(file_name), file_name_string.data(), size_needed, nullptr, nullptr); + + std::size_t found = file_name_string.find("bambu-studio.exe"); + if (found == (file_name_string.size() - 16)) { + lib_path = library_name + ".dll"; + lib_path = file_name_string.replace(found, 16, lib_path); + } +#else +#endif + return lib_path; +} + + int NetworkAgent::initialize_network_module(bool using_backup) { //int ret = -1; @@ -159,7 +188,7 @@ int NetworkAgent::initialize_network_module(bool using_backup) //first load the library #if defined(_MSC_VER) || defined(_WIN32) - library = plugin_folder.string() + "/" + std::string(BAMBU_NETWORK_LIBRARY) + ".dll"; + library = plugin_folder.string() + "\\" + std::string(BAMBU_NETWORK_LIBRARY) + ".dll"; wchar_t lib_wstr[128]; memset(lib_wstr, 0, sizeof(lib_wstr)); ::MultiByteToWideChar(CP_UTF8, NULL, library.c_str(), strlen(library.c_str())+1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0])); @@ -170,6 +199,19 @@ int NetworkAgent::initialize_network_module(bool using_backup) ::MultiByteToWideChar(CP_UTF8, NULL, library.c_str(), strlen(library.c_str()) + 1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0])); netwoking_module = LoadLibrary(lib_wstr); }*/ + if (!netwoking_module) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", try load library directly from current directory"); + + std::string library_path = get_libpath_in_current_directory(std::string(BAMBU_NETWORK_LIBRARY)); + if (library_path.empty()) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", can not get path in current directory for %1%") % BAMBU_NETWORK_LIBRARY; + return -1; + } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", current path %1%")%library_path; + memset(lib_wstr, 0, sizeof(lib_wstr)); + ::MultiByteToWideChar(CP_UTF8, NULL, library_path.c_str(), strlen(library_path.c_str())+1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0])); + netwoking_module = LoadLibrary(lib_wstr); + } #else #if defined(__WXMAC__) library = plugin_folder.string() + "/" + std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + ".dylib"; @@ -234,6 +276,8 @@ int NetworkAgent::initialize_network_module(bool using_backup) connect_printer_ptr = reinterpret_cast(get_network_function("bambu_network_connect_printer")); disconnect_printer_ptr = reinterpret_cast(get_network_function("bambu_network_disconnect_printer")); send_message_to_printer_ptr = reinterpret_cast(get_network_function("bambu_network_send_message_to_printer")); + check_cert_ptr = reinterpret_cast(get_network_function("bambu_network_update_cert")); + install_device_cert_ptr = reinterpret_cast(get_network_function("bambu_network_install_device_cert")); start_discovery_ptr = reinterpret_cast(get_network_function("bambu_network_start_discovery")); change_user_ptr = reinterpret_cast(get_network_function("bambu_network_change_user")); is_user_login_ptr = reinterpret_cast(get_network_function("bambu_network_is_user_login")); @@ -246,6 +290,8 @@ int NetworkAgent::initialize_network_module(bool using_backup) build_logout_cmd_ptr = reinterpret_cast(get_network_function("bambu_network_build_logout_cmd")); build_login_info_ptr = reinterpret_cast(get_network_function("bambu_network_build_login_info")); ping_bind_ptr = reinterpret_cast(get_network_function("bambu_network_ping_bind")); + bind_detect_ptr = reinterpret_cast(get_network_function("bambu_network_bind_detect")); + set_server_callback_ptr = reinterpret_cast(get_network_function("bambu_network_set_server_callback")); get_model_id_from_desgin_id_ptr = reinterpret_cast(get_network_function("bambu_network_get_model_id_from_desgin_id")); bind_ptr = reinterpret_cast(get_network_function("bambu_network_bind")); unbind_ptr = reinterpret_cast(get_network_function("bambu_network_unbind")); @@ -356,6 +402,7 @@ int NetworkAgent::unload_network_module() connect_printer_ptr = nullptr; disconnect_printer_ptr = nullptr; send_message_to_printer_ptr = nullptr; + check_cert_ptr = nullptr; start_discovery_ptr = nullptr; change_user_ptr = nullptr; is_user_login_ptr = nullptr; @@ -446,12 +493,18 @@ void* NetworkAgent::get_bambu_source_entry() memset(lib_wstr, 0, sizeof(lib_wstr)); ::MultiByteToWideChar(CP_UTF8, NULL, library.c_str(), strlen(library.c_str())+1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0])); source_module = LoadLibrary(lib_wstr); - /*if (!source_module) { - library = std::string(BAMBU_SOURCE_LIBRARY) + ".dll"; + if (!source_module) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", try load BambuSource directly from current directory"); + std::string library_path = get_libpath_in_current_directory(std::string(BAMBU_SOURCE_LIBRARY)); + if (library_path.empty()) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", can not get path in current directory for %1%") % BAMBU_SOURCE_LIBRARY; + return source_module; + } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", current path %1%")%library_path; memset(lib_wstr, 0, sizeof(lib_wstr)); - ::MultiByteToWideChar(CP_UTF8, NULL, library.c_str(), strlen(library.c_str()) + 1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0])); + ::MultiByteToWideChar(CP_UTF8, NULL, library_path.c_str(), strlen(library_path.c_str()) + 1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0])); source_module = LoadLibrary(lib_wstr); - }*/ + } #else #if defined(__WXMAC__) library = plugin_folder.string() + "/" + std::string("lib") + std::string(BAMBU_SOURCE_LIBRARY) + ".dylib"; @@ -805,11 +858,11 @@ int NetworkAgent::stop_device_subscribe() return ret; } -int NetworkAgent::send_message(std::string dev_id, std::string json_str, int qos) +int NetworkAgent::send_message(std::string dev_id, std::string json_str, int qos, int flag) { int ret = 0; if (network_agent && send_message_ptr) { - ret = send_message_ptr(network_agent, dev_id, json_str, qos); + ret = send_message_ptr(network_agent, dev_id, json_str, qos, flag); if (ret) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%, dev_id=%3%, json_str=%4%, qos=%5%")%network_agent %ret %dev_id %json_str %qos; } @@ -839,11 +892,11 @@ int NetworkAgent::disconnect_printer() return ret; } -int NetworkAgent::send_message_to_printer(std::string dev_id, std::string json_str, int qos) +int NetworkAgent::send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag) { int ret = 0; if (network_agent && send_message_to_printer_ptr) { - ret = send_message_to_printer_ptr(network_agent, dev_id, json_str, qos); + ret = send_message_to_printer_ptr(network_agent, dev_id, json_str, qos, flag); if (ret) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%, dev_id=%3%, json_str=%4%, qos=%5%") %network_agent %ret %dev_id %json_str %qos; @@ -851,6 +904,24 @@ int NetworkAgent::send_message_to_printer(std::string dev_id, std::string json_s return ret; } +int NetworkAgent::check_cert() +{ + int ret = 0; + if (network_agent && check_cert_ptr) { + ret = check_cert_ptr(network_agent); + if (ret) + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") % network_agent % ret; + } + return ret; +} + +void NetworkAgent::install_device_cert(std::string dev_id, bool lan_only) +{ + if (network_agent && install_device_cert_ptr) { + install_device_cert_ptr(network_agent, dev_id, lan_only); + } +} + bool NetworkAgent::start_discovery(bool start, bool sending) { bool ret = false; @@ -881,11 +952,11 @@ bool NetworkAgent::is_user_login() return ret; } -int NetworkAgent::user_logout() +int NetworkAgent::user_logout(bool request) { int ret = 0; if (network_agent && user_logout_ptr) { - ret = user_logout_ptr(network_agent); + ret = user_logout_ptr(network_agent, request); if (ret) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%")%network_agent %ret; } @@ -979,6 +1050,30 @@ int NetworkAgent::ping_bind(std::string ping_code) return ret; } +int NetworkAgent::bind_detect(std::string dev_ip, std::string sec_link, detectResult& detect) +{ + int ret = 0; + if (network_agent && bind_detect_ptr) { + ret = bind_detect_ptr(network_agent, dev_ip, sec_link, detect); + if (ret) + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%, dev_ip=%3%") + % network_agent % ret % dev_ip; + } + return ret; +} + +int NetworkAgent::set_server_callback(OnServerErrFn fn) +{ + int ret = 0; + if (network_agent && set_server_callback_ptr) { + ret = set_server_callback_ptr(network_agent, fn); + if (ret) + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") + % network_agent % ret; + } + return ret; +} + int NetworkAgent::bind(std::string dev_ip, std::string dev_id, std::string sec_link, std::string timezone, bool improved, OnUpdateStatusFn update_fn) { int ret = 0; diff --git a/src/slic3r/Utils/NetworkAgent.hpp b/src/slic3r/Utils/NetworkAgent.hpp index 59663fcb0b6..6c7978e8140 100644 --- a/src/slic3r/Utils/NetworkAgent.hpp +++ b/src/slic3r/Utils/NetworkAgent.hpp @@ -38,14 +38,16 @@ typedef int (*func_del_subscribe)(void *agent, std::vector dev_list typedef void (*func_enable_multi_machine)(void *agent, bool enable); typedef int (*func_start_device_subscribe)(void* agent); typedef int (*func_stop_device_subscribe)(void* agent); -typedef int (*func_send_message)(void *agent, std::string dev_id, std::string json_str, int qos); +typedef int (*func_send_message)(void *agent, std::string dev_id, std::string json_str, int qos, int flag); typedef int (*func_connect_printer)(void *agent, std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl); typedef int (*func_disconnect_printer)(void *agent); -typedef int (*func_send_message_to_printer)(void *agent, std::string dev_id, std::string json_str, int qos); +typedef int (*func_send_message_to_printer)(void *agent, std::string dev_id, std::string json_str, int qos, int flag); +typedef int (*func_check_cert)(void* agent); +typedef void (*func_install_device_cert)(void* agent, std::string dev_id, bool lan_only); typedef bool (*func_start_discovery)(void *agent, bool start, bool sending); typedef int (*func_change_user)(void *agent, std::string user_info); typedef bool (*func_is_user_login)(void *agent); -typedef int (*func_user_logout)(void *agent); +typedef int (*func_user_logout)(void *agent, bool request); typedef std::string (*func_get_user_id)(void *agent); typedef std::string (*func_get_user_name)(void *agent); typedef std::string (*func_get_user_avatar)(void *agent); @@ -55,6 +57,8 @@ typedef std::string (*func_build_logout_cmd)(void *agent); typedef std::string (*func_build_login_info)(void *agent); typedef int (*func_get_model_id_from_desgin_id)(void *agent, std::string& desgin_id, std::string& model_id); typedef int (*func_ping_bind)(void *agent, std::string ping_code); +typedef int (*func_bind_detect)(void *agent, std::string dev_ip, std::string sec_link, detectResult& detect); +typedef int (*func_set_server_callback)(void *agent, OnServerErrFn fn); typedef int (*func_bind)(void *agent, std::string dev_ip, std::string dev_id, std::string sec_link, std::string timezone, bool improved, OnUpdateStatusFn update_fn); typedef int (*func_unbind)(void *agent, std::string dev_id); typedef std::string (*func_get_bambulab_host)(void *agent); @@ -110,11 +114,13 @@ typedef int (*func_get_model_mall_rating_result)(void *agent, int job_id, std::s typedef int (*func_get_mw_user_preference)(void *agent, std::function callback); typedef int (*func_get_mw_user_4ulist)(void *agent, int seed, int limit, std::function callback); + //the NetworkAgent class class NetworkAgent { public: + static std::string get_libpath_in_current_directory(std::string library_name); static int initialize_network_module(bool using_backup = false); static int unload_network_module(); #if defined(_MSC_VER) || defined(_WIN32) @@ -154,14 +160,16 @@ class NetworkAgent void enable_multi_machine(bool enable); int start_device_subscribe(); int stop_device_subscribe(); - int send_message(std::string dev_id, std::string json_str, int qos); + int send_message(std::string dev_id, std::string json_str, int qos, int flag); int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl); int disconnect_printer(); - int send_message_to_printer(std::string dev_id, std::string json_str, int qos); + int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag); + int check_cert(); + void install_device_cert(std::string dev_id, bool lan_only); bool start_discovery(bool start, bool sending); int change_user(std::string user_info); bool is_user_login(); - int user_logout(); + int user_logout(bool request = false); std::string get_user_id(); std::string get_user_name(); std::string get_user_avatar(); @@ -171,6 +179,8 @@ class NetworkAgent std::string build_login_info(); int get_model_id_from_desgin_id(std::string& desgin_id, std::string& model_id); int ping_bind(std::string ping_code); + int bind_detect(std::string dev_ip, std::string sec_link, detectResult& detect); + int set_server_callback(OnServerErrFn fn); int bind(std::string dev_ip, std::string dev_id, std::string sec_link, std::string timezone, bool improved, OnUpdateStatusFn update_fn); int unbind(std::string dev_id); std::string get_bambulab_host(); @@ -224,6 +234,7 @@ class NetworkAgent int get_mw_user_preference(std::function callback); int get_mw_user_4ulist(int seed, int limit, std::function callback); + void *get_network_agent() { return network_agent; } private: bool enable_track = false; @@ -264,6 +275,8 @@ class NetworkAgent static func_connect_printer connect_printer_ptr; static func_disconnect_printer disconnect_printer_ptr; static func_send_message_to_printer send_message_to_printer_ptr; + static func_check_cert check_cert_ptr; + static func_install_device_cert install_device_cert_ptr; static func_start_discovery start_discovery_ptr; static func_change_user change_user_ptr; static func_is_user_login is_user_login_ptr; @@ -277,6 +290,8 @@ class NetworkAgent static func_build_login_info build_login_info_ptr; static func_get_model_id_from_desgin_id get_model_id_from_desgin_id_ptr; static func_ping_bind ping_bind_ptr; + static func_bind_detect bind_detect_ptr; + static func_set_server_callback set_server_callback_ptr; static func_bind bind_ptr; static func_unbind unbind_ptr; static func_get_bambulab_host get_bambulab_host_ptr; diff --git a/src/slic3r/Utils/bambu_networking.hpp b/src/slic3r/Utils/bambu_networking.hpp index c4d992bcf14..4aa6001cabd 100644 --- a/src/slic3r/Utils/bambu_networking.hpp +++ b/src/slic3r/Utils/bambu_networking.hpp @@ -36,6 +36,7 @@ namespace BBL { #define BAMBU_NETWORK_ERR_PARSE_CONFIG_FAILED -23 #define BAMBU_NETWORK_ERR_NO_CORRESPONDING_BUCKET -24 #define BAMBU_NETWORK_ERR_GET_INSTANCE_ID_FAILED -25 +#define BAMBU_NETWORK_SIGNED_ERROR -26 //bind error #define BAMBU_NETWORK_ERR_BIND_CREATE_SOCKET_FAILED -1010 //failed to create socket @@ -78,6 +79,7 @@ namespace BBL { #define BAMBU_NETWORK_ERR_PRINT_SP_PATCH_PROJECT_FAILED -3110 //failed to patch project #define BAMBU_NETWORK_ERR_PRINT_SP_POST_TASK_FAILED -3120 //failed to post task #define BAMBU_NETWORK_ERR_PRINT_SP_WAIT_PRINTER_FAILED -3130 //failed to wait the ack from printer +#define BAMBU_NETOWRK_ERR_PRINT_SP_ENC_FLAG_NOT_READY -3140 //failed to get flag info //start_local_print error #define BAMBU_NETWORK_ERR_PRINT_LP_FILE_OVER_SIZE -4010 //the size of the uploaded file cannot exceed 1 GB @@ -95,7 +97,7 @@ namespace BBL { #define BAMBU_NETWORK_LIBRARY "bambu_networking" #define BAMBU_NETWORK_AGENT_NAME "bambu_network_agent" -#define BAMBU_NETWORK_AGENT_VERSION "01.09.02.05" +#define BAMBU_NETWORK_AGENT_VERSION "01.10.02.05" //iot preset type strings #define IOT_PRINTER_TYPE_STRING "printer" @@ -138,6 +140,9 @@ typedef std::function ResultFn; typedef std::function CancelFn; typedef std::function info)> CheckFn; +//err callbacks +typedef std::function OnServerErrFn; + enum SendingPrintJobStage { PrintingStageCreate = 0, PrintingStageUpload = 1, @@ -172,6 +177,17 @@ enum ConnectStatus { ConnectStatusLost = 2, }; +struct detectResult { + std::string result_msg; + std::string command; + std::string dev_id; + std::string model_id; + std::string dev_name; + std::string version; + std::string bind_state; + std::string connect_type; +}; + /* print job*/ struct PrintParams { /* basic info */ @@ -239,6 +255,13 @@ struct CertificateInformation { std::string serial_number; }; +enum class MessageFlag : int +{ + MSG_FLAG_NONE = 0, + MSG_SIGN = 1 << 0, + MSG_ENCRYPT = 1 << 1, +}; + } #endif diff --git a/version.inc b/version.inc index 7eb37fdde40..f7523a00a0e 100644 --- a/version.inc +++ b/version.inc @@ -17,4 +17,4 @@ set(ORCA_VERSION_MAJOR ${CMAKE_MATCH_1}) set(ORCA_VERSION_MINOR ${CMAKE_MATCH_2}) set(ORCA_VERSION_PATCH ${CMAKE_MATCH_3}) -set(SLIC3R_VERSION "01.09.05.51") +set(SLIC3R_VERSION "01.10.02.51")