Improvements in ConnectTab and PrinterPick Dialog

Webview access token sending and compatible printer request.

Printer Pick Dialog UI changes

Connect request_config improvements

Switch printer or send gcode dialog
This commit is contained in:
David Kocik 2024-03-19 09:37:48 +01:00
parent 7ad9431e3a
commit 123a299a9b
10 changed files with 121 additions and 74 deletions

View File

@ -2885,7 +2885,6 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo
const auto ask_and_select_default_materials = [this](const wxString &message, const std::set<const VendorProfile::PrinterModel*> &printer_models, Technology technology)
{
//wxMessageDialog msg(q, message, _L("Notice"), wxYES_NO);
MessageDialog msg(q, message, _L("Notice"), wxYES_NO);
if (msg.ShowModal() == wxID_YES)
select_default_materials_for_printer_models(technology, printer_models);

View File

@ -5862,35 +5862,54 @@ void Plater::connect_gcode()
}
BOOST_LOG_TRIVIAL(debug) << "Message from Printer pick webview: " << dialog_msg;
std::string model_name = p->user_account->get_model_from_json(dialog_msg);
std::string nozzle = p->user_account->get_nozzle_from_json(dialog_msg);
assert(!model_name.empty());
std::string connect_printer_model = p->user_account->get_model_from_json(dialog_msg);
std::string connect_nozzle = p->user_account->get_nozzle_from_json(dialog_msg);
std::string connect_filament = p->user_account->get_keyword_from_json(dialog_msg, "filament_type");
assert(!connect_printer_model.empty());
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
const Preset* preset = preset_bundle->printers.find_system_preset_by_model_and_variant(model_name, nozzle);
// TODO: preset check
const Preset* selected_printer_preset = &preset_bundle->printers.get_selected_preset();
const Preset* selected_filament_preset = &preset_bundle->filaments.get_selected_preset();
const std::string selected_nozzle_serialized = dynamic_cast<const ConfigOptionFloats*>(selected_printer_preset->config.option("nozzle_diameter"))->serialize();
const std::string selected_filament_serialized = selected_filament_preset ->config.option("filament_type")->serialize();
const std::string selected_printer_model_serialized = selected_printer_preset->config.option("printer_model")->serialize();
const Preset* connect_printer_preset = preset_bundle->printers.find_system_preset_by_model_and_variant(connect_printer_model, connect_nozzle);
// if selected (in connect) preset is not visible, make it visible and selected
if (!preset->is_visible) {
size_t preset_id = preset_bundle->printers.get_preset_idx_by_name(preset->name);
assert(preset_id != size_t(-1));
preset_bundle->printers.select_preset(preset_id);
wxGetApp().get_tab(Preset::Type::TYPE_PRINTER)->select_preset(preset->name);
p->notification_manager->close_notification_of_type(NotificationType::PrusaConnectPrinters);
p->notification_manager->push_notification(NotificationType::PrusaConnectPrinters, NotificationManager::NotificationLevel::ImportantNotificationLevel, format(_u8L("Changed Printer to %1%."), preset->name));
select_view_3D("3D");
return;
}
// if selected (in connect) preset is not selected in slicer, select it
if (preset_bundle->printers.get_selected_preset_name() != preset->name) {
size_t preset_id = preset_bundle->printers.get_preset_idx_by_name(preset->name);
assert(preset_id != size_t(-1));
preset_bundle->printers.select_preset(preset_id);
wxGetApp().get_tab(Preset::Type::TYPE_PRINTER)->select_preset(preset->name);
p->notification_manager->close_notification_of_type(NotificationType::PrusaConnectPrinters);
p->notification_manager->push_notification(NotificationType::PrusaConnectPrinters, NotificationManager::NotificationLevel::ImportantNotificationLevel, format(_u8L("Changed Printer to %1%."), preset->name));
select_view_3D("3D");
return;
if (connect_printer_model != selected_printer_model_serialized || (!connect_nozzle.empty() && connect_nozzle != selected_nozzle_serialized) || (!connect_filament.empty() && connect_filament != selected_filament_serialized)) {
wxString line1 = _L("The printer profile you've selected for upload is not fully compatible with profiles selected for slicing.");
wxString line2 = GUI::format_wxstr(_L("PrusaSlicer Profile: %1%, filament: %3%"), selected_printer_preset->name, selected_nozzle_serialized, selected_filament_serialized);
wxString line3 = GUI::format_wxstr(_L("Selected Printer: %1%, filament: %3%"), connect_printer_preset->name, connect_nozzle, connect_filament);
wxString line4 =_L("Choose YES to continue upload, choose NO to switch selected printer in PrusaSlicer.");
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_NO) {
// if selected (in connect) preset is not visible, make it visible and selected
if (!connect_printer_preset->is_visible) {
size_t preset_id = preset_bundle->printers.get_preset_idx_by_name(connect_printer_preset->name);
assert(preset_id != size_t(-1));
preset_bundle->printers.select_preset(preset_id);
wxGetApp().get_tab(Preset::Type::TYPE_PRINTER)->select_preset(connect_printer_preset->name);
p->notification_manager->close_notification_of_type(NotificationType::PrusaConnectPrinters);
p->notification_manager->push_notification(NotificationType::PrusaConnectPrinters, NotificationManager::NotificationLevel::ImportantNotificationLevel, format(_u8L("Changed Printer to %1%."), connect_printer_preset->name));
select_view_3D("3D");
}
// if selected (in connect) preset is not selected in slicer, select it
if (preset_bundle->printers.get_selected_preset_name() != connect_printer_preset->name) {
size_t preset_id = preset_bundle->printers.get_preset_idx_by_name(connect_printer_preset->name);
assert(preset_id != size_t(-1));
preset_bundle->printers.select_preset(preset_id);
wxGetApp().get_tab(Preset::Type::TYPE_PRINTER)->select_preset(connect_printer_preset->name);
p->notification_manager->close_notification_of_type(NotificationType::PrusaConnectPrinters);
p->notification_manager->push_notification(NotificationType::PrusaConnectPrinters, NotificationManager::NotificationLevel::ImportantNotificationLevel, format(_u8L("Changed Printer to %1%."), connect_printer_preset->name));
select_view_3D("3D");
}
// TODO: select filament
return;
} else if (modal_res != wxID_YES) {
// exit dialog without selecting yes / no
return;
}
}
const std::string connect_state = p->user_account->get_keyword_from_json(dialog_msg, "connect_state");
@ -5904,34 +5923,18 @@ void Plater::connect_gcode()
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;
}
PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *preset);
PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *connect_printer_preset);
ph_printer.config.set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnectNew));
// use existing structures to pass data
ph_printer.config.opt_string("printhost_apikey") = team_id;
ph_printer.config.opt_string("print_host") = uuid;
DynamicPrintConfig* physical_printer_config = &ph_printer.config;
// Old PrusaConnect - requires prusaconnect_api_key in
//std::string api_key = p->user_account->get_keyword_from_json(dialog_msg, "prusaconnect_api_key");
//if (api_key.empty()) {
// // TODO error dialog
// return;
//}
//const std::string connect_address = "https://dev.connect.prusa3d.com";
//PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *preset);
//ph_printer.config.opt_string("printhost_apikey") = api_key;
//ph_printer.config.opt_string("print_host") = connect_address;
//ph_printer.config.set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnect));
//DynamicPrintConfig* physical_printer_config = &ph_printer.config;
send_gcode_inner(physical_printer_config);
}

View File

@ -865,8 +865,11 @@ static PrinterStatesCount get_printe_states_count(const std::vector<size_t>& sta
if (state == ConnectPrinterState::CONNECT_PRINTER_OFFLINE)
states_cnt.offline_cnt += states[i];
else if (state == ConnectPrinterState::CONNECT_PRINTER_PAUSED ||
state == ConnectPrinterState::CONNECT_PRINTER_STOPED ||
state == ConnectPrinterState::CONNECT_PRINTER_PRINTING)
state == ConnectPrinterState::CONNECT_PRINTER_STOPPED ||
state == ConnectPrinterState::CONNECT_PRINTER_PRINTING ||
state == ConnectPrinterState::CONNECT_PRINTER_BUSY ||
state == ConnectPrinterState::CONNECT_PRINTER_ATTENTION ||
state == ConnectPrinterState::CONNECT_PRINTER_ERROR)
states_cnt.busy_cnt += states[i];
else
states_cnt.available_cnt += states[i];

View File

@ -476,7 +476,6 @@ Sidebar::Sidebar(Plater *parent)
init_scalable_btn(&m_btn_send_gcode , "export_gcode", _L("Send to printer") + " " +GUI::shortkey_ctrl_prefix() + "Shift+G");
init_scalable_btn(&m_btn_export_gcode_removable, "export_to_sd", _L("Export to SD card / Flash drive") + " " + GUI::shortkey_ctrl_prefix() + "U");
init_scalable_btn(&m_btn_connect_gcode, "connect_gcode", _L("Send to Connect") + " " + GUI::shortkey_ctrl_prefix() + "Shift+G");
// regular buttons "Slice now" and "Export G-code"
@ -495,6 +494,7 @@ Sidebar::Sidebar(Plater *parent)
init_btn(&m_btn_export_gcode, _L("Export G-code") + dots , scaled_height);
init_btn(&m_btn_reslice , _L("Slice now") , scaled_height);
init_btn(&m_btn_connect_gcode, _L("Send to Connect"), scaled_height);
enable_buttons(false);
@ -502,9 +502,9 @@ Sidebar::Sidebar(Plater *parent)
auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL);
complect_btns_sizer->Add(m_btn_export_gcode, 1, wxEXPAND);
complect_btns_sizer->Add(m_btn_connect_gcode, 1, wxLEFT, margin_5);
complect_btns_sizer->Add(m_btn_send_gcode, 0, wxLEFT, margin_5);
complect_btns_sizer->Add(m_btn_export_gcode_removable, 0, wxLEFT, margin_5);
complect_btns_sizer->Add(m_btn_connect_gcode, 0, wxLEFT, margin_5);
btns_sizer->Add(m_btn_reslice, 0, wxEXPAND | wxTOP, margin_5);
btns_sizer->Add(complect_btns_sizer, 0, wxEXPAND | wxTOP, margin_5);
@ -778,7 +778,7 @@ void Sidebar::sys_color_changed()
wxGetApp().UpdateDarkUI(win);
for (wxWindow* win : std::vector<wxWindow*>{ m_scrolled_panel, m_presets_panel })
wxGetApp().UpdateAllStaticTextDarkUI(win);
for (wxWindow* btn : std::vector<wxWindow*>{ m_btn_reslice, m_btn_export_gcode })
for (wxWindow* btn : std::vector<wxWindow*>{ m_btn_reslice, m_btn_export_gcode, m_btn_connect_gcode })
wxGetApp().UpdateDarkUI(btn, true);
m_frequently_changed_parameters->sys_color_changed();
@ -800,7 +800,6 @@ void Sidebar::sys_color_changed()
// btn...->msw_rescale() updates icon on button, so use it
m_btn_send_gcode ->sys_color_changed();
m_btn_export_gcode_removable->sys_color_changed();
m_btn_connect_gcode ->sys_color_changed();
m_scrolled_panel->Layout();
m_scrolled_panel->Refresh();

View File

@ -78,9 +78,9 @@ class Sidebar : public wxPanel
wxButton* m_btn_export_gcode { nullptr };
wxButton* m_btn_reslice { nullptr };
wxButton* m_btn_connect_gcode { nullptr };
ScalableButton* m_btn_send_gcode { nullptr };
ScalableButton* m_btn_export_gcode_removable{ nullptr }; //exports to removable drives (appears only if removable drive is connected)
ScalableButton* m_btn_connect_gcode { nullptr };
std::unique_ptr<FreqChangedParams> m_frequently_changed_parameters;
std::unique_ptr<ObjectManipulation> m_object_manipulation;

View File

@ -320,5 +320,16 @@ std::string UserAccount::get_keyword_from_json(const std::string& json, const st
}
return out;
}
std::string UserAccount::get_printer_type_from_name(const std::string& printer_name) const
{
for (const auto& pair : printer_type_and_name_table) {
if (pair.second == printer_name) {
return pair.first;
}
}
assert(true); // This assert means printer_type_and_name_table needs a update
return {};
}
}} // namespace slic3r::GUI

View File

@ -15,11 +15,13 @@ enum class ConnectPrinterState {
CONNECT_PRINTER_OFFLINE,
CONNECT_PRINTER_PRINTING,
CONNECT_PRINTER_PAUSED,//?
CONNECT_PRINTER_STOPED,//?
CONNECT_PRINTER_STOPPED,//?
CONNECT_PRINTER_IDLE,
CONNECT_PRINTER_FINISHED,
CONNECT_PRINTER_READY, //?
CONNECT_PRINTER_ATTENTION,
CONNECT_PRINTER_BUSY,
CONNECT_PRINTER_ERROR,
CONNECT_PRINTER_STATE_COUNT
};
@ -71,6 +73,8 @@ public:
std::string get_keyword_from_json(const std::string& json, const std::string& keyword) const;
const std::map<std::string, ConnectPrinterState>& get_printer_state_table() const { return printer_state_table; }
std::string get_printer_type_from_name(const std::string& printer_name) const;
private:
void set_username(const std::string& username);
@ -118,11 +122,12 @@ private:
{"OFFLINE" , ConnectPrinterState::CONNECT_PRINTER_OFFLINE},
{"PRINTING" , ConnectPrinterState::CONNECT_PRINTER_PRINTING},
{"PAUSED" , ConnectPrinterState::CONNECT_PRINTER_PAUSED},
{"STOPED" , ConnectPrinterState::CONNECT_PRINTER_STOPED},
{"STOPPED" , ConnectPrinterState::CONNECT_PRINTER_STOPPED},
{"IDLE" , ConnectPrinterState::CONNECT_PRINTER_IDLE},
{"FINISHED" , ConnectPrinterState::CONNECT_PRINTER_FINISHED},
{"READY" , ConnectPrinterState::CONNECT_PRINTER_READY},
{"ATTENTION", ConnectPrinterState::CONNECT_PRINTER_ATTENTION},
{"BUSY" , ConnectPrinterState::CONNECT_PRINTER_BUSY},
};
};
}} // namespace slic3r::GUI

View File

@ -8,6 +8,7 @@
#include "slic3r/GUI/Plater.hpp"
#include "libslic3r_version.h"
#include "libslic3r/Utils.hpp"
#include "libslic3r/libslic3r.h"
#include "slic3r/GUI/UserAccount.hpp"
#include "slic3r/GUI/format.hpp"
@ -497,15 +498,19 @@ void ConnectRequestHandler::on_request_config()
/*
accessToken?: string;
clientVersion?: string;
colorMode?: "LIGHT" | "DARK";
language?: ConnectLanguage;
sessionId?: string;
*/
//const std::string token = wxGetApp().plater()->get_user_account()->get_access_token();
//const std::string init_options = GUI::format("{\"accessToken\": \"%1%\" }", token);
const std::string token = wxGetApp().plater()->get_user_account()->get_shared_session_key();
const std::string init_options = GUI::format("{\"sessionId\": \"%1%\" }", token);
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";
const wxString language = GUI::wxGetApp().current_language_code();
const std::string init_options = GUI::format("{\"accessToken\": \"%1%\" , \"clientVersion\": \"%2%\", \"colorMode\": \"%3%\", \"language\": \"%4%\"}", token, SLIC3R_VERSION, dark_mode, language);
wxString script = GUI::format_wxstr("window._prusaConnect_v1.init(%1%)", init_options);
run_script_bridge(script);
}
void ConnectRequestHandler::on_request_language_action()
{
@ -538,10 +543,8 @@ void ConnectWebViewPanel::on_script_message(wxWebViewEvent& evt)
void ConnectWebViewPanel::on_request_update_selected_printer_action()
{
/*
assert(!m_message_data.empty());
wxGetApp().handle_connect_request_printer_pick(m_message_data);
*/
}
@ -613,14 +616,9 @@ void PrinterWebViewPanel::send_credentials()
}
WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url)
: wxDialog(parent, wxID_ANY, "Webview Dialog", wxDefaultPosition, wxSize(1366, 768)/* wxSize(100 * wxGetApp().em_unit(), 100 * wxGetApp().em_unit())*/)
WebViewDialog::WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size)
: wxDialog(parent, wxID_ANY, dialog_name, wxDefaultPosition, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
////std::string strlang = wxGetApp().app_config->get("language");
////if (strlang != "")
//// url = wxString::Format("file://%s/web/homepage/index.html?lang=%s", from_u8(resources_dir()), strlang);
////m_bbl_user_agent = wxString::Format("BBL-Slicer/v%s", SLIC3R_VERSION);
wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
// Create the webview
@ -648,22 +646,23 @@ void WebViewDialog::run_script(const wxString& javascript)
bool res = WebView::run_script(m_browser, javascript);
}
PrinterPickWebViewDialog::PrinterPickWebViewDialog(wxWindow* parent, std::string& ret_val)
// : WebViewDialog(parent, L"https://dev.connect.prusa3d.com/prusa-slicer/printers")
: WebViewDialog(parent, L"https://dev.connect.prusa3d.com/connect-slicer-app/printer-list")
: WebViewDialog(parent, L"https://dev.connect.prusa3d.com/connect-slicer-app/printer-list", _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())))
, m_ret_val(ret_val)
{
m_actions["WEBAPP_READY"] = std::bind(&PrinterPickWebViewDialog::request_compatible_printers, this);
Centre();
}
void PrinterPickWebViewDialog::on_show(wxShowEvent& evt)
{
/*
if (evt.IsShown()) {
std::string token = wxGetApp().plater()->get_user_account()->get_access_token();
wxString script = GUI::format_wxstr("window.setAccessToken(\'%1%\')", token);
// TODO: should this be happening every OnShow?
run_script(script);
}
*/
}
void PrinterPickWebViewDialog::on_script_message(wxWebViewEvent& evt)
{
@ -676,5 +675,31 @@ void PrinterPickWebViewDialog::on_request_update_selected_printer_action()
this->EndModal(wxID_OK);
}
void PrinterPickWebViewDialog::request_compatible_printers()
{
//PrinterParams: {
//material: Material;
//nozzleDiameter: number;
//printerType: string;
//}
const Preset& selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset();
const Preset& selected_filament = wxGetApp().preset_bundle->filaments.get_selected_preset();
const std::string nozzle_diameter_serialized = dynamic_cast<const ConfigOptionFloats*>(selected_printer.config.option("nozzle_diameter"))->serialize();
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 printer_type = wxGetApp().plater()->get_user_account()->get_printer_type_from_name(printer_model_serialized);
assert(!filament_type_serialized.empty() && !nozzle_diameter_serialized.empty() && !printer_type.empty());
const std::string request = GUI::format(
"{"
"\"material\": \"%1%\", "
"\"nozzleDiameter\": %2%, "
"\"printerType\": \"%3%\" "
"}", filament_type_serialized, nozzle_diameter_serialized, printer_type);
wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request);
run_script(script);
}
} // GUI
} // Slic3r

View File

@ -123,6 +123,7 @@ protected:
std::map<std::string, std::function<void(void)>> m_actions;
std::string m_message_data;
};
class ConnectWebViewPanel : public WebViewPanel, public ConnectRequestHandler
@ -158,7 +159,7 @@ private:
class WebViewDialog : public wxDialog
{
public:
WebViewDialog(wxWindow* parent, const wxString& url);
WebViewDialog(wxWindow* parent, const wxString& url, const wxString& dialog_name, const wxSize& size);
virtual ~WebViewDialog();
virtual void on_show(wxShowEvent& evt) = 0;
@ -180,6 +181,7 @@ protected:
void on_request_update_selected_printer_action() override;
void run_script_bridge(const wxString& script) override { run_script(script); }
private:
void request_compatible_printers();
std::string& m_ret_val;
};

View File

@ -710,7 +710,7 @@ bool PrusaLink::get_storage(wxArrayString& storage_path, wxArrayString& storage_
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get storage at: %2%") % name % url;
wxString wlang = GUI::wxGetApp().current_language_code();
std::string lang = GUI::format(wlang.SubString(0, 1));
std::string lang = GUI::into_u8(wlang.SubString(0, 1));
auto http = Http::get(std::move(url));
set_auth(http);
@ -1161,7 +1161,7 @@ void PrusaConnect::set_http_post_header_args(Http& http, PrintHostPostUploadActi
{
// Language for accept message
wxString wlang = GUI::wxGetApp().current_language_code();
std::string lang = GUI::format(wlang.SubString(0, 1));
std::string lang = GUI::into_u8(wlang.SubString(0, 1));
http.header("Accept-Language", lang);
// Post action
if (post_action == PrintHostPostUploadAction::StartPrint) {