fix: load 3mf project after sync (#13834)

# Description

Resolves https://github.com/OrcaSlicer/OrcaSlicer/issues/13830

The issue was that when OrcaSlicer was open with a 3mf file, the project
is first loaded, then when the sync finishes, it overrides the project
settings. This occurs when are working on a 3mf file and you click the
sync presets button as well.

The fix was to snapshot the current state of the settings, and then
restore whatever was marked as dirty to it's original state, preserving
the 3mf project settings.

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
This commit is contained in:
Ian Chua
2026-05-28 10:34:09 +08:00
committed by GitHub

View File

@@ -5855,15 +5855,59 @@ void GUI_App::reload_settings()
if (is_closing() || !preset_bundle || !app_config || !mainframe)
return;
// Snapshot each collection's edited config BEFORE any mutation.
// load_pending_vendors() via apply_vendor_config() can call select_preset(0)
// resetting all selections to defaults and overwriting m_edited_preset.
// The cloud load_user_presets() can also trigger select_preset() via
// remove_users_preset() and overwrite m_edited_preset.config via load_user_preset().
struct PresetSnapshot { std::string name; DynamicPrintConfig config; bool dirty; };
auto snapshot_collection = [](const PresetCollection& col) -> PresetSnapshot {
auto& sel = col.get_selected_preset();
auto& ed = col.get_edited_preset();
return {sel.name, ed.config, sel.is_dirty};
};
PresetSnapshot print_snap = snapshot_collection(preset_bundle->prints);
PresetSnapshot filament_snap = snapshot_collection(preset_bundle->filaments);
PresetSnapshot printer_snap = snapshot_collection(preset_bundle->printers);
// Check the user presets for any system vendors that need to be installed
for (auto data : user_presets) {
if (!check_preset_parent_available(data))
add_pending_vendor_preset(data);
}
load_pending_vendors();
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
// Re-apply any edited config that was wiped during vendor loading or sync.
auto restore_snapshot = [](PresetCollection& col, const PresetSnapshot& snap, const char* label) {
auto& ed = col.get_edited_preset();
bool changed = !ed.config.equals(snap.config);
BOOST_LOG_TRIVIAL(info) << "reload_settings restore " << label
<< ": snap_name=" << snap.name << " snap_dirty=" << snap.dirty
<< " current_name=" << ed.name << " changed=" << changed;
if (!snap.dirty) return; // nothing to protect, let cloud updates stand
Preset* p = col.find_preset(snap.name, false, true);
if (p && p->name == snap.name) {
BOOST_LOG_TRIVIAL(info) << "reload_settings RESTORING " << label
<< ": name=" << snap.name;
// If the snapshot preset is not currently selected, re-select it first.
if (col.get_selected_preset().name != snap.name)
col.select_preset_by_name(snap.name, true);
ed = col.get_edited_preset();
ed.config = snap.config;
col.get_selected_preset().is_dirty = snap.dirty;
ed.is_dirty = snap.dirty;
} else {
BOOST_LOG_TRIVIAL(info) << "reload_settings restore " << label
<< ": preset not found name=" << snap.name;
}
};
restore_snapshot(preset_bundle->prints, print_snap, "print");
restore_snapshot(preset_bundle->filaments, filament_snap, "filament");
restore_snapshot(preset_bundle->printers, printer_snap, "printer");
// Orca: settings changed, refresh ui to reflect the new preset values
mainframe->update_side_preset_ui();
for (auto tab : tabs_list) {