From 859bc9c7864b441ce0cb95e7318df3becb17cc7c Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 26 Apr 2024 15:05:30 +0200 Subject: [PATCH 01/28] Use printer_variant to compare nozzle diameter in connect printer state. Do not concider models without nozzle. --- src/slic3r/GUI/PresetComboBoxes.cpp | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 0c57f8ce9f..9158fd04b6 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -932,19 +932,11 @@ static std::string get_connect_state_suffix_for_printer(const Preset& printer_pr // process real data from Connect if (auto printer_state_map = wxGetApp().plater()->get_user_account()->get_printer_state_map(); !printer_state_map.empty()) { - // printer_state_map has only one nozzle value. Take a first value from "nozzle_diameter" opt. - std::string nozzle_diameter_serialized; - if (printer_preset.config.has("nozzle_diameter")) { - nozzle_diameter_serialized = dynamic_cast(printer_preset.config.option("nozzle_diameter"))->serialize(); - if (size_t comma = nozzle_diameter_serialized.find(','); comma != std::string::npos) - nozzle_diameter_serialized = nozzle_diameter_serialized.substr(0, comma); - } for (const auto& [printer_model_nozzle_pair, states] : printer_state_map) { if (printer_model_nozzle_pair.first == printer_preset.config.opt_string("printer_model") - && (printer_model_nozzle_pair.second.empty() - || printer_model_nozzle_pair.second == nozzle_diameter_serialized) - ) { + && printer_model_nozzle_pair.second == printer_preset.config.opt_string("printer_variant")) + { PrinterStatesCount states_cnt = get_printe_states_count(states); if (states_cnt.available_cnt > 0) @@ -963,19 +955,11 @@ static wxString get_connect_info_line(const Preset& printer_preset) { if (auto printer_state_map = wxGetApp().plater()->get_user_account()->get_printer_state_map(); !printer_state_map.empty()) { - // printer_state_map has only one nozzle value. Take a first value from "nozzle_diameter" opt. - std::string nozzle_diameter_serialized; - if (printer_preset.config.has("nozzle_diameter")) { - nozzle_diameter_serialized = dynamic_cast(printer_preset.config.option("nozzle_diameter"))->serialize(); - if (size_t comma = nozzle_diameter_serialized.find(','); comma != std::string::npos) - nozzle_diameter_serialized = nozzle_diameter_serialized.substr(0, comma); - } for (const auto& [printer_model_nozzle_pair, states] : printer_state_map) { if (printer_model_nozzle_pair.first == printer_preset.config.opt_string("printer_model") - && (printer_model_nozzle_pair.second.empty() - || printer_model_nozzle_pair.second == nozzle_diameter_serialized) - ) { + && printer_model_nozzle_pair.second == printer_preset.config.opt_string("printer_variant")) + { PrinterStatesCount states_cnt = get_printe_states_count(states); return format_wxstr(_L("Available: %1%, Offline: %2%, Busy: %3%. Total: %4% printers"), From 79a7abeca604a1849d16bf2a68e4d3f15cd3db9e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Sun, 28 Apr 2024 09:58:46 +0200 Subject: [PATCH 02/28] nozzle_diameter changed to printer_variant --- src/slic3r/GUI/WebViewDialog.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 06d34fab59..18aa970be4 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -735,10 +735,7 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF() //} const Preset& selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset(); const Preset& selected_filament = wxGetApp().preset_bundle->filaments.get_selected_preset(); - std::string nozzle_diameter_serialized = dynamic_cast(selected_printer.config.option("nozzle_diameter"))->serialize(); - // Sending only first nozzle diamenter for now. - if (size_t comma = nozzle_diameter_serialized.find(','); comma != std::string::npos) - nozzle_diameter_serialized = nozzle_diameter_serialized.substr(0, comma); + std::string nozzle_diameter_serialized = selected_printer.config.opt_string("printer_variant"); // Sending only first filament type for now. This should change to array of values const std::string filament_type_serialized = selected_filament.config.option("filament_type")->serialize(); const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize(); From f6e8a1e89837590ab4f268d780672ccd762bdbaa Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 30 Apr 2024 10:15:31 +0200 Subject: [PATCH 03/28] Do not set user agent on webview creation. It caused not loading of the webview edge backend when running 2 different versions of PS. --- src/slic3r/GUI/WebView.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/slic3r/GUI/WebView.cpp b/src/slic3r/GUI/WebView.cpp index f980556c3d..4b5f8bcbeb 100644 --- a/src/slic3r/GUI/WebView.cpp +++ b/src/slic3r/GUI/WebView.cpp @@ -21,8 +21,7 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url) if (webView) { wxString correct_url = url.empty() ? wxString("") : wxURI(url).BuildURI(); -#ifdef __WIN32__ - webView->SetUserAgent(wxString::Format("PrusaSlicer/v%s", SLIC3R_VERSION)); +#ifdef __WIN32_ webView->Create(parent, wxID_ANY, correct_url, wxDefaultPosition, wxDefaultSize); //We register the wxfs:// protocol for testing purposes //webView->RegisterHandler(wxSharedPtr(new wxWebViewArchiveHandler("wxfs"))); @@ -34,7 +33,6 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url) // And the memory: file system //webView->RegisterHandler(wxSharedPtr(new wxWebViewFSHandler("memory"))); webView->Create(parent, wxID_ANY, correct_url, wxDefaultPosition, wxDefaultSize); - webView->SetUserAgent(wxString::Format("PrusaSlicer/v%s", SLIC3R_VERSION)); #endif #ifndef __WIN32__ Slic3r::GUI::wxGetApp().CallAfter([webView] { From 2de65cfa6aae8add4ba29a63d9469a3d41cea785 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 6 May 2024 14:22:53 +0200 Subject: [PATCH 04/28] Do not escape upload path in PrusaConnectNew init_upload --- src/slic3r/Utils/PrusaConnect.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/slic3r/Utils/PrusaConnect.cpp b/src/slic3r/Utils/PrusaConnect.cpp index 87f367ffb5..e7e35794e1 100644 --- a/src/slic3r/Utils/PrusaConnect.cpp +++ b/src/slic3r/Utils/PrusaConnect.cpp @@ -90,8 +90,8 @@ bool PrusaConnectNew::init_upload(PrintHostUpload upload_data, std::string& out) const std::string name = get_name(); const std::string file_size = std::to_string(size); const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token(); - const std::string escaped_upload_path = escape_path_by_element(upload_data.upload_path); - const std::string escaped_upload_filename = escape_path_by_element(upload_data.upload_path.filename()); + const std::string upload_path = upload_data.upload_path.generic_string(); + const std::string upload_filename = upload_data.upload_path.filename().string(); std::string url = GUI::format("%1%/app/users/teams/%2%/uploads", get_host(), m_team_id); const std::string request_body_json = GUI::format( "{" @@ -101,9 +101,9 @@ bool PrusaConnectNew::init_upload(PrintHostUpload upload_data, std::string& out) "\"force\": true, " "\"printer_uuid\": \"%4%\"" "}" - , escaped_upload_filename + , upload_filename , file_size - , upload_data.storage + "/" + escaped_upload_path + , upload_data.storage + "/" + upload_path , m_uuid ); @@ -156,7 +156,7 @@ bool PrusaConnectNew::upload(PrintHostUpload upload_data, ProgressFn progress_fn } const std::string name = get_name(); const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token(); - const std::string escaped_upload_path = escape_string(upload_data.storage + "/" + upload_data.upload_path.string()); + const std::string escaped_upload_path = upload_data.storage + "/" + escape_path_by_element(upload_data.upload_path.string()); const std::string to_print = upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false"; const std::string to_queue = upload_data.post_action == PrintHostPostUploadAction::QueuePrint ? "true" : "false"; std::string url = GUI::format("%1%/app/teams/%2%/files/raw?upload_id=%3%&force=true&printer_uuid=%4%&path=%5%&to_print=%6%&to_queue=%7%", get_host(), m_team_id, upload_id, m_uuid, escaped_upload_path, to_print, to_queue); From f83213d9585582a5e341c9d8804951294d883d63 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 6 May 2024 14:43:16 +0200 Subject: [PATCH 05/28] Fix of opening avatar file for write. --- src/slic3r/GUI/Plater.cpp | 4 ++++ src/slic3r/GUI/UserAccount.cpp | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b48edca87c..256b3ec198 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -964,6 +964,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) boost::filesystem::path path = user_account->get_avatar_path(true); FILE* file; file = fopen(path.string().c_str(), "wb"); + if (file == NULL) { + BOOST_LOG_TRIVIAL(error) << "Failed to create file to store avatar picture at: " << path; + return; + } fwrite(evt.data.c_str(), 1, evt.data.size(), file); fclose(file); this->main_frame->refresh_account_menu(true); diff --git a/src/slic3r/GUI/UserAccount.cpp b/src/slic3r/GUI/UserAccount.cpp index 992fc39b00..65c9bc40d1 100644 --- a/src/slic3r/GUI/UserAccount.cpp +++ b/src/slic3r/GUI/UserAccount.cpp @@ -1,6 +1,7 @@ #include "UserAccount.hpp" #include "format.hpp" +#include "GUI.hpp" #include "libslic3r/Utils.hpp" @@ -78,7 +79,7 @@ boost::filesystem::path UserAccount::get_avatar_path(bool logged) const { if (logged) { const std::string filename = "prusaslicer-avatar-" + m_instance_hash + m_avatar_extension; - return boost::filesystem::path(wxStandardPaths::Get().GetTempDir().utf8_str().data()) / filename; + return GUI::into_path(wxStandardPaths::Get().GetTempDir()) / filename; } else { return boost::filesystem::path(resources_dir()) / "icons" / "user.svg"; } From 32d2115334f0772c59026cc7d2b66d31e642f1f9 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 3 May 2024 13:28:52 +0200 Subject: [PATCH 06/28] Set user agent to SLIC3R_APP_FULL_NAME --- src/slic3r/GUI/WebView.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/WebView.cpp b/src/slic3r/GUI/WebView.cpp index 4b5f8bcbeb..fe191f4747 100644 --- a/src/slic3r/GUI/WebView.cpp +++ b/src/slic3r/GUI/WebView.cpp @@ -22,6 +22,7 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url) wxString correct_url = url.empty() ? wxString("") : wxURI(url).BuildURI(); #ifdef __WIN32_ + webView->SetUserAgent(SLIC3R_APP_FULL_NAME); webView->Create(parent, wxID_ANY, correct_url, wxDefaultPosition, wxDefaultSize); //We register the wxfs:// protocol for testing purposes //webView->RegisterHandler(wxSharedPtr(new wxWebViewArchiveHandler("wxfs"))); @@ -33,6 +34,7 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url) // And the memory: file system //webView->RegisterHandler(wxSharedPtr(new wxWebViewFSHandler("memory"))); webView->Create(parent, wxID_ANY, correct_url, wxDefaultPosition, wxDefaultSize); + webView->SetUserAgent(wxString::FromUTF8(SLIC3R_APP_FULL_NAME)); #endif #ifndef __WIN32__ Slic3r::GUI::wxGetApp().CallAfter([webView] { From 76d7af0b055b7b89f5daaa414aa0d33acec56369 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 6 May 2024 11:11:12 +0200 Subject: [PATCH 07/28] Add developer panel and error handling to webview dialog --- src/slic3r/GUI/WebViewDialog.cpp | 358 ++++++++++++++++++++++++++++++- src/slic3r/GUI/WebViewDialog.hpp | 70 +++++- 2 files changed, 421 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 18aa970be4..d149f33744 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -95,8 +95,6 @@ WebViewPanel::WebViewPanel(wxWindow *parent, const wxString& default_url, const m_dev_tools = m_tools_menu->AppendCheckItem(wxID_ANY, _L("Enable Dev Tools")); #endif - //Zoom - m_zoomFactor = 100; Bind(wxEVT_SHOW, &WebViewPanel::on_show, this); @@ -438,7 +436,7 @@ case type: \ WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER); } - BOOST_LOG_TRIVIAL(error) << "WebView error: " << category; + BOOST_LOG_TRIVIAL(error) << "WebViewPanel error: " << category; load_error_page(); #ifdef DEBUG_URL_PANEL m_info->ShowMessage(_L("An error occurred loading ") + evt.GetURL() + "\n" + @@ -655,6 +653,40 @@ WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxStri , m_loading_html(loading_html) { wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); +#ifdef DEBUG_URL_PANEL + // Create the button + bSizer_toolbar = new wxBoxSizer(wxHORIZONTAL); + + m_button_back = new wxButton(this, wxID_ANY, wxT("Back"), wxDefaultPosition, wxDefaultSize, 0); + m_button_back->Enable(false); + bSizer_toolbar->Add(m_button_back, 0, wxALL, 5); + + m_button_forward = new wxButton(this, wxID_ANY, wxT("Forward"), wxDefaultPosition, wxDefaultSize, 0); + m_button_forward->Enable(false); + bSizer_toolbar->Add(m_button_forward, 0, wxALL, 5); + + m_button_stop = new wxButton(this, wxID_ANY, wxT("Stop"), wxDefaultPosition, wxDefaultSize, 0); + + bSizer_toolbar->Add(m_button_stop, 0, wxALL, 5); + + m_button_reload = new wxButton(this, wxID_ANY, wxT("Reload"), wxDefaultPosition, wxDefaultSize, 0); + bSizer_toolbar->Add(m_button_reload, 0, wxALL, 5); + + m_url = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); + bSizer_toolbar->Add(m_url, 1, wxALL | wxEXPAND, 5); + + m_button_tools = new wxButton(this, wxID_ANY, wxT("Tools"), wxDefaultPosition, wxDefaultSize, 0); + bSizer_toolbar->Add(m_button_tools, 0, wxALL, 5); + + // Create panel for find toolbar. + wxPanel* panel = new wxPanel(this); + topsizer->Add(bSizer_toolbar, 0, wxEXPAND, 0); + topsizer->Add(panel, wxSizerFlags().Expand()); + + // Create sizer for panel. + wxBoxSizer* panel_sizer = new wxBoxSizer(wxVERTICAL); + panel->SetSizer(panel_sizer); +#endif topsizer->SetMinSize(size); SetSizerAndFit(topsizer); @@ -668,19 +700,337 @@ WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxStri topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); +#ifdef DEBUG_URL_PANEL + // Create the Tools menu + m_tools_menu = new wxMenu(); + wxMenuItem* viewSource = m_tools_menu->Append(wxID_ANY, _L("View Source")); + wxMenuItem* viewText = m_tools_menu->Append(wxID_ANY, _L("View Text")); + m_tools_menu->AppendSeparator(); + + wxMenu* script_menu = new wxMenu; + + m_script_custom = script_menu->Append(wxID_ANY, "Custom script"); + m_tools_menu->AppendSubMenu(script_menu, _L("Run Script")); + wxMenuItem* addUserScript = m_tools_menu->Append(wxID_ANY, _L("Add user script")); + wxMenuItem* setCustomUserAgent = m_tools_menu->Append(wxID_ANY, _L("Set custom user agent")); + + m_context_menu = m_tools_menu->AppendCheckItem(wxID_ANY, _L("Enable Context Menu")); + m_dev_tools = m_tools_menu->AppendCheckItem(wxID_ANY, _L("Enable Dev Tools")); + +#endif + Bind(wxEVT_SHOW, &WebViewDialog::on_show, this); Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &WebViewDialog::on_script_message, this, m_browser->GetId()); + + // Connect the webview events + Bind(wxEVT_WEBVIEW_ERROR, &WebViewDialog::on_error, this, m_browser->GetId()); + //Connect the idle events + Bind(wxEVT_IDLE, &WebViewDialog::on_idle, this); + Bind(wxEVT_CLOSE_WINDOW, &WebViewDialog::on_close, this); +#ifdef DEBUG_URL_PANEL + // Connect the button events + Bind(wxEVT_BUTTON, &WebViewDialog::on_back_button, this, m_button_back->GetId()); + Bind(wxEVT_BUTTON, &WebViewDialog::on_forward_button, this, m_button_forward->GetId()); + Bind(wxEVT_BUTTON, &WebViewDialog::on_stop_button, this, m_button_stop->GetId()); + Bind(wxEVT_BUTTON, &WebViewDialog::on_reload_button, this, m_button_reload->GetId()); + Bind(wxEVT_BUTTON, &WebViewDialog::on_tools_clicked, this, m_button_tools->GetId()); + Bind(wxEVT_TEXT_ENTER, &WebViewDialog::on_url, this, m_url->GetId()); + + // Connect the menu events + Bind(wxEVT_MENU, &WebViewDialog::on_view_source_request, this, viewSource->GetId()); + Bind(wxEVT_MENU, &WebViewDialog::on_view_text_request, this, viewText->GetId()); + Bind(wxEVT_MENU, &WebViewDialog::On_enable_context_menu, this, m_context_menu->GetId()); + Bind(wxEVT_MENU, &WebViewDialog::On_enable_dev_tools, this, m_dev_tools->GetId()); + + Bind(wxEVT_MENU, &WebViewDialog::on_run_script_custom, this, m_script_custom->GetId()); + Bind(wxEVT_MENU, &WebViewDialog::on_add_user_script, this, addUserScript->GetId()); +#endif m_browser->LoadURL(url); +#ifdef DEBUG_URL_PANEL + m_url->SetLabelText(url); +#endif } WebViewDialog::~WebViewDialog() { } + + + + +void WebViewDialog::on_idle(wxIdleEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + if (m_browser->IsBusy()) { + wxSetCursor(wxCURSOR_ARROWWAIT); + } else { + wxSetCursor(wxNullCursor); + if (m_load_error_page) { + m_load_error_page = false; + m_browser->LoadURL(GUI::format_wxstr("file://%1%/web/connection_failed.html", boost::filesystem::path(resources_dir()).generic_string())); + } + } +#ifdef DEBUG_URL_PANEL + m_button_stop->Enable(m_browser->IsBusy()); +#endif +} + +/** + * Callback invoked when user entered an URL and pressed enter + */ +void WebViewDialog::on_url(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; +#ifdef DEBUG_URL_PANEL + m_browser->LoadURL(m_url->GetValue()); + m_browser->SetFocus(); +#endif +} + +/** + * Callback invoked when user pressed the "back" button + */ +void WebViewDialog::on_back_button(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + m_browser->GoBack(); +} + +/** + * Callback invoked when user pressed the "forward" button + */ +void WebViewDialog::on_forward_button(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + m_browser->GoForward(); +} + +/** + * Callback invoked when user pressed the "stop" button + */ +void WebViewDialog::on_stop_button(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + m_browser->Stop(); +} + +/** + * Callback invoked when user pressed the "reload" button + */ +void WebViewDialog::on_reload_button(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + m_browser->Reload(); +} + +void WebViewDialog::on_close(wxCloseEvent& evt) +{ + this->Hide(); +} + +void WebViewDialog::on_script_message(wxWebViewEvent& evt) +{ +} + +/** + * Invoked when user selects the "View Source" menu item + */ +void WebViewDialog::on_view_source_request(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + + SourceViewDialog dlg(this, m_browser->GetPageSource()); + dlg.ShowModal(); +} + +/** + * Invoked when user selects the "View Text" menu item + */ +void WebViewDialog::on_view_text_request(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + + wxDialog textViewDialog(this, wxID_ANY, "Page Text", + wxDefaultPosition, wxSize(700, 500), + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + wxTextCtrl* text = new wxTextCtrl(this, wxID_ANY, m_browser->GetPageText(), + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | + wxTE_RICH | + wxTE_READONLY); + + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(text, 1, wxEXPAND); + SetSizer(sizer); + textViewDialog.ShowModal(); +} + +/** + * Invoked when user selects the "Menu" item + */ +void WebViewDialog::on_tools_clicked(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + +#ifdef DEBUG_URL_PANEL + m_context_menu->Check(m_browser->IsContextMenuEnabled()); + m_dev_tools->Check(m_browser->IsAccessToDevToolsEnabled()); + + wxPoint position = ScreenToClient(wxGetMousePosition()); + PopupMenu(m_tools_menu, position.x, position.y); +#endif +} + + +void WebViewDialog::on_run_script_custom(wxCommandEvent& WXUNUSED(evt)) +{ + wxTextEntryDialog dialog + ( + this, + "Please enter JavaScript code to execute", + wxGetTextFromUserPromptStr, + m_javascript, + wxOK | wxCANCEL | wxCENTRE | wxTE_MULTILINE + ); + if (dialog.ShowModal() != wxID_OK) + return; + + run_script(dialog.GetValue()); +} + +void WebViewDialog::on_add_user_script(wxCommandEvent& WXUNUSED(evt)) +{ + wxString userScript = "window.wx_test_var = 'wxWidgets webview sample';"; + wxTextEntryDialog dialog + ( + this, + "Enter the JavaScript code to run as the initialization script that runs before any script in the HTML document.", + wxGetTextFromUserPromptStr, + userScript, + wxOK | wxCANCEL | wxCENTRE | wxTE_MULTILINE + ); + if (dialog.ShowModal() != wxID_OK) + return; + + if (!m_browser->AddUserScript(dialog.GetValue())) + wxLogError("Could not add user script"); +} + +void WebViewDialog::on_set_custom_user_agent(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + + wxString customUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1"; + wxTextEntryDialog dialog + ( + this, + "Enter the custom user agent string you would like to use.", + wxGetTextFromUserPromptStr, + customUserAgent, + wxOK | wxCANCEL | wxCENTRE + ); + if (dialog.ShowModal() != wxID_OK) + return; + + if (!m_browser->SetUserAgent(customUserAgent)) + wxLogError("Could not set custom user agent"); +} + +void WebViewDialog::on_clear_selection(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + + m_browser->ClearSelection(); +} + +void WebViewDialog::on_delete_selection(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + + m_browser->DeleteSelection(); +} + +void WebViewDialog::on_select_all(wxCommandEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + + m_browser->SelectAll(); +} + +void WebViewDialog::On_enable_context_menu(wxCommandEvent& evt) +{ + if (!m_browser) + return; + + m_browser->EnableContextMenu(evt.IsChecked()); +} +void WebViewDialog::On_enable_dev_tools(wxCommandEvent& evt) +{ + if (!m_browser) + return; + + m_browser->EnableAccessToDevTools(evt.IsChecked()); +} + +/** + * Callback invoked when a loading error occurs + */ +void WebViewDialog::on_error(wxWebViewEvent& evt) +{ +#define WX_ERROR_CASE(type) \ +case type: \ + category = #type; \ + break; + + wxString category; + switch (evt.GetInt()) + { + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CONNECTION); + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CERTIFICATE); + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_AUTH); + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_SECURITY); + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_NOT_FOUND); + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_REQUEST); + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_USER_CANCELLED); + WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER); + } + + BOOST_LOG_TRIVIAL(error) << "WebViewDialog error: " << category; + load_error_page(); +} + +void WebViewDialog::load_error_page() +{ + if (!m_browser) + return; + + m_browser->Stop(); + m_load_error_page = true; +} + void WebViewDialog::run_script(const wxString& javascript) { - if (!m_browser) + if (!m_browser) return; + // Remember the script we run in any case, so the next time the user opens + // the "Run Script" dialog box, it is shown there for convenient updating. + m_javascript = javascript; + BOOST_LOG_TRIVIAL(debug) << "RunScript " << javascript; m_browser->RunScriptAsync(javascript); } diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp index f25ec21399..0cc13ffa8f 100644 --- a/src/slic3r/GUI/WebViewDialog.hpp +++ b/src/slic3r/GUI/WebViewDialog.hpp @@ -76,7 +76,6 @@ protected: wxMenuItem* m_context_menu; wxMenuItem* m_dev_tools; #endif - long m_zoomFactor; // Last executed JavaScript snippet, for convenience. wxString m_javascript; @@ -90,6 +89,71 @@ protected: bool m_shown { false }; }; + +class WebViewDialog : public wxDialog +{ +public: + WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size, const std::string& loading_html = "loading"); + virtual ~WebViewDialog(); + + virtual void on_show(wxShowEvent& evt) = 0; + virtual void on_script_message(wxWebViewEvent& evt) = 0; + + void on_idle(wxIdleEvent& evt); + void on_url(wxCommandEvent& evt); + void on_back_button(wxCommandEvent& evt); + void on_forward_button(wxCommandEvent& evt); + void on_stop_button(wxCommandEvent& evt); + void on_reload_button(wxCommandEvent& evt); + + void on_view_source_request(wxCommandEvent& evt); + void on_view_text_request(wxCommandEvent& evt); + void on_tools_clicked(wxCommandEvent& evt); + void on_error(wxWebViewEvent& evt); + + void on_run_script_custom(wxCommandEvent& evt); + void on_add_user_script(wxCommandEvent& evt); + void on_set_custom_user_agent(wxCommandEvent& evt); + void on_clear_selection(wxCommandEvent& evt); + void on_delete_selection(wxCommandEvent& evt); + void on_select_all(wxCommandEvent& evt); + void On_enable_context_menu(wxCommandEvent& evt); + void On_enable_dev_tools(wxCommandEvent& evt); + void on_close(wxCloseEvent& evt); + + void run_script(const wxString& javascript); + + void load_error_page(); + +protected: + wxWebView* m_browser; + std::string m_loading_html; + + bool m_load_error_page{ false }; +#ifdef DEBUG_URL_PANEL + + wxBoxSizer* bSizer_toolbar; + wxButton* m_button_back; + wxButton* m_button_forward; + wxButton* m_button_stop; + wxButton* m_button_reload; + wxTextCtrl* m_url; + wxButton* m_button_tools; + + wxMenu* m_tools_menu; + wxMenuItem* m_script_custom; + + wxStaticText* m_info_text; + + wxMenuItem* m_context_menu; + wxMenuItem* m_dev_tools; +#endif + // Last executed JavaScript snippet, for convenience. + wxString m_javascript; + wxString m_response_js; + wxString m_default_url; +}; + class ConnectRequestHandler { public: @@ -144,7 +208,7 @@ private: bool m_api_key_sent {false}; }; - +/* class WebViewDialog : public wxDialog { public: @@ -160,7 +224,7 @@ protected: wxWebView* m_browser; std::string m_loading_html; }; - +*/ class PrinterPickWebViewDialog : public WebViewDialog, public ConnectRequestHandler { public: From 44cf71390bd79b3b9c57b837aadfa67ab17f65ff Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 6 May 2024 16:07:14 +0200 Subject: [PATCH 08/28] Passing uuid from connect webview to connect printerpick TODO: More sofisticated logic to pass or not pass uuid --- src/slic3r/GUI/GUI_App.cpp | 2 ++ src/slic3r/GUI/UserAccount.hpp | 4 ++++ src/slic3r/GUI/WebViewDialog.cpp | 9 ++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a72bfc5a8f..185f3d81c2 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3681,6 +3681,7 @@ bool GUI_App::select_printer_from_connect(const std::string& msg) { // parse message std::string model_name = plater()->get_user_account()->get_keyword_from_json(msg, "printer_model"); + std::string uuid = plater()->get_user_account()->get_keyword_from_json(msg, "uuid"); if (model_name.empty()) { std::vector compatible_printers; plater()->get_user_account()->fill_supported_printer_models_from_json(msg, compatible_printers); @@ -3707,6 +3708,7 @@ bool GUI_App::select_printer_from_connect(const std::string& msg) NotificationType::SelectPrinterFromConnect , printer_preset ? NotificationManager::NotificationLevel::ImportantNotificationLevel : NotificationManager::NotificationLevel::WarningNotificationLevel , out); + plater()->get_user_account()->set_current_printer_uuid_from_connect(uuid); return printer_preset; } diff --git a/src/slic3r/GUI/UserAccount.hpp b/src/slic3r/GUI/UserAccount.hpp index 9d597acf1c..a31c70ca63 100644 --- a/src/slic3r/GUI/UserAccount.hpp +++ b/src/slic3r/GUI/UserAccount.hpp @@ -72,6 +72,8 @@ public: const std::map& get_printer_state_table() const { return printer_state_table; } + void set_current_printer_uuid_from_connect(const std::string& uuid) { m_current_printer_uuid_from_connect = uuid; } + std::string get_current_printer_uuid_from_connect() const { return m_current_printer_uuid_from_connect; } private: void set_username(const std::string& username); @@ -86,6 +88,8 @@ private: size_t m_fail_counter { 0 }; std::string m_avatar_extension; + std::string m_current_printer_uuid_from_connect; + const std::map printer_state_table = { {"OFFLINE" , ConnectPrinterState::CONNECT_PRINTER_OFFLINE}, {"PRINTING" , ConnectPrinterState::CONNECT_PRINTER_PRINTING}, diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index d149f33744..1b0859a68d 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -1089,14 +1089,15 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF() // Sending only first filament type for now. This should change to array of values const std::string filament_type_serialized = selected_filament.config.option("filament_type")->serialize(); const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize(); - + const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(); const std::string request = GUI::format( "{" + "\"printerUuid\": \"%4%\", " "\"printerModel\": \"%3%\", " "\"nozzleDiameter\": %2%, " "\"material\": \"%1%\" " - "}", filament_type_serialized, nozzle_diameter_serialized, printer_model_serialized); + "}", filament_type_serialized, nozzle_diameter_serialized, printer_model_serialized, uuid); wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request); run_script(script); @@ -1107,11 +1108,13 @@ void PrinterPickWebViewDialog::request_compatible_printers_SLA() const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize(); const Preset& selected_material = wxGetApp().preset_bundle->sla_materials.get_selected_preset(); const std::string material_type_serialized = selected_material.config.option("material_type")->serialize(); + const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(); const std::string request = GUI::format( "{" + "\"printerUuid\": \"%3%\", " "\"material\": \"%1%\", " "\"printerModel\": \"%2%\" " - "}", material_type_serialized, printer_model_serialized); + "}", material_type_serialized, printer_model_serialized, uuid); wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request); run_script(script); From cb265cdfeee5d4553b6f505ff3b1b6a76d9a2ea5 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 7 May 2024 09:29:57 +0200 Subject: [PATCH 09/28] use boost::nowide::fopen to store avatar --- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/UserAccount.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 256b3ec198..28b69e3e5b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -963,7 +963,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->q->Bind(EVT_UA_AVATAR_SUCCESS, [this](UserAccountSuccessEvent& evt) { boost::filesystem::path path = user_account->get_avatar_path(true); FILE* file; - file = fopen(path.string().c_str(), "wb"); + file = boost::nowide::fopen(path.generic_string().c_str(), "wb"); if (file == NULL) { BOOST_LOG_TRIVIAL(error) << "Failed to create file to store avatar picture at: " << path; return; diff --git a/src/slic3r/GUI/UserAccount.cpp b/src/slic3r/GUI/UserAccount.cpp index 65c9bc40d1..7eff95758c 100644 --- a/src/slic3r/GUI/UserAccount.cpp +++ b/src/slic3r/GUI/UserAccount.cpp @@ -79,7 +79,7 @@ boost::filesystem::path UserAccount::get_avatar_path(bool logged) const { if (logged) { const std::string filename = "prusaslicer-avatar-" + m_instance_hash + m_avatar_extension; - return GUI::into_path(wxStandardPaths::Get().GetTempDir()) / filename; + return into_path(wxStandardPaths::Get().GetTempDir()) / filename; } else { return boost::filesystem::path(resources_dir()) / "icons" / "user.svg"; } From df40aecacc1d48f1f546c895a1a15766a0d66fec Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 2 May 2024 16:47:55 +0200 Subject: [PATCH 10/28] New Connect adresses. --- src/slic3r/GUI/WebViewDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 1b0859a68d..6045d259ae 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -546,7 +546,7 @@ void ConnectRequestHandler::on_request_config() } ConnectWebViewPanel::ConnectWebViewPanel(wxWindow* parent) - : WebViewPanel(parent, L"https://connect.prusa3d.com/connect-slicer-app/", "connect_loading") + : WebViewPanel(parent, L"https://connect.prusa3d.com/", "connect_loading") { } @@ -1036,7 +1036,7 @@ void WebViewDialog::run_script(const wxString& javascript) PrinterPickWebViewDialog::PrinterPickWebViewDialog(wxWindow* parent, std::string& ret_val) : WebViewDialog(parent - , L"https://connect.prusa3d.com/connect-slicer-app/printer-list" + , L"https://connect.prusa3d.com/slicer-select-printer" , _L("Choose a printer") , wxSize(std::max(parent->GetClientSize().x / 2, 100 * wxGetApp().em_unit()), std::max(parent->GetClientSize().y / 2, 50 * wxGetApp().em_unit())) , "connect_loading") From 9435515a8c6222fb003b509fa71c80eef02e900f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 13 May 2024 09:12:48 +0200 Subject: [PATCH 11/28] Resend config to connect on new access token. --- src/slic3r/GUI/MainFrame.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index b6644e0f75..8d6572af94 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -749,6 +749,7 @@ void MainFrame::create_preset_tabs() void MainFrame::add_connect_webview_tab() { if (m_connect_webview_added) { + m_connect_webview->resend_config(); return; } // parameters of InsertNewPage (to prevent ambigous overloaded function) From 98ec4e808d0300631ca2ba834be7145bd5dfeedb Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 13 May 2024 12:02:29 +0200 Subject: [PATCH 12/28] Remove script handler on EndModal. --- src/slic3r/GUI/Plater.cpp | 10 +++++++--- src/slic3r/GUI/WebViewDialog.cpp | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 28b69e3e5b..454428b71a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5877,9 +5877,13 @@ void Plater::connect_gcode() { assert(p->user_account->is_logged()); std::string dialog_msg; - if(PrinterPickWebViewDialog(this, dialog_msg).ShowModal() != wxID_OK) { - return; - } + { + //PrinterPickWebViewDialog* dialog = new PrinterPickWebViewDialog(this, dialog_msg); + PrinterPickWebViewDialog dialog(this, dialog_msg); + if (dialog.ShowModal() != wxID_OK) { + return; + } + } if (dialog_msg.empty()) { show_error(this, _L("Failed to select a printer. PrusaConnect did not return a value.")); return; diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 6045d259ae..f05086dad2 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -1063,6 +1063,7 @@ void PrinterPickWebViewDialog::on_script_message(wxWebViewEvent& evt) void PrinterPickWebViewDialog::on_request_update_selected_printer_action() { m_ret_val = m_message_data; + m_browser->RemoveScriptMessageHandler("_prusaSlicer"); this->EndModal(wxID_OK); } From 65a581a026fab671b9e62675f54f4359d5456092 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 13 May 2024 16:57:21 +0200 Subject: [PATCH 13/28] Use only uuid from Connect request and get rest of the data from endpoint --- src/slic3r/GUI/GUI_App.cpp | 32 +++++++++++++++++++-- src/slic3r/GUI/GUI_App.hpp | 3 +- src/slic3r/GUI/Plater.cpp | 10 +++++++ src/slic3r/GUI/UserAccount.cpp | 4 +++ src/slic3r/GUI/UserAccount.hpp | 3 +- src/slic3r/GUI/UserAccountCommunication.cpp | 15 ++++++++++ src/slic3r/GUI/UserAccountCommunication.hpp | 1 + src/slic3r/GUI/UserAccountSession.cpp | 2 ++ src/slic3r/GUI/UserAccountSession.hpp | 5 ++++ src/slic3r/GUI/WebViewDialog.cpp | 2 +- 10 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 185f3d81c2..ddc66e93dc 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3727,11 +3727,29 @@ bool GUI_App::select_filament_preset(const Preset* preset, size_t extruder_index } void GUI_App::search_and_select_filaments(const std::string& material, size_t extruder_index, std::string& out_message) { - const DynamicPrintConfig& config = preset_bundle->extruders_filaments[extruder_index].get_selected_preset()->config; + const Preset* preset = preset_bundle->extruders_filaments[extruder_index].get_selected_preset(); // selected is ok - if (config.has("filament_type") && config.option("filament_type")->serialize() == material) { + if (!preset->is_default && preset->config.has("filament_type") && preset->config.option("filament_type")->serialize() == material) { return; } + // find installed compatible filament that is Prusa with suitable type and select it + for (const auto& filament : preset_bundle->extruders_filaments[extruder_index]) { + if (filament.is_compatible + && !filament.preset->is_default + && filament.preset->is_visible + && (!filament.preset->vendor || !filament.preset->vendor->templates_profile) + && filament.preset->config.has("filament_type") + && filament.preset->config.option("filament_type")->serialize() == material + && filament.preset->name.compare(0, 9, "Prusament") == 0 + && select_filament_preset(filament.preset, extruder_index) + ) + { + out_message += /*(extruder_count == 1) + ? GUI::format(_L("Selected Filament:\n%1%"), filament_preset.preset->name) + : */GUI::format(_L("Extruder %1%: Selected Filament %2%\n"), extruder_index + 1, filament.preset->name); + return; + } + } // find first installed compatible filament with suitable type and select it for (const auto& filament : preset_bundle->extruders_filaments[extruder_index]) { if (filament.is_compatible @@ -3800,7 +3818,15 @@ void GUI_App::select_filament_from_connect(const std::string& msg) } } -void GUI_App::handle_connect_request_printer_pick(const std::string& msg) +void GUI_App::handle_connect_request_printer_select(const std::string& msg) +{ + // Here comes code from ConnectWebViewPanel + // It only contains uuid of a printer to be selected + // Lets queue it and wait on result. The result is send via event to plater, where it is send to handle_connect_request_printer_select_inner + std::string uuid = plater()->get_user_account()->get_keyword_from_json(msg, "uuid"); + plater()->get_user_account()->enqueue_printer_data_action(uuid); +} +void GUI_App::handle_connect_request_printer_select_inner(const std::string & msg) { BOOST_LOG_TRIVIAL(debug) << "Handling web request: " << msg; // return to plater diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 0f2b84a434..d37c659c51 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -413,7 +413,8 @@ public: int request_user_unbind(std::string dev_id) { return 0; } bool select_printer_from_connect(const std::string& cmd); void select_filament_from_connect(const std::string& cmd); - void handle_connect_request_printer_pick(const std::string& cmd); + void handle_connect_request_printer_select(const std::string& cmd); + void handle_connect_request_printer_select_inner(const std::string& cmd); void show_printer_webview_tab(); // return true if preset vas invisible and we have to installed it to make it selectable bool select_printer_preset(const Preset* printer_preset); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 454428b71a..1633a412e8 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -975,6 +975,16 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) wxGetApp().update_login_dialog(); #endif // 0 }); + this->q->Bind(EVT_UA_PRUSACONNECT_PRINTER_DATA_SUCCESS, [this](UserAccountSuccessEvent& evt) { + wxGetApp().handle_connect_request_printer_select_inner(evt.data); + }); + this->q->Bind(EVT_UA_PRUSACONNECT_PRINTER_DATA_FAIL, [this](UserAccountFailEvent& evt) { + BOOST_LOG_TRIVIAL(error) << "Failed communication with Prusa Account: " << evt.data; + user_account->on_communication_fail(); + std::string msg = _u8L("Failed to select printer from PrusaConnect."); + this->notification_manager->close_notification_of_type(NotificationType::SelectFilamentFromConnect); + this->notification_manager->push_notification(NotificationType::SelectFilamentFromConnect, NotificationManager::NotificationLevel::WarningNotificationLevel, msg); + }); } wxGetApp().other_instance_message_handler()->init(this->q); diff --git a/src/slic3r/GUI/UserAccount.cpp b/src/slic3r/GUI/UserAccount.cpp index 7eff95758c..a6117e2a50 100644 --- a/src/slic3r/GUI/UserAccount.cpp +++ b/src/slic3r/GUI/UserAccount.cpp @@ -97,6 +97,10 @@ void UserAccount::enqueue_avatar_action() { m_communication->enqueue_avatar_action(m_account_user_data["avatar"]); } +void UserAccount::enqueue_printer_data_action(const std::string& uuid) +{ + m_communication->enqueue_printer_data_action(uuid); +} bool UserAccount::on_login_code_recieved(const std::string& url_message) { diff --git a/src/slic3r/GUI/UserAccount.hpp b/src/slic3r/GUI/UserAccount.hpp index a31c70ca63..a204a05c31 100644 --- a/src/slic3r/GUI/UserAccount.hpp +++ b/src/slic3r/GUI/UserAccount.hpp @@ -45,7 +45,7 @@ public: void enqueue_connect_status_action(); void enqueue_connect_printer_models_action(); void enqueue_avatar_action(); - + void enqueue_printer_data_action(const std::string& uuid); // Clears all data and connections, called on logout or EVT_UA_RESET void clear(); @@ -74,6 +74,7 @@ public: void set_current_printer_uuid_from_connect(const std::string& uuid) { m_current_printer_uuid_from_connect = uuid; } std::string get_current_printer_uuid_from_connect() const { return m_current_printer_uuid_from_connect; } + private: void set_username(const std::string& username); diff --git a/src/slic3r/GUI/UserAccountCommunication.cpp b/src/slic3r/GUI/UserAccountCommunication.cpp index 6d8045d2b7..d2d1aa3e68 100644 --- a/src/slic3r/GUI/UserAccountCommunication.cpp +++ b/src/slic3r/GUI/UserAccountCommunication.cpp @@ -333,6 +333,21 @@ void UserAccountCommunication::enqueue_avatar_action(const std::string& url) } wakeup_session_thread(); } + +void UserAccountCommunication::enqueue_printer_data_action(const std::string& uuid) +{ + { + std::lock_guard lock(m_session_mutex); + if (!m_session->is_initialized()) { + BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in."; + return; + } + m_session->enqueue_action(UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_DATA_FROM_UUID, nullptr, nullptr, uuid); + } + wakeup_session_thread(); +} + + void UserAccountCommunication::init_session_thread() { m_thread = std::thread([this]() { diff --git a/src/slic3r/GUI/UserAccountCommunication.hpp b/src/slic3r/GUI/UserAccountCommunication.hpp index 15fc41aece..114bfa977b 100644 --- a/src/slic3r/GUI/UserAccountCommunication.hpp +++ b/src/slic3r/GUI/UserAccountCommunication.hpp @@ -43,6 +43,7 @@ public: void enqueue_connect_printer_models_action(); void enqueue_avatar_action(const std::string& url); void enqueue_test_connection(); + void enqueue_printer_data_action(const std::string& uuid); // Callbacks - called from UI after receiving Event from Session thread. Some might use Session thread. // diff --git a/src/slic3r/GUI/UserAccountSession.cpp b/src/slic3r/GUI/UserAccountSession.cpp index 65bfc670ab..69c974001f 100644 --- a/src/slic3r/GUI/UserAccountSession.cpp +++ b/src/slic3r/GUI/UserAccountSession.cpp @@ -25,8 +25,10 @@ wxDEFINE_EVENT(EVT_UA_SUCCESS, UserAccountSuccessEvent); wxDEFINE_EVENT(EVT_UA_PRUSACONNECT_STATUS_SUCCESS, UserAccountSuccessEvent); wxDEFINE_EVENT(EVT_UA_PRUSACONNECT_PRINTER_MODELS_SUCCESS, UserAccountSuccessEvent); wxDEFINE_EVENT(EVT_UA_AVATAR_SUCCESS, UserAccountSuccessEvent); +wxDEFINE_EVENT(EVT_UA_PRUSACONNECT_PRINTER_DATA_SUCCESS, UserAccountSuccessEvent); wxDEFINE_EVENT(EVT_UA_FAIL, UserAccountFailEvent); wxDEFINE_EVENT(EVT_UA_RESET, UserAccountFailEvent); +wxDEFINE_EVENT(EVT_UA_PRUSACONNECT_PRINTER_DATA_FAIL, UserAccountFailEvent); void UserActionPost::perform(/*UNUSED*/ wxEvtHandler* evt_handler, /*UNUSED*/ const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) const { diff --git a/src/slic3r/GUI/UserAccountSession.hpp b/src/slic3r/GUI/UserAccountSession.hpp index eaaafac0c1..e465b6e17b 100644 --- a/src/slic3r/GUI/UserAccountSession.hpp +++ b/src/slic3r/GUI/UserAccountSession.hpp @@ -23,8 +23,10 @@ wxDECLARE_EVENT(EVT_UA_SUCCESS, UserAccountSuccessEvent); wxDECLARE_EVENT(EVT_UA_PRUSACONNECT_STATUS_SUCCESS, UserAccountSuccessEvent); wxDECLARE_EVENT(EVT_UA_PRUSACONNECT_PRINTER_MODELS_SUCCESS, UserAccountSuccessEvent); wxDECLARE_EVENT(EVT_UA_AVATAR_SUCCESS, UserAccountSuccessEvent); +wxDECLARE_EVENT(EVT_UA_PRUSACONNECT_PRINTER_DATA_SUCCESS, UserAccountSuccessEvent); wxDECLARE_EVENT(EVT_UA_FAIL, UserAccountFailEvent); // Soft fail - clears only after some number of fails wxDECLARE_EVENT(EVT_UA_RESET, UserAccountFailEvent); // Hard fail - clears all +wxDECLARE_EVENT(EVT_UA_PRUSACONNECT_PRINTER_DATA_FAIL, UserAccountFailEvent); // Failed to get data for printer to select, soft fail, action does not repeat typedef std::function UserActionSuccessFn; @@ -41,6 +43,7 @@ enum class UserAccountActionID { USER_ACCOUNT_ACTION_CONNECT_STATUS, // status of all printers by UUID USER_ACCOUNT_ACTION_CONNECT_PRINTER_MODELS, // status of all printers by UUID with printer_model. Should be called once to save printer models. USER_ACCOUNT_ACTION_AVATAR, + USER_ACCOUNT_ACTION_CONNECT_DATA_FROM_UUID, }; class UserAction { @@ -115,6 +118,7 @@ public: m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_STATUS] = std::make_unique("CONNECT_STATUS", "https://connect.prusa3d.com/slicer/status", EVT_UA_PRUSACONNECT_STATUS_SUCCESS, EVT_UA_FAIL); m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_PRINTER_MODELS] = std::make_unique("CONNECT_PRINTER_MODELS", "https://connect.prusa3d.com/slicer/printer_list", EVT_UA_PRUSACONNECT_PRINTER_MODELS_SUCCESS, EVT_UA_FAIL); m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_AVATAR] = std::make_unique("AVATAR", "https://media.printables.com/media/", EVT_UA_AVATAR_SUCCESS, EVT_UA_FAIL); + m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_DATA_FROM_UUID] = std::make_unique("USER_ACCOUNT_ACTION_CONNECT_DATA_FROM_UUID", "https://connect.prusa3d.com/app/printers/", EVT_UA_PRUSACONNECT_PRINTER_DATA_SUCCESS, EVT_UA_FAIL); } ~UserAccountSession() { @@ -126,6 +130,7 @@ public: m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_TEST_CONNECTION].reset(nullptr); m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_STATUS].reset(nullptr); m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_AVATAR].reset(nullptr); + m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_DATA_FROM_UUID].reset(nullptr); } void clear() { m_access_token.clear(); diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index f05086dad2..32cd5520cd 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -570,7 +570,7 @@ void ConnectWebViewPanel::sys_color_changed() void ConnectWebViewPanel::on_request_update_selected_printer_action() { assert(!m_message_data.empty()); - wxGetApp().handle_connect_request_printer_pick(m_message_data); + wxGetApp().handle_connect_request_printer_select(m_message_data); } From 7c63c2dbfb2e5db6fc2efb24308af76a673e9282 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 13 May 2024 17:50:42 +0200 Subject: [PATCH 14/28] WIP new upload --- src/slic3r/GUI/Plater.cpp | 41 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1633a412e8..2cf3cfeace 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5899,7 +5899,7 @@ void Plater::connect_gcode() return; } BOOST_LOG_TRIVIAL(debug) << "Message from Printer pick webview: " << dialog_msg; - + /* PresetBundle* preset_bundle = wxGetApp().preset_bundle; // Connect data std::vector compatible_printers; @@ -6037,14 +6037,49 @@ void Plater::connect_gcode() show_error(this, _L("Failed to select a printer. Missing data (uuid and team id) for chosen printer.")); return; } + */ + +/* +{ + set_ready: boolean, // uzivatel potvrdil ze je tiskarne ready a muze se tisknout, pouziva se pro tisknout ted a odlozeny tisk + position: -1 | 0, // -1 = posledni ve fronte, 0 = prvni ve fronte + wait_until: number | undefined, // timestamp pro odlozeny tisk + + file_name: string, // tady budeme predavat jak se uzivatel rozhodl soubor pojmenovat, kdyz ho neprejmenuje, tak vratime to stejne co nam predtim posle slicer + printer_uuid: string // uuid vybrane tiskarny +} +*/ + const Preset* selected_printer_preset = &wxGetApp().preset_bundle->printers.get_selected_preset(); + /* + bool set_ready; + int position; + int wait_until; + std::string filename; + std::string printer_uuid; + std::string team_id; + */ + bool set_ready = true; + int position = -1; + int wait_until = 0; + std::string filename = "print.bgcode"; + std::string printer_uuid = "1234-1234-1234-1234"; + std::string team_id = "1234"; + PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *selected_printer_preset); ph_printer.config.set_key_value("host_type", new ConfigOptionEnum(htPrusaConnectNew)); // use existing structures to pass data ph_printer.config.opt_string("printhost_apikey") = team_id; - ph_printer.config.opt_string("print_host") = uuid; + ph_printer.config.opt_string("print_host") = printer_uuid; DynamicPrintConfig* physical_printer_config = &ph_printer.config; - send_gcode_inner(physical_printer_config); + PrintHostJob upload_job(physical_printer_config); + assert(!upload_job.empty()); + + upload_job.upload_data.upload_path = filename; + upload_job.upload_data.post_action = PrintHostPostUploadAction::None; + + p->export_gcode(fs::path(), false, std::move(upload_job)); + } void Plater::send_gcode() From 5e5f2c493dbfe7e2df70d699550f7073946083c3 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 15 May 2024 14:37:16 +0200 Subject: [PATCH 15/28] New request naming --- src/slic3r/GUI/WebViewDialog.cpp | 19 +++++++++++++++---- src/slic3r/GUI/WebViewDialog.hpp | 9 ++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 32cd5520cd..a3778c292f 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -471,8 +471,10 @@ ConnectRequestHandler::ConnectRequestHandler() { m_actions["REQUEST_ACCESS_TOKEN"] = std::bind(&ConnectRequestHandler::on_request_access_token, this); m_actions["REQUEST_CONFIG"] = std::bind(&ConnectRequestHandler::on_request_config, this); - m_actions["UPDATE_SELECTED_PRINTER"] = std::bind(&ConnectRequestHandler::on_request_update_selected_printer_action, this); m_actions["WEBAPP_READY"] = std::bind(&ConnectRequestHandler::request_compatible_printers, this); + m_actions["SELECT_PRINTER"] = std::bind(&ConnectRequestHandler::on_request_select_printer, this); + m_actions["PRINT"] = std::bind(&ConnectRequestHandler::on_request_print, this); + m_actions["REQUEST_SELECTED_PRINTER"] = std::bind(&ConnectRequestHandler::on_request_print, this); } ConnectRequestHandler::~ConnectRequestHandler() { @@ -567,12 +569,16 @@ void ConnectWebViewPanel::sys_color_changed() resend_config(); } -void ConnectWebViewPanel::on_request_update_selected_printer_action() +void ConnectWebViewPanel::on_request_select_printer() { assert(!m_message_data.empty()); wxGetApp().handle_connect_request_printer_select(m_message_data); } - +void ConnectWebViewPanel::on_request_print() +{ + // PRINT request is not defined for ConnectWebViewPanel + assert(true); +} PrinterWebViewPanel::PrinterWebViewPanel(wxWindow* parent, const wxString& default_url) : WebViewPanel(parent, default_url) @@ -1060,7 +1066,12 @@ void PrinterPickWebViewDialog::on_script_message(wxWebViewEvent& evt) handle_message(into_u8(evt.GetString())); } -void PrinterPickWebViewDialog::on_request_update_selected_printer_action() +void PrinterPickWebViewDialog::on_request_select_printer() +{ + // SELECT_PRINTER request is not defined for PrinterPickWebViewDialog + assert(true); +} +void PrinterPickWebViewDialog::on_request_print() { m_ret_val = m_message_data; m_browser->RemoveScriptMessageHandler("_prusaSlicer"); diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp index 0cc13ffa8f..0f3c523ead 100644 --- a/src/slic3r/GUI/WebViewDialog.hpp +++ b/src/slic3r/GUI/WebViewDialog.hpp @@ -166,7 +166,8 @@ protected: // action callbacs stored in m_actions virtual void on_request_access_token(); virtual void on_request_config(); - virtual void on_request_update_selected_printer_action() = 0; + virtual void on_request_select_printer() = 0; + virtual void on_request_print() = 0; virtual void run_script_bridge(const wxString& script) = 0; virtual void request_compatible_printers() = 0; @@ -183,7 +184,8 @@ public: void logout(); void sys_color_changed() override; protected: - void on_request_update_selected_printer_action() override; + void on_request_select_printer() override; + void on_request_print() override; void request_compatible_printers() override {} void run_script_bridge(const wxString& script) override {run_script(script); } }; @@ -232,7 +234,8 @@ public: void on_show(wxShowEvent& evt) override; void on_script_message(wxWebViewEvent& evt) override; protected: - void on_request_update_selected_printer_action() override; + void on_request_select_printer() override; + void on_request_print() override; void request_compatible_printers() override; void request_compatible_printers_FFF(); void request_compatible_printers_SLA(); From 535ecf7b34e09ac12bcedbb442251f8b56caf502 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 15 May 2024 15:37:12 +0200 Subject: [PATCH 16/28] Passing filename to Connect PrinterPick --- src/slic3r/GUI/Plater.cpp | 26 +++++++++++++++++++ src/slic3r/GUI/Plater.hpp | 1 + src/slic3r/GUI/WebViewDialog.cpp | 44 +++++++++++++++++--------------- src/slic3r/GUI/WebViewDialog.hpp | 22 ++++++++-------- 4 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2cf3cfeace..a238a5df61 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6119,6 +6119,32 @@ void Plater::send_gcode() send_gcode_inner(physical_printer_config); } +std::string Plater::get_upload_filename() +{ + // Obtain default output path + fs::path default_output_file; + try { + // Update the background processing, so that the placeholder parser will get the correct values for the ouput file template. + // Also if there is something wrong with the current configuration, a pop-up dialog will be shown and the export will not be performed. + unsigned int state = this->p->update_restart_background_process(false, false); + if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) + return {}; + default_output_file = this->p->background_process.output_filepath_for_project(into_path(get_project_filename(".3mf"))); + } + catch (const Slic3r::PlaceholderParserError& ex) { + // Show the error with monospaced font. + show_error(this, ex.what(), true); + return {}; + } + catch (const std::exception& ex) { + show_error(this, ex.what(), false); + return {}; + } + default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); + + return default_output_file.string(); +} + void Plater::send_gcode_inner(DynamicPrintConfig* physical_printer_config) { PrintHostJob upload_job(physical_printer_config); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 462c875e2e..5c113a394f 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -227,6 +227,7 @@ public: void send_gcode_inner(DynamicPrintConfig* physical_printer_config); void eject_drive(); void connect_gcode(); + std::string get_upload_filename(); void take_snapshot(const std::string &snapshot_name); void take_snapshot(const wxString &snapshot_name); diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index a3778c292f..13c8cc1c01 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -469,12 +469,13 @@ SourceViewDialog::SourceViewDialog(wxWindow* parent, wxString source) : ConnectRequestHandler::ConnectRequestHandler() { - m_actions["REQUEST_ACCESS_TOKEN"] = std::bind(&ConnectRequestHandler::on_request_access_token, this); - m_actions["REQUEST_CONFIG"] = std::bind(&ConnectRequestHandler::on_request_config, this); - m_actions["WEBAPP_READY"] = std::bind(&ConnectRequestHandler::request_compatible_printers, this); - m_actions["SELECT_PRINTER"] = std::bind(&ConnectRequestHandler::on_request_select_printer, this); - m_actions["PRINT"] = std::bind(&ConnectRequestHandler::on_request_print, this); - m_actions["REQUEST_SELECTED_PRINTER"] = std::bind(&ConnectRequestHandler::on_request_print, this); + m_actions["REQUEST_ACCESS_TOKEN"] = std::bind(&ConnectRequestHandler::on_connect_action_request_access_token, this); + m_actions["REQUEST_CONFIG"] = std::bind(&ConnectRequestHandler::on_connect_action_request_config, this); + m_actions["WEBAPP_READY"] = std::bind(&ConnectRequestHandler::on_connect_action_webapp_ready, this); + m_actions["SELECT_PRINTER"] = std::bind(&ConnectRequestHandler::on_connect_action_select_printer, this); + m_actions["PRINT"] = std::bind(&ConnectRequestHandler::on_connect_action_print, this); + // obsolete + //m_actions["REQUEST_SELECTED_PRINTER"] = std::bind(&ConnectRequestHandler::on_connect_action_print, this); } ConnectRequestHandler::~ConnectRequestHandler() { @@ -516,17 +517,17 @@ void ConnectRequestHandler::handle_message(const std::string& message) void ConnectRequestHandler::resend_config() { - on_request_config(); + on_connect_action_request_config(); } -void ConnectRequestHandler::on_request_access_token() +void ConnectRequestHandler::on_connect_action_request_access_token() { std::string token = wxGetApp().plater()->get_user_account()->get_access_token(); wxString script = GUI::format_wxstr("window._prusaConnect_v1.setAccessToken(\'%1%\')", token); run_script_bridge(script); } -void ConnectRequestHandler::on_request_config() +void ConnectRequestHandler::on_connect_action_request_config() { /* accessToken?: string; @@ -535,7 +536,6 @@ void ConnectRequestHandler::on_request_config() language?: ConnectLanguage; sessionId?: string; */ - const std::string token = wxGetApp().plater()->get_user_account()->get_access_token(); //const std::string sesh = wxGetApp().plater()->get_user_account()->get_shared_session_key(); const std::string dark_mode = wxGetApp().dark_mode() ? "DARK" : "LIGHT"; @@ -569,12 +569,12 @@ void ConnectWebViewPanel::sys_color_changed() resend_config(); } -void ConnectWebViewPanel::on_request_select_printer() +void ConnectWebViewPanel::on_connect_action_select_printer() { assert(!m_message_data.empty()); wxGetApp().handle_connect_request_printer_select(m_message_data); } -void ConnectWebViewPanel::on_request_print() +void ConnectWebViewPanel::on_connect_action_print() { // PRINT request is not defined for ConnectWebViewPanel assert(true); @@ -1066,19 +1066,19 @@ void PrinterPickWebViewDialog::on_script_message(wxWebViewEvent& evt) handle_message(into_u8(evt.GetString())); } -void PrinterPickWebViewDialog::on_request_select_printer() +void PrinterPickWebViewDialog::on_connect_action_select_printer() { // SELECT_PRINTER request is not defined for PrinterPickWebViewDialog assert(true); } -void PrinterPickWebViewDialog::on_request_print() +void PrinterPickWebViewDialog::on_connect_action_print() { m_ret_val = m_message_data; m_browser->RemoveScriptMessageHandler("_prusaSlicer"); this->EndModal(wxID_OK); } -void PrinterPickWebViewDialog::request_compatible_printers() +void PrinterPickWebViewDialog::on_connect_action_webapp_ready() { if (Preset::printer_technology(wxGetApp().preset_bundle->printers.get_selected_preset().config) == ptFFF) { @@ -1094,6 +1094,7 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF() //material: Material; //nozzleDiameter: number; //printerType: string; + //filename: string; //} const Preset& selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset(); const Preset& selected_filament = wxGetApp().preset_bundle->filaments.get_selected_preset(); @@ -1102,14 +1103,15 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF() const std::string filament_type_serialized = selected_filament.config.option("filament_type")->serialize(); const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize(); const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(); - + const std::string filename = wxGetApp().plater()->get_upload_filename(); const std::string request = GUI::format( "{" "\"printerUuid\": \"%4%\", " "\"printerModel\": \"%3%\", " "\"nozzleDiameter\": %2%, " - "\"material\": \"%1%\" " - "}", filament_type_serialized, nozzle_diameter_serialized, printer_model_serialized, uuid); + "\"material\": \"%1%\", " + "\"filename\": \"%5%\" " + "}", filament_type_serialized, nozzle_diameter_serialized, printer_model_serialized, uuid, filename); wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request); run_script(script); @@ -1121,12 +1123,14 @@ void PrinterPickWebViewDialog::request_compatible_printers_SLA() const Preset& selected_material = wxGetApp().preset_bundle->sla_materials.get_selected_preset(); const std::string material_type_serialized = selected_material.config.option("material_type")->serialize(); const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(); + const std::string filename = wxGetApp().plater()->get_upload_filename(); const std::string request = GUI::format( "{" "\"printerUuid\": \"%3%\", " "\"material\": \"%1%\", " - "\"printerModel\": \"%2%\" " - "}", material_type_serialized, printer_model_serialized, uuid); + "\"printerModel\": \"%2%\", " + "\"filename\": \"%4%\" " + "}", material_type_serialized, printer_model_serialized, uuid, filename); wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request); run_script(script); diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp index 0f3c523ead..457fbe16d1 100644 --- a/src/slic3r/GUI/WebViewDialog.hpp +++ b/src/slic3r/GUI/WebViewDialog.hpp @@ -164,12 +164,12 @@ public: void resend_config(); protected: // action callbacs stored in m_actions - virtual void on_request_access_token(); - virtual void on_request_config(); - virtual void on_request_select_printer() = 0; - virtual void on_request_print() = 0; + virtual void on_connect_action_request_access_token(); + virtual void on_connect_action_request_config(); + virtual void on_connect_action_select_printer() = 0; + virtual void on_connect_action_print() = 0; virtual void run_script_bridge(const wxString& script) = 0; - virtual void request_compatible_printers() = 0; + virtual void on_connect_action_webapp_ready() = 0; std::map> m_actions; std::string m_message_data; @@ -184,9 +184,9 @@ public: void logout(); void sys_color_changed() override; protected: - void on_request_select_printer() override; - void on_request_print() override; - void request_compatible_printers() override {} + void on_connect_action_select_printer() override; + void on_connect_action_print() override; + void on_connect_action_webapp_ready() override {} void run_script_bridge(const wxString& script) override {run_script(script); } }; @@ -234,9 +234,9 @@ public: void on_show(wxShowEvent& evt) override; void on_script_message(wxWebViewEvent& evt) override; protected: - void on_request_select_printer() override; - void on_request_print() override; - void request_compatible_printers() override; + void on_connect_action_select_printer() override; + void on_connect_action_print() override; + void on_connect_action_webapp_ready() override; void request_compatible_printers_FFF(); void request_compatible_printers_SLA(); void run_script_bridge(const wxString& script) override { run_script(script); } From 1264f57f84b4c4c50368acd9132c75123230afd2 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 15 May 2024 17:00:54 +0200 Subject: [PATCH 17/28] Compatible printer check when sending uuid to connect. --- src/slic3r/GUI/Plater.cpp | 1 + src/slic3r/GUI/UserAccount.cpp | 64 ++++++++++++++++++++++++-------- src/slic3r/GUI/UserAccount.hpp | 4 +- src/slic3r/GUI/WebViewDialog.cpp | 4 +- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a238a5df61..13f2b3f35e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -976,6 +976,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) #endif // 0 }); this->q->Bind(EVT_UA_PRUSACONNECT_PRINTER_DATA_SUCCESS, [this](UserAccountSuccessEvent& evt) { + this->user_account->set_current_printer_data(evt.data); wxGetApp().handle_connect_request_printer_select_inner(evt.data); }); this->q->Bind(EVT_UA_PRUSACONNECT_PRINTER_DATA_FAIL, [this](UserAccountFailEvent& evt) { diff --git a/src/slic3r/GUI/UserAccount.cpp b/src/slic3r/GUI/UserAccount.cpp index a6117e2a50..8102c810f6 100644 --- a/src/slic3r/GUI/UserAccount.cpp +++ b/src/slic3r/GUI/UserAccount.cpp @@ -198,6 +198,24 @@ namespace { } return pt::ptree(); } + + void fill_supported_printer_models_from_json_inner(const pt::ptree& ptree, std::vector& result) { + std::string printer_model = parse_tree_for_param(ptree, "printer_model"); + if (!printer_model.empty()) { + result.emplace_back(printer_model); + } + pt::ptree out = parse_tree_for_subtree(ptree, "supported_printer_models"); + if (out.empty()) { + BOOST_LOG_TRIVIAL(error) << "Failed to find supported_printer_models in printer detail."; + return; + } + for (const auto& sub : out) { + if (printer_model != sub.second.data()) { + result.emplace_back(sub.second.data()); + } + + } + } } bool UserAccount::on_connect_printers_success(const std::string& data, AppConfig* app_config, bool& out_printers_changed) @@ -308,6 +326,36 @@ bool UserAccount::on_connect_uiid_map_success(const std::string& data, AppConfig return on_connect_printers_success(data, app_config, out_printers_changed); } +std::string UserAccount::get_current_printer_uuid_from_connect(const std::string& selected_printer_id) const +{ + if (m_current_printer_data_json_from_connect.empty() || m_current_printer_uuid_from_connect.empty()) { + return {}; + } + + pt::ptree ptree; + try { + std::stringstream ss(m_current_printer_data_json_from_connect); + pt::read_json(ss, ptree); + } + catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "Could not parse Printer data from Connect. " << e.what(); + return {}; + } + + std::string data_uuid = parse_tree_for_param(ptree, "uuid"); + assert(data_uuid == m_current_printer_uuid_from_connect); + + //std::string model_name = parse_tree_for_param(ptree, "printer_model"); + std::vector compatible_printers; + fill_supported_printer_models_from_json_inner(ptree, compatible_printers); + if (compatible_printers.empty()) { + return {}; + } + + return std::find(compatible_printers.begin(), compatible_printers.end(), selected_printer_id) == compatible_printers.end() ? "" : m_current_printer_uuid_from_connect; +} + + std::string UserAccount::get_nozzle_from_json(const std::string& message) const { std::string out; @@ -358,21 +406,7 @@ void UserAccount::fill_supported_printer_models_from_json(const std::string& jso pt::ptree ptree; pt::read_json(ss, ptree); - std::string printer_model = parse_tree_for_param(ptree, "printer_model"); - if (!printer_model.empty()) { - result.emplace_back(printer_model); - } - pt::ptree out = parse_tree_for_subtree(ptree, "supported_printer_models"); - if (out.empty()) { - BOOST_LOG_TRIVIAL(error) << "Failed to find supported_printer_models in printer detail."; - return; - } - for (const auto& sub : out) { - if (printer_model != sub.second.data()) { - result.emplace_back(sub.second.data()); - } - - } + fill_supported_printer_models_from_json_inner(ptree, result); } catch (const std::exception& e) { BOOST_LOG_TRIVIAL(error) << "Could not parse prusaconnect message. " << e.what(); diff --git a/src/slic3r/GUI/UserAccount.hpp b/src/slic3r/GUI/UserAccount.hpp index a204a05c31..bfcdae5521 100644 --- a/src/slic3r/GUI/UserAccount.hpp +++ b/src/slic3r/GUI/UserAccount.hpp @@ -73,8 +73,9 @@ public: const std::map& get_printer_state_table() const { return printer_state_table; } void set_current_printer_uuid_from_connect(const std::string& uuid) { m_current_printer_uuid_from_connect = uuid; } - std::string get_current_printer_uuid_from_connect() const { return m_current_printer_uuid_from_connect; } + std::string get_current_printer_uuid_from_connect(const std::string& selected_printer_id) const; + void set_current_printer_data(const std::string& data) { m_current_printer_data_json_from_connect = data; } private: void set_username(const std::string& username); @@ -90,6 +91,7 @@ private: std::string m_avatar_extension; std::string m_current_printer_uuid_from_connect; + std::string m_current_printer_data_json_from_connect; const std::map printer_state_table = { {"OFFLINE" , ConnectPrinterState::CONNECT_PRINTER_OFFLINE}, diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 13c8cc1c01..8bfeeadc1e 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -1102,7 +1102,7 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF() // Sending only first filament type for now. This should change to array of values const std::string filament_type_serialized = selected_filament.config.option("filament_type")->serialize(); const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize(); - const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(); + const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(printer_model_serialized); const std::string filename = wxGetApp().plater()->get_upload_filename(); const std::string request = GUI::format( "{" @@ -1122,7 +1122,7 @@ void PrinterPickWebViewDialog::request_compatible_printers_SLA() const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize(); const Preset& selected_material = wxGetApp().preset_bundle->sla_materials.get_selected_preset(); const std::string material_type_serialized = selected_material.config.option("material_type")->serialize(); - const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(); + const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(printer_model_serialized); const std::string filename = wxGetApp().plater()->get_upload_filename(); const std::string request = GUI::format( "{" From 64c497ce0dbfa8e6703f1f92ef12b491f1cd8fe9 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 16 May 2024 12:31:55 +0200 Subject: [PATCH 18/28] Upload to Connect changes --- src/slic3r/GUI/Plater.cpp | 32 +++++++++++++++++++++++-------- src/slic3r/Utils/PrintHost.hpp | 4 ++++ src/slic3r/Utils/PrusaConnect.cpp | 16 +++++++++++++++- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 13f2b3f35e..6289f60293 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6059,12 +6059,12 @@ void Plater::connect_gcode() std::string printer_uuid; std::string team_id; */ - bool set_ready = true; - int position = -1; - int wait_until = 0; - std::string filename = "print.bgcode"; - std::string printer_uuid = "1234-1234-1234-1234"; - std::string team_id = "1234"; + std::string set_ready = p->user_account->get_keyword_from_json(dialog_msg, "set_ready"); + std::string position = p->user_account->get_keyword_from_json(dialog_msg, "position"); + std::string wait_until = p->user_account->get_keyword_from_json(dialog_msg, "wait_until"); + std::string filename = p->user_account->get_keyword_from_json(dialog_msg, "filename"); + std::string printer_uuid = p->user_account->get_keyword_from_json(dialog_msg, "printer_uuid"); + std::string team_id = p->user_account->get_keyword_from_json(dialog_msg, "team_id"); PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *selected_printer_preset); ph_printer.config.set_key_value("host_type", new ConfigOptionEnum(htPrusaConnectNew)); @@ -6075,8 +6075,24 @@ void Plater::connect_gcode() PrintHostJob upload_job(physical_printer_config); assert(!upload_job.empty()); - - upload_job.upload_data.upload_path = filename; + /* + wxArrayString storage_paths; + wxArrayString storage_names; + { + wxBusyCursor wait; + try { + upload_job.printhost->get_storage(storage_paths, storage_names); + } + catch (const Slic3r::IOError& ex) { + show_error(this, ex.what(), false); + return; + } + } + */ + upload_job.upload_data.set_ready = set_ready; + upload_job.upload_data.position = position; + upload_job.upload_data.wait_until = wait_until; + upload_job.upload_data.upload_path = filename + ".bgcode"; upload_job.upload_data.post_action = PrintHostPostUploadAction::None; p->export_gcode(fs::path(), false, std::move(upload_job)); diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp index 89f0e1168a..f7b3a5175c 100644 --- a/src/slic3r/Utils/PrintHost.hpp +++ b/src/slic3r/Utils/PrintHost.hpp @@ -41,6 +41,10 @@ struct PrintHostUpload std::string storage; PrintHostPostUploadAction post_action { PrintHostPostUploadAction::None }; + + std::string set_ready; + std::string position; + std::string wait_until; }; class PrintHost diff --git a/src/slic3r/Utils/PrusaConnect.cpp b/src/slic3r/Utils/PrusaConnect.cpp index e7e35794e1..d3c8119ac9 100644 --- a/src/slic3r/Utils/PrusaConnect.cpp +++ b/src/slic3r/Utils/PrusaConnect.cpp @@ -159,7 +159,21 @@ bool PrusaConnectNew::upload(PrintHostUpload upload_data, ProgressFn progress_fn const std::string escaped_upload_path = upload_data.storage + "/" + escape_path_by_element(upload_data.upload_path.string()); const std::string to_print = upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false"; const std::string to_queue = upload_data.post_action == PrintHostPostUploadAction::QueuePrint ? "true" : "false"; - std::string url = GUI::format("%1%/app/teams/%2%/files/raw?upload_id=%3%&force=true&printer_uuid=%4%&path=%5%&to_print=%6%&to_queue=%7%", get_host(), m_team_id, upload_id, m_uuid, escaped_upload_path, to_print, to_queue); + const std::string set_ready = upload_data.set_ready.empty() ? "" : "&set_ready=" + upload_data.set_ready; + const std::string position = upload_data.position.empty() ? "" : "&position=" + upload_data.position; + const std::string wait_until = upload_data.wait_until.empty() ? "" : "&wait_until=" + upload_data.wait_until; + const std::string url = GUI::format( + "%1%/app/teams/%2%/files/raw" + "?upload_id=%3%" + "&force=true" + "&printer_uuid=%4%" + "&path=%5%" + "&to_print=%6%" + "&to_queue=%7%" + "%8%" + "%9%" + "%10%" + , get_host(), m_team_id, upload_id, m_uuid, escaped_upload_path, to_print, to_queue, set_ready, position, wait_until); bool res = true; BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%") From c0aa09791f5eaeced40601d058ed91455d75c6f7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 16 May 2024 15:32:53 +0200 Subject: [PATCH 19/28] fix of upload filename --- src/slic3r/GUI/Plater.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6289f60293..3923af4231 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6092,7 +6092,7 @@ void Plater::connect_gcode() upload_job.upload_data.set_ready = set_ready; upload_job.upload_data.position = position; upload_job.upload_data.wait_until = wait_until; - upload_job.upload_data.upload_path = filename + ".bgcode"; + upload_job.upload_data.upload_path = filename; upload_job.upload_data.post_action = PrintHostPostUploadAction::None; p->export_gcode(fs::path(), false, std::move(upload_job)); @@ -6159,7 +6159,7 @@ std::string Plater::get_upload_filename() } default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); - return default_output_file.string(); + return default_output_file.filename().string(); } void Plater::send_gcode_inner(DynamicPrintConfig* physical_printer_config) From 2c09c034b38b6010fd982fab49f72ed1a93b1c1e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 16 May 2024 18:04:11 +0200 Subject: [PATCH 20/28] Remove deprecated arguments from connect upload --- src/slic3r/GUI/Plater.cpp | 1 - src/slic3r/Utils/PrusaConnect.cpp | 10 +++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3923af4231..2f605121b4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6093,7 +6093,6 @@ void Plater::connect_gcode() upload_job.upload_data.position = position; upload_job.upload_data.wait_until = wait_until; upload_job.upload_data.upload_path = filename; - upload_job.upload_data.post_action = PrintHostPostUploadAction::None; p->export_gcode(fs::path(), false, std::move(upload_job)); diff --git a/src/slic3r/Utils/PrusaConnect.cpp b/src/slic3r/Utils/PrusaConnect.cpp index d3c8119ac9..1393f90887 100644 --- a/src/slic3r/Utils/PrusaConnect.cpp +++ b/src/slic3r/Utils/PrusaConnect.cpp @@ -157,8 +157,6 @@ bool PrusaConnectNew::upload(PrintHostUpload upload_data, ProgressFn progress_fn const std::string name = get_name(); const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token(); const std::string escaped_upload_path = upload_data.storage + "/" + escape_path_by_element(upload_data.upload_path.string()); - const std::string to_print = upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false"; - const std::string to_queue = upload_data.post_action == PrintHostPostUploadAction::QueuePrint ? "true" : "false"; const std::string set_ready = upload_data.set_ready.empty() ? "" : "&set_ready=" + upload_data.set_ready; const std::string position = upload_data.position.empty() ? "" : "&position=" + upload_data.position; const std::string wait_until = upload_data.wait_until.empty() ? "" : "&wait_until=" + upload_data.wait_until; @@ -168,12 +166,10 @@ bool PrusaConnectNew::upload(PrintHostUpload upload_data, ProgressFn progress_fn "&force=true" "&printer_uuid=%4%" "&path=%5%" - "&to_print=%6%" - "&to_queue=%7%" + "%6%" + "%7%" "%8%" - "%9%" - "%10%" - , get_host(), m_team_id, upload_id, m_uuid, escaped_upload_path, to_print, to_queue, set_ready, position, wait_until); + , get_host(), m_team_id, upload_id, m_uuid, escaped_upload_path, set_ready, position, wait_until); bool res = true; BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%") From 9a5fee2d1943eef4789f52e39fd8a18b7b2e7bf4 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 16 May 2024 19:14:14 +0200 Subject: [PATCH 21/28] Upload path fix --- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/Utils/PrusaConnect.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2f605121b4..a9d00f92a7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6092,7 +6092,7 @@ void Plater::connect_gcode() upload_job.upload_data.set_ready = set_ready; upload_job.upload_data.position = position; upload_job.upload_data.wait_until = wait_until; - upload_job.upload_data.upload_path = filename; + upload_job.upload_data.upload_path = boost::filesystem::path(filename); p->export_gcode(fs::path(), false, std::move(upload_job)); diff --git a/src/slic3r/Utils/PrusaConnect.cpp b/src/slic3r/Utils/PrusaConnect.cpp index 1393f90887..297986cf6f 100644 --- a/src/slic3r/Utils/PrusaConnect.cpp +++ b/src/slic3r/Utils/PrusaConnect.cpp @@ -90,7 +90,7 @@ bool PrusaConnectNew::init_upload(PrintHostUpload upload_data, std::string& out) const std::string name = get_name(); const std::string file_size = std::to_string(size); const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token(); - const std::string upload_path = upload_data.upload_path.generic_string(); + //const std::string upload_path = upload_data.upload_path.generic_string(); const std::string upload_filename = upload_data.upload_path.filename().string(); std::string url = GUI::format("%1%/app/users/teams/%2%/uploads", get_host(), m_team_id); const std::string request_body_json = GUI::format( @@ -103,7 +103,7 @@ bool PrusaConnectNew::init_upload(PrintHostUpload upload_data, std::string& out) "}" , upload_filename , file_size - , upload_data.storage + "/" + upload_path + , upload_data.upload_path.string() , m_uuid ); From 9f95549dcfa0d5626b23c1c32b9f00a336c5de20 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 17 May 2024 12:19:02 +0200 Subject: [PATCH 22/28] Pass path string without converting to boost --- src/slic3r/GUI/Plater.cpp | 178 ++---------------------------- src/slic3r/Utils/PrintHost.hpp | 1 + src/slic3r/Utils/PrusaConnect.cpp | 2 +- 3 files changed, 11 insertions(+), 170 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a9d00f92a7..6f46fbeff9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5889,7 +5889,6 @@ void Plater::connect_gcode() assert(p->user_account->is_logged()); std::string dialog_msg; { - //PrinterPickWebViewDialog* dialog = new PrinterPickWebViewDialog(this, dialog_msg); PrinterPickWebViewDialog dialog(this, dialog_msg); if (dialog.ShowModal() != wxID_OK) { return; @@ -5900,171 +5899,24 @@ void Plater::connect_gcode() return; } BOOST_LOG_TRIVIAL(debug) << "Message from Printer pick webview: " << dialog_msg; - /* - PresetBundle* preset_bundle = wxGetApp().preset_bundle; - // Connect data - std::vector compatible_printers; - p->user_account->fill_supported_printer_models_from_json(dialog_msg, compatible_printers); - std::string connect_nozzle = p->user_account->get_nozzle_from_json(dialog_msg); - - std::vector connect_materials; - p->user_account->fill_material_from_json(dialog_msg, connect_materials); - - std::vector compatible_printer_presets; - for (const std::string& cp : compatible_printers) { - const Preset* found_preset = preset_bundle->printers.find_system_preset_by_model_and_variant(cp, connect_nozzle); - if (found_preset) { - compatible_printer_presets.emplace_back(found_preset); - } - } - if (compatible_printer_presets.empty()) { - show_error(this, _L("No compatible printer presets found.")); - return; - } - // Selected profiles - const Preset* selected_printer_preset = &preset_bundle->printers.get_selected_preset(); - const std::string selected_printer_model_serialized = selected_printer_preset->config.option("printer_model")->serialize(); - - bool selected_filament_ok = true; - if (Preset::printer_technology(selected_printer_preset->config) == ptFFF) { - size_t extruder_count = preset_bundle->extruders_filaments.size(); - for (size_t i = 0; i < extruder_count; i++) { - if (connect_materials.size() <= i) { - selected_filament_ok = false; - break; - } - const Preset* selected_filament_preset = preset_bundle->extruders_filaments[i].get_selected_preset(); - if (selected_filament_preset && selected_filament_preset->config.has("filament_type") - && selected_filament_preset->config.option("filament_type")->serialize() != connect_materials[i]) - { - selected_filament_ok = false; - break; - } - } - } - - - bool is_first = compatible_printer_presets.front()->name == selected_printer_preset->name; - bool found = false; - for (const Preset* connect_preset : compatible_printer_presets) { - if (!connect_preset) { - continue; - } - if (selected_printer_preset->name == connect_preset->name) { - found = true; - break; - } - } - // Dialog to select action - if (!found) { - wxString line1 = _L("The printer you've selected for upload is not compatible with profiles selected for slicing."); - wxString line2 = GUI::format_wxstr(_L("PrusaSlicer Profile:\n%1%"), selected_printer_preset->name); - wxString line3 = _L("Known profiles compatible with printer selected for upload:"); - wxString printers_line; - for (const Preset* connect_preset : compatible_printer_presets) { - if (!connect_preset) { - continue; - } - printers_line += GUI::format_wxstr(_L("\n%1%"), connect_preset->name); - } - wxString line4 = _L("Do you still wish to upload?"); - wxString message = GUI::format_wxstr("%1%\n\n%2%\n\n%3%%4%\n\n%5%", line1, line2, line3, printers_line,line4); - MessageDialog msg_dialog(this, message, _L("Do you wish to upload?"), wxYES_NO); - auto modal_res = msg_dialog.ShowModal(); - if (modal_res != wxID_YES) { - return; - } - } else if (!is_first) { - wxString line1 = _L("The printer you've selected for upload might not be compatible with profiles selected for slicing."); - wxString line2 = GUI::format_wxstr(_L("PrusaSlicer Profile:\n%1%"), selected_printer_preset->name); - wxString line3 = _L("Known profiles compatible with printer selected for upload:"); - wxString printers_line; - for (const Preset* connect_preset : compatible_printer_presets) { - if (!connect_preset) { - continue; - } - printers_line += GUI::format_wxstr(_L("\n%1%"), connect_preset->name); - } - wxString line4 = _L("Do you still wish to upload?"); - wxString message = GUI::format_wxstr("%1%\n\n%2%\n\n%3%%4%\n\n%5%", line1, line2, line3, printers_line, line4); - MessageDialog msg_dialog(this, message, _L("Do you wish to upload?"), wxYES_NO); - auto modal_res = msg_dialog.ShowModal(); - if (modal_res != wxID_YES) { - return; - } - } - - if (!connect_materials.empty() && !selected_filament_ok) { - wxString line1 = _L("The printer you've selected has different filament type than filament profile selected for slicing."); - wxString connect_filament_types = "\n"; - for (size_t i = 0; i < connect_materials.size(); i++) { - connect_filament_types += GUI::format_wxstr(_L("Extruder %1%: %2%\n"), i + 1, connect_materials[i]); - } - wxString line2 = GUI::format_wxstr(_L("PrusaConnect Filament Type: %1%"), connect_filament_types); - - wxString selected_filament_types = "\n"; - for (size_t i = 0; i < preset_bundle->extruders_filaments.size(); i++) { - const Preset* selected_filament_preset = preset_bundle->extruders_filaments[i].get_selected_preset(); - std::string filament_serialized; - if (selected_filament_preset && selected_filament_preset->config.has("filament_type")) { - filament_serialized = selected_filament_preset->config.option("filament_type")->serialize(); - } - selected_filament_types += GUI::format_wxstr(_L("Extruder %1%: %2%\n"), i + 1, filament_serialized); - } - wxString line3 = GUI::format_wxstr(_L("PrusaSlicer Filament Type: %1%"), selected_filament_types); - wxString line4 = _L("Do you still wish to upload?"); - wxString message = GUI::format_wxstr("%1%\n\n%2%\n%3%\n\n%4%", line1, line2, line3, line4); - MessageDialog msg_dialog(this, message, _L("Do you wish to upload?"), wxYES_NO); - auto modal_res = msg_dialog.ShowModal(); - if (modal_res != wxID_YES) { - return; - } - } - - const std::string connect_state = p->user_account->get_keyword_from_json(dialog_msg, "connect_state"); - const std::string printer_state = p->user_account->get_keyword_from_json(dialog_msg, "printer_state"); - const std::map& printer_state_table = p->user_account->get_printer_state_table(); - const auto state = printer_state_table.find(connect_state); - assert(state != printer_state_table.end()); - // TODO: all states that does not allow to upload - if (state->second == ConnectPrinterState::CONNECT_PRINTER_OFFLINE) { - show_error(this, _L("Failed to select a printer. Chosen printer is in offline state.")); - return; - } - - const std::string uuid = p->user_account->get_keyword_from_json(dialog_msg, "uuid"); - const std::string team_id = p->user_account->get_keyword_from_json(dialog_msg, "team_id"); - if (uuid.empty() || team_id.empty()) { - show_error(this, _L("Failed to select a printer. Missing data (uuid and team id) for chosen printer.")); - return; - } - */ /* { set_ready: boolean, // uzivatel potvrdil ze je tiskarne ready a muze se tisknout, pouziva se pro tisknout ted a odlozeny tisk position: -1 | 0, // -1 = posledni ve fronte, 0 = prvni ve fronte wait_until: number | undefined, // timestamp pro odlozeny tisk - file_name: string, // tady budeme predavat jak se uzivatel rozhodl soubor pojmenovat, kdyz ho neprejmenuje, tak vratime to stejne co nam predtim posle slicer printer_uuid: string // uuid vybrane tiskarny } */ const Preset* selected_printer_preset = &wxGetApp().preset_bundle->printers.get_selected_preset(); - /* - bool set_ready; - int position; - int wait_until; - std::string filename; - std::string printer_uuid; - std::string team_id; - */ - std::string set_ready = p->user_account->get_keyword_from_json(dialog_msg, "set_ready"); - std::string position = p->user_account->get_keyword_from_json(dialog_msg, "position"); - std::string wait_until = p->user_account->get_keyword_from_json(dialog_msg, "wait_until"); - std::string filename = p->user_account->get_keyword_from_json(dialog_msg, "filename"); - std::string printer_uuid = p->user_account->get_keyword_from_json(dialog_msg, "printer_uuid"); - std::string team_id = p->user_account->get_keyword_from_json(dialog_msg, "team_id"); + + const std::string set_ready = p->user_account->get_keyword_from_json(dialog_msg, "set_ready"); + const std::string position = p->user_account->get_keyword_from_json(dialog_msg, "position"); + const std::string wait_until = p->user_account->get_keyword_from_json(dialog_msg, "wait_until"); + const std::string filename = p->user_account->get_keyword_from_json(dialog_msg, "filename"); + const std::string printer_uuid = p->user_account->get_keyword_from_json(dialog_msg, "printer_uuid"); + const std::string team_id = p->user_account->get_keyword_from_json(dialog_msg, "team_id"); PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *selected_printer_preset); ph_printer.config.set_key_value("host_type", new ConfigOptionEnum(htPrusaConnectNew)); @@ -6075,24 +5927,12 @@ void Plater::connect_gcode() PrintHostJob upload_job(physical_printer_config); assert(!upload_job.empty()); - /* - wxArrayString storage_paths; - wxArrayString storage_names; - { - wxBusyCursor wait; - try { - upload_job.printhost->get_storage(storage_paths, storage_names); - } - catch (const Slic3r::IOError& ex) { - show_error(this, ex.what(), false); - return; - } - } - */ + upload_job.upload_data.set_ready = set_ready; upload_job.upload_data.position = position; upload_job.upload_data.wait_until = wait_until; upload_job.upload_data.upload_path = boost::filesystem::path(filename); + upload_job.upload_data.connect_path = filename; p->export_gcode(fs::path(), false, std::move(upload_job)); diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp index f7b3a5175c..99fe6e671d 100644 --- a/src/slic3r/Utils/PrintHost.hpp +++ b/src/slic3r/Utils/PrintHost.hpp @@ -45,6 +45,7 @@ struct PrintHostUpload std::string set_ready; std::string position; std::string wait_until; + std::string connect_path; }; class PrintHost diff --git a/src/slic3r/Utils/PrusaConnect.cpp b/src/slic3r/Utils/PrusaConnect.cpp index 297986cf6f..f64339b16a 100644 --- a/src/slic3r/Utils/PrusaConnect.cpp +++ b/src/slic3r/Utils/PrusaConnect.cpp @@ -103,7 +103,7 @@ bool PrusaConnectNew::init_upload(PrintHostUpload upload_data, std::string& out) "}" , upload_filename , file_size - , upload_data.upload_path.string() + , upload_data.connect_path , m_uuid ); From e3d41bc814849415bf95a4e056a2b5c52ae8a914 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 17 May 2024 15:07:31 +0200 Subject: [PATCH 23/28] Polling 10 seconds --- src/slic3r/GUI/UserAccountCommunication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/UserAccountCommunication.cpp b/src/slic3r/GUI/UserAccountCommunication.cpp index d2d1aa3e68..611bd18159 100644 --- a/src/slic3r/GUI/UserAccountCommunication.cpp +++ b/src/slic3r/GUI/UserAccountCommunication.cpp @@ -355,7 +355,7 @@ void UserAccountCommunication::init_session_thread() // Wait for 5 seconds or wakeup call { std::unique_lock lck(m_thread_stop_mutex); - m_thread_stop_condition.wait_for(lck, std::chrono::seconds(5), [this] { return m_thread_stop || m_thread_wakeup; }); + m_thread_stop_condition.wait_for(lck, std::chrono::seconds(10), [this] { return m_thread_stop || m_thread_wakeup; }); } if (m_thread_stop) // Stop the worker thread. From 84653cc984e195857727ebd2cc4904912b30beda Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 17 May 2024 15:13:31 +0200 Subject: [PATCH 24/28] Remove "total" from status line. --- src/slic3r/GUI/PresetComboBoxes.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 9158fd04b6..9d42a80a65 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -962,11 +962,10 @@ static wxString get_connect_info_line(const Preset& printer_preset) { PrinterStatesCount states_cnt = get_printe_states_count(states); - return format_wxstr(_L("Available: %1%, Offline: %2%, Busy: %3%. Total: %4% printers"), + return format_wxstr(_L("Available: %1%, Offline: %2%, Busy: %3%"), format("%1%" , states_cnt.available_cnt), format("%1%" , states_cnt.offline_cnt), - format("%1%", states_cnt.busy_cnt), - format("%1%", states_cnt.total)); + format("%1%", states_cnt.busy_cnt)); } } } From e553ac5360a0c0fcadae73345b0f2f1bb77ef02b Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 20 May 2024 13:03:58 +0200 Subject: [PATCH 25/28] Fix of webview dialog closing. Custom script message handlers. --- src/slic3r/GUI/WebView.cpp | 15 ++++++----- src/slic3r/GUI/WebView.hpp | 2 +- src/slic3r/GUI/WebViewDialog.cpp | 46 +++++++++++++++----------------- src/slic3r/GUI/WebViewDialog.hpp | 33 +++++++---------------- 4 files changed, 42 insertions(+), 54 deletions(-) diff --git a/src/slic3r/GUI/WebView.cpp b/src/slic3r/GUI/WebView.cpp index fe191f4747..5a97802506 100644 --- a/src/slic3r/GUI/WebView.cpp +++ b/src/slic3r/GUI/WebView.cpp @@ -1,12 +1,13 @@ #include "WebView.hpp" #include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/GUI.hpp" #include #include #include -wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url) +wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url, std::vector& message_handlers) { #if wxUSE_WEBVIEW_EDGE bool backend_available = wxWebView::IsBackendAvailable(wxWebViewBackendEdge); @@ -37,12 +38,14 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, const wxString& url) webView->SetUserAgent(wxString::FromUTF8(SLIC3R_APP_FULL_NAME)); #endif #ifndef __WIN32__ - Slic3r::GUI::wxGetApp().CallAfter([webView] { + Slic3r::GUI::wxGetApp().CallAfter([message_handlers, webView] { #endif - if (!webView->AddScriptMessageHandler("_prusaSlicer")) { - // TODO: dialog to user !!! - //wxLogError("Could not add script message handler"); - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Could not add script message handler"; + for (const std::string& handler : message_handlers) { + if (!webView->AddScriptMessageHandler(Slic3r::GUI::into_u8(handler))) { + // TODO: dialog to user !!! + //wxLogError("Could not add script message handler"); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Could not add script message handler " << handler; + } } #ifndef __WIN32__ }); diff --git a/src/slic3r/GUI/WebView.hpp b/src/slic3r/GUI/WebView.hpp index 40ea745f10..b391662c1a 100644 --- a/src/slic3r/GUI/WebView.hpp +++ b/src/slic3r/GUI/WebView.hpp @@ -7,7 +7,7 @@ class wxString; namespace WebView { - wxWebView *CreateWebView(wxWindow *parent, const wxString& url); + wxWebView *CreateWebView(wxWindow *parent, const wxString& url, std::vector& message_handlers); }; #endif // !slic3r_GUI_WebView_hpp_ diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 8bfeeadc1e..3804ec4ea3 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -22,10 +22,11 @@ namespace Slic3r { namespace GUI { -WebViewPanel::WebViewPanel(wxWindow *parent, const wxString& default_url, const std::string& loading_html/* = "loading"*/) +WebViewPanel::WebViewPanel(wxWindow *parent, const wxString& default_url, const std::vector& message_handler_names, const std::string& loading_html/* = "loading"*/) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) , m_default_url (default_url) , m_loading_html(loading_html) + , m_script_message_hadler_names(message_handler_names) { wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); #ifdef DEBUG_URL_PANEL @@ -70,7 +71,7 @@ WebViewPanel::WebViewPanel(wxWindow *parent, const wxString& default_url, const SetSizer(topsizer); // Create the webview - m_browser = WebView::CreateWebView(this, /*m_default_url*/ GUI::format_wxstr("file://%1%/web/%2%.html", boost::filesystem::path(resources_dir()).generic_string(), m_loading_html)); + m_browser = WebView::CreateWebView(this, /*m_default_url*/ GUI::format_wxstr("file://%1%/web/%2%.html", boost::filesystem::path(resources_dir()).generic_string(), m_loading_html), m_script_message_hadler_names); if (!m_browser) { wxStaticText* text = new wxStaticText(this, wxID_ANY, _L("Failed to load a web browser.")); topsizer->Add(text, 0, wxALIGN_LEFT | wxBOTTOM, 10); @@ -122,8 +123,6 @@ WebViewPanel::WebViewPanel(wxWindow *parent, const wxString& default_url, const #endif //Connect the idle events Bind(wxEVT_IDLE, &WebViewPanel::on_idle, this); - Bind(wxEVT_CLOSE_WINDOW, &WebViewPanel::on_close, this); - } WebViewPanel::~WebViewPanel() @@ -245,11 +244,6 @@ void WebViewPanel::on_reload_button(wxCommandEvent& WXUNUSED(evt)) m_browser->Reload(); } -void WebViewPanel::on_close(wxCloseEvent& evt) -{ - this->Hide(); -} - void WebViewPanel::on_script_message(wxWebViewEvent& evt) { } @@ -548,7 +542,7 @@ void ConnectRequestHandler::on_connect_action_request_config() } ConnectWebViewPanel::ConnectWebViewPanel(wxWindow* parent) - : WebViewPanel(parent, L"https://connect.prusa3d.com/", "connect_loading") + : WebViewPanel(parent, L"https://connect.prusa3d.com/", { "_prusaSlicer" }, "connect_loading") { } @@ -581,7 +575,7 @@ void ConnectWebViewPanel::on_connect_action_print() } PrinterWebViewPanel::PrinterWebViewPanel(wxWindow* parent, const wxString& default_url) - : WebViewPanel(parent, default_url) + : WebViewPanel(parent, default_url, {}) { if (!m_browser) return; @@ -654,9 +648,10 @@ void PrinterWebViewPanel::sys_color_changed() { } -WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size, const std::string& loading_html/* = "loading"*/) +WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size, const std::vector& message_handler_names, const std::string& loading_html/* = "loading"*/) : wxDialog(parent, wxID_ANY, dialog_name, wxDefaultPosition, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , m_loading_html(loading_html) + , m_script_message_hadler_names (message_handler_names) { wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); #ifdef DEBUG_URL_PANEL @@ -697,7 +692,7 @@ WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxStri SetSizerAndFit(topsizer); // Create the webview - m_browser = WebView::CreateWebView(this, GUI::format_wxstr("file://%1%/web/%2%.html", boost::filesystem::path(resources_dir()).generic_string(), m_loading_html)); + m_browser = WebView::CreateWebView(this, GUI::format_wxstr("file://%1%/web/%2%.html", boost::filesystem::path(resources_dir()).generic_string(), m_loading_html), m_script_message_hadler_names); if (!m_browser) { wxStaticText* text = new wxStaticText(this, wxID_ANY, _L("Failed to load a web browser.")); topsizer->Add(text, 0, wxALIGN_LEFT | wxBOTTOM, 10); @@ -732,7 +727,6 @@ WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxStri Bind(wxEVT_WEBVIEW_ERROR, &WebViewDialog::on_error, this, m_browser->GetId()); //Connect the idle events Bind(wxEVT_IDLE, &WebViewDialog::on_idle, this); - Bind(wxEVT_CLOSE_WINDOW, &WebViewDialog::on_close, this); #ifdef DEBUG_URL_PANEL // Connect the button events Bind(wxEVT_BUTTON, &WebViewDialog::on_back_button, this, m_button_back->GetId()); @@ -752,6 +746,8 @@ WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxStri Bind(wxEVT_MENU, &WebViewDialog::on_add_user_script, this, addUserScript->GetId()); #endif + Bind(wxEVT_CLOSE_WINDOW, ([this](wxCloseEvent& evt) { EndModal(wxID_CANCEL); })); + m_browser->LoadURL(url); #ifdef DEBUG_URL_PANEL m_url->SetLabelText(url); @@ -761,10 +757,6 @@ WebViewDialog::~WebViewDialog() { } - - - - void WebViewDialog::on_idle(wxIdleEvent& WXUNUSED(evt)) { if (!m_browser) @@ -836,11 +828,6 @@ void WebViewDialog::on_reload_button(wxCommandEvent& WXUNUSED(evt)) m_browser->Reload(); } -void WebViewDialog::on_close(wxCloseEvent& evt) -{ - this->Hide(); -} - void WebViewDialog::on_script_message(wxWebViewEvent& evt) { } @@ -1040,11 +1027,23 @@ void WebViewDialog::run_script(const wxString& javascript) m_browser->RunScriptAsync(javascript); } +void WebViewDialog::EndModal(int retCode) +{ + if (m_browser) { + for (const std::string& handler : m_script_message_hadler_names) { + m_browser->RemoveScriptMessageHandler(GUI::into_u8(handler)); + } + } + + wxDialog::EndModal(retCode); +} + PrinterPickWebViewDialog::PrinterPickWebViewDialog(wxWindow* parent, std::string& ret_val) : WebViewDialog(parent , L"https://connect.prusa3d.com/slicer-select-printer" , _L("Choose a printer") , wxSize(std::max(parent->GetClientSize().x / 2, 100 * wxGetApp().em_unit()), std::max(parent->GetClientSize().y / 2, 50 * wxGetApp().em_unit())) + ,{"_prusaSlicer"} , "connect_loading") , m_ret_val(ret_val) { @@ -1074,7 +1073,6 @@ void PrinterPickWebViewDialog::on_connect_action_select_printer() void PrinterPickWebViewDialog::on_connect_action_print() { m_ret_val = m_message_data; - m_browser->RemoveScriptMessageHandler("_prusaSlicer"); this->EndModal(wxID_OK); } diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp index 457fbe16d1..6b95ff8975 100644 --- a/src/slic3r/GUI/WebViewDialog.hpp +++ b/src/slic3r/GUI/WebViewDialog.hpp @@ -16,7 +16,7 @@ namespace GUI { class WebViewPanel : public wxPanel { public: - WebViewPanel(wxWindow *parent, const wxString& default_url, const std::string& loading_html = "loading"); + WebViewPanel(wxWindow *parent, const wxString& default_url, const std::vector& message_handler_names, const std::string& loading_html = "loading"); virtual ~WebViewPanel(); void load_url(const wxString& url); @@ -47,7 +47,6 @@ public: void on_select_all(wxCommandEvent& evt); void On_enable_context_menu(wxCommandEvent& evt); void On_enable_dev_tools(wxCommandEvent& evt); - void on_close(wxCloseEvent& evt); wxString get_default_url() const { return m_default_url; } void set_default_url(const wxString& url) { m_default_url = url; } @@ -55,7 +54,7 @@ public: virtual void sys_color_changed(); protected: - wxWebView* m_browser; + wxWebView* m_browser { nullptr }; bool m_load_default_url { false }; #ifdef DEBUG_URL_PANEL @@ -87,13 +86,15 @@ protected: bool m_load_error_page { false }; bool m_shown { false }; + + std::vector m_script_message_hadler_names; }; class WebViewDialog : public wxDialog { public: - WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size, const std::string& loading_html = "loading"); + WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size, const std::vector& message_handler_names, const std::string& loading_html = "loading"); virtual ~WebViewDialog(); virtual void on_show(wxShowEvent& evt) = 0; @@ -119,14 +120,14 @@ public: void on_select_all(wxCommandEvent& evt); void On_enable_context_menu(wxCommandEvent& evt); void On_enable_dev_tools(wxCommandEvent& evt); - void on_close(wxCloseEvent& evt); void run_script(const wxString& javascript); void load_error_page(); + virtual void EndModal(int retCode) wxOVERRIDE; protected: - wxWebView* m_browser; + wxWebView* m_browser {nullptr}; std::string m_loading_html; bool m_load_error_page{ false }; @@ -152,6 +153,8 @@ protected: wxString m_javascript; wxString m_response_js; wxString m_default_url; + + std::vector m_script_message_hadler_names; }; class ConnectRequestHandler @@ -210,23 +213,6 @@ private: bool m_api_key_sent {false}; }; -/* -class WebViewDialog : public wxDialog -{ -public: - WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size, const std::string& loading_html = "loading"); - virtual ~WebViewDialog(); - - virtual void on_show(wxShowEvent& evt) = 0; - virtual void on_script_message(wxWebViewEvent& evt) = 0; - - void run_script(const wxString& javascript); - -protected: - wxWebView* m_browser; - std::string m_loading_html; -}; -*/ class PrinterPickWebViewDialog : public WebViewDialog, public ConnectRequestHandler { public: @@ -240,6 +226,7 @@ protected: void request_compatible_printers_FFF(); void request_compatible_printers_SLA(); void run_script_bridge(const wxString& script) override { run_script(script); } + private: std::string& m_ret_val; }; From 835e6d4805e213ab7f1b245c05400241772f3399 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 20 May 2024 15:06:56 +0200 Subject: [PATCH 26/28] Fix of path sharing during upload. --- src/slic3r/GUI/Plater.cpp | 1 - src/slic3r/Utils/PrintHost.hpp | 1 - src/slic3r/Utils/PrusaConnect.cpp | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6f46fbeff9..6428d299dc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5932,7 +5932,6 @@ void Plater::connect_gcode() upload_job.upload_data.position = position; upload_job.upload_data.wait_until = wait_until; upload_job.upload_data.upload_path = boost::filesystem::path(filename); - upload_job.upload_data.connect_path = filename; p->export_gcode(fs::path(), false, std::move(upload_job)); diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp index 99fe6e671d..f7b3a5175c 100644 --- a/src/slic3r/Utils/PrintHost.hpp +++ b/src/slic3r/Utils/PrintHost.hpp @@ -45,7 +45,6 @@ struct PrintHostUpload std::string set_ready; std::string position; std::string wait_until; - std::string connect_path; }; class PrintHost diff --git a/src/slic3r/Utils/PrusaConnect.cpp b/src/slic3r/Utils/PrusaConnect.cpp index f64339b16a..19da1cb832 100644 --- a/src/slic3r/Utils/PrusaConnect.cpp +++ b/src/slic3r/Utils/PrusaConnect.cpp @@ -103,7 +103,7 @@ bool PrusaConnectNew::init_upload(PrintHostUpload upload_data, std::string& out) "}" , upload_filename , file_size - , upload_data.connect_path + , upload_data.upload_path.generic_string() , m_uuid ); From 3e1baf0a6169759079520104f2caa6e45706d345 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 20 May 2024 15:35:35 +0200 Subject: [PATCH 27/28] Do not poll printers when window is not active. --- src/slic3r/GUI/MainFrame.cpp | 4 ++-- src/slic3r/GUI/Plater.cpp | 7 +++++-- src/slic3r/GUI/Plater.hpp | 2 +- src/slic3r/GUI/UserAccount.hpp | 2 ++ src/slic3r/GUI/UserAccountCommunication.cpp | 10 ++++++++++ src/slic3r/GUI/UserAccountCommunication.hpp | 2 ++ 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 8d6572af94..7d2ffdcabb 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -272,8 +272,8 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S //FIXME it seems this method is not called on application start-up, at least not on Windows. Why? // The same applies to wxEVT_CREATE, it is not being called on startup on Windows. Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& event) { - if (m_plater != nullptr && event.GetActive()) - m_plater->on_activate(); + if (m_plater != nullptr) + m_plater->on_activate(event.GetActive()); event.Skip(); }); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6428d299dc..7fe362f5ea 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6300,9 +6300,12 @@ void Plater::force_print_bed_update() p->config->opt_string("printer_model", true) = "\x01\x00\x01"; } -void Plater::on_activate() +void Plater::on_activate(bool active) { - this->p->show_delayed_error_message(); + this->p->user_account->on_activate_window(active); + if (active) { + this->p->show_delayed_error_message(); + } } // Get vector of extruder colors considering filament color, if extruder color is undefined. diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 5c113a394f..28c33b13c3 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -253,7 +253,7 @@ public: void force_filament_cb_update(); void force_print_bed_update(); // On activating the parent window. - void on_activate(); + void on_activate(bool active); std::vector get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result = nullptr) const; std::vector get_colors_for_color_print(const GCodeProcessorResult* const result = nullptr) const; diff --git a/src/slic3r/GUI/UserAccount.hpp b/src/slic3r/GUI/UserAccount.hpp index bfcdae5521..533fdff970 100644 --- a/src/slic3r/GUI/UserAccount.hpp +++ b/src/slic3r/GUI/UserAccount.hpp @@ -58,6 +58,8 @@ public: bool on_connect_printers_success(const std::string& data, AppConfig* app_config, bool& out_printers_changed); bool on_connect_uiid_map_success(const std::string& data, AppConfig* app_config, bool& out_printers_changed); + void on_activate_window(bool active) { m_communication->on_activate_window(active); } + std::string get_username() const { return m_username; } std::string get_access_token(); std::string get_shared_session_key(); diff --git a/src/slic3r/GUI/UserAccountCommunication.cpp b/src/slic3r/GUI/UserAccountCommunication.cpp index 611bd18159..2796ae525e 100644 --- a/src/slic3r/GUI/UserAccountCommunication.cpp +++ b/src/slic3r/GUI/UserAccountCommunication.cpp @@ -360,6 +360,10 @@ void UserAccountCommunication::init_session_thread() if (m_thread_stop) // Stop the worker thread. break; + // Do not process_action_queue if window is not active and thread was not forced to wakeup + if (!m_window_is_active && !m_thread_wakeup) { + continue; + } m_thread_wakeup = false; { std::lock_guard lock(m_session_mutex); @@ -369,6 +373,12 @@ void UserAccountCommunication::init_session_thread() }); } +void UserAccountCommunication::on_activate_window(bool active) +{ + std::lock_guard lck(m_thread_stop_mutex); + m_window_is_active = active; +} + void UserAccountCommunication::wakeup_session_thread() { { diff --git a/src/slic3r/GUI/UserAccountCommunication.hpp b/src/slic3r/GUI/UserAccountCommunication.hpp index 114bfa977b..b630b95ec2 100644 --- a/src/slic3r/GUI/UserAccountCommunication.hpp +++ b/src/slic3r/GUI/UserAccountCommunication.hpp @@ -51,6 +51,7 @@ public: // Exchanges code for tokens and shared_session_key void on_login_code_recieved(const std::string& url_message); + void on_activate_window(bool active); void set_username(const std::string& username); void set_remember_session(bool b); @@ -71,6 +72,7 @@ private: std::condition_variable m_thread_stop_condition; bool m_thread_stop { false }; bool m_thread_wakeup{ false }; + bool m_window_is_active{ true }; std::string m_code_verifier; wxEvtHandler* m_evt_handler; AppConfig* m_app_config; From e95cc5d09c8b582d1dd80631e16bbec9c6f2de0f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 20 May 2024 16:43:29 +0200 Subject: [PATCH 28/28] Follow-up 26d52595 - Fixed a crash after switching from "Settings in separate dialog" mode to "Old" mode, when "Connect" tab is selected (SPE-2314) --- src/slic3r/GUI/MainFrame.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 7d2ffdcabb..103af94052 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -404,17 +404,11 @@ void MainFrame::update_layout() { m_plater->Reparent(m_tabpanel); m_plater->Layout(); -// m_tabpanel->InsertNewPage(0, m_plater, _L("Plater"), std::string("plater"), true); m_main_sizer->Add(m_tabpanel, 1, wxEXPAND | wxTOP, 1); m_plater->Show(); m_tabpanel->ShowFull(); m_tmp_top_bar->Hide(); - - // update Tabs - if (old_layout == ESettingsLayout::Dlg) - if (int sel = m_tabpanel->GetSelection(); sel != wxNOT_FOUND) - m_tabpanel->SetSelection(sel+1);// call SetSelection to correct layout after switching from Dlg to Old mode break; } case ESettingsLayout::Dlg: