Reworked AppConfig to mark itself as dirty reliably with any configuration

change and saving AppConfig on idle.
This commit is contained in:
Vojtech Bubnik 2023-02-13 10:08:12 +01:00
parent db77331004
commit 8913fdf6ab
9 changed files with 182 additions and 140 deletions

View File

@ -487,6 +487,46 @@ void AppConfig::save()
m_dirty = false; m_dirty = false;
} }
bool AppConfig::erase(const std::string &section, const std::string &key)
{
if (auto it_storage = m_storage.find(section); it_storage != m_storage.end()) {
auto &section = it_storage->second;
auto it = section.find(key);
if (it != section.end()) {
section.erase(it);
m_dirty = true;
return true;
}
}
return false;
}
bool AppConfig::set_section(const std::string &section, std::map<std::string, std::string> data)
{
auto it_section = m_storage.find(section);
if (it_section == m_storage.end()) {
if (data.empty())
return false;
it_section = m_storage.insert({ section, {} }).first;
}
auto &dst = it_section->second;
if (dst == data)
return false;
dst = std::move(data);
m_dirty = true;
return true;
}
bool AppConfig::clear_section(const std::string &section)
{
if (auto it_section = m_storage.find(section); it_section != m_storage.end() && ! it_section->second.empty()) {
it_section->second.clear();
m_dirty = true;
return true;
}
return false;
}
bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
{ {
const auto it_v = m_vendors.find(vendor); const auto it_v = m_vendors.find(vendor);
@ -495,28 +535,47 @@ bool AppConfig::get_variant(const std::string &vendor, const std::string &model,
return it_m == it_v->second.end() ? false : it_m->second.find(variant) != it_m->second.end(); return it_m == it_v->second.end() ? false : it_m->second.find(variant) != it_m->second.end();
} }
void AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable) bool AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable)
{ {
if (enable) { if (enable) {
if (get_variant(vendor, model, variant)) { return; } if (get_variant(vendor, model, variant))
return false;
m_vendors[vendor][model].insert(variant); m_vendors[vendor][model].insert(variant);
} else { } else {
auto it_v = m_vendors.find(vendor); auto it_v = m_vendors.find(vendor);
if (it_v == m_vendors.end()) { return; } if (it_v == m_vendors.end())
return false;
auto it_m = it_v->second.find(model); auto it_m = it_v->second.find(model);
if (it_m == it_v->second.end()) { return; } if (it_m == it_v->second.end())
return false;
auto it_var = it_m->second.find(variant); auto it_var = it_m->second.find(variant);
if (it_var == it_m->second.end()) { return; } if (it_var == it_m->second.end())
return false;
it_m->second.erase(it_var); it_m->second.erase(it_var);
} }
// If we got here, there was an update // If we got here, there was an update
m_dirty = true; m_dirty = true;
return true;
} }
void AppConfig::set_vendors(const AppConfig &from) bool AppConfig::set_vendors(const VendorMap &vendors)
{ {
m_vendors = from.m_vendors; if (m_vendors != vendors) {
m_dirty = true; m_vendors = vendors;
m_dirty = true;
return true;
} else
return false;
}
bool AppConfig::set_vendors(VendorMap &&vendors)
{
if (m_vendors != vendors) {
m_vendors = std::move(vendors);
m_dirty = true;
return true;
} else
return false;
} }
std::string AppConfig::get_last_dir() const std::string AppConfig::get_last_dir() const
@ -551,34 +610,52 @@ std::vector<std::string> AppConfig::get_recent_projects() const
return ret; return ret;
} }
void AppConfig::set_recent_projects(const std::vector<std::string>& recent_projects) bool AppConfig::set_recent_projects(const std::vector<std::string>& recent_projects)
{ {
auto it = m_storage.find("recent_projects"); static constexpr const char *section = "recent_projects";
if (it == m_storage.end()) auto it_section = m_storage.find(section);
it = m_storage.insert(std::map<std::string, std::map<std::string, std::string>>::value_type("recent_projects", std::map<std::string, std::string>())).first; if (it_section == m_storage.end()) {
if (recent_projects.empty())
it->second.clear(); return false;
for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i) it_section = m_storage.insert({ std::string(section), {} }).first;
{
it->second[std::to_string(i + 1)] = recent_projects[i];
} }
auto &dst = it_section->second;
std::map<std::string, std::string> src;
for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i)
src[std::to_string(i + 1)] = recent_projects[i];
if (src != dst) {
dst = std::move(src);
m_dirty = true;
return true;
} else
return false;
} }
void AppConfig::set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, bool AppConfig::set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone,
float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz) float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz)
{ {
std::string key = std::string("mouse_device:") + name; const std::string key = std::string("mouse_device:") + name;
auto it = m_storage.find(key); auto it_section = m_storage.find(key);
if (it == m_storage.end()) if (it_section == m_storage.end())
it = m_storage.insert(std::map<std::string, std::map<std::string, std::string>>::value_type(key, std::map<std::string, std::string>())).first; it_section = m_storage.insert({ key, {} }).first;
auto &dst = it_section->second;
it->second.clear(); std::map<std::string, std::string> src;
it->second["translation_speed"] = float_to_string_decimal_point(translation_speed); src["translation_speed"] = float_to_string_decimal_point(translation_speed);
it->second["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone); src["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone);
it->second["rotation_speed"] = float_to_string_decimal_point(rotation_speed); src["rotation_speed"] = float_to_string_decimal_point(rotation_speed);
it->second["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone); src["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone);
it->second["zoom_speed"] = float_to_string_decimal_point(zoom_speed); src["zoom_speed"] = float_to_string_decimal_point(zoom_speed);
it->second["swap_yz"] = swap_yz ? "1" : "0"; src["swap_yz"] = swap_yz ? "1" : "0";
if (src != dst) {
dst = std::move(src);
m_dirty = true;
return true;
} else
return false;
} }
std::vector<std::string> AppConfig::get_mouse_device_names() const std::vector<std::string> AppConfig::get_mouse_device_names() const
@ -592,16 +669,16 @@ std::vector<std::string> AppConfig::get_mouse_device_names() const
return out; return out;
} }
void AppConfig::update_config_dir(const std::string &dir) bool AppConfig::update_config_dir(const std::string &dir)
{ {
this->set("recent", "config_directory", dir); return this->set("recent", "config_directory", dir);
} }
void AppConfig::update_skein_dir(const std::string &dir) bool AppConfig::update_skein_dir(const std::string &dir)
{ {
if (is_shapes_dir(dir)) if (is_shapes_dir(dir))
return; // do not save "shapes gallery" directory return false; // do not save "shapes gallery" directory
this->set("recent", "skein_directory", dir); return this->set("recent", "skein_directory", dir);
} }
/* /*
std::string AppConfig::get_last_output_dir(const std::string &alt) const std::string AppConfig::get_last_output_dir(const std::string &alt) const
@ -636,9 +713,9 @@ std::string AppConfig::get_last_output_dir(const std::string& alt, const bool re
return is_shapes_dir(alt) ? get_last_dir() : alt; return is_shapes_dir(alt) ? get_last_dir() : alt;
} }
void AppConfig::update_last_output_dir(const std::string& dir, const bool removable) bool AppConfig::update_last_output_dir(const std::string& dir, const bool removable)
{ {
this->set("", (removable ? "last_output_path_removable" : "last_output_path"), dir); return this->set("", (removable ? "last_output_path_removable" : "last_output_path"), dir);
} }
@ -656,7 +733,7 @@ void AppConfig::reset_selections()
} }
} }
std::string AppConfig::config_path() std::string AppConfig::config_path() const
{ {
std::string path = (m_mode == EAppMode::Editor) ? std::string path = (m_mode == EAppMode::Editor) ?
(boost::filesystem::path(Slic3r::data_dir()) / (SLIC3R_APP_KEY ".ini")).make_preferred().string() : (boost::filesystem::path(Slic3r::data_dir()) / (SLIC3R_APP_KEY ".ini")).make_preferred().string() :
@ -691,7 +768,7 @@ std::string AppConfig::profile_folder_url() const
return PROFILE_FOLDER_URL; return PROFILE_FOLDER_URL;
} }
bool AppConfig::exists() bool AppConfig::exists() const
{ {
return boost::filesystem::exists(config_path()); return boost::filesystem::exists(config_path());
} }

View File

@ -58,9 +58,13 @@ public:
} }
std::string get(const std::string &section, const std::string &key) const std::string get(const std::string &section, const std::string &key) const
{ std::string value; this->get(section, key, value); return value; } { std::string value; this->get(section, key, value); return value; }
bool get_bool(const std::string &section, const std::string &key) const
{ return this->get(section, key) == "1"; }
std::string get(const std::string &key) const std::string get(const std::string &key) const
{ std::string value; this->get("", key, value); return value; } { std::string value; this->get("", key, value); return value; }
void set(const std::string &section, const std::string &key, const std::string &value) bool get_bool(const std::string &key) const
{ return this->get(key) == "1"; }
bool set(const std::string &section, const std::string &key, const std::string &value)
{ {
#ifndef NDEBUG #ifndef NDEBUG
{ {
@ -74,10 +78,12 @@ public:
if (old != value) { if (old != value) {
old = value; old = value;
m_dirty = true; m_dirty = true;
return true;
} }
return false;
} }
void set(const std::string &key, const std::string &value) bool set(const std::string &key, const std::string &value)
{ this->set("", key, value); } { return this->set("", key, value); }
bool has(const std::string &section, const std::string &key) const bool has(const std::string &section, const std::string &key) const
{ {
auto it = m_storage.find(section); auto it = m_storage.find(section);
@ -89,40 +95,32 @@ public:
bool has(const std::string &key) const bool has(const std::string &key) const
{ return this->has("", key); } { return this->has("", key); }
void erase(const std::string &section, const std::string &key) bool erase(const std::string &section, const std::string &key);
{
auto it = m_storage.find(section);
if (it != m_storage.end()) {
it->second.erase(key);
}
}
bool has_section(const std::string &section) const bool has_section(const std::string &section) const
{ return m_storage.find(section) != m_storage.end(); } { return m_storage.find(section) != m_storage.end(); }
const std::map<std::string, std::string>& get_section(const std::string &section) const const std::map<std::string, std::string>& get_section(const std::string &section) const
{ auto it = m_storage.find(section); assert(it != m_storage.end()); return it->second; } { auto it = m_storage.find(section); assert(it != m_storage.end()); return it->second; }
void set_section(const std::string &section, const std::map<std::string, std::string>& data) bool set_section(const std::string &section, std::map<std::string, std::string> data);
{ m_storage[section] = data; } bool clear_section(const std::string &section);
void clear_section(const std::string &section)
{ m_storage[section].clear(); }
typedef std::map<std::string, std::map<std::string, std::set<std::string>>> VendorMap; typedef std::map<std::string, std::map<std::string, std::set<std::string>>> VendorMap;
bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const; bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const;
void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable); bool set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable);
void set_vendors(const AppConfig &from); bool set_vendors(const AppConfig &from) { return this->set_vendors(from.vendors()); }
void set_vendors(const VendorMap &vendors) { m_vendors = vendors; m_dirty = true; } bool set_vendors(const VendorMap &vendors);
void set_vendors(VendorMap &&vendors) { m_vendors = std::move(vendors); m_dirty = true; } bool set_vendors(VendorMap &&vendors);
const VendorMap& vendors() const { return m_vendors; } const VendorMap& vendors() const { return m_vendors; }
// return recent/skein_directory or recent/config_directory or empty string. // return recent/skein_directory or recent/config_directory or empty string.
std::string get_last_dir() const; std::string get_last_dir() const;
void update_config_dir(const std::string &dir); bool update_config_dir(const std::string &dir);
void update_skein_dir(const std::string &dir); bool update_skein_dir(const std::string &dir);
//std::string get_last_output_dir(const std::string &alt) const; //std::string get_last_output_dir(const std::string &alt) const;
//void update_last_output_dir(const std::string &dir); //void update_last_output_dir(const std::string &dir);
std::string get_last_output_dir(const std::string& alt, const bool removable = false) const; std::string get_last_output_dir(const std::string& alt, const bool removable = false) const;
void update_last_output_dir(const std::string &dir, const bool removable = false); bool update_last_output_dir(const std::string &dir, const bool removable = false);
// reset the current print / filament / printer selections, so that // reset the current print / filament / printer selections, so that
// the PresetBundle::load_selections(const AppConfig &config) call will select // the PresetBundle::load_selections(const AppConfig &config) call will select
@ -130,7 +128,7 @@ public:
void reset_selections(); void reset_selections();
// Get the default config path from Slic3r::data_dir(). // Get the default config path from Slic3r::data_dir().
std::string config_path(); std::string config_path() const;
// Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating) // Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
bool legacy_datadir() const { return m_legacy_datadir; } bool legacy_datadir() const { return m_legacy_datadir; }
@ -140,9 +138,9 @@ public:
// This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file. // This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file.
std::string version_check_url() const; std::string version_check_url() const;
// Get the Slic3r url to vendor index archive zip. // Get the Slic3r url to vendor index archive zip.
std::string index_archive_url() const; std::string index_archive_url() const;
// Get the Slic3r url to folder with vendor profile files. // Get the Slic3r url to folder with vendor profile files.
std::string profile_folder_url() const; std::string profile_folder_url() const;
// Returns the original Slic3r version found in the ini file before it was overwritten // Returns the original Slic3r version found in the ini file before it was overwritten
@ -150,12 +148,12 @@ public:
Semver orig_version() const { return m_orig_version; } Semver orig_version() const { return m_orig_version; }
// Does the config file exist? // Does the config file exist?
bool exists(); bool exists() const;
std::vector<std::string> get_recent_projects() const; std::vector<std::string> get_recent_projects() const;
void set_recent_projects(const std::vector<std::string>& recent_projects); bool set_recent_projects(const std::vector<std::string>& recent_projects);
void set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz); bool set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz);
std::vector<std::string> get_mouse_device_names() const; std::vector<std::string> get_mouse_device_names() const;
bool get_mouse_device_translation_speed(const std::string& name, double& speed) const bool get_mouse_device_translation_speed(const std::string& name, double& speed) const
{ return get_3dmouse_device_numeric_value(name, "translation_speed", speed); } { return get_3dmouse_device_numeric_value(name, "translation_speed", speed); }

View File

@ -4710,12 +4710,6 @@ CLIMiscConfigDef::CLIMiscConfigDef()
"or an existing PrusaSlicer window is activated. " "or an existing PrusaSlicer window is activated. "
"Overrides the \"single_instance\" configuration value from application preferences."); "Overrides the \"single_instance\" configuration value from application preferences.");
/*
def = this->add("autosave", coString);
def->label = L("Autosave");
def->tooltip = L("Automatically export current configuration to the specified file.");
*/
def = this->add("datadir", coString); def = this->add("datadir", coString);
def->label = L("Data directory"); def->label = L("Data directory");
def->tooltip = L("Load and store settings at the given directory. This is useful for maintaining different profiles or including configurations from a network storage."); def->tooltip = L("Load and store settings at the given directory. This is useful for maintaining different profiles or including configurations from a network storage.");

View File

@ -36,10 +36,8 @@ void Camera::set_type(EType type)
{ {
if (m_type != type && (type == EType::Ortho || type == EType::Perspective)) { if (m_type != type && (type == EType::Ortho || type == EType::Perspective)) {
m_type = type; m_type = type;
if (m_update_config_on_type_change_enabled) { if (m_update_config_on_type_change_enabled)
wxGetApp().app_config->set("use_perspective_camera", (m_type == EType::Perspective) ? "1" : "0"); wxGetApp().app_config->set("use_perspective_camera", (m_type == EType::Perspective) ? "1" : "0");
wxGetApp().app_config->save();
}
} }
} }

View File

@ -804,7 +804,7 @@ void GUI_App::post_init()
} }
// show "Did you know" notification // show "Did you know" notification
if (app_config->get("show_hints") == "1" && ! is_gcode_viewer()) if (app_config->get_bool("show_hints") && ! is_gcode_viewer())
plater_->get_notification_manager()->push_hint_notification(true); plater_->get_notification_manager()->push_hint_notification(true);
// The extra CallAfter() is needed because of Mac, where this is the only way // The extra CallAfter() is needed because of Mac, where this is the only way
@ -832,7 +832,6 @@ void GUI_App::post_init()
// Set PrusaSlicer version and save to PrusaSlicer.ini or PrusaSlicerGcodeViewer.ini. // Set PrusaSlicer version and save to PrusaSlicer.ini or PrusaSlicerGcodeViewer.ini.
app_config->set("version", SLIC3R_VERSION); app_config->set("version", SLIC3R_VERSION);
app_config->save();
#ifdef _WIN32 #ifdef _WIN32
// Sets window property to mainframe so other instances can indentify it. // Sets window property to mainframe so other instances can indentify it.
@ -859,14 +858,9 @@ GUI_App::GUI_App(EAppMode mode)
GUI_App::~GUI_App() GUI_App::~GUI_App()
{ {
if (app_config != nullptr) delete app_config;
delete app_config; delete preset_bundle;
delete preset_updater;
if (preset_bundle != nullptr)
delete preset_bundle;
if (preset_updater != nullptr)
delete preset_updater;
} }
// If formatted for github, plaintext with OpenGL extensions enclosed into <details>. // If formatted for github, plaintext with OpenGL extensions enclosed into <details>.
@ -1145,8 +1139,8 @@ bool GUI_App::on_init_inner()
// If load_language() fails, the application closes. // If load_language() fails, the application closes.
load_language(wxString(), true); load_language(wxString(), true);
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
bool init_dark_color_mode = app_config->get("dark_color_mode") == "1"; bool init_dark_color_mode = app_config->get_bool("dark_color_mode");
bool init_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1"; bool init_sys_menu_enabled = app_config->get_bool("sys_menu_enabled");
NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled); NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled);
#endif #endif
// initialize label colors and fonts // initialize label colors and fonts
@ -1169,13 +1163,13 @@ bool GUI_App::on_init_inner()
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
// app_config can be updated in check_older_app_config(), so check if dark_color_mode and sys_menu_enabled was changed // app_config can be updated in check_older_app_config(), so check if dark_color_mode and sys_menu_enabled was changed
if (bool new_dark_color_mode = app_config->get("dark_color_mode") == "1"; if (bool new_dark_color_mode = app_config->get_bool("dark_color_mode");
init_dark_color_mode != new_dark_color_mode) { init_dark_color_mode != new_dark_color_mode) {
NppDarkMode::SetDarkMode(new_dark_color_mode); NppDarkMode::SetDarkMode(new_dark_color_mode);
init_ui_colours(); init_ui_colours();
update_ui_colours_from_appconfig(); update_ui_colours_from_appconfig();
} }
if (bool new_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1"; if (bool new_sys_menu_enabled = app_config->get_bool("sys_menu_enabled");
init_sys_menu_enabled != new_sys_menu_enabled) init_sys_menu_enabled != new_sys_menu_enabled)
NppDarkMode::SetSystemMenuForApp(new_sys_menu_enabled); NppDarkMode::SetSystemMenuForApp(new_sys_menu_enabled);
#endif #endif
@ -1201,7 +1195,7 @@ bool GUI_App::on_init_inner()
} }
SplashScreen* scrn = nullptr; SplashScreen* scrn = nullptr;
if (app_config->get("show_splash_screen") == "1") { if (app_config->get_bool("show_splash_screen")) {
// make a bitmap with dark grey banner on the left side // make a bitmap with dark grey banner on the left side
wxBitmap bmp = SplashScreen::MakeBitmap(wxBitmap(from_u8(var(is_editor() ? "splashscreen.jpg" : "splashscreen-gcodepreview.jpg")), wxBITMAP_TYPE_JPEG)); wxBitmap bmp = SplashScreen::MakeBitmap(wxBitmap(from_u8(var(is_editor() ? "splashscreen.jpg" : "splashscreen-gcodepreview.jpg")), wxBITMAP_TYPE_JPEG));
@ -1248,9 +1242,9 @@ bool GUI_App::on_init_inner()
if (is_editor()) { if (is_editor()) {
#ifdef __WXMSW__ #ifdef __WXMSW__
if (app_config->get("associate_3mf") == "1") if (app_config->get_bool("associate_3mf"))
associate_3mf_files(); associate_3mf_files();
if (app_config->get("associate_stl") == "1") if (app_config->get_bool("associate_stl"))
associate_stl_files(); associate_stl_files();
#endif // __WXMSW__ #endif // __WXMSW__
@ -1290,14 +1284,14 @@ bool GUI_App::on_init_inner()
} }
else { else {
#ifdef __WXMSW__ #ifdef __WXMSW__
if (app_config->get("associate_gcode") == "1") if (app_config->get_bool("associate_gcode"))
associate_gcode_files(); associate_gcode_files();
#endif // __WXMSW__ #endif // __WXMSW__
} }
std::string delayed_error_load_presets; std::string delayed_error_load_presets;
// Suppress the '- default -' presets. // Suppress the '- default -' presets.
preset_bundle->set_default_suppressed(app_config->get("no_defaults") == "1"); preset_bundle->set_default_suppressed(app_config->get_bool("no_defaults"));
try { try {
// Enable all substitutions (in both user and system profiles), but log the substitutions in user profiles only. // 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 // If there are substitutions in system profiles, then a "reconfigure" event shall be triggered, which will force
@ -1387,7 +1381,7 @@ bool GUI_App::on_init_inner()
this->post_init(); this->post_init();
} }
if (m_post_initialized && app_config->dirty() && app_config->get("autosave") == "1") if (m_post_initialized && app_config->dirty())
app_config->save(); app_config->save();
}); });
@ -1448,7 +1442,7 @@ bool GUI_App::dark_mode()
return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode(); return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode();
#else #else
if (wxGetApp().app_config->has("dark_color_mode")) if (wxGetApp().app_config->has("dark_color_mode"))
return wxGetApp().app_config->get("dark_color_mode") == "1"; return wxGetApp().app_config->get_bool("dark_color_mode");
return check_dark_mode(); return check_dark_mode();
#endif #endif
} }
@ -1685,7 +1679,6 @@ void GUI_App::set_label_clr_modified(const wxColour& clr)
m_color_label_modified = clr; m_color_label_modified = clr;
const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
app_config->set("label_clr_modified", str); app_config->set("label_clr_modified", str);
app_config->save();
} }
void GUI_App::set_label_clr_sys(const wxColour& clr) void GUI_App::set_label_clr_sys(const wxColour& clr)
@ -1695,7 +1688,6 @@ void GUI_App::set_label_clr_sys(const wxColour& clr)
m_color_label_sys = clr; m_color_label_sys = clr;
const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
app_config->set("label_clr_sys", str); app_config->set("label_clr_sys", str);
app_config->save();
} }
const std::string& GUI_App::get_mode_btn_color(int mode_id) const std::string& GUI_App::get_mode_btn_color(int mode_id)
@ -1727,13 +1719,12 @@ void GUI_App::set_mode_palette(const std::vector<wxColour>& palette)
if (save) { if (save) {
mainframe->update_mode_markers(); mainframe->update_mode_markers();
app_config->set("mode_palette", escape_strings_cstyle(m_mode_palette)); app_config->set("mode_palette", escape_strings_cstyle(m_mode_palette));
app_config->save();
} }
} }
bool GUI_App::tabs_as_menu() const bool GUI_App::tabs_as_menu() const
{ {
return app_config->get("tabs_as_menu") == "1"; // || dark_mode(); return app_config->get_bool("tabs_as_menu"); // || dark_mode();
} }
wxSize GUI_App::get_min_size() const wxSize GUI_App::get_min_size() const
@ -1902,14 +1893,14 @@ static void update_scrolls(wxWindow* window)
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
void GUI_App::force_menu_update() void GUI_App::force_menu_update()
{ {
NppDarkMode::SetSystemMenuForApp(app_config->get("sys_menu_enabled") == "1"); NppDarkMode::SetSystemMenuForApp(app_config->get_bool("sys_menu_enabled"));
} }
#endif //_MSW_DARK_MODE #endif //_MSW_DARK_MODE
void GUI_App::force_colors_update() void GUI_App::force_colors_update()
{ {
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
NppDarkMode::SetDarkMode(app_config->get("dark_color_mode") == "1"); NppDarkMode::SetDarkMode(app_config->get_bool("dark_color_mode"));
if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl()) if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl())
NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND); NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND);
NppDarkMode::SetDarkTitleBar(mainframe->GetHWND()); NppDarkMode::SetDarkTitleBar(mainframe->GetHWND());
@ -2158,7 +2149,6 @@ bool GUI_App::select_language()
// m_wxLocale->GetCanonicalName() // m_wxLocale->GetCanonicalName()
// 3) new_language_info->CanonicalName is a safe bet. It points to a valid dictionary name. // 3) new_language_info->CanonicalName is a safe bet. It points to a valid dictionary name.
app_config->set("translation_language", new_language_info->CanonicalName.ToUTF8().data()); app_config->set("translation_language", new_language_info->CanonicalName.ToUTF8().data());
app_config->save();
return true; return true;
} }
} }
@ -2367,7 +2357,6 @@ bool GUI_App::save_mode(const /*ConfigOptionMode*/int mode)
return false; return false;
} }
app_config->set("view_mode", mode_str); app_config->set("view_mode", mode_str);
app_config->save();
update_mode(); update_mode();
return true; return true;
} }
@ -2569,13 +2558,13 @@ void GUI_App::open_preferences(const std::string& highlight_option /*= std::stri
#ifdef _WIN32 #ifdef _WIN32
if (is_editor()) { if (is_editor()) {
if (app_config->get("associate_3mf") == "1") if (app_config->get_bool("associate_3mf"))
associate_3mf_files(); associate_3mf_files();
if (app_config->get("associate_stl") == "1") if (app_config->get_bool("associate_stl"))
associate_stl_files(); associate_stl_files();
} }
else { else {
if (app_config->get("associate_gcode") == "1") if (app_config->get_bool("associate_gcode"))
associate_gcode_files(); associate_gcode_files();
} }
#endif // _WIN32 #endif // _WIN32
@ -3178,7 +3167,6 @@ void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name)
WindowMetrics metrics = WindowMetrics::from_window(window); WindowMetrics metrics = WindowMetrics::from_window(window);
app_config->set(config_key, metrics.serialize()); app_config->set(config_key, metrics.serialize());
app_config->save();
} }
void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized) void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized)
@ -3372,7 +3360,6 @@ void GUI_App::associate_gcode_files()
void GUI_App::on_version_read(wxCommandEvent& evt) void GUI_App::on_version_read(wxCommandEvent& evt)
{ {
app_config->set("version_online", into_u8(evt.GetString())); app_config->set("version_online", into_u8(evt.GetString()));
app_config->save();
std::string opt = app_config->get("notify_release"); std::string opt = app_config->get("notify_release");
if (this->plater_ == nullptr || (!m_app_updater->get_triggered_by_user() && opt != "all" && opt != "release")) { if (this->plater_ == nullptr || (!m_app_updater->get_triggered_by_user() && opt != "all" && opt != "release")) {
BOOST_LOG_TRIVIAL(info) << "Version online: " << evt.GetString() << ". User does not wish to be notified."; BOOST_LOG_TRIVIAL(info) << "Version online: " << evt.GetString() << ". User does not wish to be notified.";

View File

@ -56,7 +56,6 @@ int GUI_Run(GUI_InitParams &params)
} }
} }
// gui->autosave = m_config.opt_string("autosave");
GUI::GUI_App::SetInstance(gui); GUI::GUI_App::SetInstance(gui);
gui->init_params = &params; gui->init_params = &params;
return wxEntry(params.argc, params.argv); return wxEntry(params.argc, params.argv);

View File

@ -652,7 +652,8 @@ void MainFrame::shutdown()
wxGetApp().other_instance_message_handler()->shutdown(this); wxGetApp().other_instance_message_handler()->shutdown(this);
// Save the slic3r.ini.Usually the ini file is saved from "on idle" callback, // Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
// but in rare cases it may not have been called yet. // but in rare cases it may not have been called yet.
wxGetApp().app_config->save(); if (wxGetApp().app_config->dirty())
wxGetApp().app_config->save();
// if (m_plater) // if (m_plater)
// m_plater->print = undef; // m_plater->print = undef;
// Slic3r::GUI::deregister_on_request_update_callback(); // Slic3r::GUI::deregister_on_request_update_callback();
@ -1253,7 +1254,6 @@ void MainFrame::init_menubar_as_editor()
recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i))); recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i)));
} }
wxGetApp().app_config->set_recent_projects(recent_projects); wxGetApp().app_config->set_recent_projects(recent_projects);
wxGetApp().app_config->save();
} }
} }
}, wxID_FILE1, wxID_FILE9); }, wxID_FILE1, wxID_FILE9);
@ -2182,7 +2182,6 @@ void MainFrame::add_to_recent_projects(const wxString& filename)
recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i))); recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i)));
} }
wxGetApp().app_config->set_recent_projects(recent_projects); wxGetApp().app_config->set_recent_projects(recent_projects);
wxGetApp().app_config->save();
} }
} }

View File

@ -464,7 +464,6 @@ void PreferencesDialog::build()
m_icon_size_sizer->ShowItems(boost::any_cast<bool>(value)); m_icon_size_sizer->ShowItems(boost::any_cast<bool>(value));
refresh_og(m_optgroup_gui); refresh_og(m_optgroup_gui);
get_app_config()->set("use_custom_toolbar_size", boost::any_cast<bool>(value) ? "1" : "0"); get_app_config()->set("use_custom_toolbar_size", boost::any_cast<bool>(value) ? "1" : "0");
get_app_config()->save();
wxGetApp().plater()->get_current_canvas3D()->render(); wxGetApp().plater()->get_current_canvas3D()->render();
return; return;
} }
@ -768,7 +767,6 @@ void PreferencesDialog::accept(wxEvent&)
for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it) for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it)
app_config->set(it->first, it->second); app_config->set(it->first, it->second);
app_config->save();
if (wxGetApp().is_editor()) { if (wxGetApp().is_editor()) {
wxGetApp().set_label_clr_sys(m_sys_colour->GetColour()); wxGetApp().set_label_clr_sys(m_sys_colour->GetColour());
wxGetApp().set_label_clr_modified(m_mod_colour->GetColour()); wxGetApp().set_label_clr_modified(m_mod_colour->GetColour());
@ -797,23 +795,17 @@ void PreferencesDialog::revert(wxEvent&)
{ {
auto app_config = get_app_config(); auto app_config = get_app_config();
bool save_app_config = false;
if (m_custom_toolbar_size != atoi(app_config->get("custom_toolbar_size").c_str())) { if (m_custom_toolbar_size != atoi(app_config->get("custom_toolbar_size").c_str())) {
app_config->set("custom_toolbar_size", (boost::format("%d") % m_custom_toolbar_size).str()); app_config->set("custom_toolbar_size", (boost::format("%d") % m_custom_toolbar_size).str());
m_icon_size_slider->SetValue(m_custom_toolbar_size); m_icon_size_slider->SetValue(m_custom_toolbar_size);
save_app_config |= true;
} }
if (m_use_custom_toolbar_size != (get_app_config()->get("use_custom_toolbar_size") == "1")) { if (m_use_custom_toolbar_size != (get_app_config()->get("use_custom_toolbar_size") == "1")) {
app_config->set("use_custom_toolbar_size", m_use_custom_toolbar_size ? "1" : "0"); app_config->set("use_custom_toolbar_size", m_use_custom_toolbar_size ? "1" : "0");
save_app_config |= true;
m_optgroup_gui->set_value("use_custom_toolbar_size", m_use_custom_toolbar_size); m_optgroup_gui->set_value("use_custom_toolbar_size", m_use_custom_toolbar_size);
m_icon_size_sizer->ShowItems(m_use_custom_toolbar_size); m_icon_size_sizer->ShowItems(m_use_custom_toolbar_size);
refresh_og(m_optgroup_gui); refresh_og(m_optgroup_gui);
} }
if (save_app_config)
app_config->save();
for (auto value : m_values) { for (auto value : m_values) {
const std::string& key = value.first; const std::string& key = value.first;
@ -955,7 +947,6 @@ void PreferencesDialog::create_icon_size_slider()
auto val = m_icon_size_slider->GetValue(); auto val = m_icon_size_slider->GetValue();
app_config->set("custom_toolbar_size", (boost::format("%d") % val).str()); app_config->set("custom_toolbar_size", (boost::format("%d") % val).str());
app_config->save();
wxGetApp().plater()->get_current_canvas3D()->render(); wxGetApp().plater()->get_current_canvas3D()->render();
if (val_label) if (val_label)

View File

@ -121,37 +121,37 @@ void EmbossStylesSerializable::store_style(AppConfig & cfg,
const EmbossStyle &fi, const EmbossStyle &fi,
unsigned index) unsigned index)
{ {
std::string section_name = create_section_name(index); std::map<std::string, std::string> data;
cfg.clear_section(section_name); data[APP_CONFIG_FONT_NAME] = fi.name;
cfg.set(section_name, APP_CONFIG_FONT_NAME, fi.name); data[APP_CONFIG_FONT_DESCRIPTOR] = fi.path;
cfg.set(section_name, APP_CONFIG_FONT_DESCRIPTOR, fi.path);
const FontProp &fp = fi.prop; const FontProp &fp = fi.prop;
cfg.set(section_name, APP_CONFIG_FONT_LINE_HEIGHT, std::to_string(fp.size_in_mm)); data[APP_CONFIG_FONT_LINE_HEIGHT] = std::to_string(fp.size_in_mm);
cfg.set(section_name, APP_CONFIG_FONT_DEPTH, std::to_string(fp.emboss)); data[APP_CONFIG_FONT_DEPTH] = std::to_string(fp.emboss);
if (fp.use_surface) if (fp.use_surface)
cfg.set(section_name, APP_CONFIG_FONT_USE_SURFACE, "true"); data[APP_CONFIG_FONT_USE_SURFACE] = "true";
if (fp.boldness.has_value()) if (fp.boldness.has_value())
cfg.set(section_name, APP_CONFIG_FONT_BOLDNESS, std::to_string(*fp.boldness)); data[APP_CONFIG_FONT_BOLDNESS] = std::to_string(*fp.boldness);
if (fp.skew.has_value()) if (fp.skew.has_value())
cfg.set(section_name, APP_CONFIG_FONT_SKEW, std::to_string(*fp.skew)); data[APP_CONFIG_FONT_SKEW] = std::to_string(*fp.skew);
if (fp.distance.has_value()) if (fp.distance.has_value())
cfg.set(section_name, APP_CONFIG_FONT_DISTANCE, std::to_string(*fp.distance)); data[APP_CONFIG_FONT_DISTANCE] = std::to_string(*fp.distance);
if (fp.angle.has_value()) if (fp.angle.has_value())
cfg.set(section_name, APP_CONFIG_FONT_ANGLE, std::to_string(*fp.angle)); data[APP_CONFIG_FONT_ANGLE] = std::to_string(*fp.angle);
if (fp.collection_number.has_value()) if (fp.collection_number.has_value())
cfg.set(section_name, APP_CONFIG_FONT_COLLECTION, std::to_string(*fp.collection_number)); data[APP_CONFIG_FONT_COLLECTION] = std::to_string(*fp.collection_number);
if (fp.char_gap.has_value()) if (fp.char_gap.has_value())
cfg.set(section_name, APP_CONFIG_FONT_CHAR_GAP, std::to_string(*fp.char_gap)); data[APP_CONFIG_FONT_CHAR_GAP] = std::to_string(*fp.char_gap);
if (fp.line_gap.has_value()) if (fp.line_gap.has_value())
cfg.set(section_name, APP_CONFIG_FONT_LINE_GAP, std::to_string(*fp.line_gap)); data[APP_CONFIG_FONT_LINE_GAP] = std::to_string(*fp.line_gap);
cfg.set_section(create_section_name(index), std::move(data));
} }
void EmbossStylesSerializable::store_style_index(AppConfig &cfg, unsigned index) { void EmbossStylesSerializable::store_style_index(AppConfig &cfg, unsigned index) {
// store actual font index // store actual font index
cfg.clear_section(AppConfig::SECTION_EMBOSS_STYLE); // active font first index is +1 to correspond with section name
// activ font first index is +1 to correspond with section name std::map<std::string, std::string> data;
std::string active_font = std::to_string(index); data[APP_CONFIG_ACTIVE_FONT] = std::to_string(index);
cfg.set(AppConfig::SECTION_EMBOSS_STYLE, APP_CONFIG_ACTIVE_FONT, active_font); cfg.set_section(AppConfig::SECTION_EMBOSS_STYLE, std::move(data));
} }
std::optional<size_t> EmbossStylesSerializable::load_style_index(const AppConfig &cfg) std::optional<size_t> EmbossStylesSerializable::load_style_index(const AppConfig &cfg)
@ -198,5 +198,4 @@ void EmbossStylesSerializable::store_styles(AppConfig &cfg, const EmbossStyles&
cfg.clear_section(section_name); cfg.clear_section(section_name);
section_name = create_section_name(++index); section_name = create_section_name(++index);
} }
cfg.save();
} }