Limit the 2.4.2 filament preset migration to presets that need it

Only presets that still name their parent as 2.4.2 did and have no printer
list of their own are offered, and a preset changed after it was found is
left alone. The startup prompt appears once, after upgrading from 2.4.2 or
earlier, as a standard dialog that keeps "Don't remind me again"; Help >
Migrate Filament Presets is unchanged. Migrating no longer overwrites an
unsaved printer-list edit or marks the project modified.
This commit is contained in:
SoftFever
2026-10-13 16:10:45 +08:00
parent ff86337026
commit decd2fb75b
13 changed files with 322 additions and 350 deletions
+78 -47
View File
@@ -2729,91 +2729,122 @@ void PresetCollection::update_after_user_presets_loaded()
return;
}
const Preset *PresetCollection::system_parent_with_inherited_printers(const Preset &preset) const
// A user preset file as written: it holds only the keys the preset sets itself, and an inherits that names a
// renamed parent by the old name the preset was made against. Throws if the file can not be read or parsed.
static json read_user_preset_file(const std::string &file)
{
if (!preset.is_user() || preset.inherits().empty())
return nullptr;
const Preset *parent = get_preset_parent(preset);
if (parent == nullptr || !parent->is_system)
return nullptr;
// A user preset that sets its own compatible_printers keeps exactly those.
const auto *own = preset.config.option<ConfigOptionStrings>("compatible_printers");
const auto *inherited = parent->config.option<ConfigOptionStrings>("compatible_printers");
return own != nullptr && inherited != nullptr && own->values == inherited->values ? parent : nullptr;
boost::nowide::ifstream in(file);
return json::parse(in);
}
std::vector<LegacyPrinterMigration> PresetCollection::legacy_printer_migrations(const std::map<std::string, std::vector<std::string>> &printers_by_parent) const
std::vector<LegacyUserFilamentPreset> PresetCollection::legacy_user_filament_presets(const std::map<std::string, std::vector<std::string>> &printers_by_parent)
{
std::vector<LegacyPrinterMigration> migrations;
auto has_entry = [&printers_by_parent](const std::string &name) { return printers_by_parent.count(name) > 0; };
std::vector<LegacyUserFilamentPreset> legacy_presets;
// The preset sync thread can add or delete presets meanwhile.
lock();
for (const Preset &preset : m_presets) {
const Preset *parent = system_parent_with_inherited_printers(preset);
if (parent == nullptr)
if (!preset.is_user() || preset.inherits().empty())
continue;
const Preset *parent = get_preset_parent(preset);
if (parent == nullptr || !parent->is_system)
continue;
// An empty list already covers every printer.
const std::vector<std::string> &own = preset.config.option<ConfigOptionStrings>("compatible_printers")->values;
if (own.empty())
continue;
// The map names the parent as it was when the map was written; a later rename keeps that name in renamed_from.
auto it = printers_by_parent.find(parent->name);
for (auto old_name = parent->renamed_from.begin(); it == printers_by_parent.end() && old_name != parent->renamed_from.end(); ++old_name)
it = printers_by_parent.find(*old_name);
// The parent's name in the older release is its current name or one in its renamed_from, so only the
// files of presets whose parent has an entry under one of those are read.
if (!has_entry(parent->name) && std::none_of(parent->renamed_from.begin(), parent->renamed_from.end(), has_entry))
continue;
LegacyUserFilamentPreset legacy{preset.name, parent->name, {}, {}};
try {
const json j = read_user_preset_file(preset.file);
// A preset whose file sets compatible_printers, even to an empty list, was given its printers on
// purpose and keeps exactly those.
if (j.contains("compatible_printers"))
continue;
legacy.inherits = j.value(BBL_JSON_KEY_INHERITS, std::string());
} catch (const std::exception &err) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": can not read " << preset.file << ": " << err.what();
continue;
}
auto it = printers_by_parent.find(legacy.inherits);
if (it == printers_by_parent.end())
continue;
LegacyPrinterMigration migration{preset.name, parent->name, {}};
for (const std::string &printer : it->second)
if (std::find(own.begin(), own.end(), printer) == own.end())
migration.printers.push_back(printer);
if (!migration.printers.empty())
migrations.push_back(std::move(migration));
legacy.printers.push_back(printer);
if (!legacy.printers.empty())
legacy_presets.push_back(std::move(legacy));
}
return migrations;
unlock();
return legacy_presets;
}
bool PresetCollection::apply_legacy_printer_migration(const LegacyPrinterMigration &migration)
bool PresetCollection::migrate_legacy_user_filament_preset(const LegacyUserFilamentPreset &legacy)
{
// Copied out under the lock: the preset sync thread can delete presets, which invalidates references into
// m_presets, while the file is written.
lock();
auto it = this->find_preset_internal(migration.preset);
if (it == m_presets.end() || it->name != migration.preset || system_parent_with_inherited_printers(*it) == nullptr) {
auto it = this->find_preset_internal(legacy.preset);
if (it == m_presets.end() || it->name != legacy.preset || !it->is_user()) {
unlock();
return false;
}
Preset &preset = *it;
std::vector<std::string> printers = preset.config.option<ConfigOptionStrings>("compatible_printers")->values;
for (const std::string &printer : migration.printers)
const std::string file = it->file;
std::vector<std::string> printers = it->config.option<ConfigOptionStrings>("compatible_printers")->values;
unlock();
for (const std::string &printer : legacy.printers)
if (std::find(printers.begin(), printers.end(), printer) == printers.end())
printers.push_back(printer);
const bool selected = m_idx_selected == static_cast<size_t>(it - m_presets.begin());
unlock();
// Only compatible_printers changes in the file. Saving the whole preset would also rewrite an inherits that
// names a renamed parent by its old name, the only name older releases know it by.
{
InstanceLock instance_lock(user_presets_lock_path());
const std::string lock_path = user_presets_lock_path();
InstanceLock instance_lock(lock_path);
// Without the lock another instance could save between the read and the write. Migrating can wait.
if (!lock_path.empty() && !instance_lock.locked())
return false;
try {
boost::nowide::ifstream in(preset.file);
json j = json::parse(in);
j["compatible_printers"] = printers;
if (const std::error_code ec = write_file_atomically(preset.file, j.dump(1, '\t'))) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed to save " << preset.file << ": " << ec.message();
json j = read_user_preset_file(file);
// Changed by hand or by another instance since the preset was found: a list of its own stands, and
// another parent would need other printers.
if (j.contains("compatible_printers") || j.value(BBL_JSON_KEY_INHERITS, std::string()) != legacy.inherits)
return false;
j["compatible_printers"] = printers;
if (const std::error_code ec = write_file_atomically(file, j.dump(1, '\t') + "\n")) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed to save " << file << ": " << ec.message();
return false;
}
} catch (const std::exception &err) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not migrate " << preset.file << ": " << err.what();
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not migrate " << file << ": " << err.what();
return false;
}
}
lock();
preset.config.option<ConfigOptionStrings>("compatible_printers")->values = printers;
if (selected)
m_edited_preset.config.option<ConfigOptionStrings>("compatible_printers", true)->values = printers;
unlock();
// Push the change to the cloud copy, as an edit in the settings tab would.
if (!preset.setting_id.empty()) {
preset.sync_info = "update";
preset.save_info();
it = this->find_preset_internal(legacy.preset);
if (it != m_presets.end() && it->name == legacy.preset) {
std::vector<std::string> &saved = it->config.option<ConfigOptionStrings>("compatible_printers", true)->values;
std::vector<std::string> &edited = m_edited_preset.config.option<ConfigOptionStrings>("compatible_printers", true)->values;
// A change to the list pending in the settings tab stays pending. Without one, the edited copy and the
// snapshot unsaved changes are measured against take the written list, so nothing reads as modified.
if (m_idx_selected == static_cast<size_t>(it - m_presets.begin()) && edited == saved) {
edited = printers;
if (m_saved_preset.name == it->name)
m_saved_preset.config.option<ConfigOptionStrings>("compatible_printers", true)->values = printers;
}
saved = printers;
// Push the change to the cloud copy, as an edit in the settings tab would.
if (!it->setting_id.empty()) {
it->sync_info = "update";
it->save_info();
}
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": user preset " << preset.name << " gets " << migration.printers.size()
unlock();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": user preset " << legacy.preset << " gets " << legacy.printers.size()
<< " printer(s) its parent listed in an older release";
return true;
}
+14 -14
View File
@@ -551,11 +551,13 @@ struct PresetConfigSubstitutions {
// PrusaSlicer and reading the user Print / Filament / Printer profiles.
using PresetsConfigSubstitutions = std::vector<PresetConfigSubstitutions>;
// A user filament preset that no longer shows on printers its system parent listed in an older release,
// and those printers. Migrating it writes them into the preset's own compatible_printers.
struct LegacyPrinterMigration {
// A user filament preset made against an older release that no longer shows on printers its system parent
// listed then, and those printers. Migrating it writes them into the preset's own compatible_printers.
struct LegacyUserFilamentPreset {
std::string preset;
std::string parent;
// The parent's name as the preset file states it: the name the older release knew it by.
std::string inherits;
std::vector<std::string> printers;
};
@@ -610,13 +612,15 @@ public:
bool load_user_preset(std::string name, std::map<std::string, std::string> preset_values, PresetsConfigSubstitutions& substitutions, ForwardCompatibilitySubstitutionRule rule, const PresetOrigin &load_origin = PresetOrigin(PresetOrigin::Kind::User));
void update_after_user_presets_loaded();
// User presets store only their diff, so a user preset inherits its system parent's compatible_printers
// and disappears from a printer once a profile update narrows that list. Lists the user presets that
// inherit the list and the printers their parent covered in an older release (printers_by_parent, keyed
// by the parent's name then) but no longer lists.
std::vector<LegacyPrinterMigration> legacy_printer_migrations(const std::map<std::string, std::vector<std::string>> &printers_by_parent) const;
// Adds the migration's printers to the preset's own compatible_printers and saves the preset to disk.
// False if the preset no longer inherits its parent's list or could not be saved.
bool apply_legacy_printer_migration(const LegacyPrinterMigration &migration);
// and disappears from a printer once a profile update narrows that list. Lists the user presets whose
// files do not set compatible_printers, and the printers their parent covered in an older release but
// no longer lists. printers_by_parent is keyed by the parent's name in that release, which is the name
// the preset file's inherits still holds.
std::vector<LegacyUserFilamentPreset> legacy_user_filament_presets(const std::map<std::string, std::vector<std::string>> &printers_by_parent);
// Adds the printers to the preset's own compatible_printers and saves the preset to disk. False if the
// preset file sets compatible_printers or names another parent by now, if another instance holds the
// user presets lock, or if the file could not be saved.
bool migrate_legacy_user_filament_preset(const LegacyUserFilamentPreset &legacy);
//BBS: get user presets
int get_user_presets(PresetBundle *preset_bundle, std::vector<Preset> &result_presets);
void set_sync_info_and_save(std::string name, std::string setting_id, std::string syncinfo, long long update_time, const std::string& user_id);
@@ -909,10 +913,6 @@ public:
size_t num_default_presets() { return m_num_default_presets; }
protected:
// The system parent of a user preset whose compatible_printers is the parent's, or nullptr: the presets
// legacy_printer_migrations() considers.
const Preset* system_parent_with_inherited_printers(const Preset &preset) const;
PresetCollection() = default;
// Deleted by the std::recursive_mutex member. PresetBundle copies by assignment.
PresetCollection(const PresetCollection &other) = delete;
+17 -30
View File
@@ -25,7 +25,6 @@
#include <memory>
#include <initializer_list>
#include <map>
#include <mutex>
#include <iterator>
#include <functional>
#include <limits>
@@ -100,32 +99,19 @@ using json = nlohmann::json;
namespace Slic3r {
// Per current system filament preset, the printers it listed in an older release and no longer does
// (resources/info/legacy_compatible_printers.json, written by orca_profile_tool.py legacy-compat).
// The file ships with the build, so it is read once it opens; until then (e.g. presets loaded before
// resources_dir() is set) every call tries again and there are no legacy printers.
// Per system filament preset of an older release, by its name then, the printers it listed that the preset it
// now loads as does not (resources/info/legacy_compatible_printers.json, written by orca_profile_tool.py
// legacy-compat). Empty if the file is missing or malformed.
static std::map<std::string, std::vector<std::string>> legacy_compatible_printers()
{
static std::mutex mutex;
static std::map<std::string, std::vector<std::string>> printers_by_parent;
static bool read = false;
std::lock_guard<std::mutex> guard(mutex);
if (!read) {
const fs::path path = fs::path(resources_dir()) / "info" / "legacy_compatible_printers.json";
const fs::path path = fs::path(resources_dir()) / "info" / "legacy_compatible_printers.json";
try {
boost::nowide::ifstream in(path.string());
if (!in) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": " << path.string() << " not found";
return {};
}
read = true;
try {
printers_by_parent = json::parse(in).at("presets").get<std::map<std::string, std::vector<std::string>>>();
} catch (const std::exception &err) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not read " << path.string() << ": " << err.what();
}
return json::parse(in).at("presets").get<std::map<std::string, std::vector<std::string>>>();
} catch (const std::exception &err) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not read " << path.string() << ": " << err.what();
return {};
}
return printers_by_parent;
}
// Project-level options imported from a loaded 3MF into project_config. s_project_options_published
@@ -1085,7 +1071,8 @@ bool PresetBundle::backup_user_folder_to_zip(const std::string &zip_path) const
Zipper zipper(zip_path);
// Directories get their own entries, which extract_archive_confined() needs to recreate them.
zipper.add_entry(std::string(PRESET_USER_DIR) + "/", nullptr, 0);
for (const fs::directory_entry &entry : fs::recursive_directory_iterator(user_dir)) {
// The loader follows symlinked folders, and migration writes the presets in them.
for (const fs::directory_entry &entry : fs::recursive_directory_iterator(user_dir, fs::directory_options::follow_directory_symlink)) {
const std::string name = (fs::path(PRESET_USER_DIR) / entry.path().lexically_relative(user_dir)).generic_string();
if (fs::is_directory(entry.status())) {
zipper.add_entry(name + "/", nullptr, 0);
@@ -1109,20 +1096,20 @@ bool PresetBundle::backup_user_folder_to_zip(const std::string &zip_path) const
}
}
std::vector<LegacyPrinterMigration> PresetBundle::legacy_printer_migrations() const
std::vector<LegacyUserFilamentPreset> PresetBundle::legacy_user_filament_presets()
{
return filaments.legacy_printer_migrations(legacy_compatible_printers());
return filaments.legacy_user_filament_presets(legacy_compatible_printers());
}
std::string PresetBundle::migrate_legacy_printers(const std::vector<LegacyPrinterMigration> &migrations, std::vector<std::string> &failed)
std::string PresetBundle::migrate_legacy_user_filament_presets(const std::vector<LegacyUserFilamentPreset> &legacy_presets, std::vector<std::string> &failed)
{
const std::string zip_path = data_dir() + "/filament_preset_migration_" +
Utils::time2str(Utils::TimeZone::utc, Utils::TimeFormat::iso8601Z) + "_backup.zip";
if (!backup_user_folder_to_zip(zip_path))
return {};
for (const LegacyPrinterMigration &migration : migrations)
if (!filaments.apply_legacy_printer_migration(migration))
failed.push_back(migration.preset);
for (const LegacyUserFilamentPreset &legacy : legacy_presets)
if (!filaments.migrate_legacy_user_filament_preset(legacy))
failed.push_back(legacy.preset);
return zip_path;
}
+6 -6
View File
@@ -379,13 +379,13 @@ public:
// Writes the user preset folder into a zip archive at zip_path, its entries under "user/".
bool backup_user_folder_to_zip(const std::string &zip_path) const;
// User filament presets that no longer show on printers their parent listed in an older release
// (resources/info/legacy_compatible_printers.json).
std::vector<LegacyPrinterMigration> legacy_printer_migrations() const;
// Backs up the user preset folder into a zip in data_dir(), then writes each migration's printers into its
// preset file. Returns the zip's path, or an empty string when the backup failed and nothing was migrated.
// User filament presets made against an older release that no longer show on printers their parent
// listed then (resources/info/legacy_compatible_printers.json).
std::vector<LegacyUserFilamentPreset> legacy_user_filament_presets();
// Backs up the user preset folder into a zip in data_dir(), then writes each preset's printers into its
// file. Returns the zip's path, or an empty string when the backup failed and nothing was migrated.
// The presets that could not be migrated are added to failed.
std::string migrate_legacy_printers(const std::vector<LegacyPrinterMigration> &migrations, std::vector<std::string> &failed);
std::string migrate_legacy_user_filament_presets(const std::vector<LegacyUserFilamentPreset> &legacy_presets, std::vector<std::string> &failed);
//BBS: project embedded preset logic
PresetsConfigSubstitutions load_project_embedded_presets(std::vector<Preset*> project_presets, ForwardCompatibilitySubstitutionRule substitution_rule);
-2
View File
@@ -362,8 +362,6 @@ set(SLIC3R_GUI_SOURCES
GUI/Lazy.hpp
GUI/LazyPage.cpp
GUI/LazyPage.hpp
GUI/LegacyPrinterMigrationDialog.cpp
GUI/LegacyPrinterMigrationDialog.hpp
GUI/LibVGCode/LibVGCodeWrapper.hpp
GUI/LibVGCode/LibVGCodeWrapper.cpp
GUI/LinuxDisplayBackend.cpp
+32 -16
View File
@@ -12,7 +12,6 @@
#include "DeviceManager.hpp"
#include "HMS.hpp"
#include "PresetBundleDialog.hpp"
#include "LegacyPrinterMigrationDialog.hpp"
#include "WebUserLoginDialog.hpp"
#include "WebViewDialog.hpp"
#include "slic3r/Utils/BBLCloudServiceAgent.hpp"
@@ -1110,8 +1109,11 @@ void GUI_App::post_init()
}
this->check_new_version_sf();
if (!cw_showed)
this->check_legacy_printer_migration(false);
// Only presets made against 2.4.2 or older, the release legacy_compatible_printers.json is generated
// against, can be missing printers, so the prompt runs only on the first start after one of those.
if (!cw_showed && m_last_config_version && m_last_config_version->valid()
&& *m_last_config_version <= Semver(2, 4, 2))
this->check_legacy_user_filament_presets(false);
const auto cloud_provider = get_printer_cloud_provider();
if (is_user_login(cloud_provider) && !app_config->get_stealth_mode()) {
// this->check_privacy_version(0);
@@ -6819,42 +6821,56 @@ void GUI_App::reload_settings()
}
}
void GUI_App::check_legacy_printer_migration(bool by_user)
void GUI_App::check_legacy_user_filament_presets(bool by_user)
{
const std::vector<LegacyPrinterMigration> migrations = preset_bundle->legacy_printer_migrations();
if (migrations.empty()) {
if (!by_user && app_config->get_bool("legacy_user_filament_presets_dont_remind"))
return;
const std::vector<LegacyUserFilamentPreset> legacy_presets = preset_bundle->legacy_user_filament_presets();
if (legacy_presets.empty()) {
if (by_user)
MessageDialog(mainframe, _L("All your filament presets are available on the printers they were made for."),
_L("Migrate Filament Presets"), wxOK | wxICON_INFORMATION).ShowModal();
return;
}
if (!by_user && app_config->get_bool("legacy_printer_migration_dont_remind"))
return;
LegacyPrinterMigrationDialog dlg(mainframe, migrations, !by_user);
wxString message = _L("OrcaSlicer 2.5.0 restructured many system filament presets to fix incorrect profiles and prepare "
"for future features. As a result, the presets below no longer show on some printers they were made "
"for. Sorry for the trouble; this is a one-time fix.\n\n"
"Add those printers back to your presets now? Your presets are backed up first. You can also do this "
"later from Help > Migrate Filament Presets.") + "\n";
for (const LegacyUserFilamentPreset &legacy : legacy_presets) {
message += "\n" + format_wxstr(_L("%1% (based on %2%)"), legacy.preset, legacy.parent);
for (const std::string &printer : legacy.printers)
message += "\n " + from_u8(printer);
}
RichMessageDialog dlg(mainframe, message, _L("Migrate Filament Presets"), wxYES | wxNO | wxICON_QUESTION);
if (!by_user)
dlg.ShowCheckBox(_L("Don't remind me again"));
const bool migrate = dlg.ShowModal() == wxID_YES;
if (dlg.dont_remind())
app_config->set_bool("legacy_printer_migration_dont_remind", true);
if (dlg.IsCheckBoxChecked())
app_config->set_bool("legacy_user_filament_presets_dont_remind", true);
if (!migrate)
return;
std::vector<std::string> failed;
const std::string backup = preset_bundle->migrate_legacy_printers(migrations, failed);
const std::string backup = preset_bundle->migrate_legacy_user_filament_presets(legacy_presets, failed);
if (backup.empty()) {
show_error(mainframe, _L("Your presets could not be backed up, so they were not migrated."));
return;
}
if (failed.size() == legacy_presets.size()) {
show_error(mainframe, format_wxstr(_L("Your filament presets could not be migrated. A backup of your presets was saved to:\n%1%"), backup));
return;
}
preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
mainframe->update_side_preset_ui();
for (auto tab : tabs_list) {
tab->reload_config();
tab->update_changed_ui();
}
if (plater_)
plater_->sidebar().update_all_preset_comboboxes();
wxString message = format_wxstr(_L("Your filament presets were migrated. Select them again in the filament list where you used them.\n\n"
"A backup of your presets was saved to:\n%1%"), backup);
message = format_wxstr(_L("Your filament presets were migrated. Select them again in the filament list where you used them.\n\n"
"A backup of your presets was saved to:\n%1%"), backup);
if (!failed.empty()) {
message += "\n\n" + _L("These presets could not be migrated:");
for (const std::string &name : failed)
+4 -4
View File
@@ -567,10 +567,10 @@ public:
void check_update(bool show_tips, int by_user);
void check_new_version(bool show_tips = false, int by_user = 0);
void check_new_version_sf(bool show_tips = false, int by_user = 0);
// Offers to migrate user filament presets that lost printers their parent listed in an older release.
// At startup it asks once per release unless the user chose not to be reminded; by_user also reports
// when there is nothing to migrate.
void check_legacy_printer_migration(bool by_user);
// Offers to migrate user filament presets made against an older release that lost printers their parent
// listed then. At startup it runs only on the first start after 2.4.2 or older, unless the user chose not
// to be reminded; by_user also reports when there is nothing to migrate.
void check_legacy_user_filament_presets(bool by_user);
bool process_network_msg(std::string dev_id, std::string msg);
void request_new_version(int by_user);
void enter_force_upgrade();
@@ -1,96 +0,0 @@
#include "LegacyPrinterMigrationDialog.hpp"
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "GUI_Utils.hpp"
#include "I18N.hpp"
#include "MainFrame.hpp"
#include "format.hpp"
#include "libslic3r/Preset.hpp"
#include "Widgets/Button.hpp"
#include "Widgets/CheckBox.hpp"
#include "Widgets/DialogButtons.hpp"
#include "Widgets/Label.hpp"
#include <wx/event.h>
#include <wx/gdicmn.h>
#include <wx/sizer.h>
#include <wx/string.h>
#include <wx/textctrl.h>
#include <wx/toplevel.h>
#include <string>
#include <vector>
namespace Slic3r { namespace GUI {
LegacyPrinterMigrationDialog::LegacyPrinterMigrationDialog(wxWindow *parent, const std::vector<LegacyPrinterMigration> &migrations,
bool offer_dont_remind)
: DPIDialog(parent ? parent : static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Migrate Filament Presets"),
wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
SetBackgroundColour(*wxWHITE);
SetFont(Label::Body_14);
auto *sizer = new wxBoxSizer(wxVERTICAL);
auto *message = new Label(this,
_L("Since OrcaSlicer 2.5.0, filament presets have been restructured to support more features. Some of your "
"presets need to be migrated to the new structure, or they will no longer be available for some of your "
"printers.\n\n"
"Would you like to migrate them now? Your presets will be backed up first, and this only needs to be done "
"once. You can also do it later from Help > Migrate Filament Presets."),
0);
message->Wrap(FromDIP(520));
sizer->Add(message, 0, wxEXPAND | wxALL, FromDIP(15));
sizer->Add(new Label(this, _L("Affected presets:")), 0, wxLEFT | wxRIGHT, FromDIP(15));
sizer->AddSpacer(FromDIP(5));
wxString details;
for (const LegacyPrinterMigration &migration : migrations) {
details += format_wxstr(_L("%1% (based on %2%)"), migration.preset, migration.parent) + "\n";
for (const std::string &printer : migration.printers)
details += " " + from_u8(printer) + "\n";
}
auto *list = new wxTextCtrl(this, wxID_ANY, details, wxDefaultPosition, wxSize(-1, FromDIP(220)),
wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP);
sizer->Add(list, 1, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(15));
if (offer_dont_remind) {
auto *dont_remind_sizer = new wxBoxSizer(wxHORIZONTAL);
m_dont_remind = new ::CheckBox(this);
auto *dont_remind_label = new Label(this, _L("Don't remind me again"));
dont_remind_label->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
m_dont_remind->SetValue(!m_dont_remind->GetValue());
e.Skip();
});
dont_remind_sizer->Add(m_dont_remind, 0, wxALIGN_CENTER_VERTICAL);
dont_remind_sizer->Add(dont_remind_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(6));
sizer->Add(dont_remind_sizer, 0, wxLEFT | wxRIGHT | wxTOP, FromDIP(15));
}
auto *buttons = new DialogButtons(this, {"Yes", "No"}, "Yes");
buttons->GetYES()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { EndModal(wxID_YES); });
buttons->GetNO()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { EndModal(wxID_NO); });
sizer->Add(buttons, 0, wxEXPAND);
SetSizerAndFit(sizer);
CenterOnParent();
wxGetApp().UpdateDlgDarkUI(this);
}
bool LegacyPrinterMigrationDialog::dont_remind() const
{
return m_dont_remind != nullptr && m_dont_remind->GetValue();
}
void LegacyPrinterMigrationDialog::on_dpi_changed(const wxRect &)
{
if (m_dont_remind != nullptr)
m_dont_remind->Rescale();
GetSizer()->SetSizeHints(this);
Refresh();
}
}} // namespace Slic3r::GUI
@@ -1,34 +0,0 @@
#pragma once
#include "GUI_Utils.hpp"
#include <vector>
class CheckBox;
class wxWindow;
class wxRect;
namespace Slic3r {
struct LegacyPrinterMigration;
namespace GUI {
// Lists the user filament presets that no longer show on printers their parent listed in an older
// release, and asks whether to migrate them. ShowModal() returns wxID_YES to migrate. With
// offer_dont_remind it also offers to stop the startup reminder for good.
class LegacyPrinterMigrationDialog : public DPIDialog
{
public:
LegacyPrinterMigrationDialog(wxWindow *parent, const std::vector<LegacyPrinterMigration> &migrations, bool offer_dont_remind);
bool dont_remind() const;
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private:
::CheckBox *m_dont_remind{nullptr};
};
}} // namespace Slic3r::GUI
+1 -1
View File
@@ -2829,7 +2829,7 @@ wxMenu* MainFrame::generate_help_menu()
append_menu_item(helpMenu, wxID_ANY, _L("Migrate Filament Presets"),
_L("Bring back filament presets that a profile update removed from printers they were made for"),
[](wxCommandEvent&) { wxGetApp().check_legacy_printer_migration(true); });
[](wxCommandEvent&) { wxGetApp().check_legacy_user_filament_presets(true); });
helpMenu->AppendSeparator();
+1 -1
View File
@@ -590,7 +590,7 @@ std::vector<NativeCommand> build_command_catalog()
return AppActionRunResult{AppActionRunResult::Level::Success};
});
add("help_migrate_filament_presets", L("Migrate Filament Presets"), L("Help"), [](const std::string&) {
wxGetApp().check_legacy_printer_migration(true);
wxGetApp().check_legacy_user_filament_presets(true);
return AppActionRunResult{AppActionRunResult::Level::Success};
});
add("help_troubleshoot", L("Troubleshoot Center"), L("Help"), [](const std::string&) {