diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index be7d7c1c7..de050a477 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -16,6 +16,7 @@
 #include <wx/tokenzr.h>
 #include <boost/algorithm/string/predicate.hpp>
 #include "OG_CustomCtrl.hpp"
+#include "MsgDialog.hpp"
 
 #ifdef __WXOSX__
 #define wxOSX true
@@ -263,7 +264,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
                     if (m_value.empty() || boost::any_cast<double>(m_value) != val) {
                         wxString msg_text = format_wxstr(_L("Input value is out of range\n"
                             "Are you sure that %s is a correct value and that you want to continue?"), str);
-                        wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO);
+//                        wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO);
+                        WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO);
                         if (dialog.ShowModal() == wxID_NO) {
                             if (m_value.empty()) {
                                 if (m_opt.min > val) val = m_opt.min;
@@ -323,7 +325,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
                 const wxString msg_text = from_u8((boost::format(_utf8(L("Do you mean %s%% instead of %s %s?\n"
                     "Select YES if you want to change this value to %s%%, \n"
                     "or NO if you are sure that %s %s is a correct value."))) % stVal % stVal % sidetext % stVal % stVal % sidetext).str());
-                wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id , wxICON_WARNING | wxYES | wxNO);
+//                wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id , wxICON_WARNING | wxYES | wxNO);
+                WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO);
                 if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) {
                     set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/);
                     str += "%%";
@@ -370,8 +373,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
                 if (!m_value.empty())
                     text_value = get_thumbnails_string(boost::any_cast<std::vector<Vec2d>>(m_value));
                 set_value(text_value, true);
-                show_error(m_parent, _L("Input value is out of range")
-                );
+                show_error(m_parent, _L("Input value is out of range"));
             }
             else if (invalid_val) {
                 wxString text_value;
diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp
index d90f4de10..de4c7e00f 100644
--- a/src/slic3r/GUI/MsgDialog.cpp
+++ b/src/slic3r/GUI/MsgDialog.cpp
@@ -107,5 +107,55 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_
 	Fit();
 }
 
+// WarningDialog
+
+WarningDialog::WarningDialog(wxWindow *parent,
+                             const wxString& message,
+                             const wxString& caption/* = wxEmptyString*/,
+                             long style/* = wxOK*/)
+    : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s warning"), SLIC3R_APP_NAME) : caption, 
+                        wxString::Format(_L("%s has a warning")+":", SLIC3R_APP_NAME), wxID_NONE)
+    , msg(message)
+{
+    // Text shown as HTML, so that mouse selection and Ctrl-V to copy will work.
+    wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
+    {
+        html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), 10 * wxGetApp().em_unit()));
+        wxFont           font             = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+        wxFont      monospace       = wxGetApp().code_font();
+        wxColour      text_clr          = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+        wxColour      bgr_clr         = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
+        auto          text_clr_str     = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
+        auto          bgr_clr_str     = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
+        const int     font_size       = font.GetPointSize();
+        int         size[]             = {font_size, font_size, font_size, font_size, font_size, font_size, font_size};
+        html->SetFonts(font.GetFaceName(), monospace.GetFaceName(), size);
+        html->SetBorders(2);
+        std::string msg_escaped = xml_escape(msg.ToUTF8().data());
+        boost::replace_all(msg_escaped, "\r\n", "<br>");
+        boost::replace_all(msg_escaped, "\n", "<br>");
+        html->SetPage("<html><body bgcolor=\"" + bgr_clr_str + "\"><font color=\"" + text_clr_str + "\">" + wxString::FromUTF8(msg_escaped.data()) + "</font></body></html>");
+        content_sizer->Add(html, 1, wxEXPAND|wxBOTTOM, BORDER);
+    }
+
+    auto add_btn = [this](wxWindowID btn_id) {
+        auto* btn = new wxButton(this, btn_id);
+        btn_sizer->Add(btn, 0, wxRIGHT, HORIZ_SPACING);
+        btn->Bind(wxEVT_BUTTON, [this, btn_id](wxCommandEvent&) { this->EndModal(btn_id); });
+    };
+
+    if (style & wxOK)
+        add_btn(wxID_OK);
+    if (style & wxYES)
+        add_btn(wxID_YES);
+    if (style & wxNO)
+        add_btn(wxID_NO);
+
+    logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 150));
+
+    SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit()));
+    Fit();
+}
+
 }
 }
diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp
index 70032089b..20d7f8dd5 100644
--- a/src/slic3r/GUI/MsgDialog.hpp
+++ b/src/slic3r/GUI/MsgDialog.hpp
@@ -66,6 +66,27 @@ private:
 };
 
 
+// Generic error dialog, used for displaying exceptions
+class WarningDialog : public MsgDialog
+{
+public:
+	// If monospaced_font is true, the error message is displayed using html <code><pre></pre></code> tags,
+	// so that the code formatting will be preserved. This is useful for reporting errors from the placeholder parser.
+	WarningDialog(	wxWindow *parent,
+		            const wxString& message,
+		            const wxString& caption = wxEmptyString,
+		            long style = wxOK);
+	WarningDialog(WarningDialog&&) = delete;
+	WarningDialog(const WarningDialog&) = delete;
+	WarningDialog &operator=(WarningDialog&&) = delete;
+	WarningDialog &operator=(const WarningDialog&) = delete;
+	virtual ~WarningDialog() = default;
+
+private:
+	wxString	msg;
+};
+
+
 }
 }