mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Fixed loading of system presets with incompatible system profile keys
before the "reconfigure" dialog is shown. Replaced boost::filesystem::copy_file() with Slic3r::copy_file() in config snapshot loading code.
This commit is contained in:
		
							parent
							
								
									1e60acde12
								
							
						
					
					
						commit
						856da036eb
					
				
					 9 changed files with 67 additions and 32 deletions
				
			
		|  | @ -10,6 +10,7 @@ | |||
| #include <boost/filesystem/operations.hpp> | ||||
| 
 | ||||
| #include "libslic3r/PresetBundle.hpp" | ||||
| #include "libslic3r/format.hpp" | ||||
| #include "libslic3r/libslic3r.h" | ||||
| #include "libslic3r/Time.hpp" | ||||
| #include "libslic3r/Config.hpp" | ||||
|  | @ -358,11 +359,12 @@ static void copy_config_dir_single_level(const boost::filesystem::path &path_src | |||
| { | ||||
|     if (! boost::filesystem::is_directory(path_dst) &&  | ||||
|         ! boost::filesystem::create_directory(path_dst)) | ||||
|         throw Slic3r::RuntimeError(std::string("Slic3r was unable to create a directory at ") + path_dst.string()); | ||||
|         throw Slic3r::RuntimeError(std::string("PrusaSlicer was unable to create a directory at ") + path_dst.string()); | ||||
| 
 | ||||
|     for (auto &dir_entry : boost::filesystem::directory_iterator(path_src)) | ||||
|         if (Slic3r::is_ini_file(dir_entry)) | ||||
| 		    boost::filesystem::copy_file(dir_entry.path(), path_dst / dir_entry.path().filename(), boost::filesystem::copy_option::overwrite_if_exists); | ||||
|             if (std::string error_message; copy_file(dir_entry.path().string(), (path_dst / dir_entry.path().filename()).string(), error_message, false) != SUCCESS) | ||||
|                 throw Slic3r::RuntimeError(format("Failed copying \"%1%\" to \"%2%\": %3%", path_src.string(), path_dst.string(), error_message)); | ||||
| } | ||||
| 
 | ||||
| static void delete_existing_ini_files(const boost::filesystem::path &path) | ||||
|  | @ -413,7 +415,7 @@ const Snapshot&	SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot: | |||
|                 ++ it; | ||||
|         // Read the active config bundle, parse the config version.
 | ||||
|         PresetBundle bundle; | ||||
|         bundle.load_configbundle((data_dir / "vendor" / (cfg.name + ".ini")).string(), PresetBundle::LoadConfigBundleAttribute::LoadVendorOnly); | ||||
|         bundle.load_configbundle((data_dir / "vendor" / (cfg.name + ".ini")).string(), PresetBundle::LoadConfigBundleAttribute::LoadVendorOnly, ForwardCompatibilitySubstitutionRule::EnableSilent); | ||||
|         for (const auto &vp : bundle.vendors) | ||||
|             if (vp.second.id == cfg.name) | ||||
|                 cfg.version.config_version = vp.second.config_version; | ||||
|  |  | |||
|  | @ -65,7 +65,9 @@ bool Bundle::load(fs::path source_path, bool ais_in_resources, bool ais_prusa_bu | |||
|     this->is_prusa_bundle = ais_prusa_bundle; | ||||
| 
 | ||||
|     std::string path_string = source_path.string(); | ||||
|     auto [config_substitutions, presets_loaded] = preset_bundle->load_configbundle(path_string, PresetBundle::LoadConfigBundleAttribute::LoadSystem); | ||||
|     // Throw when parsing invalid configuration. Only valid configuration is supposed to be provided over the air.
 | ||||
|     auto [config_substitutions, presets_loaded] = preset_bundle->load_configbundle( | ||||
|         path_string, PresetBundle::LoadConfigBundleAttribute::LoadSystem, ForwardCompatibilitySubstitutionRule::Disable); | ||||
|     UNUSED(config_substitutions); | ||||
|     // No substitutions shall be reported when loading a system config bundle, no substitutions are allowed.
 | ||||
|     assert(config_substitutions.empty()); | ||||
|  | @ -2590,7 +2592,8 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese | |||
|     // Reloading the configs after some modifications were done to PrusaSlicer.ini.
 | ||||
|     // Just perform the substitutions silently, as the substitutions were already presented to the user on application start-up
 | ||||
|     // and the Wizard shall not create any new values that would require substitution.
 | ||||
|     PresetsConfigSubstitutions substitutions = preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilent, preferred_model); | ||||
|     // Throw on substitutions in system profiles, as the system profiles provided over the air should be compatible with this PrusaSlicer version.
 | ||||
|     preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem, preferred_model); | ||||
| 
 | ||||
|     if (page_custom->custom_wanted()) { | ||||
|         page_firmware->apply_custom_config(*custom_config); | ||||
|  |  | |||
|  | @ -912,7 +912,10 @@ bool GUI_App::on_init_inner() | |||
|     // Suppress the '- default -' presets.
 | ||||
|     preset_bundle->set_default_suppressed(app_config->get("no_defaults") == "1"); | ||||
|     try { | ||||
|         init_params->preset_substitutions = preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::Enable); | ||||
|         // Enable all substitutions (in both user and system profiles), but log the substitutions in user profiles only.
 | ||||
|         // If there are substitutions in system profiles, then a "reconfigure" event shall be triggered, which will force
 | ||||
|         // installation of a compatible system preset, thus nullifying the system preset substitutions.
 | ||||
|         init_params->preset_substitutions = preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSystemSilent); | ||||
|     } catch (const std::exception &ex) { | ||||
|         show_error(nullptr, ex.what()); | ||||
|     } | ||||
|  | @ -1874,6 +1877,9 @@ void GUI_App::add_config_menu(wxMenuBar *menu) | |||
|                         Config::SnapshotDB::singleton().take_snapshot(*app_config, Config::Snapshot::SNAPSHOT_BEFORE_ROLLBACK); | ||||
|                     try { | ||||
|                         app_config->set("on_snapshot", Config::SnapshotDB::singleton().restore_snapshot(dlg.snapshot_to_activate(), *app_config).id); | ||||
|                         // Enable substitutions, log both user and system substitutions. There should not be any substitutions performed when loading system
 | ||||
|                         // presets because compatibility of profiles shall be verified using the min_slic3r_version keys in config index, but users
 | ||||
|                         // are known to be creative and mess with the config files in various ways.
 | ||||
|                         if (PresetsConfigSubstitutions all_substitutions = preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::Enable); | ||||
|                             ! all_substitutions.empty()) | ||||
|                             show_substitutions_info(all_substitutions); | ||||
|  |  | |||
|  | @ -1809,7 +1809,9 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re | |||
|     size_t presets_imported = 0; | ||||
|     PresetsConfigSubstitutions config_substitutions; | ||||
|     try { | ||||
|         std::tie(config_substitutions, presets_imported) = wxGetApp().preset_bundle->load_configbundle(file.ToUTF8().data(), PresetBundle::LoadConfigBundleAttribute::SaveImported); | ||||
|         // Report all substitutions.
 | ||||
|         std::tie(config_substitutions, presets_imported) = wxGetApp().preset_bundle->load_configbundle( | ||||
|             file.ToUTF8().data(), PresetBundle::LoadConfigBundleAttribute::SaveImported, ForwardCompatibilitySubstitutionRule::Enable); | ||||
|     } catch (const std::exception &ex) { | ||||
|         show_error(this, ex.what()); | ||||
|         return; | ||||
|  |  | |||
|  | @ -65,6 +65,10 @@ void copy_file_fix(const fs::path &source, const fs::path &target) | |||
| 				_L("Copying of file %1% to %2% failed: %3%"), | ||||
| 				source, target, error_message)); | ||||
| 	} | ||||
| 	// Permissions should be copied from the source file by copy_file(). We are not sure about the source
 | ||||
| 	// permissions, let's rewrite them with 644.
 | ||||
| 	static constexpr const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read; | ||||
| 	fs::permissions(target, perms); | ||||
| } | ||||
| 
 | ||||
| struct Update | ||||
|  | @ -611,7 +615,8 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons | |||
| 			update.install(); | ||||
| 
 | ||||
| 			PresetBundle bundle; | ||||
| 			bundle.load_configbundle(update.source.string(), PresetBundle::LoadConfigBundleAttribute::LoadSystem); | ||||
| 			// Throw when parsing invalid configuration. Only valid configuration is supposed to be provided over the air.
 | ||||
| 			bundle.load_configbundle(update.source.string(), PresetBundle::LoadConfigBundleAttribute::LoadSystem, ForwardCompatibilitySubstitutionRule::Disable); | ||||
| 
 | ||||
| 			BOOST_LOG_TRIVIAL(info) << format("Deleting %1% conflicting presets", bundle.prints.size() + bundle.filaments.size() + bundle.printers.size()); | ||||
| 
 | ||||
|  | @ -715,7 +720,8 @@ static void reload_configs_update_gui() | |||
| 	auto* app_config = GUI::wxGetApp().app_config; | ||||
| 	// System profiles should not trigger any substitutions, user profiles may trigger substitutions, but these substitutions
 | ||||
| 	// were already presented to the user on application start up. Just do substitutions now and keep quiet about it.
 | ||||
| 	GUI::wxGetApp().preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilent); | ||||
| 	// However throw on substitutions in system profiles, those shall never happen with system profiles installed over the air.
 | ||||
| 	GUI::wxGetApp().preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem); | ||||
| 	GUI::wxGetApp().load_current_presets(); | ||||
| 	GUI::wxGetApp().plater()->set_bed_shape(); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik