OrcaSlicer/src/slic3r/GUI/DeviceErrorDialog.cpp
xin.zhang b39bc5bf8f ENH: HMS add action 39; modify display of 29
JIRA: [STUDIO-13191]
Change-Id: I411fb4c56b395d576aaca7b610aa613e4f6cf806
(cherry picked from commit 45f756d5353f84814a2c7baa3290879a7bef3d6f)
2025-10-02 14:08:21 +08:00

391 lines
14 KiB
C++

#include "DeviceErrorDialog.hpp"
#include "HMS.hpp"
#include "Widgets/Button.hpp"
#include "GUI_App.hpp"
#include "MainFrame.hpp"
namespace Slic3r {
namespace GUI
{
DeviceErrorDialog::DeviceErrorDialog(MachineObject* obj, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
:DPIDialog(parent, id, title, pos, size, style), m_obj(obj)
{
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
SetBackgroundColour(*wxWHITE);
SetTitle(_L("Error"));
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(350), 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_scroll_area = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scroll_area->SetScrollRate(0, 5);
m_scroll_area->SetBackgroundColour(*wxWHITE);
m_scroll_area->SetMinSize(wxSize(FromDIP(320), FromDIP(250)));
wxBoxSizer* text_sizer = new wxBoxSizer(wxVERTICAL);
m_error_msg_label = new Label(m_scroll_area, wxEmptyString, LB_AUTO_WRAP);
m_error_picture = new wxStaticBitmap(m_scroll_area, wxID_ANY, wxBitmap(), wxDefaultPosition, wxSize(FromDIP(300), FromDIP(180)));
//Label* dev_name = new Label(m_scroll_area, wxString::FromUTF8(obj->dev_name) + ":", LB_AUTO_WRAP);
//dev_name->SetMaxSize(wxSize(FromDIP(300), -1));
//dev_name->SetMinSize(wxSize(FromDIP(300), -1));
//dev_name->Wrap(FromDIP(300));
//text_sizer->Add(dev_name, 0, wxALIGN_CENTER, FromDIP(5));
//text_sizer->AddSpacer(5);
text_sizer->Add(m_error_picture, 0, wxALIGN_CENTER, FromDIP(5));
text_sizer->AddSpacer(10);
text_sizer->Add(m_error_msg_label, 0, wxALIGN_CENTER, FromDIP(5));
m_error_code_label = new Label(m_scroll_area, wxEmptyString, LB_AUTO_WRAP);
text_sizer->AddSpacer(5);
text_sizer->Add(m_error_code_label, 0, wxALIGN_CENTER, FromDIP(5));
m_scroll_area->SetSizer(text_sizer);
auto bottom_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer_button = new wxBoxSizer(wxVERTICAL);
bottom_sizer->Add(m_sizer_button, 0, wxEXPAND | wxRIGHT | wxLEFT, 0);
wxBoxSizer* m_center_sizer = new wxBoxSizer(wxVERTICAL);
m_center_sizer->Add(0, 0, 1, wxTOP, FromDIP(5));
m_center_sizer->Add(m_scroll_area, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
m_center_sizer->Add(bottom_sizer, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(20));
m_center_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
m_sizer_main = new wxBoxSizer(wxVERTICAL);
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
m_sizer_main->Add(m_center_sizer, 0, wxBOTTOM | wxEXPAND, FromDIP(5));
SetSizer(m_sizer_main);
Layout();
m_sizer_main->Fit(this);
init_button_list();
CenterOnParent();
wxGetApp().UpdateDlgDarkUI(this);
Bind(wxEVT_WEBREQUEST_STATE, &DeviceErrorDialog::on_webrequest_state, this);
}
DeviceErrorDialog::~DeviceErrorDialog()
{
if (web_request.IsOk() && web_request.GetState() == wxWebRequest::State_Active)
{
BOOST_LOG_TRIVIAL(info) << "web_request: cancelled";
web_request.Cancel();
}
m_error_picture->SetBitmap(wxBitmap());
}
void DeviceErrorDialog::on_webrequest_state(wxWebRequestEvent& evt)
{
BOOST_LOG_TRIVIAL(trace) << "monitor: monitor_panel web request state = " << evt.GetState();
switch (evt.GetState())
{
case wxWebRequest::State_Completed:
{
wxImage img(*evt.GetResponse().GetStream());
wxImage resize_img = img.Scale(FromDIP(320), FromDIP(180), wxIMAGE_QUALITY_HIGH);
wxBitmap error_prompt_pic = resize_img;
m_error_picture->SetBitmap(error_prompt_pic);
Layout();
Fit();
break;
}
case wxWebRequest::State_Failed:
case wxWebRequest::State_Cancelled:
case wxWebRequest::State_Unauthorized:
{
m_error_picture->SetBitmap(wxBitmap());
break;
}
case wxWebRequest::State_Active:
case wxWebRequest::State_Idle: break;
default: break;
}
}
void DeviceErrorDialog::init_button(ActionButton style, wxString buton_text)
{
if (btn_bg_white.count() == 0)
{
btn_bg_white = StateColor(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
}
Button* print_error_button = new Button(this, buton_text);
print_error_button->SetBackgroundColor(btn_bg_white);
print_error_button->SetBorderColor(wxColour(38, 46, 48));
print_error_button->SetFont(Label::Body_14);
print_error_button->SetSize(wxSize(FromDIP(300), FromDIP(30)));
print_error_button->SetMinSize(wxSize(FromDIP(300), FromDIP(30)));
print_error_button->SetMaxSize(wxSize(-1, FromDIP(30)));
print_error_button->SetCornerRadius(FromDIP(5));
print_error_button->Hide();
m_button_list[style] = print_error_button;
m_button_list[style]->Bind(wxEVT_LEFT_DOWN, [this, style](wxMouseEvent& e)
{
this->on_button_click(style);
e.Skip();
});
}
void DeviceErrorDialog::init_button_list()
{
init_button(RESUME_PRINTING, _L("Resume Printing"));
init_button(RESUME_PRINTING_DEFECTS, _L("Resume (defects acceptable)"));
init_button(RESUME_PRINTING_PROBELM_SOLVED, _L("Resume (problem solved)"));
init_button(STOP_PRINTING, _L("Stop Printing"));// pop up recheck dialog?
init_button(CHECK_ASSISTANT, _L("Check Assistant"));
init_button(FILAMENT_EXTRUDED, _L("Filament Extruded, Continue"));
init_button(RETRY_FILAMENT_EXTRUDED, _L("Not Extruded Yet, Retry"));
init_button(CONTINUE, _L("Finished, Continue"));
init_button(LOAD_VIRTUAL_TRAY, _L("Load Filament"));
init_button(OK_BUTTON, _L("OK"));
init_button(FILAMENT_LOAD_RESUME, _L("Filament Loaded, Resume"));
init_button(JUMP_TO_LIVEVIEW, _L("View Liveview"));
init_button(NO_REMINDER_NEXT_TIME, _L("No Reminder Next Time"));
init_button(IGNORE_NO_REMINDER_NEXT_TIME, _L("Ignore. Don't Remind Next Time"));
init_button(IGNORE_RESUME, _L("Ignore this and Resume"));
init_button(PROBLEM_SOLVED_RESUME, _L("Problem Solved and Resume"));
init_button(TURN_OFF_FIRE_ALARM, _L("Got it, Turn off the Fire Alarm."));
init_button(RETRY_PROBLEM_SOLVED, _L("Retry (problem solved)"));
init_button(STOP_DRYING, _L("Stop Drying"));
}
void DeviceErrorDialog::on_dpi_changed(const wxRect& suggested_rect)
{
for (auto used_button : m_used_button) { used_button->Rescale();}
wxGetApp().UpdateDlgDarkUI(this);
Refresh();
}
static const std::unordered_set<string> s_jump_liveview_error_codes = { "0300-8003", "0300-8002", "0300-800A"};
void DeviceErrorDialog::show_error_code(int error_code)
{
if (m_error_code == error_code) { return;}
if (wxGetApp().get_hms_query()->is_internal_error(m_obj, error_code)) { return;}
/* error code str*/
std::string error_str = m_obj->get_error_code_str(error_code);
/* error code message*/
wxString error_msg = wxGetApp().get_hms_query()->query_print_error_msg(m_obj, error_code);
if (error_msg.IsEmpty()) { error_msg = _L("Unknown error.");}
/* action buttons*/
std::vector<int> used_button;
wxString error_image_url = wxGetApp().get_hms_query()->query_print_image_action(m_obj, error_code, used_button);
if (s_jump_liveview_error_codes.count(error_str)) { used_button.emplace_back(DeviceErrorDialog::JUMP_TO_LIVEVIEW);}// special case
/* do update*/
update_contents(error_msg, error_str, error_image_url, used_button);
wxGetApp().UpdateDlgDarkUI(this);
Show();
Raise();
this->RequestUserAttention(wxUSER_ATTENTION_ERROR);
}
void DeviceErrorDialog::update_contents(const wxString& text, const wxString& error_code, const wxString& image_url, const std::vector<int>& btns)
{
if (error_code.empty()) { return; }
/* buttons*/
{
m_sizer_button->Clear();
m_used_button.clear();
// Show the used buttons
bool need_remove_close_btn = false;
std::unordered_set<int> shown_btns;
for (int button_id : btns)
{
need_remove_close_btn |= (button_id == REMOVE_CLOSE_BTN); // special case, do not show close button
auto iter = m_button_list.find(button_id);
if (iter != m_button_list.end())
{
m_sizer_button->Add(iter->second, 0, wxALL, FromDIP(5));
iter->second->Show();
m_used_button.insert(iter->second);
}
}
// Special case, do not show close button
if (need_remove_close_btn)
{
SetWindowStyle(GetWindowStyle() & ~wxCLOSE_BOX);
}
else
{
SetWindowStyle(GetWindowStyle() | wxCLOSE_BOX);
}
// Hide unused buttons
for (const auto& pair : m_button_list)
{
if (m_used_button.count(pair.second) == 0) { pair.second->Hide(); }
}
}
/* image */
if (!image_url.empty())
{
const wxImage& img = wxGetApp().get_hms_query()->query_image_from_local(image_url);
if (!img.IsOk() && image_url.Contains("http"))
{
web_request = wxWebSession::GetDefault().CreateRequest(this, image_url);
BOOST_LOG_TRIVIAL(trace) << "monitor: create new webrequest, state = " << web_request.GetState();
if (web_request.GetState() == wxWebRequest::State_Idle) web_request.Start();
BOOST_LOG_TRIVIAL(trace) << "monitor: start new webrequest, state = " << web_request.GetState();
}
else
{
const wxImage& resize_img = img.Scale(FromDIP(320), FromDIP(180), wxIMAGE_QUALITY_HIGH);
m_error_picture->SetBitmap(wxBitmap(resize_img));
}
m_error_picture->Show();
}
else
{
m_error_picture->Hide();
}
/* error code*/
const wxString& show_time = wxDateTime::Now().Format("%H%M%d");
const wxString& error_code_msg = wxString::Format("[%S %S]", error_code, show_time);
m_error_code_label->SetMaxSize(wxSize(FromDIP(300), -1));
m_error_code_label->SetMinSize(wxSize(FromDIP(300), -1));
m_error_code_label->SetLabelText(error_code_msg);
/* error message*/
m_error_msg_label->SetMaxSize(wxSize(FromDIP(300), -1));
m_error_msg_label->SetMinSize(wxSize(FromDIP(300), -1));
m_error_msg_label->SetLabelText(text);
/* update layout*/
{
m_scroll_area->Layout();
auto text_size = m_error_msg_label->GetBestSize();
if (text_size.y < FromDIP(360))
{
if (!image_url.empty())
{
m_scroll_area->SetMinSize(wxSize(FromDIP(320), text_size.y + FromDIP(220)));
}
else
{
m_scroll_area->SetMinSize(wxSize(FromDIP(320), text_size.y + FromDIP(50)));
}
}
else
{
m_scroll_area->SetMinSize(wxSize(FromDIP(320), FromDIP(340)));
}
Layout();
Fit();
}
};
void DeviceErrorDialog::on_button_click(ActionButton btn_id)
{
switch (btn_id) {
case DeviceErrorDialog::RESUME_PRINTING: {
m_obj->command_hms_resume(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::RESUME_PRINTING_DEFECTS: {
m_obj->command_hms_resume(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::RESUME_PRINTING_PROBELM_SOLVED: {
m_obj->command_hms_resume(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::STOP_PRINTING: {
m_obj->command_hms_stop(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::CHECK_ASSISTANT: {
wxGetApp().mainframe->m_monitor->jump_to_HMS(); // go to assistant page
break;
}
case DeviceErrorDialog::FILAMENT_EXTRUDED: {
m_obj->command_ams_control("done");
break;
}
case DeviceErrorDialog::RETRY_FILAMENT_EXTRUDED: {
m_obj->command_ams_control("resume");
return;// do not hide the dialogs
}
case DeviceErrorDialog::CONTINUE: {
m_obj->command_ams_control("resume");
break;
}
case DeviceErrorDialog::LOAD_VIRTUAL_TRAY: {
//m_ams_control->SwitchAms(std::to_string(VIRTUAL_TRAY_MAIN_ID));
//on_ams_load_curr();
break;/*AP, unknown what it is*/
}
case DeviceErrorDialog::OK_BUTTON: {
m_obj->command_clean_print_error(m_obj->subtask_id_, m_error_code);
break;/*do nothing*/
}
case DeviceErrorDialog::FILAMENT_LOAD_RESUME: {
m_obj->command_hms_resume(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::JUMP_TO_LIVEVIEW: {
Slic3r::GUI::wxGetApp().mainframe->jump_to_monitor();
Slic3r::GUI::wxGetApp().mainframe->m_monitor->jump_to_LiveView();
break;
}
case DeviceErrorDialog::NO_REMINDER_NEXT_TIME: {
m_obj->command_hms_idle_ignore(std::to_string(m_error_code), 0); /*the type is 0, supported by AP*/
break;
}
case DeviceErrorDialog::IGNORE_NO_REMINDER_NEXT_TIME: {
m_obj->command_hms_ignore(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::IGNORE_RESUME: {
m_obj->command_hms_ignore(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::PROBLEM_SOLVED_RESUME: {
m_obj->command_hms_resume(std::to_string(m_error_code), m_obj->job_id_);
break;
}
case DeviceErrorDialog::TURN_OFF_FIRE_ALARM: {
m_obj->command_stop_buzzer();
break;
}
case DeviceErrorDialog::RETRY_PROBLEM_SOLVED: {
m_obj->command_ams_control("resume");
break;
}
case DeviceErrorDialog::STOP_DRYING: {
m_obj->command_ams_drying_stop();
break;
}
case DeviceErrorDialog::ERROR_BUTTON_COUNT: break;
default: break;
}
Hide();
}
}
} // namespace Slic3r::GUI