Browse Source

Substitutions : Implemented InfoDialog

YuSanka 3 years ago
parent
commit
1e60acde12

+ 71 - 0
resources/icons/white/info.svg

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   id="error"
+   x="0px"
+   y="0px"
+   viewBox="0 0 200 200"
+   enable-background="new 0 0 100 100"
+   xml:space="preserve"
+   sodipodi:docname="notification_error.svg"
+   width="200"
+   height="200"
+   inkscape:version="1.0 (4035a4fb49, 2020-05-01)"><metadata
+   id="metadata19"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs17" /><sodipodi:namedview
+   inkscape:document-rotation="0"
+   pagecolor="#ffffff"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="2560"
+   inkscape:window-height="1377"
+   id="namedview15"
+   showgrid="false"
+   inkscape:zoom="5.04"
+   inkscape:cx="117.17146"
+   inkscape:cy="98.609664"
+   inkscape:window-x="-8"
+   inkscape:window-y="-8"
+   inkscape:window-maximized="1"
+   inkscape:current-layer="error" />
+<g
+   id="g4"
+   transform="matrix(2.52,0,0,2.52,-26,-26)">
+	<path
+   fill="#FFFFFF"
+   d="m 50,54.25 c -2.35,0 -4.25,-1.9 -4.25,-4.25 V 35 c 0,-2.35 1.9,-4.25 4.25,-4.25 2.35,0 4.25,1.9 4.25,4.25 v 15 c 0,2.35 -1.9,4.25 -4.25,4.25 z"
+   id="path2" />
+</g>
+<g
+   id="g8"
+   transform="matrix(2.52,0,0,2.52,-26,-26)">
+	<circle
+   fill="#FFFFFF"
+   cx="50"
+   cy="65"
+   r="5"
+   id="circle6" />
+</g>
+<g
+   id="g12"
+   transform="matrix(2.52,0,0,2.52,-26,-26)">
+	<path
+   fill="#FFFFFF"
+   d="M 50,89.25 C 28.36,89.25 10.75,71.64 10.75,50 10.75,28.36 28.36,10.75 50,10.75 71.64,10.75 89.25,28.36 89.25,50 89.25,71.64 71.64,89.25 50,89.25 Z m 0,-70 C 33.05,19.25 19.25,33.04 19.25,50 19.25,66.95 33.04,80.75 50,80.75 66.95,80.75 80.75,66.96 80.75,50 80.75,33.05 66.95,19.25 50,19.25 Z"
+   id="path10" />
+</g>
+</svg>

+ 1 - 1
src/libslic3r/Utils.hpp

@@ -238,7 +238,7 @@ inline typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER
 	return container[next_idx_modulo(idx, container.size())];
 }
 
-extern std::string xml_escape(std::string text);
+extern std::string xml_escape(std::string text, bool is_marked = false);
 
 
 #if defined __GNUC__ && __GNUC__ < 5 && !defined __clang__

+ 3 - 3
src/libslic3r/utils.cpp

@@ -888,7 +888,7 @@ unsigned get_current_pid()
 #endif
 }
 
-std::string xml_escape(std::string text)
+std::string xml_escape(std::string text, bool is_marked/* = false*/)
 {
     std::string::size_type pos = 0;
     for (;;)
@@ -903,8 +903,8 @@ std::string xml_escape(std::string text)
         case '\"': replacement = "&quot;"; break;
         case '\'': replacement = "&apos;"; break;
         case '&':  replacement = "&amp;";  break;
-        case '<':  replacement = "&lt;";   break;
-        case '>':  replacement = "&gt;";   break;
+        case '<':  replacement = is_marked ? "<" :"&lt;"; break;
+        case '>':  replacement = is_marked ? ">" :"&gt;"; break;
         default: break;
         }
 

+ 86 - 0
src/slic3r/GUI/GUI.cpp

@@ -244,6 +244,92 @@ void warning_catcher(wxWindow* parent, const wxString& message)
 	msg.ShowModal();
 }
 
+static void add_config_substitutions(const ConfigSubstitutions& conf_substitutions, wxString& changes)
+{
+	for (const ConfigSubstitution& conf_substitution : conf_substitutions) {
+		wxString new_val;
+		if (!conf_substitution.opt_def)
+			continue;
+		if (conf_substitution.opt_def->type == coEnum) {
+			const std::vector<std::string>& labels = conf_substitution.opt_def->enum_labels;
+			const std::vector<std::string>& values = conf_substitution.opt_def->enum_values;
+			int val = conf_substitution.new_value->getInt();
+
+			bool is_infill = conf_substitution.opt_def->opt_key == "top_fill_pattern" ||
+				conf_substitution.opt_def->opt_key == "bottom_fill_pattern" ||
+				conf_substitution.opt_def->opt_key == "fill_pattern";
+
+			// Each infill doesn't use all list of infill declared in PrintConfig.hpp.
+			// So we should "convert" val to the correct one
+			if (is_infill) {
+				for (const auto& key_val : *conf_substitution.opt_def->enum_keys_map)
+					if ((int)key_val.second == val) {
+						auto it = std::find(values.begin(), values.end(), key_val.first);
+						if (it == values.end())
+							break;
+						new_val = from_u8(_utf8(labels[it - values.begin()]));
+						break;
+					}
+				new_val = _L("Undef");
+			}
+			else
+				new_val = from_u8(_utf8(labels[val]));
+		}
+		else if (conf_substitution.opt_def->type == coBool)
+			new_val = conf_substitution.new_value->getBool() ? "true" : "false";
+
+		changes += "\n" + GUI::format(_L("New unknown value <b>\"%1%\"</b> was changed to defaul value <b>\"%2%\"</b>"), conf_substitution.old_value, new_val);
+	}
+}
+
+void show_substitutions_info(const PresetsConfigSubstitutions& presets_config_substitutions) 
+{
+	wxString changes;
+
+	auto preset_type_name = [](Preset::Type type) {
+		return	type == Slic3r::Preset::TYPE_PRINT			? _L("Print") :
+				type == Slic3r::Preset::TYPE_SLA_PRINT		? _L("SLA Print") :
+				type == Slic3r::Preset::TYPE_FILAMENT		? _L("Filament") :
+				type == Slic3r::Preset::TYPE_SLA_MATERIAL	? _L("SLA Material") :
+				type == Slic3r::Preset::TYPE_PRINTER		? _L("Printer") : "";
+	};
+
+	for (const PresetConfigSubstitutions& substitution : presets_config_substitutions) {
+		changes += "\n<p>" + GUI::format(_L(" %1% Preset : <b>%2%</b>"), preset_type_name(substitution.preset_type), substitution.preset_name);
+		if (!substitution.preset_file.empty())
+			changes += GUI::format(" (%1%)", substitution.preset_file);
+		changes += "</p>";
+
+		add_config_substitutions(substitution.substitutions, changes);
+	}
+	if (!changes.IsEmpty())
+		changes += "\n\n";
+
+	wxString message = format(_L("Loading profiles found following incompatibilities:%1%"
+								 " To recover these files, incompatible values were changed to default values.\n"
+							     " But data in files won't be changed until you save them in PrusaSlicer."), changes);
+
+	InfoDialog msg(nullptr, message);
+	msg.ShowModal();
+}
+
+void show_substitutions_info(const ConfigSubstitutions& config_substitutions, const std::string& filename)
+{
+	wxString changes = "\n";
+
+	add_config_substitutions(config_substitutions, changes);
+
+	if (!changes.IsEmpty())
+	changes += "\n\n";
+
+	wxString message = format(_L("Loading <b>%1%</b> file found incompatibilities.\n"
+								 "To recover this file, incompatible values were changed to default values:%2%"
+							     "But data in files won't be changed until you save them in PrusaSlicer."), from_u8(filename), changes);
+
+	InfoDialog msg(nullptr, message);
+	msg.ShowModal();
+}
+
 void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, const std::string& items)
 {
     if (comboCtrl == nullptr)

+ 3 - 0
src/slic3r/GUI/GUI.hpp

@@ -7,6 +7,7 @@ namespace boost::filesystem { class path; }
 #include <wx/string.h>
 
 #include "libslic3r/Config.hpp"
+#include "libslic3r/Preset.hpp"
 
 class wxWindow;
 class wxMenuBar;
@@ -48,6 +49,8 @@ void show_info(wxWindow* parent, const wxString& message, const wxString& title
 void show_info(wxWindow* parent, const char* message, const char* title = nullptr);
 inline void show_info(wxWindow* parent, const std::string& message,const std::string& title = std::string()) { show_info(parent, message.c_str(), title.c_str()); }
 void warning_catcher(wxWindow* parent, const wxString& message);
+void show_substitutions_info(const PresetsConfigSubstitutions& presets_config_substitutions);
+void show_substitutions_info(const ConfigSubstitutions& config_substitutions, const std::string& filename);
 
 // Creates a wxCheckListBoxComboPopup inside the given wxComboCtrl, filled with the given text and items.
 // Items data must be separated by '|', and contain the item name to be shown followed by its initial value (0 for false, 1 for true).

+ 5 - 12
src/slic3r/GUI/GUI_App.cpp

@@ -626,12 +626,8 @@ void GUI_App::post_init()
             this->plater()->load_gcode(wxString::FromUTF8(this->init_params->input_files[0].c_str()));
     }
     else {
-        if (! this->init_params->preset_substitutions.empty()) {
-            // TODO: Add list of changes from all_substitutions
-            show_error(nullptr, GUI::format(_L("Loading profiles found following incompatibilities."
-                " To recover these files, incompatible values were changed to default values."
-                " But data in files won't be changed until you save them in PrusaSlicer.")));
-        } 
+        if (! this->init_params->preset_substitutions.empty())
+            show_substitutions_info(this->init_params->preset_substitutions);
 
 #if 0
         // Load the cummulative config over the currently active profiles.
@@ -1879,12 +1875,9 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
                     try {
                         app_config->set("on_snapshot", Config::SnapshotDB::singleton().restore_snapshot(dlg.snapshot_to_activate(), *app_config).id);
                         if (PresetsConfigSubstitutions all_substitutions = preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::Enable);
-                            ! all_substitutions.empty()) {
-                            // TODO:
-                            show_error(nullptr, GUI::format(_L("Loading profiles found following incompatibilities."
-                                " To recover these files, incompatible values were changed to default values."
-                                " But data in files won't be changed until you save them in PrusaSlicer.")));
-                        }
+                            ! all_substitutions.empty())
+                            show_substitutions_info(all_substitutions);
+
                         // Load the currently selected preset into the GUI, update the preset selection box.
                         load_current_presets();
                     } catch (std::exception &ex) {

+ 1 - 1
src/slic3r/GUI/Jobs/SLAImportJob.cpp

@@ -159,7 +159,7 @@ void SLAImportJob::process()
     }
 
     if (! config_substitutions.empty()) {
-        //FIXME Add reporting here "Loading profiles found following incompatibilities."
+        show_substitutions_info(config_substitutions, path);
     }
     
     update_status(100, was_canceled() ? _(L("Importing canceled.")) :

+ 4 - 12
src/slic3r/GUI/MainFrame.cpp

@@ -1749,12 +1749,8 @@ bool MainFrame::load_config_file(const std::string &path)
 {
     try {
         ConfigSubstitutions config_substitutions = wxGetApp().preset_bundle->load_config_file(path, ForwardCompatibilitySubstitutionRule::Enable);
-        if (! config_substitutions.empty()) {
-            // TODO: Add list of changes from all_substitutions
-            show_error(nullptr, GUI::format(_L("Loading profiles found following incompatibilities."
-                " To recover these files, incompatible values were changed to default values."
-                " But data in files won't be changed until you save them in PrusaSlicer.")));
-        }
+        if (!config_substitutions.empty())
+            show_substitutions_info(config_substitutions, path);
     } catch (const std::exception &ex) {
         show_error(this, ex.what());
         return false;
@@ -1819,12 +1815,8 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re
         return;
     }
 
-    if (! config_substitutions.empty()) {
-        // TODO: Add list of changes from all_substitutions
-        show_error(nullptr, GUI::format(_L("Loading profiles found following incompatibilities."
-            " To recover these files, incompatible values were changed to default values."
-            " But data in files won't be changed until you save them in PrusaSlicer.")));
-    }
+    if (! config_substitutions.empty())
+        show_substitutions_info(config_substitutions);
 
     // Load the currently selected preset into the GUI, update the preset selection box.
 	wxGetApp().load_current_presets();

+ 38 - 0
src/slic3r/GUI/MsgDialog.cpp

@@ -211,5 +211,43 @@ MessageDialog::MessageDialog(wxWindow* parent,
 }
 #endif
 
+
+// InfoDialog
+
+InfoDialog::InfoDialog(wxWindow* parent, const wxString& msg)
+	: MsgDialog(parent, wxString::Format(_L("%s information"), SLIC3R_APP_NAME), _L("Note that"))
+	, msg(msg)
+{
+	this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+
+	// 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(), -1));
+		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() - 1;
+		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(), true);
+		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);
+	}
+
+	// Set info bitmap
+	logo->SetBitmap(create_scaled_bitmap("info", this, 84));
+
+	SetMinSize(wxSize(60 * wxGetApp().em_unit(), 30 * wxGetApp().em_unit()));
+	Fit();
+}
+
+
 }
 }

+ 2 - 6
src/slic3r/GUI/Plater.cpp

@@ -2261,12 +2261,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
                         // and place the loaded config over the base.
                         config += std::move(config_loaded);
                     }
-                    if (! config_substitutions.empty()) {
-                        // TODO:
-                        show_error(nullptr, GUI::format(_L("Loading profiles found following incompatibilities."
-                            " To recover these files, incompatible values were changed to default values."
-                            " But data in files won't be changed until you save them in PrusaSlicer.")));
-                    }
+                    if (! config_substitutions.empty())
+                        show_substitutions_info(config_substitutions.substitutions, filename.string());
 
                     this->model.custom_gcode_per_print_z = model.custom_gcode_per_print_z;
                 }