diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index 00d31ca600..b4322e3155 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -251,6 +251,16 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, const std::funct create(m_content, 84); } + +HtmlCapableRichMessageDialog::HtmlCapableRichMessageDialog(wxWindow *parent, + const wxString &msg, + const wxString &caption, + long style, + const std::function &on_link_clicked) + : RichMessageDialogBase(parent, HtmlContent{msg, false, true, on_link_clicked}, caption, style) +{} + + // WarningDialog WarningDialog::WarningDialog(wxWindow *parent, @@ -276,17 +286,23 @@ MessageDialog::MessageDialog(wxWindow* parent, add_msg_content(this, content_sizer, HtmlContent{ get_wraped_wxString(message) }); finalize(); } +#endif -// RichMessageDialog +// RichMessageDialogBase -RichMessageDialog::RichMessageDialog(wxWindow* parent, +RichMessageDialogBase::RichMessageDialogBase(wxWindow* parent, const wxString& message, const wxString& caption/* = wxEmptyString*/, long style/* = wxOK*/) + : RichMessageDialogBase(parent, HtmlContent{get_wraped_wxString(message)}, caption, style) +{} + +RichMessageDialogBase::RichMessageDialogBase(wxWindow* parent, const HtmlContent& content, const wxString& caption, long style) : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, style) { - add_msg_content(this, content_sizer, HtmlContent{ get_wraped_wxString(message) }); + m_content = content; // We need a copy for the on_link_clicked lambda. + add_msg_content(this, content_sizer, m_content); m_checkBox = new ::CheckBox(this, m_checkBoxText); wxGetApp().UpdateDarkUI(m_checkBox); @@ -294,10 +310,11 @@ RichMessageDialog::RichMessageDialog(wxWindow* parent, btn_sizer->Insert(0, m_checkBox, wxALIGN_CENTER_VERTICAL); - finalize(); + finalize(); } -int RichMessageDialog::ShowModal() + +int RichMessageDialogBase::ShowModal() { if (m_checkBoxText.IsEmpty()) m_checkBox->Hide(); @@ -309,7 +326,7 @@ int RichMessageDialog::ShowModal() return wxDialog::ShowModal(); } -#endif + // InfoDialog diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index 66ee97f911..e568b1f1da 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -106,42 +106,9 @@ public: wxString get_wraped_wxString(const wxString& text_in, size_t line_len = 80); -#ifdef _WIN32 -// Generic static line, used intead of wxStaticLine -class StaticLine: public wxTextCtrl -{ -public: - StaticLine( wxWindow* parent, - wxWindowID id = wxID_ANY, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxLI_HORIZONTAL, - const wxString& name = wxString::FromAscii(wxTextCtrlNameStr)) - : wxTextCtrl(parent, id, wxEmptyString, pos, size!=wxDefaultSize ? size : (style == wxLI_HORIZONTAL ? wxSize(10, 1) : wxSize(1, 10)), wxSIMPLE_BORDER, wxDefaultValidator, name) - { - this->Enable(false); - } - ~StaticLine() {} -}; - -// Generic message dialog, used intead of wxMessageDialog -class MessageDialog : public MsgDialog -{ -public: - // NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxMessageDialog - MessageDialog( wxWindow *parent, - const wxString& message, - const wxString& caption = wxEmptyString, - long style = wxOK); - MessageDialog(MessageDialog&&) = delete; - MessageDialog(const MessageDialog&) = delete; - MessageDialog &operator=(MessageDialog&&) = delete; - MessageDialog &operator=(const MessageDialog&) = delete; - virtual ~MessageDialog() = default; -}; // Generic rich message dialog, used intead of wxRichMessageDialog -class RichMessageDialog : public MsgDialog +class RichMessageDialogBase : public MsgDialog { CheckBox* m_checkBox{ nullptr }; wxString m_checkBoxText; @@ -149,15 +116,13 @@ class RichMessageDialog : public MsgDialog public: // NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxRichMessageDialog - RichMessageDialog( wxWindow *parent, - const wxString& message, - const wxString& caption = wxEmptyString, - long style = wxOK); - RichMessageDialog(RichMessageDialog&&) = delete; - RichMessageDialog(const RichMessageDialog&) = delete; - RichMessageDialog &operator=(RichMessageDialog&&) = delete; - RichMessageDialog &operator=(const RichMessageDialog&) = delete; - virtual ~RichMessageDialog() = default; + RichMessageDialogBase(wxWindow* parent, const wxString& message, const wxString& caption = wxEmptyString, long style = wxOK); + RichMessageDialogBase(wxWindow* parent, const HtmlContent& content, const wxString& caption = wxEmptyString, long style = wxOK); + RichMessageDialogBase(RichMessageDialogBase&&) = delete; + RichMessageDialogBase(const RichMessageDialogBase&) = delete; + RichMessageDialogBase &operator=(RichMessageDialogBase&&) = delete; + RichMessageDialogBase &operator=(const RichMessageDialogBase&) = delete; + virtual ~RichMessageDialogBase() = default; int ShowModal() override; @@ -278,7 +243,47 @@ private: m_ok, m_cancel, m_help; + + HtmlContent m_content; }; + + +#ifdef _WIN32 +// Generic static line, used intead of wxStaticLine +class StaticLine: public wxTextCtrl +{ +public: + StaticLine( wxWindow* parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxLI_HORIZONTAL, + const wxString& name = wxString::FromAscii(wxTextCtrlNameStr)) + : wxTextCtrl(parent, id, wxEmptyString, pos, size!=wxDefaultSize ? size : (style == wxLI_HORIZONTAL ? wxSize(10, 1) : wxSize(1, 10)), wxSIMPLE_BORDER, wxDefaultValidator, name) + { + this->Enable(false); + } + ~StaticLine() {} +}; + +// Generic message dialog, used intead of wxMessageDialog +class MessageDialog : public MsgDialog +{ +public: + // NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxMessageDialog + MessageDialog(wxWindow *parent, + const wxString& message, + const wxString& caption = wxEmptyString, + long style = wxOK); + MessageDialog(MessageDialog &&) = delete; + MessageDialog(const MessageDialog &) = delete; + MessageDialog &operator=(MessageDialog &&) = delete; + MessageDialog &operator=(const MessageDialog &) = delete; + virtual ~MessageDialog() = default; +}; + +using RichMessageDialog = RichMessageDialogBase; + #else // just a wrapper for wxStaticLine to use the same code on all platforms class StaticLine : public wxStaticLine @@ -320,6 +325,16 @@ public: }; #endif +class HtmlCapableRichMessageDialog : public RichMessageDialogBase +{ +public: + HtmlCapableRichMessageDialog(wxWindow *parent, const wxString &msg, const wxString& caption, long style, const std::function &on_link_clicked); + ~HtmlCapableRichMessageDialog() {} + +private: + HtmlContent m_content; +}; + // Generic info dialog, used for displaying exceptions class InfoDialog : public MsgDialog { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b16477cabc..febdedb502 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6694,14 +6694,14 @@ static wxString check_binary_vs_ascii_gcode_extension(PrinterTechnology pt, cons if (binary_output && ascii_extension) { // TRN The placeholder %1% is the file extension the user has selected. err_out = format_wxstr(_L("Cannot save binary G-code with %1% extension.\n\n" - "Use a different extension or disable binary G-code export " - "in Print Settings."), ext, "output_filename_format;print", "gcode_binary;print"); + "Use a different extension or disable binary G-code export " + "in Printer Settings."), ext, "binary_gcode;printer"); } if (!binary_output && binary_extension) { // TRN The placeholder %1% is the file extension the user has selected. err_out = format_wxstr(_L("Cannot save ASCII G-code with %1% extension.\n\n" - "Use a different extension or enable binary G-code export " - "in Print Settings."), ext, "output_filename_format;print", "gcode_binary;print"); + "Use a different extension or enable binary G-code export " + "in Printer Settings."), ext, "binary_gcode;printer"); } } return err_out; @@ -6725,9 +6725,14 @@ static void alert_when_exporting_binary_gcode(bool binary_output, const std::str const std::string option_key = "dont_warn_about_firmware_version_when_exporting_binary_gcode"; if (app_config->get(option_key) != "1") { - RichMessageDialog dialog(parent, _L("You are exporting binary G-code for a Prusa printer. Please, make sure that your printer " - "is running firmware version 5.1.0-alpha2 or later. Older firmwares are not able to handle binary G-codes."), - _L("Exporting binary G-code"), wxICON_WARNING | wxOK); + const wxString url = "https://prusa.io/binary-gcode"; + HtmlCapableRichMessageDialog dialog(parent, + format_wxstr(_L("You are exporting binary G-code for a Prusa printer. Exporting binary G-code allows faster upload. " + "Ensure your printer runs firmware version 5.1.0 or later, as older versions do not support binary G-codes.\n\n" + "To learn more about binary G-code, visit %1%."), + url), + _L("Warning"), wxOK, + [&url](const std::string&) { wxGetApp().open_browser_with_warning_dialog(url); }); dialog.ShowCheckBox(_L("Don't show again")); if (dialog.ShowModal() == wxID_OK && dialog.IsCheckBoxChecked()) app_config->set(option_key, "1");