mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
		
						commit
						8a03d5642d
					
				
					 10 changed files with 364 additions and 240 deletions
				
			
		|  | @ -64,6 +64,7 @@ add_library(libslic3r STATIC | |||
|     Fill/FillRectilinear3.hpp | ||||
|     Flow.cpp | ||||
|     Flow.hpp | ||||
|     format.hpp | ||||
|     Format/3mf.cpp | ||||
|     Format/3mf.hpp | ||||
|     Format/AMF.cpp | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include "Config.hpp" | ||||
| #include "format.hpp" | ||||
| #include "Utils.hpp" | ||||
| #include <assert.h> | ||||
| #include <fstream> | ||||
|  | @ -464,7 +465,7 @@ bool ConfigBase::set_deserialize_nothrow(const t_config_option_key &opt_key_src, | |||
| void ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const std::string &value_src, bool append) | ||||
| { | ||||
| 	if (! this->set_deserialize_nothrow(opt_key_src, value_src, append)) | ||||
| 		throw BadOptionTypeException((boost::format("ConfigBase::set_deserialize() failed for parameter \"%1%\", value \"%2%\"") % opt_key_src % value_src).str()); | ||||
| 		throw BadOptionTypeException(format("ConfigBase::set_deserialize() failed for parameter \"%1%\", value \"%2%\"", opt_key_src,  value_src)); | ||||
| } | ||||
| 
 | ||||
| void ConfigBase::set_deserialize(std::initializer_list<SetDeserializeItem> items) | ||||
|  | @ -620,7 +621,7 @@ void ConfigBase::load_from_gcode_file(const std::string &file) | |||
| 
 | ||||
|     size_t key_value_pairs = load_from_gcode_string(data.data()); | ||||
|     if (key_value_pairs < 80) | ||||
|         throw std::runtime_error((boost::format("Suspiciously low number of configuration values extracted from %1%: %2%") % file % key_value_pairs).str()); | ||||
|         throw std::runtime_error(format("Suspiciously low number of configuration values extracted from %1%: %2%", file, key_value_pairs)); | ||||
| } | ||||
| 
 | ||||
| // Load the config keys from the given string.
 | ||||
|  |  | |||
							
								
								
									
										57
									
								
								src/libslic3r/format.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/libslic3r/format.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | |||
| #ifndef slic3r_format_hpp_ | ||||
| #define slic3r_format_hpp_ | ||||
| 
 | ||||
| // Functional wrapper around boost::format.
 | ||||
| // One day we may replace this wrapper with C++20 format
 | ||||
| // https://en.cppreference.com/w/cpp/utility/format/format
 | ||||
| // though C++20 format uses a different template pattern for position independent parameters.
 | ||||
| // 
 | ||||
| // Boost::format works around the missing variadic templates by an ugly % chaining operator. The usage of boost::format looks like this:
 | ||||
| // (boost::format("template") % arg1 %arg2).str()
 | ||||
| // This wrapper allows for a nicer syntax:
 | ||||
| // Slic3r::format("template", arg1, arg2)
 | ||||
| // One can also override Slic3r::internal::format::cook() function to convert a Slic3r::format() argument to something that
 | ||||
| // boost::format may convert to string, see slic3r/GUI/I18N.hpp for a "cook" function to convert wxString to UTF8.
 | ||||
| 
 | ||||
| #include <boost/format.hpp> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| // https://gist.github.com/gchudnov/6a90d51af004d97337ec
 | ||||
| namespace internal { | ||||
| 	namespace format { | ||||
| 		// Default "cook" function - just forward.
 | ||||
| 		template<typename T> | ||||
| 		inline T&& cook(T&& arg) { | ||||
| 		  	return std::forward<T>(arg); | ||||
| 		} | ||||
| 
 | ||||
| 		// End of the recursive chain.
 | ||||
| 		inline std::string format_recursive(boost::format& message) { | ||||
| 		  	return message.str(); | ||||
| 		} | ||||
| 
 | ||||
| 		template<typename TValue, typename... TArgs> | ||||
| 		std::string format_recursive(boost::format& message, TValue&& arg, TArgs&&... args) { | ||||
| 			// Format, possibly convert the argument by the "cook" function.
 | ||||
| 		  	message % cook(std::forward<TValue>(arg)); | ||||
| 		  	return format_recursive(message, std::forward<TArgs>(args)...); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| template<typename... TArgs> | ||||
| inline std::string format(const char* fmt, TArgs&&... args) { | ||||
| 	boost::format message(fmt); | ||||
| 	return internal::format::format_recursive(message, std::forward<TArgs>(args)...); | ||||
| } | ||||
| 
 | ||||
| template<typename... TArgs> | ||||
| inline std::string format(const std::string& fmt, TArgs&&... args) { | ||||
| 	boost::format message(fmt); | ||||
| 	return internal::format::format_recursive(message, std::forward<TArgs>(args)...); | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| #endif // slic3r_format_hpp_
 | ||||
|  | @ -111,6 +111,7 @@ | |||
| #include "BoundingBox.hpp" | ||||
| #include "ClipperUtils.hpp" | ||||
| #include "Config.hpp" | ||||
| #include "format.hpp" | ||||
| #include "I18N.hpp" | ||||
| #include "MultiPoint.hpp" | ||||
| #include "Point.hpp" | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ set(SLIC3R_GUI_SOURCES | |||
|     GUI/ConfigSnapshotDialog.hpp | ||||
|     GUI/3DScene.cpp | ||||
|     GUI/3DScene.hpp | ||||
|     GUI/format.hpp | ||||
|     GUI/GLShader.cpp | ||||
|     GUI/GLShader.hpp     | ||||
|     GUI/GLCanvas3D.hpp | ||||
|  |  | |||
|  | @ -20,11 +20,13 @@ | |||
| #include <cmath> | ||||
| #include <boost/algorithm/string/replace.hpp> | ||||
| #include "Field.hpp" | ||||
| #include "format.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| using GUI::from_u8; | ||||
| using GUI::into_u8; | ||||
| using GUI::format_wxstr; | ||||
| 
 | ||||
| namespace DoubleSlider { | ||||
| 
 | ||||
|  | @ -530,7 +532,7 @@ wxString Control::get_label(int tick) const | |||
|     const wxString str = m_values.empty() ?  | ||||
|                          wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None) : | ||||
|                          wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None); | ||||
|     return from_u8((boost::format("%1%\n(%2%)") % str % (m_values.empty() ? value : value+1)).str()); | ||||
|     return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value+1); | ||||
| } | ||||
| 
 | ||||
| void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side/*=true*/) const | ||||
|  | @ -1001,16 +1003,16 @@ wxString Control::get_tooltip(int tick/*=-1*/) | |||
| 
 | ||||
|         // Show custom Gcode as a first string of tooltop
 | ||||
|         tooltip = "    "; | ||||
|         tooltip +=  tick_code_it->gcode == ColorChangeCode ?    (   m_mode == t_mode::SingleExtruder                ?  | ||||
|                         from_u8((boost::format(_utf8(L("Color change (\"%1%\")"))) % tick_code_it->gcode ).str()) : | ||||
|                         from_u8((boost::format(_utf8(L("Color change (\"%1%\") for Extruder %2%"))) %  | ||||
|                                                tick_code_it->gcode % tick_code_it->extruder).str()) )                   : | ||||
|                     tick_code_it->gcode == PausePrintCode ? | ||||
|                         from_u8((boost::format(_utf8(L("Pause print (\"%1%\")"))) % tick_code_it->gcode ).str())      : | ||||
|                     tick_code_it->gcode == ToolChangeCode ? | ||||
|                         from_u8((boost::format(_utf8(L("Extruder (tool) is changed to Extruder \"%1%\""))) %  | ||||
|                                                tick_code_it->extruder ).str())                                          : | ||||
|                         from_u8(tick_code_it->gcode); | ||||
|         tooltip +=   | ||||
|         	tick_code_it->gcode == ColorChangeCode ? | ||||
|         		(m_mode == t_mode::SingleExtruder ? | ||||
|                 	format_wxstr(_L("Color change (\"%1%\")"), tick_code_it->gcode) : | ||||
|                     format_wxstr(_L("Color change (\"%1%\") for Extruder %2%"), tick_code_it->gcode, tick_code_it->extruder)) : | ||||
| 	            tick_code_it->gcode == PausePrintCode ? | ||||
| 	                format_wxstr(_L("Pause print (\"%1%\")"), tick_code_it->gcode) : | ||||
| 		            tick_code_it->gcode == ToolChangeCode ? | ||||
| 		                format_wxstr(_L("Extruder (tool) is changed to Extruder \"%1%\""), tick_code_it->extruder) : | ||||
| 		                from_u8(tick_code_it->gcode); | ||||
| 
 | ||||
|         // If tick is marked as a conflict (exclamation icon),
 | ||||
|         // we should to explain why
 | ||||
|  | @ -1176,8 +1178,8 @@ void Control::append_add_color_change_menu_item(wxMenu* menu, bool switch_curren | |||
|         } | ||||
| 
 | ||||
|         const wxString menu_name = switch_current_code ?  | ||||
|                                    from_u8((boost::format(_utf8(L("Switch code to Color change (%1%) for:"))) % ColorChangeCode).str()) :  | ||||
|                                    from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % ColorChangeCode).str()); | ||||
|                                    format_wxstr(_L("Switch code to Color change (%1%) for:"), ColorChangeCode) :  | ||||
|                                    format_wxstr(_L("Add color change (%1%) for:"), ColorChangeCode); | ||||
|         wxMenuItem* add_color_change_menu_item = menu->AppendSubMenu(add_color_change_menu, menu_name, ""); | ||||
|         add_color_change_menu_item->SetBitmap(create_scaled_bitmap("colorchange_add_m")); | ||||
|     } | ||||
|  | @ -1615,8 +1617,8 @@ static void upgrade_text_entry_dialog(wxTextEntryDialog* dlg, double min = -1.0, | |||
| 
 | ||||
| static std::string get_custom_code(const std::string& code_in, double height) | ||||
| { | ||||
|     wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + ":"; | ||||
|     wxString msg_header = from_u8((boost::format(_utf8(L("Custom G-code on current layer (%1% mm)."))) % height).str()); | ||||
|     wxString msg_text = _L("Enter custom G-code used on current layer") + ":"; | ||||
|     wxString msg_header = format_wxstr(_L("Custom G-code on current layer (%1% mm)."), height); | ||||
| 
 | ||||
|     // get custom gcode
 | ||||
|     wxTextEntryDialog dlg(nullptr, msg_text, msg_header, code_in, | ||||
|  | @ -1631,8 +1633,8 @@ static std::string get_custom_code(const std::string& code_in, double height) | |||
| 
 | ||||
| static std::string get_pause_print_msg(const std::string& msg_in, double height) | ||||
| { | ||||
|     wxString msg_text = from_u8(_utf8(L("Enter short message shown on Printer display when a print is paused"))) + ":"; | ||||
|     wxString msg_header = from_u8((boost::format(_utf8(L("Message for pause print on current layer (%1% mm)."))) % height).str()); | ||||
|     wxString msg_text = _L("Enter short message shown on Printer display when a print is paused") + ":"; | ||||
|     wxString msg_header = format_wxstr(_L("Message for pause print on current layer (%1% mm)."), height); | ||||
| 
 | ||||
|     // get custom gcode
 | ||||
|     wxTextEntryDialog dlg(nullptr, msg_text, msg_header, from_u8(msg_in), | ||||
|  |  | |||
|  | @ -138,7 +138,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| ObjectInfo::ObjectInfo(wxWindow *parent) : | ||||
|     wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _(L("Info"))), wxVERTICAL) | ||||
|     wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Info")), wxVERTICAL) | ||||
| { | ||||
|     GetStaticBox()->SetFont(wxGetApp().bold_font()); | ||||
| 
 | ||||
|  | @ -157,13 +157,13 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : | |||
|         return text; | ||||
|     }; | ||||
| 
 | ||||
|     init_info_label(&info_size, _(L("Size"))); | ||||
|     label_volume = init_info_label(&info_volume, _(L("Volume"))); | ||||
|     init_info_label(&info_facets, _(L("Facets"))); | ||||
|     label_materials = init_info_label(&info_materials, _(L("Materials"))); | ||||
|     init_info_label(&info_size, _L("Size")); | ||||
|     label_volume = init_info_label(&info_volume, _L("Volume")); | ||||
|     init_info_label(&info_facets, _L("Facets")); | ||||
|     label_materials = init_info_label(&info_materials, _L("Materials")); | ||||
|     Add(grid_sizer, 0, wxEXPAND); | ||||
| 
 | ||||
|     auto *info_manifold_text = new wxStaticText(parent, wxID_ANY, _(L("Manifold")) + ":"); | ||||
|     auto *info_manifold_text = new wxStaticText(parent, wxID_ANY, _L("Manifold") + ":"); | ||||
|     info_manifold_text->SetFont(wxGetApp().small_font()); | ||||
|     info_manifold = new wxStaticText(parent, wxID_ANY, ""); | ||||
|     info_manifold->SetFont(wxGetApp().small_font()); | ||||
|  | @ -213,7 +213,7 @@ private: | |||
| }; | ||||
| 
 | ||||
| SlicedInfo::SlicedInfo(wxWindow *parent) : | ||||
|     wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _(L("Sliced Info"))), wxVERTICAL) | ||||
|     wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Sliced Info")), wxVERTICAL) | ||||
| { | ||||
|     GetStaticBox()->SetFont(wxGetApp().bold_font()); | ||||
| 
 | ||||
|  | @ -232,13 +232,13 @@ SlicedInfo::SlicedInfo(wxWindow *parent) : | |||
|         info_vec.push_back(std::pair<wxStaticText*, wxStaticText*>(text, info_label)); | ||||
|     }; | ||||
| 
 | ||||
|     init_info_label(_(L("Used Filament (m)"))); | ||||
|     init_info_label(_(L("Used Filament (mm³)"))); | ||||
|     init_info_label(_(L("Used Filament (g)"))); | ||||
|     init_info_label(_(L("Used Material (unit)"))); | ||||
|     init_info_label(_(L("Cost (money)"))); | ||||
|     init_info_label(_(L("Estimated printing time"))); | ||||
|     init_info_label(_(L("Number of tool changes"))); | ||||
|     init_info_label(_L("Used Filament (m)")); | ||||
|     init_info_label(_L("Used Filament (mm³)")); | ||||
|     init_info_label(_L("Used Filament (g)")); | ||||
|     init_info_label(_L("Used Material (unit)")); | ||||
|     init_info_label(_L("Cost (money)")); | ||||
|     init_info_label(_L("Estimated printing time")); | ||||
|     init_info_label(_L("Number of tool changes")); | ||||
| 
 | ||||
|     Add(grid_sizer, 0, wxEXPAND); | ||||
|     this->Show(false); | ||||
|  | @ -345,7 +345,7 @@ PresetBitmapComboBox(parent, wxSize(15 * wxGetApp().em_unit(), -1)), | |||
|     } | ||||
| 
 | ||||
|     edit_btn = new ScalableButton(parent, wxID_ANY, "cog"); | ||||
|     edit_btn->SetToolTip(_(L("Click to edit preset"))); | ||||
|     edit_btn->SetToolTip(_L("Click to edit preset")); | ||||
| 
 | ||||
|     edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) | ||||
|     { | ||||
|  | @ -546,7 +546,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) : | |||
|     line.append_option(option); | ||||
| 
 | ||||
|     auto wiping_dialog_btn = [this](wxWindow* parent) { | ||||
|         m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); | ||||
|         m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _L("Purging volumes") + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); | ||||
|         m_wiping_dialog_button->SetFont(wxGetApp().normal_font()); | ||||
|         auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|         sizer->Add(m_wiping_dialog_button, 0, wxALIGN_CENTER_VERTICAL); | ||||
|  | @ -817,11 +817,11 @@ Sidebar::Sidebar(Plater *parent) | |||
|     }; | ||||
| 
 | ||||
|     p->combos_filament.push_back(nullptr); | ||||
|     init_combo(&p->combo_print,         _(L("Print settings")),     Preset::TYPE_PRINT,         false); | ||||
|     init_combo(&p->combos_filament[0],  _(L("Filament")),           Preset::TYPE_FILAMENT,      true); | ||||
|     init_combo(&p->combo_sla_print,     _(L("SLA print settings")), Preset::TYPE_SLA_PRINT,     false); | ||||
|     init_combo(&p->combo_sla_material,  _(L("SLA material")),       Preset::TYPE_SLA_MATERIAL,  false); | ||||
|     init_combo(&p->combo_printer,       _(L("Printer")),            Preset::TYPE_PRINTER,       false); | ||||
|     init_combo(&p->combo_print,         _L("Print settings"),     Preset::TYPE_PRINT,         false); | ||||
|     init_combo(&p->combos_filament[0],  _L("Filament"),           Preset::TYPE_FILAMENT,      true); | ||||
|     init_combo(&p->combo_sla_print,     _L("SLA print settings"), Preset::TYPE_SLA_PRINT,     false); | ||||
|     init_combo(&p->combo_sla_material,  _L("SLA material"),       Preset::TYPE_SLA_MATERIAL,  false); | ||||
|     init_combo(&p->combo_printer,       _L("Printer"),            Preset::TYPE_PRINTER,       false); | ||||
| 
 | ||||
|     const int margin_5  = int(0.5*wxGetApp().em_unit());// 5;
 | ||||
| 
 | ||||
|  | @ -880,9 +880,9 @@ Sidebar::Sidebar(Plater *parent) | |||
|         (*btn)->Hide(); | ||||
|     }; | ||||
| 
 | ||||
|     init_scalable_btn(&p->btn_send_gcode   , "export_gcode", _(L("Send to printer")) + "\tCtrl+Shift+G"); | ||||
|     init_scalable_btn(&p->btn_remove_device, "eject_sd"       , _(L("Remove device")) + "\tCtrl+T"); | ||||
| 	init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _(L("Export to SD card / Flash drive")) + "\tCtrl+U"); | ||||
|     init_scalable_btn(&p->btn_send_gcode   , "export_gcode", _L("Send to printer") + "\tCtrl+Shift+G"); | ||||
|     init_scalable_btn(&p->btn_remove_device, "eject_sd"       , _L("Remove device") + "\tCtrl+T"); | ||||
| 	init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _L("Export to SD card / Flash drive") + "\tCtrl+U"); | ||||
| 
 | ||||
|     // regular buttons "Slice now" and "Export G-code" 
 | ||||
| 
 | ||||
|  | @ -893,8 +893,8 @@ Sidebar::Sidebar(Plater *parent) | |||
|         (*btn)->SetFont(wxGetApp().bold_font()); | ||||
|     }; | ||||
| 
 | ||||
|     init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots , scaled_height); | ||||
|     init_btn(&p->btn_reslice     , _(L("Slice now"))            , scaled_height); | ||||
|     init_btn(&p->btn_export_gcode, _L("Export G-code") + dots , scaled_height); | ||||
|     init_btn(&p->btn_reslice     , _L("Slice now")            , scaled_height); | ||||
| 
 | ||||
|     enable_buttons(false); | ||||
| 
 | ||||
|  | @ -1044,7 +1044,7 @@ void Sidebar::update_reslice_btn_tooltip() const | |||
| { | ||||
|     wxString tooltip = wxString("Slice") + " [" + GUI::shortkey_ctrl_prefix() + "R]"; | ||||
|     if (m_mode != comSimple) | ||||
|         tooltip += wxString("\n") + _(L("Hold Shift to Slice & Export G-code")); | ||||
|         tooltip += wxString("\n") + _L("Hold Shift to Slice & Export G-code"); | ||||
|     p->btn_reslice->SetToolTip(tooltip); | ||||
| } | ||||
| 
 | ||||
|  | @ -1154,16 +1154,16 @@ void Sidebar::show_info_sizer() | |||
| 
 | ||||
|     const auto& stats = model_object->get_object_stl_stats();//model_object->volumes.front()->mesh.stl.stats;
 | ||||
|     p->object_info->info_volume->SetLabel(wxString::Format("%.2f", stats.volume)); | ||||
|     p->object_info->info_facets->SetLabel(wxString::Format(_(L("%d (%d shells)")), static_cast<int>(model_object->facets_count()), stats.number_of_parts)); | ||||
|     p->object_info->info_facets->SetLabel(wxString::Format(_L("%d (%d shells)"), static_cast<int>(model_object->facets_count()), stats.number_of_parts)); | ||||
| 
 | ||||
|     int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + | ||||
|         stats.facets_added + stats.facets_reversed + stats.backwards_edges; | ||||
|     if (errors > 0) { | ||||
|         wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors)")), errors); | ||||
|         wxString tooltip = wxString::Format(_L("Auto-repaired (%d errors)"), errors); | ||||
|         p->object_info->info_manifold->SetLabel(tooltip); | ||||
| 
 | ||||
|         tooltip += ":\n" + wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, " | ||||
|                                         "%d facets added, %d facets reversed, %d backwards edges")), | ||||
|         tooltip += ":\n" + wxString::Format(_L("%d degenerate facets, %d edges fixed, %d facets removed, " | ||||
|                                         "%d facets added, %d facets reversed, %d backwards edges"), | ||||
|                                         stats.degenerate_facets, stats.edges_fixed, stats.facets_removed, | ||||
|                                         stats.facets_added, stats.facets_reversed, stats.backwards_edges); | ||||
| 
 | ||||
|  | @ -1172,7 +1172,7 @@ void Sidebar::show_info_sizer() | |||
|         p->object_info->manifold_warning_icon->SetToolTip(tooltip); | ||||
|     } | ||||
|     else { | ||||
|         p->object_info->info_manifold->SetLabel(_(L("Yes"))); | ||||
|         p->object_info->info_manifold->SetLabel(_L("Yes")); | ||||
|         p->object_info->showing_manifold_warning_icon = false; | ||||
|         p->object_info->info_manifold->SetToolTip(""); | ||||
|         p->object_info->manifold_warning_icon->SetToolTip(""); | ||||
|  | @ -1193,10 +1193,10 @@ void Sidebar::update_sliced_info_sizer() | |||
|         if (p->plater->printer_technology() == ptSLA) | ||||
|         { | ||||
|             const SLAPrintStatistics& ps = p->plater->sla_print().print_statistics(); | ||||
|             wxString new_label = _(L("Used Material (ml)")) + ":"; | ||||
|             wxString new_label = _L("Used Material (ml)") + ":"; | ||||
|             const bool is_supports = ps.support_used_material > 0.0; | ||||
|             if (is_supports) | ||||
|                 new_label += from_u8((boost::format("\n    - %s\n    - %s") % _utf8(L("object(s)")) % _utf8(L("supports and pad"))).str()); | ||||
|                 new_label += format_wxstr("\n    - %s\n    - %s", _L("object(s)"), _L("supports and pad")); | ||||
| 
 | ||||
|             wxString info_text = is_supports ? | ||||
|                 wxString::Format("%.2f \n%.2f \n%.2f", (ps.objects_used_material + ps.support_used_material) / 1000, | ||||
|  | @ -1218,7 +1218,7 @@ void Sidebar::update_sliced_info_sizer() | |||
|             p->sliced_info->SetTextAndShow(siCost, str_total_cost, "Cost"); | ||||
| 
 | ||||
|             wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : get_time_dhms(float(ps.estimated_print_time)); | ||||
|             p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _(L("Estimated printing time")) + ":"); | ||||
|             p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _L("Estimated printing time") + ":"); | ||||
| 
 | ||||
|             // Hide non-SLA sliced info parameters
 | ||||
|             p->sliced_info->SetTextAndShow(siFilament_m, "N/A"); | ||||
|  | @ -1231,9 +1231,9 @@ void Sidebar::update_sliced_info_sizer() | |||
|             const PrintStatistics& ps = p->plater->fff_print().print_statistics(); | ||||
|             const bool is_wipe_tower = ps.total_wipe_tower_filament > 0; | ||||
| 
 | ||||
|             wxString new_label = _(L("Used Filament (m)")); | ||||
|             wxString new_label = _L("Used Filament (m)"); | ||||
|             if (is_wipe_tower) | ||||
|                 new_label += from_u8((boost::format(":\n    - %1%\n    - %2%") % _utf8(L("objects")) % _utf8(L("wipe tower"))).str()); | ||||
|                 new_label += format_wxstr(":\n    - %1%\n    - %2%", _L("objects"), _L("wipe tower")); | ||||
| 
 | ||||
|             wxString info_text = is_wipe_tower ? | ||||
|                                 wxString::Format("%.2f \n%.2f \n%.2f", ps.total_used_filament / 1000, | ||||
|  | @ -1245,9 +1245,9 @@ void Sidebar::update_sliced_info_sizer() | |||
|             p->sliced_info->SetTextAndShow(siFilament_mm3,  wxString::Format("%.2f", ps.total_extruded_volume)); | ||||
|             p->sliced_info->SetTextAndShow(siFilament_g,    ps.total_weight == 0.0 ? "N/A" : wxString::Format("%.2f", ps.total_weight)); | ||||
| 
 | ||||
|             new_label = _(L("Cost")); | ||||
|             new_label = _L("Cost"); | ||||
|             if (is_wipe_tower) | ||||
|                 new_label += from_u8((boost::format(":\n    - %1%\n    - %2%") % _utf8(L("objects")) % _utf8(L("wipe tower"))).str()); | ||||
|                 new_label += format_wxstr(":\n    - %1%\n    - %2%", _L("objects"), _L("wipe tower")); | ||||
| 
 | ||||
|             info_text = ps.total_cost == 0.0 ? "N/A" : | ||||
|                         is_wipe_tower ? | ||||
|  | @ -1260,10 +1260,10 @@ void Sidebar::update_sliced_info_sizer() | |||
|             if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") | ||||
|                 p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A"); | ||||
|             else { | ||||
|                 new_label = _(L("Estimated printing time")) +":"; | ||||
|                 new_label = _L("Estimated printing time") +":"; | ||||
|                 info_text = ""; | ||||
|                 wxString str_color = _(L("Color")); | ||||
|                 wxString str_pause = _(L("Pause")); | ||||
|                 wxString str_color = _L("Color"); | ||||
|                 wxString str_pause = _L("Pause"); | ||||
| 
 | ||||
|                 auto fill_labels = [str_color, str_pause](const std::vector<std::pair<CustomGcodeType, std::string>>& times,  | ||||
|                                                           wxString& new_label, wxString& info_text) | ||||
|  | @ -1276,25 +1276,25 @@ void Sidebar::update_sliced_info_sizer() | |||
|                     for (int i = (int)times.size() - 1; i >= 0; --i) | ||||
|                     { | ||||
|                         if (i == 0 || times[i - 1].first == cgtPausePrint) | ||||
|                             new_label += from_u8((boost::format("\n      - %1%%2%") % (std::string(str_color.ToUTF8()) + " ") % color_change_count).str()); | ||||
|                             new_label += format_wxstr("\n      - %1%%2%", str_color + " ", color_change_count); | ||||
|                         else if (times[i - 1].first == cgtColorChange) | ||||
|                             new_label += from_u8((boost::format("\n      - %1%%2%") % (std::string(str_color.ToUTF8()) + " ") % color_change_count--).str()); | ||||
|                             new_label += format_wxstr("\n      - %1%%2%", str_color + " ", color_change_count--); | ||||
| 
 | ||||
|                         if (i != (int)times.size() - 1 && times[i].first == cgtPausePrint) | ||||
|                             new_label += from_u8((boost::format(" -> %1%") % std::string(str_pause.ToUTF8())).str()); | ||||
|                             new_label += format_wxstr(" -> %1%", str_pause); | ||||
| 
 | ||||
|                         info_text += from_u8((boost::format("\n%1%") % times[i].second).str()); | ||||
|                         info_text += format_wxstr("\n%1%", times[i].second); | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 if (ps.estimated_normal_print_time != "N/A") { | ||||
|                     new_label += from_u8((boost::format("\n   - %1%") % _utf8(L("normal mode"))).str()); | ||||
|                     info_text += from_u8((boost::format("\n%1%") % ps.estimated_normal_print_time).str()); | ||||
|                     new_label += format_wxstr("\n   - %1%", _L("normal mode")); | ||||
|                     info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time); | ||||
|                     fill_labels(ps.estimated_normal_custom_gcode_print_times, new_label, info_text); | ||||
|                 } | ||||
|                 if (ps.estimated_silent_print_time != "N/A") { | ||||
|                     new_label += from_u8((boost::format("\n   - %1%") % _utf8(L("stealth mode"))).str()); | ||||
|                     info_text += from_u8((boost::format("\n%1%") % ps.estimated_silent_print_time).str()); | ||||
|                     new_label += format_wxstr("\n   - %1%", _L("stealth mode")); | ||||
|                     info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time); | ||||
|                     fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); | ||||
|                 } | ||||
|                 p->sliced_info->SetTextAndShow(siEstimatedTime,  info_text,      new_label); | ||||
|  | @ -1397,11 +1397,11 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi | |||
|     wxString snapshot_label; | ||||
|     assert(! paths.empty()); | ||||
|     if (paths.size() == 1) { | ||||
|         snapshot_label = _(L("Load File")); | ||||
|         snapshot_label = _L("Load File"); | ||||
|         snapshot_label += ": "; | ||||
|         snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str()); | ||||
|     } else { | ||||
|         snapshot_label = _(L("Load Files")); | ||||
|         snapshot_label = _L("Load Files"); | ||||
|         snapshot_label += ": "; | ||||
|         snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str()); | ||||
|         for (size_t i = 1; i < paths.size(); ++ i) { | ||||
|  | @ -2202,11 +2202,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|     this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this](RemovableDriveEjectEvent &evt) { | ||||
| 		if (evt.data.second) { | ||||
| 			this->show_action_buttons(this->ready_to_slice); | ||||
| 			Slic3r::GUI::show_info(this->q, (boost::format(_utf8(L("Unmounting successful. The device %s(%s) can now be safely removed from the computer."))) | ||||
| 				% evt.data.first.name % evt.data.first.path).str()); | ||||
| 			Slic3r::GUI::show_info(this->q, format_wxstr(_L("Unmounting successful. The device %s(%s) can now be safely removed from the computer."), | ||||
| 				evt.data.first.name, evt.data.first.path)); | ||||
| 		} else | ||||
| 			Slic3r::GUI::show_info(this->q, (boost::format(_utf8(L("Ejecting of device %s(%s) has failed."))) | ||||
| 				% evt.data.first.name % evt.data.first.path).str()); | ||||
| 			Slic3r::GUI::show_info(this->q, format_wxstr(_L("Ejecting of device %s(%s) has failed."), | ||||
| 				evt.data.first.name, evt.data.first.path)); | ||||
| 	}); | ||||
|     this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this](RemovableDrivesChangedEvent &) { this->show_action_buttons(this->ready_to_slice); }); | ||||
|     // Start the background thread and register this window as a target for update events.
 | ||||
|  | @ -2218,7 +2218,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
| #endif /* _WIN32 */ | ||||
| 
 | ||||
|     // Initialize the Undo / Redo stack with a first snapshot.
 | ||||
|     this->take_snapshot(_(L("New Project"))); | ||||
|     this->take_snapshot(_L("New Project")); | ||||
| } | ||||
| 
 | ||||
| Plater::priv::~priv() | ||||
|  | @ -2332,7 +2332,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     const auto loading = _(L("Loading")) + dots; | ||||
|     const auto loading = _L("Loading") + dots; | ||||
|     wxProgressDialog dlg(loading, loading); | ||||
|     dlg.Pulse(); | ||||
| 
 | ||||
|  | @ -2342,7 +2342,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
|     for (size_t i = 0; i < input_files.size(); i++) { | ||||
|         const auto &path = input_files[i]; | ||||
|         const auto filename = path.filename(); | ||||
|         const auto dlg_info = from_u8((boost::format(_utf8(L("Processing input file %s"))) % from_path(filename)).str()) + "\n"; | ||||
|         const auto dlg_info = format_wxstr(_L("Processing input file %s"), from_path(filename)) + "\n"; | ||||
|         dlg.Update(100 * i / input_files.size(), dlg_info); | ||||
| 
 | ||||
|         const bool type_3mf = std::regex_match(path.string(), pattern_3mf); | ||||
|  | @ -2370,9 +2370,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
|                                 if (object->volumes.size() > 1) | ||||
|                                 { | ||||
|                                     Slic3r::GUI::show_info(nullptr, | ||||
|                                         _(L("You cannot load SLA project with a multi-part object on the bed")) + "\n\n" + | ||||
|                                         _(L("Please check your object list before preset changing.")), | ||||
|                                         _(L("Attention!"))); | ||||
|                                         _L("You cannot load SLA project with a multi-part object on the bed") + "\n\n" + | ||||
|                                         _L("Please check your object list before preset changing."), | ||||
|                                         _L("Attention!")); | ||||
|                                     return obj_idxs; | ||||
|                                 } | ||||
|                         } | ||||
|  | @ -2415,19 +2415,19 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
| 
 | ||||
|             if (! is_project_file) { | ||||
|                 if (model.looks_like_multipart_object()) { | ||||
|                     wxMessageDialog msg_dlg(q, _(L( | ||||
|                     wxMessageDialog msg_dlg(q, _L( | ||||
|                         "This file contains several objects positioned at multiple heights.\n" | ||||
|                         "Instead of considering them as multiple objects, should I consider\n" | ||||
|                         "this file as a single object having multiple parts?")) + "\n", | ||||
|                         _(L("Multi-part object detected")), wxICON_WARNING | wxYES | wxNO); | ||||
|                         "this file as a single object having multiple parts?") + "\n", | ||||
|                         _L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO); | ||||
|                     if (msg_dlg.ShowModal() == wxID_YES) { | ||||
|                         model.convert_multipart_object(nozzle_dmrs->values.size()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else if ((wxGetApp().get_mode() == comSimple) && (type_3mf || type_any_amf) && model_has_advanced_features(model)) { | ||||
|                 wxMessageDialog msg_dlg(q, _(L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?"))+"\n", | ||||
|                     _(L("Detected advanced data")), wxICON_WARNING | wxYES | wxNO); | ||||
|                 wxMessageDialog msg_dlg(q, _L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?")+"\n", | ||||
|                     _L("Detected advanced data"), wxICON_WARNING | wxYES | wxNO); | ||||
|                 if (msg_dlg.ShowModal() == wxID_YES) | ||||
|                 { | ||||
|                     Slic3r::GUI::wxGetApp().save_mode(comAdvanced); | ||||
|  | @ -2449,8 +2449,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
|                 for (auto obj : model.objects) | ||||
|                     if ( obj->volumes.size()>1 ) { | ||||
|                         Slic3r::GUI::show_error(nullptr, | ||||
|                             from_u8((boost::format(_utf8(L("You can't to add the object(s) from %s because of one or some of them is(are) multi-part"))) | ||||
|                                              % from_path(filename)).str())); | ||||
|                             format_wxstr(_L("You can't to add the object(s) from %s because of one or some of them is(are) multi-part"), | ||||
|                                         from_path(filename))); | ||||
|                         return obj_idxs; | ||||
|                     } | ||||
|             } | ||||
|  | @ -2468,11 +2468,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
|     } | ||||
| 
 | ||||
|     if (new_model != nullptr && new_model->objects.size() > 1) { | ||||
|         wxMessageDialog msg_dlg(q, _(L( | ||||
|         wxMessageDialog msg_dlg(q, _L( | ||||
|                 "Multiple objects were loaded for a multi-material printer.\n" | ||||
|                 "Instead of considering them as multiple objects, should I consider\n" | ||||
|                 "these files to represent a single object having multiple parts?")) + "\n", | ||||
|                 _(L("Multi-part object detected")), wxICON_WARNING | wxYES | wxNO); | ||||
|                 "these files to represent a single object having multiple parts?") + "\n", | ||||
|                 _L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO); | ||||
|         if (msg_dlg.ShowModal() == wxID_YES) { | ||||
|             new_model->convert_multipart_object(nozzle_dmrs->values.size()); | ||||
|         } | ||||
|  | @ -2485,7 +2485,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
|     { | ||||
|         wxGetApp().app_config->update_skein_dir(input_files[input_files.size() - 1].parent_path().string()); | ||||
|         // XXX: Plater.pm had @loaded_files, but didn't seem to fill them with the filenames...
 | ||||
|         statusbar()->set_status_text(_(L("Loaded"))); | ||||
|         statusbar()->set_status_text(_L("Loaded")); | ||||
|     } | ||||
| 
 | ||||
|     // automatic selection of added objects
 | ||||
|  | @ -2587,8 +2587,8 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode | |||
| 
 | ||||
|     if (scaled_down) { | ||||
|         GUI::show_info(q, | ||||
|             _(L("Your object appears to be too large, so it was automatically scaled down to fit your print bed.")), | ||||
|             _(L("Object too large?"))); | ||||
|             _L("Your object appears to be too large, so it was automatically scaled down to fit your print bed."), | ||||
|             _L("Object too large?")); | ||||
|     } | ||||
| 
 | ||||
|     for (const size_t idx : obj_idxs) { | ||||
|  | @ -2650,26 +2650,26 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type) | |||
|         case FT_STL: | ||||
|         { | ||||
|             output_file.replace_extension("stl"); | ||||
|             dlg_title = _(L("Export STL file:")); | ||||
|             dlg_title = _L("Export STL file:"); | ||||
|             break; | ||||
|         } | ||||
|         case FT_AMF: | ||||
|         { | ||||
|             // XXX: Problem on OS X with double extension?
 | ||||
|             output_file.replace_extension("zip.amf"); | ||||
|             dlg_title = _(L("Export AMF file:")); | ||||
|             dlg_title = _L("Export AMF file:"); | ||||
|             break; | ||||
|         } | ||||
|         case FT_3MF: | ||||
|         { | ||||
|             output_file.replace_extension("3mf"); | ||||
|             dlg_title = _(L("Save file as:")); | ||||
|             dlg_title = _L("Save file as:"); | ||||
|             break; | ||||
|         } | ||||
|         case FT_OBJ: | ||||
|         { | ||||
|             output_file.replace_extension("obj"); | ||||
|             dlg_title = _(L("Export OBJ file:")); | ||||
|             dlg_title = _L("Export OBJ file:"); | ||||
|             break; | ||||
|         } | ||||
|         default: break; | ||||
|  | @ -2741,15 +2741,12 @@ void Plater::priv::object_list_changed() | |||
| 
 | ||||
| void Plater::priv::select_all() | ||||
| { | ||||
| //    this->take_snapshot(_(L("Select All")));
 | ||||
| 
 | ||||
|     view3D->select_all(); | ||||
|     this->sidebar->obj_list()->update_selections(); | ||||
| } | ||||
| 
 | ||||
| void Plater::priv::deselect_all() | ||||
| { | ||||
| //    this->take_snapshot(_(L("Deselect All")));
 | ||||
|     view3D->deselect_all(); | ||||
| } | ||||
| 
 | ||||
|  | @ -2771,7 +2768,7 @@ void Plater::priv::remove(size_t obj_idx) | |||
| 
 | ||||
| void Plater::priv::delete_object_from_model(size_t obj_idx) | ||||
| { | ||||
|     wxString snapshot_label = _(L("Delete Object")); | ||||
|     wxString snapshot_label = _L("Delete Object"); | ||||
|     if (! model.objects[obj_idx]->name.empty()) | ||||
|         snapshot_label += ": " + wxString::FromUTF8(model.objects[obj_idx]->name.c_str()); | ||||
|     Plater::TakeSnapshot snapshot(q, snapshot_label); | ||||
|  | @ -2782,7 +2779,7 @@ void Plater::priv::delete_object_from_model(size_t obj_idx) | |||
| 
 | ||||
| void Plater::priv::reset() | ||||
| { | ||||
|     Plater::TakeSnapshot snapshot(q, _(L("Reset Project"))); | ||||
|     Plater::TakeSnapshot snapshot(q, _L("Reset Project")); | ||||
| 
 | ||||
|     set_project_filename(wxEmptyString); | ||||
| 
 | ||||
|  | @ -2813,7 +2810,7 @@ void Plater::priv::mirror(Axis axis) | |||
| 
 | ||||
| void Plater::priv::arrange() | ||||
| { | ||||
|     this->take_snapshot(_(L("Arrange"))); | ||||
|     this->take_snapshot(_L("Arrange")); | ||||
|     m_ui_jobs.start(Jobs::Arrange); | ||||
| } | ||||
| 
 | ||||
|  | @ -2821,7 +2818,7 @@ void Plater::priv::arrange() | |||
| // This method will find an optimal orientation for the currently selected item
 | ||||
| // Very similar in nature to the arrange method above...
 | ||||
| void Plater::priv::sla_optimize_rotation() { | ||||
|     this->take_snapshot(_(L("Optimize Rotation"))); | ||||
|     this->take_snapshot(_L("Optimize Rotation")); | ||||
|     m_ui_jobs.start(Jobs::Rotoptimize); | ||||
| } | ||||
| 
 | ||||
|  | @ -2867,7 +2864,7 @@ void Plater::priv::find_new_position(const ModelInstancePtrs &instances, | |||
| } | ||||
| 
 | ||||
| void Plater::priv::ArrangeJob::process() { | ||||
|     static const auto arrangestr = _(L("Arranging")); | ||||
|     static const auto arrangestr = _L("Arranging"); | ||||
| 
 | ||||
|     // FIXME: I don't know how to obtain the minimum distance, it depends
 | ||||
|     // on printer technology. I guess the following should work but it crashes.
 | ||||
|  | @ -2894,14 +2891,14 @@ void Plater::priv::ArrangeJob::process() { | |||
|             }, stopfn); | ||||
|     } catch (std::exception & /*e*/) { | ||||
|         GUI::show_error(plater().q, | ||||
|                         _(L("Could not arrange model objects! " | ||||
|                             "Some geometries may be invalid."))); | ||||
|                         _L("Could not arrange model objects! " | ||||
|                            "Some geometries may be invalid.")); | ||||
|     } | ||||
| 
 | ||||
|     // finalize just here.
 | ||||
|     update_status(int(count), | ||||
|                   was_canceled() ? _(L("Arranging canceled.")) | ||||
|                                  : _(L("Arranging done."))); | ||||
|                   was_canceled() ? _L("Arranging canceled.") | ||||
|                                  : _L("Arranging done.")); | ||||
| } | ||||
| 
 | ||||
| void Plater::priv::RotoptimizeJob::process() | ||||
|  | @ -2917,7 +2914,7 @@ void Plater::priv::RotoptimizeJob::process() | |||
|         [this](unsigned s) { | ||||
|             if (s < 100) | ||||
|                 update_status(int(s), | ||||
|                               _(L("Searching for optimal orientation"))); | ||||
|                               _L("Searching for optimal orientation")); | ||||
|         }, | ||||
|         [this]() { return was_canceled(); }); | ||||
| 
 | ||||
|  | @ -2950,8 +2947,8 @@ void Plater::priv::RotoptimizeJob::process() | |||
|     } | ||||
| 
 | ||||
|     update_status(100, | ||||
|                   was_canceled() ? _(L("Orientation search canceled.")) | ||||
|                                  : _(L("Orientation found."))); | ||||
|                   was_canceled() ? _L("Orientation search canceled.") | ||||
|                                  : _L("Orientation found.")); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -2968,7 +2965,7 @@ void Plater::priv::split_object() | |||
| 
 | ||||
|     if (current_model_object->volumes.size() > 1) | ||||
|     { | ||||
|         Slic3r::GUI::warning_catcher(q, _(L("The selected object can't be split because it contains more than one volume/material."))); | ||||
|         Slic3r::GUI::warning_catcher(q, _L("The selected object can't be split because it contains more than one volume/material.")); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -2976,10 +2973,10 @@ void Plater::priv::split_object() | |||
|     ModelObjectPtrs new_objects; | ||||
|     current_model_object->split(&new_objects); | ||||
|     if (new_objects.size() == 1) | ||||
|         Slic3r::GUI::warning_catcher(q, _(L("The selected object couldn't be split because it contains only one part."))); | ||||
|         Slic3r::GUI::warning_catcher(q, _L("The selected object couldn't be split because it contains only one part.")); | ||||
|     else | ||||
|     { | ||||
|         Plater::TakeSnapshot snapshot(q, _(L("Split to Objects"))); | ||||
|         Plater::TakeSnapshot snapshot(q, _L("Split to Objects")); | ||||
| 
 | ||||
|         unsigned int counter = 1; | ||||
|         for (ModelObject* m : new_objects) | ||||
|  | @ -3104,7 +3101,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool | |||
|     if ((return_state & UPDATE_BACKGROUND_PROCESS_INVALID) != 0) | ||||
|     { | ||||
|         // Validation of the background data failed.
 | ||||
|         const wxString invalid_str = _(L("Invalid data")); | ||||
|         const wxString invalid_str = _L("Invalid data"); | ||||
|         for (auto btn : {ActionButtonType::abReslice, ActionButtonType::abSendGCode, ActionButtonType::abExport}) | ||||
|             sidebar->set_btn_label(btn, invalid_str); | ||||
|     } | ||||
|  | @ -3113,13 +3110,13 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool | |||
|         // Background data is valid.
 | ||||
|         if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 || | ||||
|             (return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 ) | ||||
|             this->statusbar()->set_status_text(_(L("Ready to slice"))); | ||||
|             this->statusbar()->set_status_text(_L("Ready to slice")); | ||||
| 
 | ||||
|         sidebar->set_btn_label(ActionButtonType::abExport, _(label_btn_export)); | ||||
|         sidebar->set_btn_label(ActionButtonType::abSendGCode, _(label_btn_send)); | ||||
| 
 | ||||
|         const wxString slice_string = background_process.running() && wxGetApp().get_mode() == comSimple ? | ||||
|                                       _(L("Slicing")) + dots : _(L("Slice now")); | ||||
|                                       _L("Slicing") + dots : _L("Slice now"); | ||||
|         sidebar->set_btn_label(ActionButtonType::abReslice, slice_string); | ||||
| 
 | ||||
|         if (background_process.finished()) | ||||
|  | @ -3151,7 +3148,7 @@ bool Plater::priv::restart_background_process(unsigned int state) | |||
|         // The print is valid and it can be started.
 | ||||
|         if (this->background_process.start()) { | ||||
|             this->statusbar()->set_cancel_callback([this]() { | ||||
|                 this->statusbar()->set_status_text(_(L("Cancelling"))); | ||||
|                 this->statusbar()->set_status_text(_L("Cancelling")); | ||||
|                 this->background_process.stop(); | ||||
|             }); | ||||
|             return true; | ||||
|  | @ -3168,7 +3165,7 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova | |||
|         return; | ||||
| 
 | ||||
|     if (background_process.is_export_scheduled()) { | ||||
|         GUI::show_error(q, _(L("Another export job is currently running."))); | ||||
|         GUI::show_error(q, _L("Another export job is currently running.")); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -3223,7 +3220,7 @@ void Plater::priv::update_sla_scene() | |||
| 
 | ||||
| void Plater::priv::reload_from_disk() | ||||
| { | ||||
|     Plater::TakeSnapshot snapshot(q, _(L("Reload from disk"))); | ||||
|     Plater::TakeSnapshot snapshot(q, _L("Reload from disk")); | ||||
| 
 | ||||
|     const Selection& selection = get_selection(); | ||||
| 
 | ||||
|  | @ -3284,7 +3281,7 @@ void Plater::priv::reload_from_disk() | |||
|     { | ||||
|         // ask user to select the missing file
 | ||||
|         fs::path search = missing_input_paths.back(); | ||||
|         wxString title = _(L("Please select the file to reload")); | ||||
|         wxString title = _L("Please select the file to reload"); | ||||
| #if defined(__APPLE__) | ||||
|         title += " (" + from_u8(search.filename().string()) + ")"; | ||||
| #endif // __APPLE__
 | ||||
|  | @ -3319,7 +3316,7 @@ void Plater::priv::reload_from_disk() | |||
|         } | ||||
|         else | ||||
|         { | ||||
|             wxString message = _(L("It is not allowed to change the file to reload")) + " (" + from_u8(search.filename().string()) + ").\n" + _(L("Do you want to retry")) + " ?"; | ||||
|             wxString message = _L("It is not allowed to change the file to reload") + " (" + from_u8(search.filename().string()) + ").\n" + _L("Do you want to retry") + " ?"; | ||||
|             wxMessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); | ||||
|             if (dlg.ShowModal() != wxID_YES) | ||||
|                 return; | ||||
|  | @ -3337,7 +3334,7 @@ void Plater::priv::reload_from_disk() | |||
|         const auto& path = input_paths[i].string(); | ||||
| 
 | ||||
|         wxBusyCursor wait; | ||||
|         wxBusyInfo info(_(L("Reload from:")) + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); | ||||
|         wxBusyInfo info(_L("Reload from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); | ||||
| 
 | ||||
|         Model new_model; | ||||
|         try | ||||
|  | @ -3426,12 +3423,12 @@ void Plater::priv::reload_from_disk() | |||
| 
 | ||||
|     if (!fail_list.empty()) | ||||
|     { | ||||
|         wxString message = _(L("Unable to reload:")) + "\n"; | ||||
|         wxString message = _L("Unable to reload:") + "\n"; | ||||
|         for (const wxString& s : fail_list) | ||||
|         { | ||||
|             message += s + "\n"; | ||||
|         } | ||||
|         wxMessageDialog dlg(q, message, _(L("Error during reload")), wxOK | wxOK_DEFAULT | wxICON_WARNING); | ||||
|         wxMessageDialog dlg(q, message, _L("Error during reload"), wxOK | wxOK_DEFAULT | wxICON_WARNING); | ||||
|         dlg.ShowModal(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -3450,7 +3447,7 @@ void Plater::priv::reload_all_from_disk() | |||
|     if (model.objects.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     Plater::TakeSnapshot snapshot(q, _(L("Reload all from disk"))); | ||||
|     Plater::TakeSnapshot snapshot(q, _L("Reload all from disk")); | ||||
|     Plater::SuppressSnapshots suppress(q); | ||||
| 
 | ||||
|     Selection& selection = get_selection(); | ||||
|  | @ -3471,7 +3468,7 @@ void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* = | |||
|     if (obj_idx < 0) | ||||
|         return; | ||||
| 
 | ||||
|     Plater::TakeSnapshot snapshot(q, _(L("Fix Throught NetFabb"))); | ||||
|     Plater::TakeSnapshot snapshot(q, _L("Fix Throught NetFabb")); | ||||
| 
 | ||||
|     fix_model_by_win10_sdk_gui(*model.objects[obj_idx], vol_idx); | ||||
|     this->update(); | ||||
|  | @ -3670,7 +3667,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) | |||
|     if (error) { | ||||
|         wxString message = evt.GetString(); | ||||
|         if (message.IsEmpty()) | ||||
|             message = _(L("Export failed")); | ||||
|             message = _L("Export failed"); | ||||
|         if (q->m_tracking_popup_menu) | ||||
|         	// We don't want to pop-up a message box when tracking a pop-up menu.
 | ||||
|         	// We postpone the error message instead.
 | ||||
|  | @ -3680,7 +3677,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) | |||
|         this->statusbar()->set_status_text(message); | ||||
|     } | ||||
|     if (canceled) | ||||
|         this->statusbar()->set_status_text(_(L("Cancelled"))); | ||||
|         this->statusbar()->set_status_text(_L("Cancelled")); | ||||
| 
 | ||||
|     this->sidebar->show_sliced_info_sizer(success); | ||||
| 
 | ||||
|  | @ -3743,8 +3740,6 @@ void Plater::priv::on_action_layersediting(SimpleEvent&) | |||
| 
 | ||||
| void Plater::priv::on_object_select(SimpleEvent& evt) | ||||
| { | ||||
| //    this->take_snapshot(_(L("Object Selection")));
 | ||||
| 
 | ||||
|     wxGetApp().obj_list()->update_selections(); | ||||
|     selection_changed(); | ||||
| } | ||||
|  | @ -3794,7 +3789,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt) | |||
|              */ | ||||
|             const MenuIdentifier id = printer_technology == ptSLA ? miObjectSLA : miObjectFFF; | ||||
|             if (wxGetApp().get_mode() == comSimple) { | ||||
|                 if (menu->FindItem(_(L("Add instance"))) != wxNOT_FOUND) | ||||
|                 if (menu->FindItem(_L("Add instance")) != wxNOT_FOUND) | ||||
|                 { | ||||
|                     /* Detach an items from the menu, but don't delete them
 | ||||
|                      * so that they can be added back later | ||||
|  | @ -3806,7 +3801,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt) | |||
|                 } | ||||
|             } | ||||
|             else { | ||||
|                 if (menu->FindItem(_(L("Add instance"))) == wxNOT_FOUND) | ||||
|                 if (menu->FindItem(_L("Add instance")) == wxNOT_FOUND) | ||||
|                 { | ||||
|                     // Prepend items to the menu, if those aren't not there
 | ||||
|                     menu->Prepend(items_set_number_of_copies[id]); | ||||
|  | @ -3935,20 +3930,20 @@ void Plater::priv::set_project_filename(const wxString& filename) | |||
| bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/) | ||||
| { | ||||
|     if (is_part) { | ||||
|         append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")), | ||||
|         append_menu_item(menu, wxID_ANY, _L("Delete") + "\tDel", _L("Remove the selected object"), | ||||
|             [this](wxCommandEvent&) { q->remove_selected();         }, "delete",            nullptr, [this]() { return can_delete(); }, q); | ||||
| 
 | ||||
|         append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")), | ||||
|         append_menu_item(menu, wxID_ANY, _L("Reload from disk"), _L("Reload the selected volumes from disk"), | ||||
|             [this](wxCommandEvent&) { q->reload_from_disk(); }, "", menu, [this]() { return can_reload_from_disk(); }, q); | ||||
| 
 | ||||
|         sidebar->obj_list()->append_menu_item_export_stl(menu); | ||||
|     } | ||||
|     else { | ||||
|         wxMenuItem* item_increase = append_menu_item(menu, wxID_ANY, _(L("Add instance")) + "\t+", _(L("Add one more instance of the selected object")), | ||||
|         wxMenuItem* item_increase = append_menu_item(menu, wxID_ANY, _L("Add instance") + "\t+", _L("Add one more instance of the selected object"), | ||||
|             [this](wxCommandEvent&) { q->increase_instances();      }, "add_copies",        nullptr, [this]() { return can_increase_instances(); }, q); | ||||
|         wxMenuItem* item_decrease = append_menu_item(menu, wxID_ANY, _(L("Remove instance")) + "\t-", _(L("Remove one instance of the selected object")), | ||||
|         wxMenuItem* item_decrease = append_menu_item(menu, wxID_ANY, _L("Remove instance") + "\t-", _L("Remove one instance of the selected object"), | ||||
|             [this](wxCommandEvent&) { q->decrease_instances();      }, "remove_copies",     nullptr, [this]() { return can_decrease_instances(); }, q); | ||||
|         wxMenuItem* item_set_number_of_copies = append_menu_item(menu, wxID_ANY, _(L("Set number of instances")) + dots, _(L("Change the number of instances of the selected object")), | ||||
|         wxMenuItem* item_set_number_of_copies = append_menu_item(menu, wxID_ANY, _L("Set number of instances") + dots, _L("Change the number of instances of the selected object"), | ||||
|             [this](wxCommandEvent&) { q->set_number_of_copies();    }, "number_of_copies",  nullptr, [this]() { return can_increase_instances(); }, q); | ||||
| 
 | ||||
| 
 | ||||
|  | @ -3957,7 +3952,7 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ | |||
|         items_set_number_of_copies.push_back(item_set_number_of_copies); | ||||
| 
 | ||||
|         // Delete menu was moved to be after +/- instace to make it more difficult to be selected by mistake.
 | ||||
|         append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")), | ||||
|         append_menu_item(menu, wxID_ANY, _L("Delete") + "\tDel", _L("Remove the selected object"), | ||||
|             [this](wxCommandEvent&) { q->remove_selected(); }, "delete",            nullptr, [this]() { return can_delete(); }, q); | ||||
| 
 | ||||
|         menu->AppendSeparator(); | ||||
|  | @ -3967,10 +3962,10 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ | |||
|         wxMenuItem* menu_item_printable = sidebar->obj_list()->append_menu_item_printable(menu, q); | ||||
|         menu->AppendSeparator(); | ||||
| 
 | ||||
|         append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected object from disk")), | ||||
|         append_menu_item(menu, wxID_ANY, _L("Reload from disk"), _L("Reload the selected object from disk"), | ||||
|             [this](wxCommandEvent&) { reload_from_disk(); }, "", nullptr, [this]() { return can_reload_from_disk(); }, q); | ||||
| 
 | ||||
|         append_menu_item(menu, wxID_ANY, _(L("Export as STL")) + dots, _(L("Export the selected object as STL file")), | ||||
|         append_menu_item(menu, wxID_ANY, _L("Export as STL") + dots, _L("Export the selected object as STL file"), | ||||
|             [this](wxCommandEvent&) { q->export_stl(false, true); }, "", nullptr,  | ||||
|             [this]() { | ||||
|                 const Selection& selection = get_selection(); | ||||
|  | @ -3999,14 +3994,14 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ | |||
|     if (mirror_menu == nullptr) | ||||
|         return false; | ||||
| 
 | ||||
|     append_menu_item(mirror_menu, wxID_ANY, _(L("Along X axis")), _(L("Mirror the selected object along the X axis")), | ||||
|     append_menu_item(mirror_menu, wxID_ANY, _L("Along X axis"), _L("Mirror the selected object along the X axis"), | ||||
|         [this](wxCommandEvent&) { mirror(X); }, "mark_X", menu); | ||||
|     append_menu_item(mirror_menu, wxID_ANY, _(L("Along Y axis")), _(L("Mirror the selected object along the Y axis")), | ||||
|     append_menu_item(mirror_menu, wxID_ANY, _L("Along Y axis"), _L("Mirror the selected object along the Y axis"), | ||||
|         [this](wxCommandEvent&) { mirror(Y); }, "mark_Y", menu); | ||||
|     append_menu_item(mirror_menu, wxID_ANY, _(L("Along Z axis")), _(L("Mirror the selected object along the Z axis")), | ||||
|     append_menu_item(mirror_menu, wxID_ANY, _L("Along Z axis"), _L("Mirror the selected object along the Z axis"), | ||||
|         [this](wxCommandEvent&) { mirror(Z); }, "mark_Z", menu); | ||||
| 
 | ||||
|     append_submenu(menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object")), "", | ||||
|     append_submenu(menu, mirror_menu, wxID_ANY, _L("Mirror"), _L("Mirror the selected object"), "", | ||||
|         [this]() { return can_mirror(); }, q); | ||||
| 
 | ||||
|     return true; | ||||
|  | @ -4018,12 +4013,12 @@ bool Plater::priv::complit_init_object_menu() | |||
|     if (split_menu == nullptr) | ||||
|         return false; | ||||
| 
 | ||||
|     append_menu_item(split_menu, wxID_ANY, _(L("To objects")), _(L("Split the selected object into individual objects")), | ||||
|     append_menu_item(split_menu, wxID_ANY, _L("To objects"), _L("Split the selected object into individual objects"), | ||||
|         [this](wxCommandEvent&) { split_object(); }, "split_object_SMALL",  &object_menu, [this]() { return can_split(); }, q); | ||||
|     append_menu_item(split_menu, wxID_ANY, _(L("To parts")), _(L("Split the selected object into individual sub-parts")), | ||||
|     append_menu_item(split_menu, wxID_ANY, _L("To parts"), _L("Split the selected object into individual sub-parts"), | ||||
|         [this](wxCommandEvent&) { split_volume(); }, "split_parts_SMALL",   &object_menu, [this]() { return can_split(); }, q); | ||||
| 
 | ||||
|     append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object")), "", | ||||
|     append_submenu(&object_menu, split_menu, wxID_ANY, _L("Split"), _L("Split the selected object"), "", | ||||
|         [this]() { return can_split() && wxGetApp().get_mode() > comSimple; }, q); | ||||
|     object_menu.AppendSeparator(); | ||||
| 
 | ||||
|  | @ -4038,13 +4033,13 @@ bool Plater::priv::complit_init_object_menu() | |||
| 
 | ||||
| bool Plater::priv::complit_init_sla_object_menu() | ||||
| { | ||||
|     append_menu_item(&sla_object_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual objects")), | ||||
|     append_menu_item(&sla_object_menu, wxID_ANY, _L("Split"), _L("Split the selected object into individual objects"), | ||||
|         [this](wxCommandEvent&) { split_object(); }, "split_object_SMALL", nullptr, [this]() { return can_split(); }, q); | ||||
| 
 | ||||
|     sla_object_menu.AppendSeparator(); | ||||
| 
 | ||||
|     // Add the automatic rotation sub-menu
 | ||||
|     append_menu_item(&sla_object_menu, wxID_ANY, _(L("Optimize orientation")), _(L("Optimize the rotation of the object for better print results.")), | ||||
|     append_menu_item(&sla_object_menu, wxID_ANY, _L("Optimize orientation"), _L("Optimize the rotation of the object for better print results."), | ||||
|         [this](wxCommandEvent&) { sla_optimize_rotation(); }); | ||||
| 
 | ||||
|     return true; | ||||
|  | @ -4052,7 +4047,7 @@ bool Plater::priv::complit_init_sla_object_menu() | |||
| 
 | ||||
| bool Plater::priv::complit_init_part_menu() | ||||
| { | ||||
|     append_menu_item(&part_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual sub-parts")), | ||||
|     append_menu_item(&part_menu, wxID_ANY, _L("Split"), _L("Split the selected object into individual sub-parts"), | ||||
|         [this](wxCommandEvent&) { split_volume(); }, "split_parts_SMALL", nullptr, [this]() { return can_split(); }, q); | ||||
| 
 | ||||
|     part_menu.AppendSeparator(); | ||||
|  | @ -4427,8 +4422,8 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator | |||
|     if (printer_technology_changed) { | ||||
|         // Switching the printer technology when jumping forwards / backwards in time. Switch to the last active printer profile of the other type.
 | ||||
|         std::string s_pt = (it_snapshot->snapshot_data.printer_technology == ptFFF) ? "FFF" : "SLA"; | ||||
|         if (! wxGetApp().check_unsaved_changes(from_u8((boost::format(_utf8( | ||||
|             L("%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."))) % s_pt).str()))) | ||||
|         if (! wxGetApp().check_unsaved_changes(format_wxstr(_L( | ||||
|             "%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."), s_pt))) | ||||
|             // Don't switch the profiles.
 | ||||
|             return; | ||||
|     } | ||||
|  | @ -4604,7 +4599,7 @@ void Plater::load_project(const wxString& filename) | |||
|         return; | ||||
| 
 | ||||
|     // Take the Undo / Redo snapshot.
 | ||||
|     Plater::TakeSnapshot snapshot(this, _(L("Load Project")) + ": " + wxString::FromUTF8(into_path(filename).stem().string().c_str())); | ||||
|     Plater::TakeSnapshot snapshot(this, _L("Load Project") + ": " + wxString::FromUTF8(into_path(filename).stem().string().c_str())); | ||||
| 
 | ||||
|     p->reset(); | ||||
| 
 | ||||
|  | @ -4632,11 +4627,11 @@ void Plater::add_model() | |||
|     wxString snapshot_label; | ||||
|     assert(! paths.empty()); | ||||
|     if (paths.size() == 1) { | ||||
|         snapshot_label = _(L("Import Object")); | ||||
|         snapshot_label = _L("Import Object"); | ||||
|         snapshot_label += ": "; | ||||
|         snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str()); | ||||
|     } else { | ||||
|         snapshot_label = _(L("Import Objects")); | ||||
|         snapshot_label = _L("Import Objects"); | ||||
|         snapshot_label += ": "; | ||||
|         snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str()); | ||||
|         for (size_t i = 1; i < paths.size(); ++ i) { | ||||
|  | @ -4705,7 +4700,7 @@ void Plater::remove(size_t obj_idx) { p->remove(obj_idx); } | |||
| void Plater::reset() { p->reset(); } | ||||
| void Plater::reset_with_confirm() | ||||
| { | ||||
|     if (wxMessageDialog((wxWindow*)this, _(L("All objects will be removed, continue?")), wxString(SLIC3R_APP_NAME) + " - " + _(L("Delete all")), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) | ||||
|     if (wxMessageDialog((wxWindow*)this, _L("All objects will be removed, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) | ||||
|         reset(); | ||||
| } | ||||
| 
 | ||||
|  | @ -4713,7 +4708,7 @@ void Plater::delete_object_from_model(size_t obj_idx) { p->delete_object_from_mo | |||
| 
 | ||||
| void Plater::remove_selected() | ||||
| { | ||||
|     Plater::TakeSnapshot snapshot(this, _(L("Delete Selected Objects"))); | ||||
|     Plater::TakeSnapshot snapshot(this, _L("Delete Selected Objects")); | ||||
|     this->p->view3D->delete_selected(); | ||||
| } | ||||
| 
 | ||||
|  | @ -4721,7 +4716,7 @@ void Plater::increase_instances(size_t num) | |||
| { | ||||
|     if (! can_increase_instances()) { return; } | ||||
| 
 | ||||
|     Plater::TakeSnapshot snapshot(this, _(L("Increase Instances"))); | ||||
|     Plater::TakeSnapshot snapshot(this, _L("Increase Instances")); | ||||
| 
 | ||||
|     int obj_idx = p->get_selected_object_idx(); | ||||
| 
 | ||||
|  | @ -4756,7 +4751,7 @@ void Plater::decrease_instances(size_t num) | |||
| { | ||||
|     if (! can_decrease_instances()) { return; } | ||||
| 
 | ||||
|     Plater::TakeSnapshot snapshot(this, _(L("Decrease Instances"))); | ||||
|     Plater::TakeSnapshot snapshot(this, _L("Decrease Instances")); | ||||
| 
 | ||||
|     int obj_idx = p->get_selected_object_idx(); | ||||
| 
 | ||||
|  | @ -4787,12 +4782,12 @@ void Plater::set_number_of_copies(/*size_t num*/) | |||
| 
 | ||||
|     ModelObject* model_object = p->model.objects[obj_idx]; | ||||
| 
 | ||||
|     const int num = wxGetNumberFromUser( " ", _(L("Enter the number of copies:")), | ||||
|                                     _(L("Copies of the selected object")), model_object->instances.size(), 0, 1000, this ); | ||||
|     const int num = wxGetNumberFromUser( " ", _L("Enter the number of copies:"), | ||||
|                                     _L("Copies of the selected object"), model_object->instances.size(), 0, 1000, this ); | ||||
|     if (num < 0) | ||||
|         return; | ||||
| 
 | ||||
|     Plater::TakeSnapshot snapshot(this, wxString::Format(_(L("Set numbers of copies to %d")), num)); | ||||
|     Plater::TakeSnapshot snapshot(this, wxString::Format(_L("Set numbers of copies to %d"), num)); | ||||
| 
 | ||||
|     int diff = num - (int)model_object->instances.size(); | ||||
|     if (diff > 0) | ||||
|  | @ -4822,7 +4817,7 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     Plater::TakeSnapshot snapshot(this, _(L("Cut by Plane"))); | ||||
|     Plater::TakeSnapshot snapshot(this, _L("Cut by Plane")); | ||||
| 
 | ||||
|     wxBusyCursor wait; | ||||
|     const auto new_objects = object->cut(instance_idx, z, keep_upper, keep_lower, rotate_lower); | ||||
|  | @ -4873,7 +4868,7 @@ void Plater::export_gcode(bool prefer_removable) | |||
| 
 | ||||
|     fs::path output_path; | ||||
|     { | ||||
|         wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")), | ||||
|         wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _L("Save G-code file as:") : _L("Save SL1 file as:"), | ||||
|             start_dir, | ||||
|             from_path(default_output_file.filename()), | ||||
|             GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_PNGZIP, default_output_file.extension().string()), | ||||
|  | @ -5008,7 +5003,7 @@ void Plater::export_stl(bool extended, bool selection_only) | |||
|     } | ||||
| 
 | ||||
|     Slic3r::store_stl(path_u8.c_str(), &mesh, true); | ||||
|     p->statusbar()->set_status_text(from_u8((boost::format(_utf8(L("STL file exported to %s"))) % path).str())); | ||||
|     p->statusbar()->set_status_text(format_wxstr(_L("STL file exported to %s"), path)); | ||||
| } | ||||
| 
 | ||||
| void Plater::export_amf() | ||||
|  | @ -5025,10 +5020,10 @@ void Plater::export_amf() | |||
|     bool full_pathnames = wxGetApp().app_config->get("export_sources_full_pathnames") == "1"; | ||||
|     if (Slic3r::store_amf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames)) { | ||||
|         // Success
 | ||||
|         p->statusbar()->set_status_text(from_u8((boost::format(_utf8(L("AMF file exported to %s"))) % path).str())); | ||||
|         p->statusbar()->set_status_text(format_wxstr(_L("AMF file exported to %s"), path)); | ||||
|     } else { | ||||
|         // Failure
 | ||||
|         p->statusbar()->set_status_text(from_u8((boost::format(_utf8(L("Error exporting AMF file %s"))) % path).str())); | ||||
|         p->statusbar()->set_status_text(format_wxstr(_L("Error exporting AMF file %s"), path)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -5057,12 +5052,12 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) | |||
|     p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true, true, true); | ||||
|     if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_data)) { | ||||
|         // Success
 | ||||
|         p->statusbar()->set_status_text(from_u8((boost::format(_utf8(L("3MF file exported to %s"))) % path).str())); | ||||
|         p->statusbar()->set_status_text(format_wxstr(_L("3MF file exported to %s"), path)); | ||||
|         p->set_project_filename(path); | ||||
|     } | ||||
|     else { | ||||
|         // Failure
 | ||||
|         p->statusbar()->set_status_text(from_u8((boost::format(_utf8(L("Error exporting 3MF file %s"))) % path).str())); | ||||
|         p->statusbar()->set_status_text(format_wxstr(_L("Error exporting 3MF file %s"), path)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -5122,10 +5117,10 @@ void Plater::reslice() | |||
|     if (p->background_process.running()) | ||||
|     { | ||||
|         if (wxGetApp().get_mode() == comSimple) | ||||
|             p->sidebar->set_btn_label(ActionButtonType::abReslice, _(L("Slicing")) + dots); | ||||
|             p->sidebar->set_btn_label(ActionButtonType::abReslice, _L("Slicing") + dots); | ||||
|         else | ||||
|         { | ||||
|             p->sidebar->set_btn_label(ActionButtonType::abReslice, _(L("Slice now"))); | ||||
|             p->sidebar->set_btn_label(ActionButtonType::abReslice, _L("Slice now")); | ||||
|             p->show_action_buttons(false); | ||||
|         } | ||||
|     } | ||||
|  | @ -5617,7 +5612,7 @@ void Plater::paste_from_clipboard() | |||
|     if (!can_paste_from_clipboard()) | ||||
|         return; | ||||
| 
 | ||||
|     Plater::TakeSnapshot snapshot(this, _(L("Paste From Clipboard"))); | ||||
|     Plater::TakeSnapshot snapshot(this, _L("Paste From Clipboard")); | ||||
|     p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										65
									
								
								src/slic3r/GUI/format.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/slic3r/GUI/format.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| #ifndef slic3r_GUI_format_hpp_ | ||||
| #define slic3r_GUI_format_hpp_ | ||||
| 
 | ||||
| // Functional wrapper around boost::format.
 | ||||
| // One day we may replace this wrapper with C++20 format
 | ||||
| // https://en.cppreference.com/w/cpp/utility/format/format
 | ||||
| // though C++20 format uses a different template pattern for position independent parameters.
 | ||||
| // This wrapper also manages implicit conversion from wxString to UTF8 and format_wxstr() variants are provided to format into wxString.
 | ||||
| 
 | ||||
| #include <libslic3r/format.hpp> | ||||
| 
 | ||||
| namespace Slic3r {  | ||||
| namespace GUI {  | ||||
| 
 | ||||
| // Format input mixing UTF8 encoded strings (const char*, std::string) and wxStrings, return a wxString.
 | ||||
| template<typename... TArgs> | ||||
| inline wxString format_wxstr(const char* fmt, TArgs&&... args) { | ||||
| 	boost::format message(fmt); | ||||
| 	return wxString::FromUTF8(Slic3r::internal::format::format_recursive(message, std::forward<TArgs>(args)...).c_str()); | ||||
| } | ||||
| template<typename... TArgs> | ||||
| inline wxString format_wxstr(const std::string& fmt, TArgs&&... args) { | ||||
| 	boost::format message(fmt); | ||||
| 	return wxString::FromUTF8(Slic3r::internal::format::format_recursive(message, std::forward<TArgs>(args)...).c_str()); | ||||
| } | ||||
| template<typename... TArgs> | ||||
| inline wxString format_wxstr(const wxString& fmt, TArgs&&... args) { | ||||
| 	return format_wxstr(fmt.ToUTF8().data()); | ||||
| } | ||||
| template<typename... TArgs> | ||||
| inline std::string format(const wxString& fmt, TArgs&&... args) { | ||||
| 	return format(fmt.ToUTF8().data()); | ||||
| } | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| 
 | ||||
| namespace internal { | ||||
| 	namespace format { | ||||
| 		// Wrapper around wxScopedCharBuffer to indicate that the content is UTF8 formatted.
 | ||||
| 		struct utf8_buffer {  | ||||
| 			// wxScopedCharBuffer is reference counted, therefore copying by value is cheap.
 | ||||
| 			wxScopedCharBuffer data; | ||||
| 		}; | ||||
| 		// Accept wxString and convert it to UTF8 to be processed by Slic3r::format().
 | ||||
| 		inline const utf8_buffer cook(const wxString &arg) { | ||||
| 			return utf8_buffer { arg.ToUTF8() }; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| namespace boost { | ||||
| 	namespace io { | ||||
| 		namespace detail { | ||||
| 			// Adaptor for boost::format to accept wxString converted to UTF8.
 | ||||
| 			inline std::ostream& operator<<(std::ostream& os, const Slic3r::internal::format::utf8_buffer& str) { | ||||
| 				os << str.data.data(); | ||||
| 				return os; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #endif /* slic3r_GUI_format_hpp_ */ | ||||
|  | @ -17,6 +17,7 @@ | |||
| #include <wx/msgdlg.h> | ||||
| 
 | ||||
| #include "libslic3r/libslic3r.h" | ||||
| #include "libslic3r/format.hpp" | ||||
| #include "libslic3r/Utils.hpp" | ||||
| #include "slic3r/GUI/GUI.hpp" | ||||
| #include "slic3r/GUI/I18N.hpp" | ||||
|  | @ -54,7 +55,7 @@ void copy_file_fix(const fs::path &source, const fs::path &target) | |||
| { | ||||
| 	static const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read;   // aka 644
 | ||||
| 
 | ||||
| 	BOOST_LOG_TRIVIAL(debug) << boost::format("PresetUpdater: Copying %1% -> %2%") % source % target; | ||||
| 	BOOST_LOG_TRIVIAL(debug) << format("PresetUpdater: Copying %1% -> %2%", source, target); | ||||
| 
 | ||||
| 	// Make sure the file has correct permission both before and after we copy over it
 | ||||
| 	if (fs::exists(target)) { | ||||
|  | @ -190,12 +191,12 @@ bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &targe | |||
| { | ||||
| 	bool res = false; | ||||
| 	fs::path tmp_path = target_path; | ||||
| 	tmp_path += (boost::format(".%1%%2%") % get_current_pid() % TMP_EXTENSION).str(); | ||||
| 	tmp_path += format(".%1%%2%", get_current_pid(), TMP_EXTENSION); | ||||
| 
 | ||||
| 	BOOST_LOG_TRIVIAL(info) << boost::format("Get: `%1%`\n\t-> `%2%`\n\tvia tmp path `%3%`") | ||||
| 		% url | ||||
| 		% target_path.string() | ||||
| 		% tmp_path.string(); | ||||
| 	BOOST_LOG_TRIVIAL(info) << format("Get: `%1%`\n\t-> `%2%`\n\tvia tmp path `%3%`", | ||||
| 		url, | ||||
| 		target_path.string(), | ||||
| 		tmp_path.string()); | ||||
| 
 | ||||
| 	Http::get(url) | ||||
| 		.on_progress([this](Http::Progress, bool &cancel) { | ||||
|  | @ -203,10 +204,10 @@ bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &targe | |||
| 		}) | ||||
| 		.on_error([&](std::string body, std::string error, unsigned http_status) { | ||||
| 			(void)body; | ||||
| 			BOOST_LOG_TRIVIAL(error) << boost::format("Error getting: `%1%`: HTTP %2%, %3%") | ||||
| 				% url | ||||
| 				% http_status | ||||
| 				% error; | ||||
| 			BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%", | ||||
| 				url, | ||||
| 				http_status, | ||||
| 				error); | ||||
| 		}) | ||||
| 		.on_complete([&](std::string body, unsigned /* http_status */) { | ||||
| 			fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); | ||||
|  | @ -235,7 +236,7 @@ void PresetUpdater::priv::sync_version() const | |||
| { | ||||
| 	if (! enabled_version_check) { return; } | ||||
| 
 | ||||
| 	BOOST_LOG_TRIVIAL(info) << boost::format("Downloading %1% online version from: `%2%`") % SLIC3R_APP_NAME % version_check_url; | ||||
| 	BOOST_LOG_TRIVIAL(info) << format("Downloading %1% online version from: `%2%`", SLIC3R_APP_NAME, version_check_url); | ||||
| 
 | ||||
| 	Http::get(version_check_url) | ||||
| 		.size_limit(SLIC3R_VERSION_BODY_MAX) | ||||
|  | @ -244,10 +245,10 @@ void PresetUpdater::priv::sync_version() const | |||
| 		}) | ||||
| 		.on_error([&](std::string body, std::string error, unsigned http_status) { | ||||
| 			(void)body; | ||||
| 			BOOST_LOG_TRIVIAL(error) << boost::format("Error getting: `%1%`: HTTP %2%, %3%") | ||||
| 				% version_check_url | ||||
| 				% http_status | ||||
| 				% error; | ||||
| 			BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%", | ||||
| 				version_check_url, | ||||
| 				http_status, | ||||
| 				error); | ||||
| 		}) | ||||
| 		.on_complete([&](std::string body, unsigned /* http_status */) { | ||||
| 			boost::trim(body); | ||||
|  | @ -257,11 +258,11 @@ void PresetUpdater::priv::sync_version() const | |||
| 			} | ||||
| 
 | ||||
| 			if (! Semver::parse(body)) { | ||||
| 				BOOST_LOG_TRIVIAL(warning) << boost::format("Received invalid contents from `%1%`: Not a correct semver: `%2%`") % SLIC3R_APP_NAME % body; | ||||
| 				BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, body); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			BOOST_LOG_TRIVIAL(info) << boost::format("Got %1% online version: `%2%`. Sending to GUI thread...") % SLIC3R_APP_NAME % body; | ||||
| 			BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, body); | ||||
| 
 | ||||
| 			wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE); | ||||
| 			evt->SetString(GUI::from_u8(body)); | ||||
|  | @ -315,11 +316,11 @@ void PresetUpdater::priv::sync_config(const VendorMap vendors) | |||
| 			try { | ||||
| 				new_index.load(idx_path_temp); | ||||
| 			} catch (const std::exception & /* err */) { | ||||
| 				BOOST_LOG_TRIVIAL(error) << boost::format("Could not load downloaded index %1% for vendor %2%: invalid index?") % idx_path_temp % vendor.name; | ||||
| 				BOOST_LOG_TRIVIAL(error) << format("Could not load downloaded index %1% for vendor %2%: invalid index?", idx_path_temp, vendor.name); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (new_index.version() < index.version()) { | ||||
| 				BOOST_LOG_TRIVIAL(warning) << boost::format("The downloaded index %1% for vendor %2% is older than the active one. Ignoring the downloaded index.") % idx_path_temp % vendor.name; | ||||
| 				BOOST_LOG_TRIVIAL(warning) << format("The downloaded index %1% for vendor %2% is older than the active one. Ignoring the downloaded index.", idx_path_temp, vendor.name); | ||||
| 				continue; | ||||
| 			} | ||||
| 			Slic3r::rename_file(idx_path_temp, idx_path); | ||||
|  | @ -331,22 +332,22 @@ void PresetUpdater::priv::sync_config(const VendorMap vendors) | |||
| 		// See if a there's a new version to download
 | ||||
| 		const auto recommended_it = index.recommended(); | ||||
| 		if (recommended_it == index.end()) { | ||||
| 			BOOST_LOG_TRIVIAL(error) << boost::format("No recommended version for vendor: %1%, invalid index?") % vendor.name; | ||||
| 			BOOST_LOG_TRIVIAL(error) << format("No recommended version for vendor: %1%, invalid index?", vendor.name); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		const auto recommended = recommended_it->config_version; | ||||
| 
 | ||||
| 		BOOST_LOG_TRIVIAL(debug) << boost::format("Got index for vendor: %1%: current version: %2%, recommended version: %3%") | ||||
| 			% vendor.name | ||||
| 			% vendor.config_version.to_string() | ||||
| 			% recommended.to_string(); | ||||
| 		BOOST_LOG_TRIVIAL(debug) << format("Got index for vendor: %1%: current version: %2%, recommended version: %3%", | ||||
| 			vendor.name, | ||||
| 			vendor.config_version.to_string(), | ||||
| 			recommended.to_string()); | ||||
| 
 | ||||
| 		if (vendor.config_version >= recommended) { continue; } | ||||
| 
 | ||||
| 		// Download a fresh bundle
 | ||||
| 		BOOST_LOG_TRIVIAL(info) << "Downloading new bundle for vendor: " << vendor.name; | ||||
| 		const auto bundle_url = (boost::format("%1%/%2%.ini") % vendor.config_update_url % recommended.to_string()).str(); | ||||
| 		const auto bundle_url = format("%1%/%2%.ini", vendor.config_update_url, recommended.to_string()); | ||||
| 		const auto bundle_path = cache_path / (vendor.id + ".ini"); | ||||
| 		if (! get_file(bundle_url, bundle_path)) { continue; } | ||||
| 		if (cancel) { return; } | ||||
|  | @ -394,7 +395,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 		auto bundle_path_idx = vendor_path / idx.path().filename(); | ||||
| 
 | ||||
| 		if (! fs::exists(bundle_path)) { | ||||
| 			BOOST_LOG_TRIVIAL(info) << boost::format("Confing bundle not installed for vendor %1%, skipping: ") % idx.vendor(); | ||||
| 			BOOST_LOG_TRIVIAL(info) << format("Confing bundle not installed for vendor %1%, skipping: ", idx.vendor()); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -405,7 +406,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 		// from the internet, or installed / updated from the installation resources.
 | ||||
| 		auto recommended = idx.recommended(); | ||||
| 		if (recommended == idx.end()) { | ||||
| 			BOOST_LOG_TRIVIAL(error) << boost::format("No recommended version for vendor: %1%, invalid index? Giving up.") % idx.vendor(); | ||||
| 			BOOST_LOG_TRIVIAL(error) << format("No recommended version for vendor: %1%, invalid index? Giving up.", idx.vendor()); | ||||
| 			// XXX: what should be done here?
 | ||||
| 			continue; | ||||
| 		} | ||||
|  | @ -413,15 +414,15 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 		const auto ver_current = idx.find(vp.config_version); | ||||
| 		const bool ver_current_found = ver_current != idx.end(); | ||||
| 
 | ||||
| 		BOOST_LOG_TRIVIAL(debug) << boost::format("Vendor: %1%, version installed: %2%%3%, version cached: %4%") | ||||
| 			% vp.name | ||||
| 			% vp.config_version.to_string() | ||||
| 			% (ver_current_found ? "" : " (not found in index!)") | ||||
| 			% recommended->config_version.to_string(); | ||||
| 		BOOST_LOG_TRIVIAL(debug) << format("Vendor: %1%, version installed: %2%%3%, version cached: %4%", | ||||
| 			vp.name, | ||||
| 			vp.config_version.to_string(), | ||||
| 			(ver_current_found ? "" : " (not found in index!)"), | ||||
| 			recommended->config_version.to_string()); | ||||
| 
 | ||||
| 		if (! ver_current_found) { | ||||
| 			// Any published config shall be always found in the latest config index.
 | ||||
| 			auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str(); | ||||
| 			auto message = format("Preset bundle `%1%` version not found in index: %2%", idx.vendor(), vp.config_version.to_string()); | ||||
| 			BOOST_LOG_TRIVIAL(error) << message; | ||||
| 			GUI::show_error(nullptr, message); | ||||
| 			continue; | ||||
|  | @ -440,7 +441,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 		} | ||||
| 
 | ||||
| 		if (recommended->config_version < vp.config_version) { | ||||
| 			BOOST_LOG_TRIVIAL(warning) << (boost::format("Recommended config version for the currently running PrusaSlicer is older than the currently installed config for vendor %1%. This should not happen.") % idx.vendor()).str(); | ||||
| 			BOOST_LOG_TRIVIAL(warning) << format("Recommended config version for the currently running PrusaSlicer is older than the currently installed config for vendor %1%. This should not happen.", idx.vendor()); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -482,7 +483,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 					found = true; | ||||
| 				} | ||||
| 			} catch (const std::exception &ex) { | ||||
| 				BOOST_LOG_TRIVIAL(info) << boost::format("Failed to load the config bundle `%1%`: %2%") % path_in_cache.string() % ex.what(); | ||||
| 				BOOST_LOG_TRIVIAL(info) << format("Failed to load the config bundle `%1%`: %2%", path_in_cache.string(), ex.what()); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -496,13 +497,13 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 			try { | ||||
| 				rsrc_vp = VendorProfile::from_ini(path_in_rsrc, false); | ||||
| 			} catch (const std::exception &ex) { | ||||
| 				BOOST_LOG_TRIVIAL(info) << boost::format("Cannot load the config bundle at `%1%`: %2%") % path_in_rsrc.string() % ex.what(); | ||||
| 				BOOST_LOG_TRIVIAL(info) << format("Cannot load the config bundle at `%1%`: %2%", path_in_rsrc.string(), ex.what()); | ||||
| 			} | ||||
| 			if (rsrc_vp.valid()) { | ||||
| 				try { | ||||
| 					rsrc_idx.load(path_idx_in_rsrc); | ||||
| 				} catch (const std::exception &ex) { | ||||
| 					BOOST_LOG_TRIVIAL(info) << boost::format("Cannot load the config index at `%1%`: %2%") % path_idx_in_rsrc.string() % ex.what(); | ||||
| 					BOOST_LOG_TRIVIAL(info) << format("Cannot load the config index at `%1%`: %2%", path_idx_in_rsrc.string(), ex.what()); | ||||
| 				} | ||||
| 				recommended = rsrc_idx.recommended(); | ||||
| 				if (recommended != rsrc_idx.end() && recommended->config_version == rsrc_vp.config_version && recommended->config_version > vp.config_version) { | ||||
|  | @ -510,8 +511,8 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 					bundle_path_idx_to_install = path_idx_in_rsrc; | ||||
| 					found = true; | ||||
| 				} else { | ||||
| 					BOOST_LOG_TRIVIAL(warning) << (boost::format("The recommended config version for vendor `%1%` in resources does not match the recommended\n" | ||||
| 					                                             " config version for this version of PrusaSlicer. Corrupted installation?") % idx.vendor()).str(); | ||||
| 					BOOST_LOG_TRIVIAL(warning) << format("The recommended config version for vendor `%1%` in resources does not match the recommended\n" | ||||
| 			                                             " config version for this version of PrusaSlicer. Corrupted installation?", idx.vendor()); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | @ -529,11 +530,11 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
|                     /*const auto existing_recommended = existing_idx.recommended(old_slic3r_version);
 | ||||
|                     if (existing_recommended != existing_idx.end() && recommended->config_version == existing_recommended->config_version) { | ||||
| 						// The user has already seen (and presumably rejected) this update
 | ||||
| 						BOOST_LOG_TRIVIAL(info) << boost::format("Downloaded index for `%1%` is the same as installed one, not offering an update.") % idx.vendor(); | ||||
| 						BOOST_LOG_TRIVIAL(info) << format("Downloaded index for `%1%` is the same as installed one, not offering an update.",idx.vendor()); | ||||
| 						continue; | ||||
| 					}*/ | ||||
| 				} catch (const std::exception &err) { | ||||
| 					BOOST_LOG_TRIVIAL(error) << boost::format("Cannot load the installed index at `%1%`: %2%") % bundle_path_idx % err.what(); | ||||
| 					BOOST_LOG_TRIVIAL(error) << format("Cannot load the installed index at `%1%`: %2%", bundle_path_idx, err.what()); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
|  | @ -542,10 +543,10 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 			{ | ||||
| 				const auto recommended_snap = SnapshotDB::singleton().snapshot_with_vendor_preset(vp.name, recommended->config_version); | ||||
| 				if (recommended_snap != SnapshotDB::singleton().end()) { | ||||
| 					BOOST_LOG_TRIVIAL(info) << boost::format("Bundle update %1% %2% already found in snapshot %3%, skipping...") | ||||
| 						% vp.name | ||||
| 						% recommended->config_version.to_string() | ||||
| 						% recommended_snap->id; | ||||
| 					BOOST_LOG_TRIVIAL(info) << format("Bundle update %1% %2% already found in snapshot %3%, skipping...", | ||||
| 						vp.name, | ||||
| 						recommended->config_version.to_string(), | ||||
| 						recommended_snap->id); | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
|  | @ -555,9 +556,9 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version | |||
| 			// offered updates and to not offer the same update again if it was cancelled by the user.
 | ||||
| 			copy_file_fix(bundle_path_idx_to_install, bundle_path_idx); | ||||
| 		} else { | ||||
| 			BOOST_LOG_TRIVIAL(warning) << boost::format("Index for vendor %1% indicates update (%2%) but the new bundle was found neither in cache nor resources") | ||||
| 				% idx.vendor() | ||||
| 				% recommended->config_version.to_string(); | ||||
| 			BOOST_LOG_TRIVIAL(warning) << format("Index for vendor %1% indicates update (%2%) but the new bundle was found neither in cache nor resources", | ||||
| 				idx.vendor(), | ||||
| 				recommended->config_version.to_string()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -572,7 +573,7 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons | |||
| 			SnapshotDB::singleton().take_snapshot(*GUI::wxGetApp().app_config, Snapshot::SNAPSHOT_DOWNGRADE); | ||||
| 		} | ||||
| 		 | ||||
| 		BOOST_LOG_TRIVIAL(info) << boost::format("Deleting %1% incompatible bundles") % updates.incompats.size(); | ||||
| 		BOOST_LOG_TRIVIAL(info) << format("Deleting %1% incompatible bundles", updates.incompats.size()); | ||||
| 
 | ||||
| 		for (auto &incompat : updates.incompats) { | ||||
| 			BOOST_LOG_TRIVIAL(info) << '\t' << incompat; | ||||
|  | @ -587,7 +588,7 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons | |||
| 			SnapshotDB::singleton().take_snapshot(*GUI::wxGetApp().app_config, Snapshot::SNAPSHOT_UPGRADE); | ||||
| 		} | ||||
| 
 | ||||
| 		BOOST_LOG_TRIVIAL(info) << boost::format("Performing %1% updates") % updates.updates.size(); | ||||
| 		BOOST_LOG_TRIVIAL(info) << format("Performing %1% updates", updates.updates.size()); | ||||
| 
 | ||||
| 		for (const auto &update : updates.updates) { | ||||
| 			BOOST_LOG_TRIVIAL(info) << '\t' << update; | ||||
|  | @ -597,8 +598,7 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons | |||
| 			PresetBundle bundle; | ||||
| 			bundle.load_configbundle(update.source.string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM); | ||||
| 
 | ||||
| 			BOOST_LOG_TRIVIAL(info) << boost::format("Deleting %1% conflicting presets") | ||||
| 				% (bundle.prints.size() + bundle.filaments.size() + bundle.printers.size()); | ||||
| 			BOOST_LOG_TRIVIAL(info) << format("Deleting %1% conflicting presets", bundle.prints.size() + bundle.filaments.size() + bundle.printers.size()); | ||||
| 
 | ||||
| 			auto preset_remover = [](const Preset &preset) { | ||||
| 				BOOST_LOG_TRIVIAL(info) << '\t' << preset.file; | ||||
|  | @ -611,8 +611,8 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons | |||
| 
 | ||||
| 			// Also apply the `obsolete_presets` property, removing obsolete ini files
 | ||||
| 
 | ||||
| 			BOOST_LOG_TRIVIAL(info) << boost::format("Deleting %1% obsolete presets") | ||||
| 				% (bundle.obsolete_presets.prints.size() + bundle.obsolete_presets.filaments.size() + bundle.obsolete_presets.printers.size()); | ||||
| 			BOOST_LOG_TRIVIAL(info) << format("Deleting %1% obsolete presets", | ||||
| 				bundle.obsolete_presets.prints.size() + bundle.obsolete_presets.filaments.size() + bundle.obsolete_presets.printers.size()); | ||||
| 
 | ||||
| 			auto obsolete_remover = [](const char *subdir, const std::string &preset) { | ||||
| 				auto path = fs::path(Slic3r::data_dir()) / subdir / preset; | ||||
|  | @ -694,7 +694,7 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver &old_slic3 | |||
| 
 | ||||
| 	auto updates = p->get_config_updates(old_slic3r_version); | ||||
| 	if (updates.incompats.size() > 0) { | ||||
| 		BOOST_LOG_TRIVIAL(info) << boost::format("%1% bundles incompatible. Asking for action...") % updates.incompats.size(); | ||||
| 		BOOST_LOG_TRIVIAL(info) << format("%1% bundles incompatible. Asking for action...", updates.incompats.size()); | ||||
| 
 | ||||
| 		std::unordered_map<std::string, wxString> incompats_map; | ||||
| 		for (const auto &incompat : updates.incompats) { | ||||
|  | @ -702,15 +702,14 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver &old_slic3 | |||
| 			const auto max_slic3r = incompat.version.max_slic3r_version; | ||||
| 			wxString restrictions; | ||||
| 			if (min_slic3r != Semver::zero() && max_slic3r != Semver::inf()) { | ||||
|                 restrictions = GUI::from_u8((boost::format(_utf8(L("requires min. %s and max. %s"))) | ||||
|                     % min_slic3r.to_string() | ||||
|                     % max_slic3r.to_string()).str() | ||||
| 				); | ||||
|                 restrictions = GUI::format_wxstr(_L("requires min. %s and max. %s"), | ||||
|                     min_slic3r.to_string(), | ||||
|                     max_slic3r.to_string()); | ||||
| 			} else if (min_slic3r != Semver::zero()) { | ||||
|                 restrictions = GUI::from_u8((boost::format(_utf8(L("requires min. %s"))) % min_slic3r.to_string()).str()); | ||||
| 				restrictions = GUI::format_wxstr(_L("requires min. %s"), min_slic3r.to_string()); | ||||
| 				BOOST_LOG_TRIVIAL(debug) << "Bundle is not downgrade, user will now have to do whole wizard. This should not happen."; | ||||
| 			} else { | ||||
|                 restrictions = GUI::from_u8((boost::format(_utf8(L("requires max. %s"))) % max_slic3r.to_string()).str()); | ||||
|                 restrictions = GUI::format_wxstr(_L("requires max. %s"), max_slic3r.to_string()); | ||||
| 			} | ||||
| 
 | ||||
| 			incompats_map.emplace(std::make_pair(incompat.vendor, std::move(restrictions))); | ||||
|  | @ -742,13 +741,13 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver &old_slic3 | |||
| 		for (const auto& update : updates.updates) { | ||||
| 			incompatible_version = (update.forced_update ? true : incompatible_version); | ||||
| 			//td::cout << update.forced_update << std::endl;
 | ||||
| 			//BOOST_LOG_TRIVIAL(info) << boost::format("Update requires higher version.");
 | ||||
| 			//BOOST_LOG_TRIVIAL(info) << format("Update requires higher version.");
 | ||||
| 		} | ||||
| 
 | ||||
| 		//forced update
 | ||||
| 		if(incompatible_version) | ||||
| 		{ | ||||
| 			BOOST_LOG_TRIVIAL(info) << boost::format("Update of %1% bundles available. At least one requires higher version of Slicer.") % updates.updates.size(); | ||||
| 			BOOST_LOG_TRIVIAL(info) << format("Update of %1% bundles available. At least one requires higher version of Slicer.", updates.updates.size()); | ||||
| 
 | ||||
| 			std::vector<GUI::MsgUpdateForced::Update> updates_msg; | ||||
| 			for (const auto& update : updates.updates) { | ||||
|  | @ -778,7 +777,7 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver &old_slic3 | |||
| 		} | ||||
| 
 | ||||
| 		// regular update
 | ||||
| 		BOOST_LOG_TRIVIAL(info) << boost::format("Update of %1% bundles available. Asking for confirmation ...") % updates.updates.size(); | ||||
| 		BOOST_LOG_TRIVIAL(info) << format("Update of %1% bundles available. Asking for confirmation ...", updates.updates.size()); | ||||
| 
 | ||||
| 		std::vector<GUI::MsgUpdateConfig::Update> updates_msg; | ||||
| 		for (const auto &update : updates.updates) { | ||||
|  | @ -813,7 +812,7 @@ void PresetUpdater::install_bundles_rsrc(std::vector<std::string> bundles, bool | |||
| { | ||||
| 	Updates updates; | ||||
| 
 | ||||
| 	BOOST_LOG_TRIVIAL(info) << boost::format("Installing %1% bundles from resources ...") % bundles.size(); | ||||
| 	BOOST_LOG_TRIVIAL(info) << format("Installing %1% bundles from resources ...", bundles.size()); | ||||
| 
 | ||||
| 	for (const auto &bundle : bundles) { | ||||
| 		auto path_in_rsrc = (p->rsrc_path / bundle).replace_extension(".ini"); | ||||
|  |  | |||
|  | @ -183,3 +183,5 @@ | |||
| #include "libslic3r/BoundingBox.hpp" | ||||
| #include "libslic3r/ClipperUtils.hpp" | ||||
| #include "libslic3r/libslic3r.h" | ||||
| 
 | ||||
| #include "GUI/format.hpp" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 enricoturri1966
						enricoturri1966