diff --git a/resources/web/other_connection_failed.html b/resources/web/other_connection_failed.html
deleted file mode 100644
index 3ea607b3be..0000000000
--- a/resources/web/other_connection_failed.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
- Connection failed
-
-
-
-
-
Connection failed
-
Something went wrong.
-
-
-
-
diff --git a/resources/web/other_error.html b/resources/web/other_error.html
new file mode 100644
index 0000000000..24b29d72d2
--- /dev/null
+++ b/resources/web/other_error.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+ Connect-Slicer integration
+
+
+
+
+
+
+
+
+
Something went wrong.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index a938865bb9..a79d6dbc2f 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -4145,7 +4145,12 @@ void GUI_App::printables_slice_request(const std::string& download_url, const st
}
void GUI_App::printables_print_request(const std::string& download_url, const std::string& model_url)
{
+ plater()->printables_to_connect_gcode(Utils::ServiceConfig::instance().printables_url() + model_url);
+}
+void GUI_App::printables_login_request()
+{
+ plater_->get_user_account()->do_login();
}
void GUI_App::open_link_in_printables(const std::string& url)
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index cf3c30c287..a85c8a8480 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -439,6 +439,7 @@ public:
void printables_download_request(const std::string& download_url, const std::string& model_url);
void printables_slice_request(const std::string& download_url, const std::string& model_url);
void printables_print_request(const std::string& download_url, const std::string& model_url);
+ void printables_login_request();
void open_link_in_printables(const std::string& url);
private:
bool on_init_inner();
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index eca7401888..0f2bd93484 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -880,9 +880,12 @@ void MainFrame::show_printables_tab(const std::string& url)
if (!m_printables_webview_added) {
return;
}
- m_tabpanel->SetSelection(m_tabpanel->FindPage(m_printables_webview));
+ // we have to set next url first, than show the tab
+ // printables_tab has to reload on show everytime
+ // so it is not possible load_url right after show
m_printables_webview->set_load_default_url_on_next_error(true);
- m_printables_webview->load_url_from_outside(url);
+ m_printables_webview->set_next_show_url(url);
+ m_tabpanel->SetSelection(m_tabpanel->FindPage(m_printables_webview));
}
void MainFrame::add_printables_webview_tab()
{
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 395f29dc8d..e22d7a260a 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -6017,6 +6017,18 @@ bool load_secret(const std::string& id, const std::string& opt, std::string& usr
#endif // wxUSE_SECRETSTORE
}
}
+
+
+void Plater::printables_to_connect_gcode(const std::string& url)
+{
+ {
+ PrintablesConnectUploadDialog dialog(this, url);
+ if (dialog.ShowModal() != wxID_OK) {
+ return;
+ }
+ }
+}
+
void Plater::connect_gcode()
{
assert(p->user_account->is_logged());
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index c492912d3a..e610e552d4 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -229,6 +229,7 @@ public:
void send_gcode_inner(DynamicPrintConfig* physical_printer_config);
void eject_drive();
void connect_gcode();
+ void printables_to_connect_gcode(const std::string& url);
std::string get_upload_filename();
void take_snapshot(const std::string &snapshot_name);
diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp
index fe33241109..b77e298be2 100644
--- a/src/slic3r/GUI/WebViewDialog.cpp
+++ b/src/slic3r/GUI/WebViewDialog.cpp
@@ -630,6 +630,31 @@ void PrinterPickWebViewDialog::on_reload_event(const std::string& message_data)
m_browser->LoadURL(m_default_url);
}
+PrintablesConnectUploadDialog::PrintablesConnectUploadDialog(wxWindow* parent, const std::string url)
+ : WebViewDialog(parent
+ , GUI::from_u8(url)
+ , _L("Choose a printer")
+ , wxSize(parent->GetClientSize().x / 4 * 3, parent->GetClientSize().y/ 5 * 4)
+ ,{"_prusaSlicer"}
+ , "connect_loading")
+{
+ SetMinSize(wxSize(std::max(parent->GetClientSize().x / 2, 100 * wxGetApp().em_unit()), std::max(parent->GetClientSize().y / 2, 70 * wxGetApp().em_unit())));
+ Centre();
+}
+
+void PrintablesConnectUploadDialog::on_dpi_changed(const wxRect &suggested_rect)
+{
+ wxWindow *parent = GetParent();
+ const wxSize &size = wxSize(
+ std::max(parent->GetClientSize().x / 2, 100 * wxGetApp().em_unit()),
+ std::max(parent->GetClientSize().y / 2, 70 * wxGetApp().em_unit())
+ );
+ SetMinSize(size);
+ Fit();
+ Refresh();
+}
+
+
LoginWebViewDialog::LoginWebViewDialog(wxWindow *parent, std::string &ret_val, const wxString& url, wxEvtHandler* evt_handler)
: WebViewDialog(parent, url, _L("Log in dialog"), wxSize(50 * wxGetApp().em_unit(), 80 * wxGetApp().em_unit()), {})
diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp
index d9e890fc3f..78fdd35c74 100644
--- a/src/slic3r/GUI/WebViewDialog.hpp
+++ b/src/slic3r/GUI/WebViewDialog.hpp
@@ -109,6 +109,15 @@ private:
std::string& m_ret_val;
};
+class PrintablesConnectUploadDialog : public WebViewDialog
+{
+public:
+ PrintablesConnectUploadDialog(wxWindow* parent, const std::string url);
+protected:
+ void on_dpi_changed(const wxRect &suggested_rect) override;
+
+};
+
class LoginWebViewDialog : public WebViewDialog
{
public:
diff --git a/src/slic3r/GUI/WebViewPanel.cpp b/src/slic3r/GUI/WebViewPanel.cpp
index 9ec5767ce4..acb0fcc67b 100644
--- a/src/slic3r/GUI/WebViewPanel.cpp
+++ b/src/slic3r/GUI/WebViewPanel.cpp
@@ -8,10 +8,10 @@
#include "slic3r/GUI/format.hpp"
#include "slic3r/GUI/WebView.hpp"
#include "slic3r/GUI/WebViewPlatformUtils.hpp"
-#include "slic3r/Utils/ServiceConfig.hpp"
-
#include "slic3r/GUI/MsgDialog.hpp"
#include "slic3r/GUI/Field.hpp"
+#include "libslic3r/AppConfig.hpp"
+#include "libslic3r/Config.hpp"
#include // IWYU pragma: keep
@@ -207,7 +207,7 @@ void WebViewPanel::on_idle(wxIdleEvent& WXUNUSED(evt))
m_load_error_page = false;
if (m_load_default_url_on_next_error) {
m_load_default_url_on_next_error = false;
- load_url(m_default_url);
+ load_default_url();
} else {
load_url(GUI::format_wxstr("file://%1%/web/%2%.html", boost::filesystem::path(resources_dir()).generic_string(), m_error_html));
}
@@ -781,7 +781,7 @@ void ConnectWebViewPanel::on_connect_action_print(const std::string& message_dat
}
PrinterWebViewPanel::PrinterWebViewPanel(wxWindow* parent, const wxString& default_url)
- : WebViewPanel(parent, default_url, {"ExternalApp"}, "other_loading_reload", "other_connection_failed")
+ : WebViewPanel(parent, default_url, {"ExternalApp"}, "other_loading_reload", "other_error")
{
if (!m_browser)
return;
@@ -857,7 +857,7 @@ void PrinterWebViewPanel::sys_color_changed()
PrintablesWebViewPanel::PrintablesWebViewPanel(wxWindow* parent)
- : WebViewPanel(parent, GUI::from_u8(Utils::ServiceConfig::instance().printables_url()), { "ExternalApp" }, "other_loading_reload", "other_connection_failed")
+ : WebViewPanel(parent, GUI::from_u8(Utils::ServiceConfig::instance().printables_url()), { "ExternalApp" }, "other_loading_reload", "other_error")
{
m_browser->Bind(wxEVT_WEBVIEW_LOADED, &PrintablesWebViewPanel::on_loaded, this);
@@ -908,27 +908,6 @@ void PrintablesWebViewPanel::on_navigation_request(wxWebViewEvent &evt)
}
}
-void PrintablesWebViewPanel::load_default_url()
-{
- std::string actual_default_url = get_url_lang_theme(Utils::ServiceConfig::instance().printables_url() + "/homepage");
- const std::string access_token = wxGetApp().plater()->get_user_account()->get_access_token();
-
- // in case of opening printables logged out - delete cookies and localstorage to get rid of last login
- if (access_token.empty()) {
- delete_cookies(m_browser, Utils::ServiceConfig::instance().printables_url());
- m_browser->AddUserScript("localStorage.clear();");
- load_url(actual_default_url);
- return;
- }
- // add token to first request
-#ifdef _WIN32
- add_request_authorization(m_browser, m_default_url, access_token);
- load_url(GUI::from_u8(actual_default_url));
-#else
- load_request(m_browser, actual_default_url, access_token);
-#endif
-}
-
void PrintablesWebViewPanel::on_loaded(wxWebViewEvent& evt)
{
#ifdef _WIN32
@@ -1000,20 +979,20 @@ void PrintablesWebViewPanel::on_show(wxShowEvent& evt)
return;
}
// in case login changed, resend login / logout
- // DK: it seems to me, it is safer to do login / logout (where logout means requesting the page again)
+ // DK1: it seems to me, it is safer to do login / logout (where logout means requesting the page again)
// on every show of panel,
// than to keep information if we have printables page in same state as slicer in terms of login
// But im afraid it will be concidered not pretty...
const std::string access_token = wxGetApp().plater()->get_user_account()->get_access_token();
if (access_token.empty()) {
- logout();
+ logout(m_next_show_url);
} else {
- login(access_token);
+ login(access_token, m_next_show_url);
}
-
+ m_next_show_url.clear();
}
-void PrintablesWebViewPanel::logout()
+void PrintablesWebViewPanel::logout(const std::string& override_url/* = std::string()*/)
{
if (!m_shown) {
return;
@@ -1021,15 +1000,18 @@ void PrintablesWebViewPanel::logout()
delete_cookies(m_browser, Utils::ServiceConfig::instance().printables_url());
m_browser->RunScript("localStorage.clear();");
+ std::string next_url = override_url.empty()
+ ? get_url_lang_theme(m_browser->GetCurrentURL())
+ : get_url_lang_theme(from_u8(override_url));
#ifdef _WIN32
- load_url(GUI::from_u8(get_url_lang_theme(m_browser->GetCurrentURL())));
+ load_url(GUI::from_u8(next_url));
#else
// We cannot do simple reload here, it would keep the access token in the header
- load_request(m_browser, get_url_lang_theme(m_browser->GetCurrentURL()), std::string());
+ load_request(m_browser, next_url, std::string());
#endif //
}
-void PrintablesWebViewPanel::login(const std::string& access_token)
+void PrintablesWebViewPanel::login(const std::string& access_token, const std::string& override_url/* = std::string()*/)
{
if (!m_shown) {
return;
@@ -1048,8 +1030,34 @@ void PrintablesWebViewPanel::login(const std::string& access_token)
, access_token);
run_script(script);
- run_script("window.location.reload();");
+ if ( override_url.empty()) {
+ run_script("window.location.reload();");
+ } else {
+ load_url(GUI::from_u8(get_url_lang_theme(from_u8(override_url))));
+ }
}
+
+void PrintablesWebViewPanel::load_default_url()
+{
+ std::string actual_default_url = get_url_lang_theme(from_u8(Utils::ServiceConfig::instance().printables_url() + "/homepage"));
+ const std::string access_token = wxGetApp().plater()->get_user_account()->get_access_token();
+
+ // in case of opening printables logged out - delete cookies and localstorage to get rid of last login
+ if (access_token.empty()) {
+ delete_cookies(m_browser, Utils::ServiceConfig::instance().printables_url());
+ m_browser->AddUserScript("localStorage.clear();");
+ load_url(actual_default_url);
+ return;
+ }
+ // add token to first request
+#ifdef _WIN32
+ add_request_authorization(m_browser, m_default_url, access_token);
+ load_url(GUI::from_u8(actual_default_url));
+#else
+ load_request(m_browser, actual_default_url, access_token);
+#endif
+}
+
void PrintablesWebViewPanel::send_refreshed_token(const std::string& access_token)
{
if (m_load_default_url) {
@@ -1071,11 +1079,6 @@ void PrintablesWebViewPanel::send_will_refresh()
run_script(script);
}
-void PrintablesWebViewPanel::load_url_from_outside(const std::string& url)
-{
- load_url(from_u8(Utils::ServiceConfig::instance().printables_url() + url));
-}
-
void PrintablesWebViewPanel::on_script_message(wxWebViewEvent& evt)
{
BOOST_LOG_TRIVIAL(error) << "received message from Printables: " << evt.GetString();
@@ -1106,11 +1109,31 @@ void PrintablesWebViewPanel::on_reload_event(const std::string& message_data)
void PrintablesWebViewPanel::on_printables_event_print_gcode(const std::string& message_data)
{
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< " " << message_data;
+
+ // { "event": "downloadFile", "url": "https://media.printables.com/somesecure.stl", "modelUrl": "https://www.printables.com/model/123" }
+ std::string download_url;
+ std::string model_url;
+ try {
+ std::stringstream ss(message_data);
+ pt::ptree ptree;
+ pt::read_json(ss, ptree);
+ if (const auto url = ptree.get_optional("url"); url) {
+ download_url = *url;
+ }
+ if (const auto url = ptree.get_optional("modelUrl"); url) {
+ model_url = *url;
+ }
+ } catch (const std::exception &e) {
+ BOOST_LOG_TRIVIAL(error) << "Could not parse printables message. " << e.what();
+ return;
+ }
+ assert(!download_url.empty() && !model_url.empty());
+ wxGetApp().printables_print_request(download_url, model_url);
}
void PrintablesWebViewPanel::on_printables_event_download_file(const std::string& message_data)
{
- BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " " << message_data;
- // { "event": "downloadFile", "url": "https://media.printables.com/somesecure.stl", "modelUrl": "https://www.printables.com/model/123" }
+ BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " " << message_data;
+ // { "event": "printGcode", "url": "https://media.printables.com/somesecure.gcode", "modelUrl": "https://www.printables.com/model/123" }
std::string download_url;
std::string model_url;
try {
@@ -1130,11 +1153,11 @@ void PrintablesWebViewPanel::on_printables_event_download_file(const std::string
assert(!download_url.empty() && !model_url.empty());
boost::filesystem::path url_path(download_url);
show_download_notification(url_path.filename().string());
- wxGetApp().printables_download_request(download_url, model_url);
+ wxGetApp().printables_download_request(download_url, model_url);
}
void PrintablesWebViewPanel::on_printables_event_slice_file(const std::string& message_data)
{
- BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " " << message_data;
+ BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " " << message_data;
// { "event": "sliceFile", "url": "https://media.printables.com/somesecure.zip", "modelUrl": "https://www.printables.com/model/123" }
std::string download_url;
std::string model_url;
@@ -1158,12 +1181,14 @@ void PrintablesWebViewPanel::on_printables_event_slice_file(const std::string& m
void PrintablesWebViewPanel::on_printables_event_required_login(const std::string& message_data)
{
- BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " " << message_data;
+ BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " " << message_data;
+ wxGetApp().printables_login_request();
}
void PrintablesWebViewPanel::show_download_notification(const std::string& filename)
{
- std::string message = GUI::format(_u8L("Downloading %1%"),filename);
+ std::string message_filename = GUI::format(_u8L("Downloading %1%"),filename);
+ std::string message_dest = GUI::format(_u8L("To %1%"), escape_string_cstyle(wxGetApp().app_config->get("url_downloader_dest")));
std::string script = GUI::format(R"(
// Inject custom CSS
var style = document.createElement('style');
@@ -1185,10 +1210,19 @@ void PrintablesWebViewPanel::show_download_notification(const std::string& filen
justify-content: space-between;
align-items: center;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3); /* Add a subtle shadow */
- min-width: 350px; /* Ensure it has a minimum width */
+ min-width: 350px;
+ max-width: 350px;
min-height: 50px;
}
-
+ .notification-popup div {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ padding-right: 20px; /* Add padding to make text truncate earlier */
+ }
+ .notification-popup b {
+ color: #ffa500;
+ }
.notification-popup a:hover {
text-decoration: underline; /* Underline on hover */
}
@@ -1223,6 +1257,7 @@ void PrintablesWebViewPanel::show_download_notification(const std::string& filen
notifDiv.innerHTML = `
PrusaSlicer: %1%
+
%2%
`;
notifDiv.className = 'notification-popup';
@@ -1239,7 +1274,7 @@ void PrintablesWebViewPanel::show_download_notification(const std::string& filen
}
appendNotification();
-)", message);
+)", message_filename, message_dest);
run_script(script);
}
diff --git a/src/slic3r/GUI/WebViewPanel.hpp b/src/slic3r/GUI/WebViewPanel.hpp
index be9e181f22..d5d276cb62 100644
--- a/src/slic3r/GUI/WebViewPanel.hpp
+++ b/src/slic3r/GUI/WebViewPanel.hpp
@@ -8,6 +8,7 @@
#include "GUI_Utils.hpp"
#include "UserAccountSession.hpp"
#include "ConnectRequestHandler.hpp"
+#include "slic3r/Utils/ServiceConfig.hpp"
#ifdef DEBUG_URL_PANEL
#include
@@ -179,11 +180,11 @@ public:
void on_script_message(wxWebViewEvent& evt) override;
void sys_color_changed() override;
- void logout();
- void login(const std::string& access_token);
+ void logout(const std::string& override_url = std::string());
+ void login(const std::string& access_token, const std::string& override_url = std::string());
void send_refreshed_token(const std::string& access_token);
void send_will_refresh();
- void load_url_from_outside(const std::string& url);
+ void set_next_show_url(const std::string& url) {m_next_show_url = Utils::ServiceConfig::instance().printables_url() + url; }
private:
void handle_message(const std::string& message);
void on_printables_event_access_token_expired(const std::string& message_data);
@@ -197,7 +198,7 @@ private:
void show_download_notification(const std::string& filename);
std::map> m_events;
-
+ std::string m_next_show_url;
/*
Eventy Slicer -> Printables
accessTokenWillChange
diff --git a/src/slic3r/GUI/format.hpp b/src/slic3r/GUI/format.hpp
index e80017174d..9c80907ee0 100644
--- a/src/slic3r/GUI/format.hpp
+++ b/src/slic3r/GUI/format.hpp
@@ -12,6 +12,7 @@
// This wrapper also manages implicit conversion from wxString to UTF8 and format_wxstr() variants are provided to format into wxString.
#include
+#include
namespace Slic3r::internal::format {
// Wrapper around wxScopedCharBuffer to indicate that the content is UTF8 formatted.