From 8913fdf6abda7e86b0148333bb05a808f622047a Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 13 Feb 2023 10:08:12 +0100 Subject: [PATCH 1/7] Reworked AppConfig to mark itself as dirty reliably with any configuration change and saving AppConfig on idle. --- src/libslic3r/AppConfig.cpp | 153 +++++++++++++----- src/libslic3r/AppConfig.hpp | 52 +++--- src/libslic3r/PrintConfig.cpp | 6 - src/slic3r/GUI/Camera.cpp | 4 +- src/slic3r/GUI/GUI_App.cpp | 55 +++---- src/slic3r/GUI/GUI_Init.cpp | 1 - src/slic3r/GUI/MainFrame.cpp | 5 +- src/slic3r/GUI/Preferences.cpp | 9 -- src/slic3r/Utils/EmbossStylesSerializable.cpp | 37 +++-- 9 files changed, 182 insertions(+), 140 deletions(-) diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 3c3a4d18d3..be16a2015e 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -487,6 +487,46 @@ void AppConfig::save() m_dirty = false; } +bool AppConfig::erase(const std::string §ion, const std::string &key) +{ + if (auto it_storage = m_storage.find(section); it_storage != m_storage.end()) { + auto §ion = 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 §ion, std::map 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 §ion) +{ + 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 { 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(); } -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 (get_variant(vendor, model, variant)) { return; } + if (get_variant(vendor, model, variant)) + return false; m_vendors[vendor][model].insert(variant); } else { 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); - 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); - if (it_var == it_m->second.end()) { return; } + if (it_var == it_m->second.end()) + return false; it_m->second.erase(it_var); } // If we got here, there was an update m_dirty = true; + return true; } -void AppConfig::set_vendors(const AppConfig &from) +bool AppConfig::set_vendors(const VendorMap &vendors) { - m_vendors = from.m_vendors; - m_dirty = true; + if (m_vendors != vendors) { + 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 @@ -551,34 +610,52 @@ std::vector AppConfig::get_recent_projects() const return ret; } -void AppConfig::set_recent_projects(const std::vector& recent_projects) +bool AppConfig::set_recent_projects(const std::vector& recent_projects) { - auto it = m_storage.find("recent_projects"); - if (it == m_storage.end()) - it = m_storage.insert(std::map>::value_type("recent_projects", std::map())).first; - - it->second.clear(); - for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i) - { - it->second[std::to_string(i + 1)] = recent_projects[i]; + static constexpr const char *section = "recent_projects"; + auto it_section = m_storage.find(section); + if (it_section == m_storage.end()) { + if (recent_projects.empty()) + return false; + it_section = m_storage.insert({ std::string(section), {} }).first; } + auto &dst = it_section->second; + + std::map 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) { - std::string key = std::string("mouse_device:") + name; - auto it = m_storage.find(key); - if (it == m_storage.end()) - it = m_storage.insert(std::map>::value_type(key, std::map())).first; + const std::string key = std::string("mouse_device:") + name; + auto it_section = m_storage.find(key); + if (it_section == m_storage.end()) + it_section = m_storage.insert({ key, {} }).first; + auto &dst = it_section->second; - it->second.clear(); - it->second["translation_speed"] = float_to_string_decimal_point(translation_speed); - it->second["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone); - it->second["rotation_speed"] = float_to_string_decimal_point(rotation_speed); - it->second["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone); - it->second["zoom_speed"] = float_to_string_decimal_point(zoom_speed); - it->second["swap_yz"] = swap_yz ? "1" : "0"; + std::map src; + src["translation_speed"] = float_to_string_decimal_point(translation_speed); + src["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone); + src["rotation_speed"] = float_to_string_decimal_point(rotation_speed); + src["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone); + src["zoom_speed"] = float_to_string_decimal_point(zoom_speed); + src["swap_yz"] = swap_yz ? "1" : "0"; + + if (src != dst) { + dst = std::move(src); + m_dirty = true; + return true; + } else + return false; } std::vector AppConfig::get_mouse_device_names() const @@ -592,16 +669,16 @@ std::vector AppConfig::get_mouse_device_names() const 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)) - return; // do not save "shapes gallery" directory - this->set("recent", "skein_directory", dir); + return false; // do not save "shapes gallery" directory + return this->set("recent", "skein_directory", dir); } /* 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; } -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) ? (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; } -bool AppConfig::exists() +bool AppConfig::exists() const { return boost::filesystem::exists(config_path()); } diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp index 78a7065d90..f3e2637692 100644 --- a/src/libslic3r/AppConfig.hpp +++ b/src/libslic3r/AppConfig.hpp @@ -58,9 +58,13 @@ public: } std::string get(const std::string §ion, const std::string &key) const { std::string value; this->get(section, key, value); return value; } + bool get_bool(const std::string §ion, const std::string &key) const + { return this->get(section, key) == "1"; } std::string get(const std::string &key) const { std::string value; this->get("", key, value); return value; } - void set(const std::string §ion, 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 §ion, const std::string &key, const std::string &value) { #ifndef NDEBUG { @@ -74,10 +78,12 @@ public: if (old != value) { old = value; m_dirty = true; + return true; } + return false; } - void set(const std::string &key, const std::string &value) - { this->set("", key, value); } + bool set(const std::string &key, const std::string &value) + { return this->set("", key, value); } bool has(const std::string §ion, const std::string &key) const { auto it = m_storage.find(section); @@ -89,40 +95,32 @@ public: bool has(const std::string &key) const { return this->has("", key); } - void erase(const std::string §ion, const std::string &key) - { - auto it = m_storage.find(section); - if (it != m_storage.end()) { - it->second.erase(key); - } - } + bool erase(const std::string §ion, const std::string &key); bool has_section(const std::string §ion) const { return m_storage.find(section) != m_storage.end(); } const std::map& get_section(const std::string §ion) const { auto it = m_storage.find(section); assert(it != m_storage.end()); return it->second; } - void set_section(const std::string §ion, const std::map& data) - { m_storage[section] = data; } - void clear_section(const std::string §ion) - { m_storage[section].clear(); } + bool set_section(const std::string §ion, std::map data); + bool clear_section(const std::string §ion); typedef std::map>> VendorMap; 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); - void set_vendors(const AppConfig &from); - void set_vendors(const VendorMap &vendors) { m_vendors = vendors; m_dirty = true; } - void set_vendors(VendorMap &&vendors) { m_vendors = std::move(vendors); m_dirty = true; } + bool set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable); + bool set_vendors(const AppConfig &from) { return this->set_vendors(from.vendors()); } + bool set_vendors(const VendorMap &vendors); + bool set_vendors(VendorMap &&vendors); const VendorMap& vendors() const { return m_vendors; } // return recent/skein_directory or recent/config_directory or empty string. std::string get_last_dir() const; - void update_config_dir(const std::string &dir); - void update_skein_dir(const std::string &dir); + bool update_config_dir(const std::string &dir); + bool update_skein_dir(const std::string &dir); //std::string get_last_output_dir(const std::string &alt) const; //void update_last_output_dir(const std::string &dir); 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 // the PresetBundle::load_selections(const AppConfig &config) call will select @@ -130,7 +128,7 @@ public: void reset_selections(); // 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) 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. std::string version_check_url() const; // 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. - 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 @@ -150,12 +148,12 @@ public: Semver orig_version() const { return m_orig_version; } // Does the config file exist? - bool exists(); + bool exists() const; std::vector get_recent_projects() const; - void set_recent_projects(const std::vector& recent_projects); + bool set_recent_projects(const std::vector& 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 get_mouse_device_names() const; bool get_mouse_device_translation_speed(const std::string& name, double& speed) const { return get_3dmouse_device_numeric_value(name, "translation_speed", speed); } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3a5a772ad0..f66bf7086e 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4710,12 +4710,6 @@ CLIMiscConfigDef::CLIMiscConfigDef() "or an existing PrusaSlicer window is activated. " "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->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."); diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 7a79b8cbf1..62b9729ec5 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -36,10 +36,8 @@ void Camera::set_type(EType type) { if (m_type != type && (type == EType::Ortho || type == EType::Perspective)) { 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->save(); - } } } diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 69167c9fda..99a83cf42e 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -804,7 +804,7 @@ void GUI_App::post_init() } // 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); // 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. app_config->set("version", SLIC3R_VERSION); - app_config->save(); #ifdef _WIN32 // 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() { - if (app_config != nullptr) - delete app_config; - - if (preset_bundle != nullptr) - delete preset_bundle; - - if (preset_updater != nullptr) - delete preset_updater; + delete app_config; + delete preset_bundle; + delete preset_updater; } // If formatted for github, plaintext with OpenGL extensions enclosed into
. @@ -1145,8 +1139,8 @@ bool GUI_App::on_init_inner() // If load_language() fails, the application closes. load_language(wxString(), true); #ifdef _MSW_DARK_MODE - bool init_dark_color_mode = app_config->get("dark_color_mode") == "1"; - bool init_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1"; + bool init_dark_color_mode = app_config->get_bool("dark_color_mode"); + bool init_sys_menu_enabled = app_config->get_bool("sys_menu_enabled"); NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled); #endif // initialize label colors and fonts @@ -1169,13 +1163,13 @@ bool GUI_App::on_init_inner() #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 - 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) { NppDarkMode::SetDarkMode(new_dark_color_mode); init_ui_colours(); 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) NppDarkMode::SetSystemMenuForApp(new_sys_menu_enabled); #endif @@ -1201,7 +1195,7 @@ bool GUI_App::on_init_inner() } 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 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()) { #ifdef __WXMSW__ - if (app_config->get("associate_3mf") == "1") + if (app_config->get_bool("associate_3mf")) associate_3mf_files(); - if (app_config->get("associate_stl") == "1") + if (app_config->get_bool("associate_stl")) associate_stl_files(); #endif // __WXMSW__ @@ -1290,14 +1284,14 @@ bool GUI_App::on_init_inner() } else { #ifdef __WXMSW__ - if (app_config->get("associate_gcode") == "1") + if (app_config->get_bool("associate_gcode")) associate_gcode_files(); #endif // __WXMSW__ } std::string delayed_error_load_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 { // 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 @@ -1387,7 +1381,7 @@ bool GUI_App::on_init_inner() 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(); }); @@ -1448,7 +1442,7 @@ bool GUI_App::dark_mode() return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode(); #else 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(); #endif } @@ -1685,7 +1679,6 @@ void GUI_App::set_label_clr_modified(const wxColour& clr) m_color_label_modified = clr; const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); app_config->set("label_clr_modified", str); - app_config->save(); } 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; const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); app_config->set("label_clr_sys", str); - app_config->save(); } 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& palette) if (save) { mainframe->update_mode_markers(); app_config->set("mode_palette", escape_strings_cstyle(m_mode_palette)); - app_config->save(); } } 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 @@ -1902,14 +1893,14 @@ static void update_scrolls(wxWindow* window) #ifdef _MSW_DARK_MODE 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 void GUI_App::force_colors_update() { #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()) NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND); NppDarkMode::SetDarkTitleBar(mainframe->GetHWND()); @@ -2158,7 +2149,6 @@ bool GUI_App::select_language() // m_wxLocale->GetCanonicalName() // 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->save(); return true; } } @@ -2367,7 +2357,6 @@ bool GUI_App::save_mode(const /*ConfigOptionMode*/int mode) return false; } app_config->set("view_mode", mode_str); - app_config->save(); update_mode(); return true; } @@ -2569,13 +2558,13 @@ void GUI_App::open_preferences(const std::string& highlight_option /*= std::stri #ifdef _WIN32 if (is_editor()) { - if (app_config->get("associate_3mf") == "1") + if (app_config->get_bool("associate_3mf")) associate_3mf_files(); - if (app_config->get("associate_stl") == "1") + if (app_config->get_bool("associate_stl")) associate_stl_files(); } else { - if (app_config->get("associate_gcode") == "1") + if (app_config->get_bool("associate_gcode")) associate_gcode_files(); } #endif // _WIN32 @@ -3178,7 +3167,6 @@ void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) WindowMetrics metrics = WindowMetrics::from_window(window); 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) @@ -3372,7 +3360,6 @@ void GUI_App::associate_gcode_files() void GUI_App::on_version_read(wxCommandEvent& evt) { app_config->set("version_online", into_u8(evt.GetString())); - app_config->save(); std::string opt = app_config->get("notify_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."; diff --git a/src/slic3r/GUI/GUI_Init.cpp b/src/slic3r/GUI/GUI_Init.cpp index 5b5cca7dc4..882c288162 100644 --- a/src/slic3r/GUI/GUI_Init.cpp +++ b/src/slic3r/GUI/GUI_Init.cpp @@ -56,7 +56,6 @@ int GUI_Run(GUI_InitParams ¶ms) } } -// gui->autosave = m_config.opt_string("autosave"); GUI::GUI_App::SetInstance(gui); gui->init_params = ¶ms; return wxEntry(params.argc, params.argv); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 69c566819e..22c9256bd8 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -652,7 +652,8 @@ void MainFrame::shutdown() wxGetApp().other_instance_message_handler()->shutdown(this); // 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. - wxGetApp().app_config->save(); + if (wxGetApp().app_config->dirty()) + wxGetApp().app_config->save(); // if (m_plater) // m_plater->print = undef; // 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))); } wxGetApp().app_config->set_recent_projects(recent_projects); - wxGetApp().app_config->save(); } } }, 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))); } wxGetApp().app_config->set_recent_projects(recent_projects); - wxGetApp().app_config->save(); } } diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 61229ba43b..1895572ae2 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -464,7 +464,6 @@ void PreferencesDialog::build() m_icon_size_sizer->ShowItems(boost::any_cast(value)); refresh_og(m_optgroup_gui); get_app_config()->set("use_custom_toolbar_size", boost::any_cast(value) ? "1" : "0"); - get_app_config()->save(); wxGetApp().plater()->get_current_canvas3D()->render(); return; } @@ -768,7 +767,6 @@ void PreferencesDialog::accept(wxEvent&) for (std::map::iterator it = m_values.begin(); it != m_values.end(); ++it) app_config->set(it->first, it->second); - app_config->save(); if (wxGetApp().is_editor()) { wxGetApp().set_label_clr_sys(m_sys_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(); - bool save_app_config = false; 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()); 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")) { 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_icon_size_sizer->ShowItems(m_use_custom_toolbar_size); refresh_og(m_optgroup_gui); } - if (save_app_config) - app_config->save(); - for (auto value : m_values) { const std::string& key = value.first; @@ -955,7 +947,6 @@ void PreferencesDialog::create_icon_size_slider() auto val = m_icon_size_slider->GetValue(); app_config->set("custom_toolbar_size", (boost::format("%d") % val).str()); - app_config->save(); wxGetApp().plater()->get_current_canvas3D()->render(); if (val_label) diff --git a/src/slic3r/Utils/EmbossStylesSerializable.cpp b/src/slic3r/Utils/EmbossStylesSerializable.cpp index a1c3c599af..111bb597b1 100644 --- a/src/slic3r/Utils/EmbossStylesSerializable.cpp +++ b/src/slic3r/Utils/EmbossStylesSerializable.cpp @@ -121,37 +121,37 @@ void EmbossStylesSerializable::store_style(AppConfig & cfg, const EmbossStyle &fi, unsigned index) { - std::string section_name = create_section_name(index); - cfg.clear_section(section_name); - cfg.set(section_name, APP_CONFIG_FONT_NAME, fi.name); - cfg.set(section_name, APP_CONFIG_FONT_DESCRIPTOR, fi.path); + std::map data; + data[APP_CONFIG_FONT_NAME] = fi.name; + data[APP_CONFIG_FONT_DESCRIPTOR] = fi.path; const FontProp &fp = fi.prop; - cfg.set(section_name, 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_LINE_HEIGHT] = std::to_string(fp.size_in_mm); + data[APP_CONFIG_FONT_DEPTH] = std::to_string(fp.emboss); 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()) - 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()) - 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()) - 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()) - 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()) - 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()) - 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()) - 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) { // store actual font index - cfg.clear_section(AppConfig::SECTION_EMBOSS_STYLE); - // activ font first index is +1 to correspond with section name - std::string active_font = std::to_string(index); - cfg.set(AppConfig::SECTION_EMBOSS_STYLE, APP_CONFIG_ACTIVE_FONT, active_font); + // active font first index is +1 to correspond with section name + std::map data; + data[APP_CONFIG_ACTIVE_FONT] = std::to_string(index); + cfg.set_section(AppConfig::SECTION_EMBOSS_STYLE, std::move(data)); } std::optional EmbossStylesSerializable::load_style_index(const AppConfig &cfg) @@ -198,5 +198,4 @@ void EmbossStylesSerializable::store_styles(AppConfig &cfg, const EmbossStyles& cfg.clear_section(section_name); section_name = create_section_name(++index); } - cfg.save(); } \ No newline at end of file From a913bd493f699c88806577d4d70c7efa630a37a2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 13 Feb 2023 14:08:00 +0100 Subject: [PATCH 2/7] Fix for #9697 - Cut tool tolerance by measurement --- src/libslic3r/Model.cpp | 6 +-- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 62 ++++++++++++++-------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 68c143fca4..bab2e5bc86 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1352,11 +1352,11 @@ void ModelVolume::apply_tolerance() vol->set_offset(pos); */ // make a "hole" wider - sf[X] *= 1. + double(cut_info.radius_tolerance); - sf[Y] *= 1. + double(cut_info.radius_tolerance); + sf[X] += double(cut_info.radius_tolerance); + sf[Y] += double(cut_info.radius_tolerance); // make a "hole" dipper - sf[Z] *= 1. + double(cut_info.height_tolerance); + sf[Z] += double(cut_info.height_tolerance); set_scaling_factor(sf); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index f1758991df..26a5a855dd 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -501,42 +501,42 @@ bool GLGizmoCut3D::render_double_input(const std::string& label, double& value_i bool GLGizmoCut3D::render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in) { - ImGui::AlignTextToFramePadding(); - m_imgui->text(label); - ImGui::SameLine(m_label_width); - ImGui::PushItemWidth(m_control_width * 0.85f); - - float value = value_in; - if (m_imperial_units) - value *= float(ObjectManipulation::mm_to_in); - float old_val = value; - constexpr float UndefMinVal = -0.1f; + const float f_mm_to_in = static_cast(ObjectManipulation::mm_to_in); + + auto render_slider = [this, UndefMinVal, f_mm_to_in] + (const std::string& label, float& val, float def_val, float max_val, const wxString& tooltip) { + float min_val = val < 0.f ? UndefMinVal : def_val; + float value = val; + if (m_imperial_units) { + min_val *= f_mm_to_in; + value *= f_mm_to_in; + } + const float old_val = value; + const std::string format = val < 0.f ? UndefLabel : (m_imperial_units ? "%.4f " + _u8L("in") : "%.2f " + _u8L("mm")); + + m_imgui->slider_float(label.c_str(), &value, min_val, max_val, format.c_str(), 1.f, true, tooltip); + val = value * (m_imperial_units ? static_cast(ObjectManipulation::in_to_mm) : 1.f); + + return !is_approx(old_val, value); + }; const BoundingBoxf3 bbox = bounding_box(); - float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0); - float min_size = value_in < 0.f ? UndefMinVal : 1.f; - if (m_imperial_units) { - mean_size *= float(ObjectManipulation::mm_to_in); - min_size *= float(ObjectManipulation::mm_to_in); - } - std::string format = value_in < 0.f ? UndefLabel : - m_imperial_units ? "%.4f " + _u8L("in") : "%.2f " + _u8L("mm"); + const float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0) * (m_imperial_units ? f_mm_to_in : 1.f); - m_imgui->slider_float(("##" + label).c_str(), &value, min_size, mean_size, format.c_str()); - value_in = value * float(m_imperial_units ? ObjectManipulation::in_to_mm : 1.0); + ImGuiWrapper::text(label); - ImGui::SameLine(m_label_width + m_control_width + 3); - ImGui::PushItemWidth(m_control_width * 0.3f); + ImGui::SameLine(m_label_width); + ImGui::PushItemWidth(m_control_width * 0.7f); - float old_tolerance, tolerance = old_tolerance = tolerance_in * 100.f; - std::string format_t = tolerance_in < 0.f ? UndefLabel : "%.f %%"; - float min_tolerance = tolerance_in < 0.f ? UndefMinVal : 0.f; + const bool is_value_changed = render_slider("##" + label, value_in, 1.f, mean_size, _L("Value")); + + ImGui::SameLine(); + ImGui::PushItemWidth(m_control_width * 0.45f); - m_imgui->slider_float(("##tolerance_" + label).c_str(), &tolerance, min_tolerance, 20.f, format_t.c_str(), 1.f, true, _L("Tolerance")); - tolerance_in = tolerance * 0.01f; + const bool is_tolerance_changed = render_slider("##tolerance_" + label, tolerance_in, 0.f, 0.5f * mean_size, _L("Tolerance")); - return !is_approx(old_val, value) || !is_approx(old_tolerance, tolerance); + return is_value_changed || is_tolerance_changed; } void GLGizmoCut3D::render_move_center_input(int axis) @@ -1597,7 +1597,7 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors) if (m_connector_size > 0) connectors[idx].radius = 0.5f * m_connector_size; if (m_connector_size_tolerance >= 0) - connectors[idx].radius_tolerance = m_connector_size_tolerance; + connectors[idx].radius_tolerance = 0.5f * m_connector_size_tolerance; }); ImGui::Separator(); @@ -1809,7 +1809,7 @@ void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors) m_connector_depth_ratio = depth_ratio; m_connector_depth_ratio_tolerance = depth_ratio_tolerance; m_connector_size = 2.f * radius; - m_connector_size_tolerance = radius_tolerance; + m_connector_size_tolerance = 2.f * radius_tolerance; m_connector_type = type; m_connector_style = size_t(style); m_connector_shape_id = size_t(shape); @@ -2260,7 +2260,7 @@ bool GLGizmoCut3D::add_connector(CutConnectors& connectors, const Vec2d& mouse_p connectors.emplace_back(pos, m_rotation_m, m_connector_size * 0.5f, m_connector_depth_ratio, - m_connector_size_tolerance, m_connector_depth_ratio_tolerance, + m_connector_size_tolerance * 0.5f, m_connector_depth_ratio_tolerance, CutConnectorAttributes( CutConnectorType(m_connector_type), CutConnectorStyle(m_connector_style), CutConnectorShape(m_connector_shape_id))); From b71e0bfd3493b5f8cf551224caac227d128b35e9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 13 Feb 2023 17:20:06 +0100 Subject: [PATCH 3/7] Follow-up https://github.com/Prusa-Development/PrusaSlicerPrivate/commit/8913fdf6abda7e86b0148333bb05a808f622047a * Deleted/Temporary commented redundant call of app_config->save() * Use app_config->get_bool() function on all places --- src/slic3r/GUI/3DScene.cpp | 4 +- src/slic3r/GUI/Camera.cpp | 2 +- src/slic3r/GUI/ConfigWizard.cpp | 10 +-- src/slic3r/GUI/GCodeViewer.cpp | 4 +- src/slic3r/GUI/GLCanvas3D.cpp | 16 ++-- src/slic3r/GUI/GUI_App.cpp | 18 ++-- src/slic3r/GUI/GUI_Init.cpp | 2 +- src/slic3r/GUI/GUI_ObjectList.cpp | 10 +-- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 12 +-- src/slic3r/GUI/GUI_Preview.cpp | 2 +- src/slic3r/GUI/GUI_Utils.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 4 +- src/slic3r/GUI/HintNotification.cpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 14 +-- src/slic3r/GUI/OG_CustomCtrl.cpp | 4 +- src/slic3r/GUI/OptionsGroup.cpp | 4 +- src/slic3r/GUI/Plater.cpp | 50 +++++------ src/slic3r/GUI/Preferences.cpp | 102 +++++++++++----------- src/slic3r/Utils/OctoPrint.cpp | 6 +- src/slic3r/Utils/PresetUpdater.cpp | 2 +- 22 files changed, 139 insertions(+), 137 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 0a07cb6f99..93e274d0d2 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -824,7 +824,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab #if ENABLE_ENVIRONMENT_MAP unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id(); - bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1"; + bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get_bool("use_environment_map"); shader->set_uniform("use_environment_tex", use_environment_texture); if (use_environment_texture) glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id)); @@ -869,7 +869,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab shader->stop_using(); if (edges_shader != nullptr) { edges_shader->start_using(); - if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get("non_manifold_edges") == "1") { + if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get_bool("non_manifold_edges")) { for (GLVolumeWithIdAndZ& volume : to_render) { volume.first->render_non_manifold_edges(); } diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 62b9729ec5..4152ca3585 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -283,7 +283,7 @@ void Camera::debug_render() const imgui.begin(std::string("Camera statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); std::string type = get_type_as_string(); - if (wxGetApp().plater()->get_mouse3d_controller().connected() || (wxGetApp().app_config->get("use_free_camera") == "1")) + if (wxGetApp().plater()->get_mouse3d_controller().connected() || (wxGetApp().app_config->get_bool("use_free_camera"))) type += "/free"; else type += "/constrained"; diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index be1e02b84b..2a17df8a13 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -1298,7 +1298,7 @@ PageUpdate::PageUpdate(ConfigWizard *parent) append_spacer(VERTICAL_SPACING); auto *box_presets = new wxCheckBox(this, wxID_ANY, _L("Update built-in Presets automatically")); - box_presets->SetValue(app_config->get("preset_update") == "1"); + box_presets->SetValue(app_config->get_bool("preset_update")); append(box_presets); append_text(wxString::Format(_L( "If enabled, %s downloads updates of built-in system presets in the background." @@ -1416,7 +1416,7 @@ PageDownloader::PageDownloader(ConfigWizard* parent) auto* box_allow_downloads = new wxCheckBox(this, wxID_ANY, _L("Allow build-in downloader")); // TODO: Do we want it like this? The downloader is allowed for very first time the wizard is run. - bool box_allow_value = (app_config->has("downloader_url_registered") ? app_config->get("downloader_url_registered") == "1" : true); + bool box_allow_value = (app_config->has("downloader_url_registered") ? app_config->get_bool("downloader_url_registered") : true); box_allow_downloads->SetValue(box_allow_value); append(box_allow_downloads); @@ -1517,7 +1517,7 @@ void DownloaderUtils::Worker::deregister() bool DownloaderUtils::Worker::on_finish() { AppConfig* app_config = wxGetApp().app_config; - bool ac_value = app_config->get("downloader_url_registered") == "1"; + bool ac_value = app_config->get_bool("downloader_url_registered"); BOOST_LOG_TRIVIAL(debug) << "PageDownloader::on_finish_downloader ac_value " << ac_value << " downloader_checked " << downloader_checked; if (ac_value && downloader_checked) { // already registered but we need to do it again @@ -1546,7 +1546,7 @@ PageReloadFromDisk::PageReloadFromDisk(ConfigWizard* parent) , full_pathnames(false) { auto* box_pathnames = new wxCheckBox(this, wxID_ANY, _L("Export full pathnames of models and parts sources into 3mf and amf files")); - box_pathnames->SetValue(wxGetApp().app_config->get("export_sources_full_pathnames") == "1"); + box_pathnames->SetValue(wxGetApp().app_config->get_bool("export_sources_full_pathnames")); append(box_pathnames); append_text(_L( "If enabled, allows the Reload from disk command to automatically find and load the files when invoked.\n" @@ -1595,7 +1595,7 @@ PageMode::PageMode(ConfigWizard *parent) append_text("\n" + _L("The size of the object can be specified in inches")); check_inch = new wxCheckBox(this, wxID_ANY, _L("Use inches")); - check_inch->SetValue(wxGetApp().app_config->get("use_inches") == "1"); + check_inch->SetValue(wxGetApp().app_config->get_bool("use_inches")); append(check_inch); on_activate(); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b6d4fb9859..186f1f4fff 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2373,7 +2373,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool statistics->models_instances_size = 0; #endif // ENABLE_GCODE_VIEWER_STATISTICS - const bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; + const bool top_layer_only = get_app_config()->get_bool("seq_top_layer_only"); SequentialView::Endpoints global_endpoints = { m_moves_count , 0 }; SequentialView::Endpoints top_layer_endpoints = global_endpoints; @@ -3221,7 +3221,7 @@ void GCodeViewer::render_legend(float& legend_height) const float icon_size = ImGui::GetTextLineHeight(); const float percent_bar_size = 2.0f * ImGui::GetTextLineHeight(); - bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; + bool imperial_units = wxGetApp().app_config->get_bool("use_inches"); auto append_item = [icon_size, percent_bar_size, &imgui, imperial_units](EItemType type, const ColorRGBA& color, const std::string& label, bool visible = true, const std::string& time = "", float percent = 0.0f, float max_percent = 0.0f, const std::array& offsets = { 0.0f, 0.0f, 0.0f, 0.0f }, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8809624343..48e614a39f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2308,7 +2308,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #endif /* __APPLE__ */ { #ifdef _WIN32 - if (wxGetApp().app_config->get("use_legacy_3DConnexion") == "1") { + if (wxGetApp().app_config->get_bool("use_legacy_3DConnexion")) { #endif //_WIN32 #ifdef __APPLE__ // On OSX use Cmd+Shift+M to "Show/Hide 3Dconnexion devices settings dialog" @@ -2783,7 +2783,7 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) return; // Calculate the zoom delta and apply it to the current zoom factor - double direction_factor = (wxGetApp().app_config->get("reverse_mouse_wheel_zoom") == "1") ? -1.0 : 1.0; + double direction_factor = wxGetApp().app_config->get_bool("reverse_mouse_wheel_zoom") ? -1.0 : 1.0; _update_camera_zoom(direction_factor * (double)evt.GetWheelRotation() / (double)evt.GetWheelDelta()); } @@ -3212,7 +3212,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (!m_moving) { if ((any_gizmo_active || evt.CmdDown() || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) { const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.0) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.0); - if (wxGetApp().app_config->get("use_free_camera") == "1") + if (wxGetApp().app_config->get_bool("use_free_camera")) // Virtual track ball (similar to the 3DConnexion mouse). wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.0)); else { @@ -3238,7 +3238,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) const Vec3d cur_pos = _mouse_to_3d(pos, &z); const Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z); Camera& camera = wxGetApp().plater()->get_camera(); - if (wxGetApp().app_config->get("use_free_camera") != "1") + if (!wxGetApp().app_config->get_bool("use_free_camera")) // Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation. // It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(), // which checks an atomics (flushes CPU caches). @@ -3806,7 +3806,7 @@ void GLCanvas3D::update_ui_from_settings() // Update OpenGL scaling on OSX after the user toggled the "use_retina_opengl" settings in Preferences dialog. const float orig_scaling = m_retina_helper->get_scale_factor(); - const bool use_retina = wxGetApp().app_config->get("use_retina_opengl") == "1"; + const bool use_retina = wxGetApp().app_config->get_bool("use_retina_opengl"); BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Use Retina OpenGL: " << use_retina; m_retina_helper->set_use_retina(use_retina); const float new_scaling = m_retina_helper->get_scale_factor(); @@ -3821,7 +3821,7 @@ void GLCanvas3D::update_ui_from_settings() #endif // ENABLE_RETINA_GL if (wxGetApp().is_editor()) - wxGetApp().plater()->enable_collapse_toolbar(wxGetApp().app_config->get("show_collapse_button") == "1"); + wxGetApp().plater()->enable_collapse_toolbar(wxGetApp().app_config->get_bool("show_collapse_button")); } GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const @@ -4725,8 +4725,8 @@ bool GLCanvas3D::_init_main_toolbar() "\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ; item.sprite_id = 10; item.enabling_callback = GLToolbarItem::Default_Enabling_Callback; - item.visibility_callback = []() { return (wxGetApp().app_config->get("new_settings_layout_mode") == "1" || - wxGetApp().app_config->get("dlg_settings_layout_mode") == "1"); }; + item.visibility_callback = []() { return wxGetApp().app_config->get_bool("new_settings_layout_mode") || + wxGetApp().app_config->get_bool("dlg_settings_layout_mode"); }; item.left.action_callback = []() { wxGetApp().mainframe->select_tab(); }; if (!m_main_toolbar.add_item(item)) return false; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 99a83cf42e..a4cfc0cb95 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1203,7 +1203,7 @@ bool GUI_App::on_init_inner() // Now this position is equal to the mainframe position wxPoint splashscreen_pos = wxDefaultPosition; bool default_splashscreen_pos = true; - if (app_config->has("window_mainframe") && app_config->get("restore_win_position") == "1") { + if (app_config->has("window_mainframe") && app_config->get_bool("restore_win_position")) { auto metrics = WindowMetrics::deserialize(app_config->get("window_mainframe")); default_splashscreen_pos = metrics == boost::none; if (!default_splashscreen_pos) @@ -1237,7 +1237,7 @@ bool GUI_App::on_init_inner() if (! older_data_dir_path.empty()) { preset_bundle->import_newer_configs(older_data_dir_path); - app_config->save(); + //app_config->save(); // It looks like redundant call of save. ysFIXME delete after testing } if (is_editor()) { @@ -1413,7 +1413,6 @@ bool GUI_App::on_init_inner() app_config->set("restore_win_position", "0"); else if (answer == wxID_NO) app_config->set("restore_win_position", "1"); - app_config->save(); } return true; @@ -2889,7 +2888,7 @@ void GUI_App::MacOpenFiles(const wxArrayString &fileNames) void GUI_App::MacOpenURL(const wxString& url) { - if (app_config && app_config->get("downloader_url_registered") != "1") + if (app_config && !app_config->get_bool("downloader_url_registered")) { BOOST_LOG_TRIVIAL(error) << "Recieved command to open URL, but it is not allowed in app configuration. URL: " << url; return; @@ -3167,6 +3166,9 @@ void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) WindowMetrics metrics = WindowMetrics::from_window(window); app_config->set(config_key, metrics.serialize()); + // save changed app_config here, before all action related to a close of application is processed + if (app_config->dirty()) + app_config->save(); } void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized) @@ -3187,7 +3189,7 @@ void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &na const wxRect& rect = metrics->get_rect(); - if (app_config->get("restore_win_position") == "1") { + if (app_config->get_bool("restore_win_position")) { // workaround for crash related to the positioning of the window on secondary monitor app_config->set("restore_win_position", (boost::format("crashed_at_%1%_pos") % name).str()); app_config->save(); @@ -3242,7 +3244,7 @@ bool GUI_App::config_wizard_startup() return true; } #ifndef __APPLE__ - else if (is_editor() && m_last_app_conf_lower_version && app_config->get("downloader_url_registered") == "1") { + else if (is_editor() && m_last_app_conf_lower_version && app_config->get_bool("downloader_url_registered")) { show_downloader_registration_dialog(); return true; } @@ -3302,11 +3304,11 @@ bool GUI_App::open_browser_with_warning_dialog(const wxString& url, wxWindow* pa } } if (launch) - launch = app_config->get(option_key) != "1"; + launch = !app_config->get_bool(option_key); } // warning dialog doesn't containe a "Remember my choice" checkbox // and will be shown only when "Suppress to open hyperlink in browser" is ON. - else if (app_config->get(option_key) == "1") { + else if (app_config->get_bool(option_key)) { MessageDialog dialog(parent, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxICON_QUESTION | wxYES_NO); launch = dialog.ShowModal() == wxID_YES; } diff --git a/src/slic3r/GUI/GUI_Init.cpp b/src/slic3r/GUI/GUI_Init.cpp index 882c288162..bf65ec8903 100644 --- a/src/slic3r/GUI/GUI_Init.cpp +++ b/src/slic3r/GUI/GUI_Init.cpp @@ -49,7 +49,7 @@ int GUI_Run(GUI_InitParams ¶ms) GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor); if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) { // G-code viewer is currently not performing instance check, a new G-code viewer is started every time. - bool gui_single_instance_setting = gui->app_config->get("single_instance") == "1"; + bool gui_single_instance_setting = gui->app_config->get_bool("single_instance"); if (Slic3r::instance_check(params.argc, params.argv, gui_single_instance_setting)) { //TODO: do we have delete gui and other stuff? return -1; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 81ec956eed..1906d2c307 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1250,7 +1250,7 @@ bool ObjectList::can_drop(const wxDataViewItem& item) const if (dragged_item_v_type == item_v_type && dragged_item_v_type != ModelVolumeType::MODEL_PART) return true; - if ((wxGetApp().app_config->get("order_volumes") == "1" && dragged_item_v_type != item_v_type) || // we can't reorder volumes outside of types + if ((wxGetApp().app_config->get_bool("order_volumes") && dragged_item_v_type != item_v_type) || // we can't reorder volumes outside of types item_v_type >= ModelVolumeType::SUPPORT_BLOCKER) // support blockers/enforcers can't change its place return false; @@ -1855,7 +1855,7 @@ void ObjectList::load_mesh_object( new_object->add_instance(); // each object should have at list one instance ModelVolume* new_volume = new_object->add_volume(mesh); - new_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); + new_object->sort_volumes(wxGetApp().app_config->get_bool("order_volumes")); new_volume->name = name; if (text_config) new_volume->text_configuration = *text_config; @@ -2327,7 +2327,7 @@ void ObjectList::merge(bool to_multipart_object) const Vec3d vol_offset = volume_offset_correction* new_volume->get_offset(); new_volume->set_offset(vol_offset); } - new_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); + new_object->sort_volumes(wxGetApp().app_config->get_bool("order_volumes")); // merge settings auto new_opt_keys = config.keys(); @@ -4896,7 +4896,7 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const wxDataViewItemArray ObjectList::reorder_volumes_and_get_selection(size_t obj_idx, std::function add_to_selection/* = nullptr*/) { - (*m_objects)[obj_idx]->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); + (*m_objects)[obj_idx]->sort_volumes(wxGetApp().app_config->get_bool("order_volumes")); wxDataViewItemArray items = add_volumes_to_object_in_list(obj_idx, std::move(add_to_selection)); @@ -4907,7 +4907,7 @@ wxDataViewItemArray ObjectList::reorder_volumes_and_get_selection(size_t obj_idx void ObjectList::apply_volumes_order() { - if (wxGetApp().app_config->get("order_volumes") != "1" || !m_objects) + if (!wxGetApp().app_config->get_bool("order_volumes") || !m_objects) return; for (size_t obj_idx = 0; obj_idx < m_objects->size(); obj_idx++) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index c295eb8fb7..0375a3ce71 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -118,8 +118,8 @@ static const wxString axes_color_back[] = { "#f5dcdc", "#dcf5dc", "#dcdcf5" }; ObjectManipulation::ObjectManipulation(wxWindow* parent) : OG_Settings(parent, true) { - m_imperial_units = wxGetApp().app_config->get("use_inches") == "1"; - m_use_colors = wxGetApp().app_config->get("color_mapinulation_panel") == "1"; + m_imperial_units = wxGetApp().app_config->get_bool("use_inches"); + m_use_colors = wxGetApp().app_config->get_bool("color_mapinulation_panel"); m_manifold_warning_bmp = ScalableBitmap(parent, "exclamation"); @@ -642,8 +642,8 @@ void ObjectManipulation::DisableUnuniformScale() void ObjectManipulation::update_ui_from_settings() { - if (m_imperial_units != (wxGetApp().app_config->get("use_inches") == "1")) { - m_imperial_units = wxGetApp().app_config->get("use_inches") == "1"; + if (m_imperial_units != wxGetApp().app_config->get_bool("use_inches")) { + m_imperial_units = wxGetApp().app_config->get_bool("use_inches"); auto update_unit_text = [](const wxString& new_unit_text, wxStaticText* widget) { widget->SetLabel(new_unit_text); @@ -667,8 +667,8 @@ void ObjectManipulation::update_ui_from_settings() } m_check_inch->SetValue(m_imperial_units); - if (m_use_colors != (wxGetApp().app_config->get("color_mapinulation_panel") == "1")) { - m_use_colors = wxGetApp().app_config->get("color_mapinulation_panel") == "1"; + if (m_use_colors != wxGetApp().app_config->get_bool("color_mapinulation_panel")) { + m_use_colors = wxGetApp().app_config->get_bool("color_mapinulation_panel"); // update colors for edit-boxes int axis_id = 0; for (ManipulationEditor* editor : m_editors) { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 7bfb252482..d9dfc7db22 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -537,7 +537,7 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee // Suggest the auto color change, if model looks like sign if (!color_change_already_exists && - wxGetApp().app_config->get("allow_auto_color_change") == "1" && + wxGetApp().app_config->get_bool("allow_auto_color_change") && m_layers_slider->IsNewPrint()) { const Print& print = wxGetApp().plater()->fff_print(); diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index d9bffa3f45..fad47035b5 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -165,7 +165,7 @@ bool check_dark_mode() { #ifdef _WIN32 void update_dark_ui(wxWindow* window) { - bool is_dark = wxGetApp().app_config->get("dark_color_mode") == "1";// ? true : check_dark_mode();// #ysDarkMSW - Allow it when we deside to support the sustem colors for application + bool is_dark = wxGetApp().app_config->get_bool("dark_color_mode");// ? true : check_dark_mode();// #ysDarkMSW - Allow it when we deside to support the sustem colors for application window->SetBackgroundColour(is_dark ? wxColour(43, 43, 43) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); window->SetForegroundColour(is_dark ? wxColour(250, 250, 250) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 26a5a855dd..0798b61f49 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -1757,7 +1757,7 @@ void GLGizmoCut3D::validate_connector_settings() void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors) { - m_imperial_units = wxGetApp().app_config->get("use_inches") == "1"; + m_imperial_units = wxGetApp().app_config->get_bool("use_inches"); m_label_width = m_imgui->get_font_size() * 6.f; m_control_width = m_imgui->get_font_size() * 9.f; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index cebef8b42b..8ed451ae5b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -2962,7 +2962,7 @@ void GLGizmoEmboss::draw_style_edit() { process(); } - bool use_inch = wxGetApp().app_config->get("use_inches") == "1"; + bool use_inch = wxGetApp().app_config->get_bool("use_inches"); draw_height(use_inch); draw_depth(use_inch); @@ -3299,7 +3299,7 @@ void GLGizmoEmboss::draw_advanced() &stored_style->prop.distance : nullptr; m_imgui->disabled_begin(!allowe_surface_distance); - bool use_inch = wxGetApp().app_config->get("use_inches") == "1"; + bool use_inch = wxGetApp().app_config->get_bool("use_inches"); const std::string undo_move_tooltip = _u8L("Undo translation"); const wxString move_tooltip = _L("Distance center of text from model surface"); bool is_moved = false; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index fc99e52c08..ece59beca8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1205,7 +1205,7 @@ void GLGizmoMeasure::render_dimensioning() ss_to_ndc_matrix * Geometry::translation_transform(v2ss_3) * q12ss); m_dimensioning.triangle.render(); - const bool use_inches = wxGetApp().app_config->get("use_inches") == "1"; + const bool use_inches = wxGetApp().app_config->get_bool("use_inches"); const double curr_value = use_inches ? ObjectManipulation::mm_to_in * distance : distance; const std::string curr_value_str = format_double(curr_value); const std::string units = use_inches ? _u8L("in") : _u8L("mm"); @@ -1973,7 +1973,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::EndTable(); } - const bool use_inches = wxGetApp().app_config->get("use_inches") == "1"; + const bool use_inches = wxGetApp().app_config->get_bool("use_inches"); const std::string units = use_inches ? " " + _u8L("in") : " " + _u8L("mm"); ImGui::Separator(); diff --git a/src/slic3r/GUI/HintNotification.cpp b/src/slic3r/GUI/HintNotification.cpp index df955fa93a..1f3d224919 100644 --- a/src/slic3r/GUI/HintNotification.cpp +++ b/src/slic3r/GUI/HintNotification.cpp @@ -883,7 +883,7 @@ void NotificationManager::HintNotification::render_close_button(ImGuiWrapper& im //render_right_arrow_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); render_logo(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); render_preferences_button(imgui, win_pos_x, win_pos_y); - if (!m_documentation_link.empty() && wxGetApp().app_config->get("suppress_hyperlinks") != "1") + if (!m_documentation_link.empty() && !wxGetApp().app_config->get_bool("suppress_hyperlinks")) { render_documentation_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 22c9256bd8..b656f056ae 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -272,7 +272,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S update_ui_from_settings(); // FIXME (?) if (m_plater != nullptr) { - m_plater->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get("show_collapse_button") == "1"); + m_plater->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get_bool("show_collapse_button")); m_plater->show_action_buttons(true); preferences_dialog = new PreferencesDialog(this); @@ -442,9 +442,9 @@ void MainFrame::update_layout() }; ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer : - (wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : - wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ( wxGetApp().tabs_as_menu() ? ESettingsLayout::Old : ESettingsLayout::New) : - wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old); + (wxGetApp().app_config->get_bool("old_settings_layout_mode") ? ESettingsLayout::Old : + wxGetApp().app_config->get_bool("new_settings_layout_mode") ? ( wxGetApp().tabs_as_menu() ? ESettingsLayout::Old : ESettingsLayout::New) : + wxGetApp().app_config->get_bool("dlg_settings_layout_mode") ? ESettingsLayout::Dlg : ESettingsLayout::Old); if (m_layout == layout) return; @@ -1001,7 +1001,7 @@ bool MainFrame::can_eject() const bool MainFrame::can_slice() const { - bool bg_proc = wxGetApp().app_config->get("background_processing") == "1"; + bool bg_proc = wxGetApp().app_config->get_bool("background_processing"); return (m_plater != nullptr) ? !m_plater->model().objects.empty() && !bg_proc : false; } @@ -1497,7 +1497,7 @@ void MainFrame::init_menubar_as_editor() windowMenu->AppendSeparator(); append_menu_item(windowMenu, wxID_ANY, _L("Open New Instance") + "\tCtrl+Shift+I", _L("Open a new PrusaSlicer instance"), - [](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, [this]() {return m_plater != nullptr && wxGetApp().app_config->get("single_instance") != "1"; }, this); + [](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, [this]() {return m_plater != nullptr && !wxGetApp().app_config->get_bool("single_instance"); }, this); windowMenu->AppendSeparator(); append_menu_item(windowMenu, wxID_ANY, _L("Compare Presets")/* + "\tCtrl+F"*/, _L("Compare presets"), @@ -2202,7 +2202,7 @@ void MainFrame::technology_changed() // Update the UI based on the current preferences. void MainFrame::update_ui_from_settings() { -// const bool bp_on = wxGetApp().app_config->get("background_processing") == "1"; +// const bool bp_on = wxGetApp().app_config->get_bool("background_processing"); // m_menu_item_reslice_now->Enable(!bp_on); // m_plater->sidebar().show_reslice(!bp_on); // m_plater->sidebar().show_export(bp_on); diff --git a/src/slic3r/GUI/OG_CustomCtrl.cpp b/src/slic3r/GUI/OG_CustomCtrl.cpp index 2f4f91302c..d18df6bb2d 100644 --- a/src/slic3r/GUI/OG_CustomCtrl.cpp +++ b/src/slic3r/GUI/OG_CustomCtrl.cpp @@ -246,7 +246,7 @@ void OG_CustomCtrl::OnMotion(wxMouseEvent& event) wxString language = wxGetApp().app_config->get("translation_language"); - bool suppress_hyperlinks = get_app_config()->get("suppress_hyperlinks") == "1"; + const bool suppress_hyperlinks = get_app_config()->get_bool("suppress_hyperlinks"); for (CtrlLine& line : ctrl_lines) { line.is_focused = is_point_in_rect(pos, line.rect_label); @@ -567,7 +567,7 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos) Field* field = ctrl->opt_group->get_field(og_line.get_options().front().opt_id); - bool suppress_hyperlinks = get_app_config()->get("suppress_hyperlinks") == "1"; + const bool suppress_hyperlinks = get_app_config()->get_bool("suppress_hyperlinks"); if (draw_just_act_buttons) { if (field) draw_act_bmps(dc, wxPoint(0, v_pos), field->undo_to_sys_bitmap(), field->undo_bitmap(), field->blink()); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 0ca0bf9db5..3659a08ccf 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -1052,7 +1052,7 @@ void ogStaticText::SetPathEnd(const std::string& link) event.Skip(); } ); Bind(wxEVT_ENTER_WINDOW, [this, link](wxMouseEvent& event) { - SetToolTip(OptionsGroup::get_url(get_app_config()->get("suppress_hyperlinks") != "1" ? link : std::string())); + SetToolTip(OptionsGroup::get_url(!get_app_config()->get_bool("suppress_hyperlinks") ? link : std::string())); FocusText(true); event.Skip(); }); @@ -1061,7 +1061,7 @@ void ogStaticText::SetPathEnd(const std::string& link) void ogStaticText::FocusText(bool focus) { - if (get_app_config()->get("suppress_hyperlinks") == "1") + if (get_app_config()->get_bool("suppress_hyperlinks")) return; SetFont(focus ? Slic3r::GUI::wxGetApp().link_font() : diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7c91b7dac1..505c33a1cf 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1292,7 +1292,7 @@ void Sidebar::show_info_sizer() int inst_idx = selection.get_instance_idx(); assert(inst_idx >= 0); - bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; + bool imperial_units = wxGetApp().app_config->get_bool("use_inches"); double koef = imperial_units ? ObjectManipulation::mm_to_in : 1.0f; ModelVolume* vol = nullptr; @@ -1388,7 +1388,7 @@ 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; - bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; + bool imperial_units = wxGetApp().app_config->get_bool("use_inches"); double koef = imperial_units ? ObjectManipulation::in_to_mm : 1000.0; wxString new_label = imperial_units ? _L("Used Filament (in)") : _L("Used Filament (m)"); @@ -1814,7 +1814,7 @@ struct Plater::priv void update_ui_from_settings(); void update_main_toolbar_tooltips(); // std::shared_ptr statusbar(); - std::string get_config(const std::string &key) const; + bool get_config_bool(const std::string &key) const; std::vector load_files(const std::vector& input_files, bool load_model, bool load_config, bool used_inches = false); std::vector load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false, bool call_selection_changed = true); @@ -1860,7 +1860,7 @@ struct Plater::priv void process_validation_warning(const std::string& warning) const; - bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; } + bool background_processing_enabled() const { return this->get_config_bool("background_processing"); } void update_print_volume_state(); void schedule_background_process(); // Update background processing thread from the current config and Model. @@ -2179,7 +2179,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // updates camera type from .ini file camera.enable_update_config_on_type_change(true); - camera.set_type(get_config("use_perspective_camera")); + camera.set_type(wxGetApp().app_config->get("use_perspective_camera")); // Load the 3DConnexion device database. mouse3d_controller.load_config(*wxGetApp().app_config); @@ -2266,7 +2266,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // collapse sidebar according to saved value if (wxGetApp().is_editor()) { - bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1"; + bool is_collapsed = get_config_bool("collapsed_sidebar"); sidebar->collapse(is_collapsed); } } @@ -2283,7 +2283,7 @@ void Plater::priv::update(unsigned int flags) { // the following line, when enabled, causes flickering on NVIDIA graphics cards // wxWindowUpdateLocker freeze_guard(q); - if (get_config("autocenter") == "1") + if (get_config_bool("autocenter")) model.center_instances_around_point(this->bed.build_volume().bed_center()); unsigned int update_status = 0; @@ -2299,7 +2299,7 @@ void Plater::priv::update(unsigned int flags) else this->schedule_background_process(); - if (get_config("autocenter") == "1" && this->sidebar->obj_manipul()->IsShown()) + if (get_config_bool("autocenter") && this->sidebar->obj_manipul()->IsShown()) this->sidebar->obj_manipul()->UpdateAndShow(true); } @@ -2314,7 +2314,7 @@ void Plater::priv::select_view(const std::string& direction) void Plater::priv::apply_free_camera_correction(bool apply/* = true*/) { camera.set_type(wxGetApp().app_config->get("use_perspective_camera")); - if (apply && wxGetApp().app_config->get("use_free_camera") != "1") + if (apply && !wxGetApp().app_config->get_bool("use_free_camera")) camera.recover_from_free_camera(); } @@ -2382,9 +2382,9 @@ void Plater::priv::update_main_toolbar_tooltips() // return main_frame->m_statusbar; //} -std::string Plater::priv::get_config(const std::string &key) const +bool Plater::priv::get_config_bool(const std::string &key) const { - return wxGetApp().app_config->get(key); + return wxGetApp().app_config->get_bool(key); } // After loading of the presets from project, check if they are visible. @@ -2761,7 +2761,7 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& mode #endif /* AUTOPLACEMENT_ON_LOAD */ for (ModelObject *model_object : model_objects) { auto *object = model.add_object(*model_object); - object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); + object->sort_volumes(get_config_bool("order_volumes")); std::string object_name = object->name.empty() ? fs::path(object->input_file).filename().string() : object->name; obj_idxs.push_back(obj_count++); @@ -3575,7 +3575,7 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const old_model_object->delete_volume(old_model_object->volumes.size() - 1); if (!sinking) old_model_object->ensure_on_bed(); - old_model_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); + old_model_object->sort_volumes(get_config_bool("order_volumes")); // if object has just one volume, rename object too if (old_model_object->volumes.size() == 1) @@ -3941,7 +3941,7 @@ void Plater::priv::reload_from_disk() old_model_object->delete_volume(old_model_object->volumes.size() - 1); if (!sinking) old_model_object->ensure_on_bed(); - old_model_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); + old_model_object->sort_volumes(get_config_bool("order_volumes")); sla::reproject_points_and_holes(old_model_object); @@ -4021,7 +4021,7 @@ void Plater::priv::reload_from_disk() old_model_object->delete_volume(old_model_object->volumes.size() - 1); if (!sinking) old_model_object->ensure_on_bed(); - old_model_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); + old_model_object->sort_volumes(get_config_bool("order_volumes")); sla::reproject_points_and_holes(old_model_object); } @@ -4275,7 +4275,7 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) if ((evt.status.flags & PrintBase::SlicingStatus::UPDATE_PRINT_STEP_WARNINGS) && static_cast(evt.status.warning_step) == psAlertWhenSupportsNeeded && - get_app_config()->get("alert_when_supports_needed") != "1") { + !get_app_config()->get_bool("alert_when_supports_needed")) { // This alerts are from psAlertWhenSupportsNeeded and the respective app settings is not Enabled, so discard the alerts. } else if (evt.status.flags & (PrintBase::SlicingStatus::UPDATE_PRINT_STEP_WARNINGS | PrintBase::SlicingStatus::UPDATE_PRINT_OBJECT_STEP_WARNINGS)) { @@ -5054,7 +5054,7 @@ void Plater::priv::show_action_buttons(const bool ready_to_slice_) const const bool send_gcode_shown = print_host_opt != nullptr && !print_host_opt->value.empty(); // when a background processing is ON, export_btn and/or send_btn are showing - if (wxGetApp().app_config->get("background_processing") == "1") + if (get_config_bool("background_processing")) { RemovableDriveManager::RemovableDrivesStatus removable_media_status = wxGetApp().removable_drive_manager()->status(); if (sidebar->show_reslice(false) | @@ -5143,7 +5143,7 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed } const GLGizmosManager& gizmos = view3D->get_canvas3d()->get_gizmos_manager(); - if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator && wxGetApp().app_config->get("clear_undo_redo_stack_on_new_project") == "1") + if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator && get_config_bool("clear_undo_redo_stack_on_new_project")) this->undo_redo_stack().clear(); this->undo_redo_stack().take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), gizmos, snapshot_data); if (snapshot_type == UndoRedo::SnapshotType::LeavingGizmoWithAction) { @@ -5650,7 +5650,7 @@ LoadProjectsDialog::LoadProjectsDialog(const std::vector& paths) wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); bool contains_projects = !paths.empty(); - bool instances_allowed = wxGetApp().app_config->get("single_instance") != "1"; + bool instances_allowed = !wxGetApp().app_config->get_bool("single_instance"); if (contains_projects) main_sizer->Add(new wxStaticText(this, wxID_ANY, get_wraped_wxString(_L("There are several files being loaded, including Project files.") + "\n" + _L("Select an action to apply to all files."))), 0, wxEXPAND | wxALL, 10); @@ -5895,7 +5895,7 @@ bool Plater::preview_zip_archive(const boost::filesystem::path& archive_path) return true; } // 1 model (or more and other instances are not allowed), 0 projects - open geometry - if (project_paths.empty() && (non_project_paths.size() == 1 || wxGetApp().app_config->get("single_instance") == "1")) + if (project_paths.empty() && (non_project_paths.size() == 1 || wxGetApp().app_config->get_bool("single_instance"))) { load_files(non_project_paths, true, false); boost::system::error_code ec; @@ -6036,7 +6036,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string& filename) { SetFont(wxGetApp().normal_font()); - bool single_instance_only = wxGetApp().app_config->get("single_instance") == "1"; + bool single_instance_only = wxGetApp().app_config->get_bool("single_instance"); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); wxArrayString choices; choices.reserve(4); @@ -6144,7 +6144,7 @@ bool Plater::load_files(const wxArrayString& filenames, bool delete_after_load/* (boost::algorithm::iends_with(filename, ".amf") && !boost::algorithm::iends_with(filename, ".zip.amf"))) load_type = ProjectDropDialog::LoadType::LoadGeometry; else { - if (wxGetApp().app_config->get("show_drop_project_dialog") == "1") { + if (wxGetApp().app_config->get_bool("show_drop_project_dialog")) { ProjectDropDialog dlg(filename); if (dlg.ShowModal() == wxID_OK) { int choice = dlg.get_action(); @@ -6294,7 +6294,7 @@ void Plater::increase_instances(size_t num) // p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec)); } - if (p->get_config("autocenter") == "1") + if (p->get_config_bool("autocenter")) arrange(); p->update(); @@ -6711,7 +6711,7 @@ void Plater::export_amf() wxBusyCursor wait; bool export_config = true; DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); - bool full_pathnames = wxGetApp().app_config->get("export_sources_full_pathnames") == "1"; + bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames"); if (Slic3r::store_amf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames)) { // Success // p->statusbar()->set_status_text(format_wxstr(_L("AMF file exported to %s"), path)); @@ -6744,7 +6744,7 @@ bool Plater::export_3mf(const boost::filesystem::path& output_path) DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); const std::string path_u8 = into_u8(path); wxBusyCursor wait; - bool full_pathnames = wxGetApp().app_config->get("export_sources_full_pathnames") == "1"; + bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames"); ThumbnailData thumbnail_data; ThumbnailsParams thumbnail_params = { {}, false, true, true, true }; p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 1895572ae2..40c5314ee4 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -87,7 +87,7 @@ void PreferencesDialog::show(const std::string& highlight_opt_key /*= std::strin // cache input values for custom toolbar size m_custom_toolbar_size = atoi(get_app_config()->get("custom_toolbar_size").c_str()); - m_use_custom_toolbar_size = get_app_config()->get("use_custom_toolbar_size") == "1"; + m_use_custom_toolbar_size = get_app_config()->get_bool("use_custom_toolbar_size"); // set Field for notify_release to its value if (m_optgroup_gui && m_optgroup_gui->get_field("notify_release") != nullptr) { @@ -100,10 +100,10 @@ void PreferencesDialog::show(const std::string& highlight_opt_key /*= std::strin auto app_config = get_app_config(); downloader->set_path_name(app_config->get("url_downloader_dest")); - downloader->allow(!app_config->has("downloader_url_registered") || app_config->get("downloader_url_registered") == "1"); + downloader->allow(!app_config->has("downloader_url_registered") || app_config->get_bool("downloader_url_registered")); for (const std::string& opt_key : {"suppress_hyperlinks", "downloader_url_registered"}) - m_optgroup_other->set_value(opt_key, app_config->get(opt_key) == "1"); + m_optgroup_other->set_value(opt_key, app_config->get_bool(opt_key)); // update colors for color pickers of the labels update_color(m_sys_colour, wxGetApp().get_label_clr_sys()); @@ -257,25 +257,25 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_general, "remember_output_path", L("Remember output directory"), L("If this is enabled, Slic3r will prompt the last output directory instead of the one containing the input files."), - app_config->has("remember_output_path") ? app_config->get("remember_output_path") == "1" : true); + app_config->has("remember_output_path") ? app_config->get_bool("remember_output_path") : true); append_bool_option(m_optgroup_general, "autocenter", L("Auto-center parts"), L("If this is enabled, Slic3r will auto-center objects around the print bed center."), - app_config->get("autocenter") == "1"); + app_config->get_bool("autocenter")); append_bool_option(m_optgroup_general, "background_processing", L("Background processing"), L("If this is enabled, Slic3r will pre-process objects as soon " "as they\'re loaded in order to save time when exporting G-code."), - app_config->get("background_processing") == "1"); + app_config->get_bool("background_processing")); append_bool_option(m_optgroup_general, "alert_when_supports_needed", L("Alert when supports needed"), L("If this is enabled, Slic3r will raise alerts when it detects " "issues in the sliced object, that can be resolved with supports (and brim). " "Examples of such issues are floating object parts, unsupported extrusions and low bed adhesion."), - app_config->get("alert_when_supports_needed") == "1"); + app_config->get_bool("alert_when_supports_needed")); m_optgroup_general->append_separator(); @@ -284,19 +284,19 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_general, "export_sources_full_pathnames", L("Export sources full pathnames to 3mf and amf"), L("If enabled, allows the Reload from disk command to automatically find and load the files when invoked."), - app_config->get("export_sources_full_pathnames") == "1"); + app_config->get_bool("export_sources_full_pathnames")); #ifdef _WIN32 // Please keep in sync with ConfigWizard append_bool_option(m_optgroup_general, "associate_3mf", L("Associate .3mf files to PrusaSlicer"), L("If enabled, sets PrusaSlicer as default application to open .3mf files."), - app_config->get("associate_3mf") == "1"); + app_config->get_bool("associate_3mf")); append_bool_option(m_optgroup_general, "associate_stl", L("Associate .stl files to PrusaSlicer"), L("If enabled, sets PrusaSlicer as default application to open .stl files."), - app_config->get("associate_stl") == "1"); + app_config->get_bool("associate_stl")); #endif // _WIN32 m_optgroup_general->append_separator(); @@ -306,23 +306,23 @@ void PreferencesDialog::build() L("Update built-in Presets automatically"), L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded " "into a separate temporary location. When a new preset version becomes available it is offered at application startup."), - app_config->get("preset_update") == "1"); + app_config->get_bool("preset_update")); append_bool_option(m_optgroup_general, "no_defaults", L("Suppress \" - default - \" presets"), L("Suppress \" - default - \" presets in the Print / Filament / Printer selections once there are any other valid presets available."), - app_config->get("no_defaults") == "1"); + app_config->get_bool("no_defaults")); append_bool_option(m_optgroup_general, "no_templates", L("Suppress \" Template \" filament presets"), L("Suppress \" Template \" filament presets in configuration wizard and sidebar visibility."), - app_config->get("no_templates") == "1"); + app_config->get_bool("no_templates")); append_bool_option(m_optgroup_general, "show_incompatible_presets", L("Show incompatible print and filament presets"), L("When checked, the print and filament presets are shown in the preset editor " "even if they are marked as incompatible with the active printer"), - app_config->get("show_incompatible_presets") == "1"); + app_config->get_bool("show_incompatible_presets")); m_optgroup_general->append_separator(); @@ -335,7 +335,7 @@ void PreferencesDialog::build() L("Show drop project dialog"), L("When checked, whenever dragging and dropping a project file on the application, shows a dialog asking to select the action to take on the file to load."), #endif - app_config->get("show_drop_project_dialog") == "1"); + app_config->get_bool("show_drop_project_dialog")); append_bool_option(m_optgroup_general, "single_instance", #if __APPLE__ @@ -346,7 +346,7 @@ void PreferencesDialog::build() L("Allow just a single PrusaSlicer instance"), L("If this is enabled, when starting PrusaSlicer and another instance of the same PrusaSlicer is already running, that instance will be reactivated instead."), #endif - app_config->has("single_instance") ? app_config->get("single_instance") == "1" : false ); + app_config->has("single_instance") ? app_config->get_bool("single_instance") : false ); m_optgroup_general->append_separator(); @@ -381,7 +381,7 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_general, "associate_gcode", L("Associate .gcode files to PrusaSlicer G-code Viewer"), L("If enabled, sets PrusaSlicer G-code Viewer as default application to open .gcode files."), - app_config->get("associate_gcode") == "1"); + app_config->get_bool("associate_gcode")); } #endif // _WIN32 @@ -390,7 +390,7 @@ void PreferencesDialog::build() L("Use Retina resolution for the 3D scene"), L("If enabled, the 3D scene will be rendered in Retina resolution. " "If you are experiencing 3D performance problems, disabling this option may help."), - app_config->get("use_retina_opengl") == "1"); + app_config->get_bool("use_retina_opengl")); #endif m_optgroup_general->append_separator(); @@ -399,24 +399,24 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_general, "show_splash_screen", L("Show splash screen"), L("Show splash screen"), - app_config->get("show_splash_screen") == "1"); + app_config->get_bool("show_splash_screen")); append_bool_option(m_optgroup_general, "restore_win_position", L("Restore window position on start"), L("If enabled, PrusaSlicer will be open at the position it was closed"), - app_config->get("restore_win_position") == "1"); + app_config->get_bool("restore_win_position")); // Clear Undo / Redo stack on new project append_bool_option(m_optgroup_general, "clear_undo_redo_stack_on_new_project", L("Clear Undo / Redo stack on new project"), L("Clear Undo / Redo stack on new project or when an existing project is loaded."), - app_config->get("clear_undo_redo_stack_on_new_project") == "1"); + app_config->get_bool("clear_undo_redo_stack_on_new_project")); #if defined(_WIN32) || defined(__APPLE__) append_bool_option(m_optgroup_general, "use_legacy_3DConnexion", L("Enable support for legacy 3DConnexion devices"), L("If enabled, the legacy 3DConnexion devices settings dialog is available by pressing CTRL+M"), - app_config->get("use_legacy_3DConnexion") == "1"); + app_config->get_bool("use_legacy_3DConnexion")); #endif // _WIN32 || __APPLE__ activate_options_tab(m_optgroup_general); @@ -434,17 +434,17 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_camera, "use_perspective_camera", L("Use perspective camera"), L("If enabled, use perspective camera. If not enabled, use orthographic camera."), - app_config->get("use_perspective_camera") == "1"); + app_config->get_bool("use_perspective_camera")); append_bool_option(m_optgroup_camera, "use_free_camera", L("Use free camera"), L("If enabled, use free camera. If not enabled, use constrained camera."), - app_config->get("use_free_camera") == "1"); + app_config->get_bool("use_free_camera")); append_bool_option(m_optgroup_camera, "reverse_mouse_wheel_zoom", L("Reverse direction of zoom with mouse wheel"), L("If enabled, reverses the direction of zoom with mouse wheel"), - app_config->get("reverse_mouse_wheel_zoom") == "1"); + app_config->get_bool("reverse_mouse_wheel_zoom")); activate_options_tab(m_optgroup_camera); @@ -492,48 +492,48 @@ void PreferencesDialog::build() L("Sequential slider applied only to top layer"), L("If enabled, changes made using the sequential slider, in preview, apply only to gcode top layer." "If disabled, changes made using the sequential slider, in preview, apply to the whole gcode."), - app_config->get("seq_top_layer_only") == "1"); + app_config->get_bool("seq_top_layer_only")); if (is_editor) { append_bool_option(m_optgroup_gui, "show_collapse_button", L("Show sidebar collapse/expand button"), L("If enabled, the button for the collapse sidebar will be appeared in top right corner of the 3D Scene"), - app_config->get("show_collapse_button") == "1"); + app_config->get_bool("show_collapse_button")); /* append_bool_option(m_optgroup_gui, "suppress_hyperlinks", L("Suppress to open hyperlink in browser"), L("If enabled, PrusaSlicer will not open a hyperlinks in your browser."), //L("If enabled, the descriptions of configuration parameters in settings tabs wouldn't work as hyperlinks. " // "If disabled, the descriptions of configuration parameters in settings tabs will work as hyperlinks."), - app_config->get("suppress_hyperlinks") == "1"); + app_config->get_bool("suppress_hyperlinks")); */ append_bool_option(m_optgroup_gui, "color_mapinulation_panel", L("Use colors for axes values in Manipulation panel"), L("If enabled, the axes names and axes values will be colorized according to the axes colors. " "If disabled, old UI will be used."), - app_config->get("color_mapinulation_panel") == "1"); + app_config->get_bool("color_mapinulation_panel")); append_bool_option(m_optgroup_gui, "order_volumes", L("Order object volumes by types"), L("If enabled, volumes will be always ordered inside the object. Correct order is Model Part, Negative Volume, Modifier, Support Blocker and Support Enforcer. " "If disabled, you can reorder Model Parts, Negative Volumes and Modifiers. But one of the model parts have to be on the first place."), - app_config->get("order_volumes") == "1"); + app_config->get_bool("order_volumes")); append_bool_option(m_optgroup_gui, "non_manifold_edges", L("Show non-manifold edges"), L("If enabled, shows non-manifold edges."), - app_config->get("non_manifold_edges") == "1"); + app_config->get_bool("non_manifold_edges")); append_bool_option(m_optgroup_gui, "allow_auto_color_change", L("Allow automatically color change"), L("If enabled, related notification will be shown, when sliced object looks like a logo or a sign."), - app_config->get("allow_auto_color_change") == "1"); + app_config->get_bool("allow_auto_color_change")); #ifdef _MSW_DARK_MODE append_bool_option(m_optgroup_gui, "tabs_as_menu", L("Set settings tabs as menu items (experimental)"), L("If enabled, Settings Tabs will be placed as menu items. If disabled, old UI will be used."), - app_config->get("tabs_as_menu") == "1"); + app_config->get_bool("tabs_as_menu")); #endif m_optgroup_gui->append_separator(); @@ -541,7 +541,7 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_gui, "show_hints", L("Show \"Tip of the day\" notification after start"), L("If enabled, useful hints are displayed at startup."), - app_config->get("show_hints") == "1"); + app_config->get_bool("show_hints")); append_enum_option(m_optgroup_gui, "notify_release", L("Notify about new releases"), @@ -557,7 +557,7 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_gui, "use_custom_toolbar_size", L("Use custom size for toolbar icons"), L("If enabled, you can change size of toolbar icons manually."), - app_config->get("use_custom_toolbar_size") == "1"); + app_config->get_bool("use_custom_toolbar_size")); } activate_options_tab(m_optgroup_gui); @@ -568,7 +568,7 @@ void PreferencesDialog::build() m_optgroup_gui->get_field("notify_release")->set_value(val, false); create_icon_size_slider(); - m_icon_size_sizer->ShowItems(app_config->get("use_custom_toolbar_size") == "1"); + m_icon_size_sizer->ShowItems(app_config->get_bool("use_custom_toolbar_size")); create_settings_mode_widget(); create_settings_text_color_widget(); @@ -594,12 +594,12 @@ void PreferencesDialog::build() L("If enabled, PrusaSlicer will not open a hyperlinks in your browser."), //L("If enabled, the descriptions of configuration parameters in settings tabs wouldn't work as hyperlinks. " // "If disabled, the descriptions of configuration parameters in settings tabs will work as hyperlinks."), - app_config->get("suppress_hyperlinks") == "1"); + app_config->get_bool("suppress_hyperlinks")); append_bool_option(m_optgroup_other, "downloader_url_registered", L("Allow downloads from Printables.com"), L("If enabled, PrusaSlicer will allow to download from Printables.com"), - app_config->get("downloader_url_registered") == "1"); + app_config->get_bool("downloader_url_registered")); activate_options_tab(m_optgroup_other); @@ -619,7 +619,7 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_render, "use_environment_map", L("Use environment map"), L("If enabled, renders object using the environment map."), - app_config->get("use_environment_map") == "1"); + app_config->get_bool("use_environment_map")); activate_options_tab(m_optgroup_render); #endif // ENABLE_ENVIRONMENT_MAP @@ -638,7 +638,7 @@ void PreferencesDialog::build() append_bool_option(m_optgroup_dark_mode, "dark_color_mode", L("Enable dark mode"), L("If enabled, UI will use Dark mode colors. If disabled, old UI will be used."), - app_config->get("dark_color_mode") == "1"); + app_config->get_bool("dark_color_mode")); if (wxPlatformInfo::Get().GetOSMajorVersion() >= 10) // Use system menu just for Window newer then Windows 10 // Use menu with ownerdrawn items by default on systems older then Windows 10 @@ -647,7 +647,7 @@ void PreferencesDialog::build() L("Use system menu for application"), L("If enabled, application will use the standart Windows system menu,\n" "but on some combination od display scales it can look ugly. If disabled, old UI will be used."), - app_config->get("sys_menu_enabled") == "1"); + app_config->get_bool("sys_menu_enabled")); } activate_options_tab(m_optgroup_dark_mode); @@ -799,7 +799,7 @@ void PreferencesDialog::revert(wxEvent&) app_config->set("custom_toolbar_size", (boost::format("%d") % m_custom_toolbar_size).str()); m_icon_size_slider->SetValue(m_custom_toolbar_size); } - 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_bool("use_custom_toolbar_size"))) { app_config->set("use_custom_toolbar_size", m_use_custom_toolbar_size ? "1" : "0"); m_optgroup_gui->set_value("use_custom_toolbar_size", m_use_custom_toolbar_size); @@ -823,17 +823,17 @@ void PreferencesDialog::revert(wxEvent&) continue; } if (key == "old_settings_layout_mode") { - m_rb_old_settings_layout_mode->SetValue(app_config->get(key) == "1"); + m_rb_old_settings_layout_mode->SetValue(app_config->get_bool(key)); m_settings_layout_changed = false; continue; } if (key == "new_settings_layout_mode") { - m_rb_new_settings_layout_mode->SetValue(app_config->get(key) == "1"); + m_rb_new_settings_layout_mode->SetValue(app_config->get_bool(key)); m_settings_layout_changed = false; continue; } if (key == "dlg_settings_layout_mode") { - m_rb_dlg_settings_layout_mode->SetValue(app_config->get(key) == "1"); + m_rb_dlg_settings_layout_mode->SetValue(app_config->get_bool(key)); m_settings_layout_changed = false; continue; } @@ -846,11 +846,11 @@ void PreferencesDialog::revert(wxEvent&) , m_optgroup_render #endif // ENABLE_ENVIRONMENT_MAP }) { - if (opt_group->set_value(key, app_config->get(key) == "1")) + if (opt_group->set_value(key, app_config->get_bool(key))) break; } if (key == "tabs_as_menu") { - m_rb_new_settings_layout_mode->Show(app_config->get(key) != "1"); + m_rb_new_settings_layout_mode->Show(!app_config->get_bool(key)); refresh_og(m_optgroup_gui); continue; } @@ -993,12 +993,12 @@ void PreferencesDialog::create_settings_mode_widget() }); }; - add_radio(&m_rb_old_settings_layout_mode, ++id, app_config->get("old_settings_layout_mode") == "1"); - add_radio(&m_rb_new_settings_layout_mode, ++id, app_config->get("new_settings_layout_mode") == "1"); - add_radio(&m_rb_dlg_settings_layout_mode, ++id, app_config->get("dlg_settings_layout_mode") == "1"); + add_radio(&m_rb_old_settings_layout_mode, ++id, app_config->get_bool("old_settings_layout_mode")); + add_radio(&m_rb_new_settings_layout_mode, ++id, app_config->get_bool("new_settings_layout_mode")); + add_radio(&m_rb_dlg_settings_layout_mode, ++id, app_config->get_bool("dlg_settings_layout_mode")); #ifdef _MSW_DARK_MODE - if (app_config->get("tabs_as_menu") == "1") { + if (app_config->get_bool("tabs_as_menu")) { m_rb_new_settings_layout_mode->Hide(); if (m_rb_new_settings_layout_mode->GetValue()) { m_rb_new_settings_layout_mode->SetValue(false); diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index 501d61423c..568f9fe670 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -300,7 +300,7 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro boost::asio::ip::address host_ip = boost::asio::ip::make_address(host, ec); if (!ec) { resolved_addr.push_back(host_ip); - } else if ( GUI::get_app_config()->get("allow_ip_resolve") == "1" && boost::algorithm::ends_with(host, ".local")){ + } else if ( GUI::get_app_config()->get_bool("allow_ip_resolve") && boost::algorithm::ends_with(host, ".local")){ Bonjour("octoprint") .set_hostname(host) .set_retries(5) // number of rounds of queries send @@ -428,7 +428,7 @@ bool OctoPrint::upload_inner_with_host(PrintHostUpload upload_data, ProgressFn p #ifdef WIN32 // Workaround for Windows 10/11 mDNS resolve issue, where two mDNS resolves in succession fail. - if (m_host.find("https://") == 0 || test_msg_or_host_ip.empty() || GUI::get_app_config()->get("allow_ip_resolve") != "1") + if (m_host.find("https://") == 0 || test_msg_or_host_ip.empty() || !GUI::get_app_config()->get_bool("allow_ip_resolve")) #endif // _WIN32 { // If https is entered we assume signed ceritificate is being used @@ -972,7 +972,7 @@ bool PrusaLink::upload_inner_with_host(PrintHostUpload upload_data, ProgressFn p storage_path += (upload_data.storage.empty() ? "/local" : upload_data.storage); #ifdef WIN32 // Workaround for Windows 10/11 mDNS resolve issue, where two mDNS resolves in succession fail. - if (m_host.find("https://") == 0 || test_msg_or_host_ip.empty() || GUI::get_app_config()->get("allow_ip_resolve") != "1") + if (m_host.find("https://") == 0 || test_msg_or_host_ip.empty() || !GUI::get_app_config()->get_bool("allow_ip_resolve")) #endif // _WIN32 { // If https is entered we assume signed ceritificate is being used diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index cd3935ea00..2b69bff528 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -213,7 +213,7 @@ void PresetUpdater::priv::set_download_prefs(const AppConfig *app_config) { enabled_version_check = app_config->get("notify_release") != "none"; version_check_url = app_config->version_check_url(); - enabled_config_update = app_config->get("preset_update") == "1" && !app_config->legacy_datadir(); + enabled_config_update = app_config->get_bool("preset_update") && !app_config->legacy_datadir(); } // Downloads a file (http get operation). Cancels if the Updater is being destroyed. From 4d5b85e675311f1e470ad6b31a5debf71ef1fd57 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 29 Dec 2022 19:26:38 +0100 Subject: [PATCH 4/7] Implemented FR #6994 - Set Number of Instances for multiple selected meshes --- src/slic3r/GUI/GUI_Factories.cpp | 8 ++++- src/slic3r/GUI/Plater.cpp | 53 +++++++++++++++++--------------- src/slic3r/GUI/Plater.hpp | 8 ++--- src/slic3r/GUI/Selection.cpp | 10 ++++++ src/slic3r/GUI/Selection.hpp | 2 ++ 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index c069475659..df8ace79a3 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -1218,9 +1218,15 @@ wxMenu* MenuFactory::multi_selection_menu() append_menu_item_merge_to_multipart_object(menu); if (extruders_count() > 1) append_menu_item_change_extruder(menu); - if (list_model()->GetItemType(sels[0]) != itVolume) + if (list_model()->GetItemType(sels[0]) != itVolume) { append_menu_item_printable(menu); + if (wxGetApp().get_mode() != comSimple) + append_menu_item(menu, wxID_ANY, _L("Set number of instances") + dots, _L("Change the number of instances of the selected objects"), + [](wxCommandEvent&) { plater()->set_number_of_copies(); }, "number_of_copies", nullptr, + []() { return plater()->can_increase_instances(); }, m_parent); + } + return menu; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 505c33a1cf..4fc59db625 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1941,7 +1941,7 @@ struct Plater::priv bool can_delete() const; bool can_delete_all() const; bool can_increase_instances() const; - bool can_decrease_instances() const; + bool can_decrease_instances(int obj_idx = -1) const; bool can_split_to_objects() const; bool can_split_to_volumes() const; bool can_arrange() const; @@ -5004,18 +5004,18 @@ bool Plater::priv::can_increase_instances() const // Prevent strobo effect during editing emboss parameters. if (q->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::Emboss) return false; - const int obj_idx = get_selected_object_idx(); - return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && - !sidebar->obj_list()->has_selected_cut_object(); + const auto obj_idxs = get_selection().get_object_idxs(); + return !obj_idxs.empty() && !sidebar->obj_list()->has_selected_cut_object(); } -bool Plater::priv::can_decrease_instances() const +bool Plater::priv::can_decrease_instances(int obj_idx /*= -1*/) const { if (!m_worker.is_idle() || q->canvas3D()->get_gizmos_manager().is_in_editing_mode()) return false; - const int obj_idx = get_selected_object_idx(); + if (obj_idx < 0) + obj_idx = get_selected_object_idx(); return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && (model.objects[obj_idx]->instances.size() > 1) && !sidebar->obj_list()->has_selected_cut_object(); @@ -6273,13 +6273,14 @@ void Plater::remove_selected() p->view3D->delete_selected(); } -void Plater::increase_instances(size_t num) +void Plater::increase_instances(size_t num, int obj_idx/* = -1*/) { if (! can_increase_instances()) { return; } Plater::TakeSnapshot snapshot(this, _L("Increase Instances")); - int obj_idx = p->get_selected_object_idx(); + if (obj_idx < 0) + obj_idx = p->get_selected_object_idx(); ModelObject* model_object = p->model.objects[obj_idx]; ModelInstance* model_instance = model_object->instances.back(); @@ -6307,13 +6308,14 @@ void Plater::increase_instances(size_t num) this->p->schedule_background_process(); } -void Plater::decrease_instances(size_t num) +void Plater::decrease_instances(size_t num, int obj_idx/* = -1*/) { - if (! can_decrease_instances()) { return; } + if (! can_decrease_instances(obj_idx)) { return; } Plater::TakeSnapshot snapshot(this, _L("Decrease Instances")); - int obj_idx = p->get_selected_object_idx(); + if (obj_idx < 0) + obj_idx = p->get_selected_object_idx(); ModelObject* model_object = p->model.objects[obj_idx]; if (model_object->instances.size() > num) { @@ -6354,26 +6356,27 @@ static long GetNumberFromUser( const wxString& msg, #endif } -void Plater::set_number_of_copies(/*size_t num*/) +void Plater::set_number_of_copies() { - int obj_idx = p->get_selected_object_idx(); - if (obj_idx == -1) + const auto obj_idxs = get_selection().get_object_idxs(); + if (obj_idxs.empty()) return; - ModelObject* model_object = p->model.objects[obj_idx]; - + const size_t init_cnt = obj_idxs.size() == 1 ? p->model.objects[*obj_idxs.begin()]->instances.size() : 1; const int num = GetNumberFromUser( " ", _L("Enter the number of copies:"), - _L("Copies of the selected object"), model_object->instances.size(), 0, 1000, this ); + _L("Copies of the selected object"), init_cnt, 0, 1000, this ); if (num < 0) return; + 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) - increase_instances(diff); - else if (diff < 0) - decrease_instances(-diff); + for (const auto obj_idx : obj_idxs) { + ModelObject* model_object = p->model.objects[obj_idx]; + const int diff = num - (int)model_object->instances.size(); + if (diff > 0) + increase_instances(diff, int(obj_idx)); + else if (diff < 0) + decrease_instances(-diff, int(obj_idx)); + } } void Plater::fill_bed_with_instances() @@ -7665,7 +7668,7 @@ void Plater::init_notification_manager() bool Plater::can_delete() const { return p->can_delete(); } bool Plater::can_delete_all() const { return p->can_delete_all(); } bool Plater::can_increase_instances() const { return p->can_increase_instances(); } -bool Plater::can_decrease_instances() const { return p->can_decrease_instances(); } +bool Plater::can_decrease_instances(int obj_idx/* = -1*/) const { return p->can_decrease_instances(obj_idx); } bool Plater::can_set_instance_to_object() const { return p->can_set_instance_to_object(); } bool Plater::can_fix_through_netfabb() const { return p->can_fix_through_netfabb(); } bool Plater::can_simplify() const { return p->can_simplify(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index d6f2d9b79e..1997293d84 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -249,9 +249,9 @@ public: void reset_with_confirm(); bool delete_object_from_model(size_t obj_idx); void remove_selected(); - void increase_instances(size_t num = 1); - void decrease_instances(size_t num = 1); - void set_number_of_copies(/*size_t num*/); + void increase_instances(size_t num = 1, int obj_idx = -1); + void decrease_instances(size_t num = 1, int obj_idx = -1); + void set_number_of_copies(); void fill_bed_with_instances(); bool is_selection_empty() const; void scale_selection_to_fit_print_volume(); @@ -350,7 +350,7 @@ public: bool can_delete() const; bool can_delete_all() const; bool can_increase_instances() const; - bool can_decrease_instances() const; + bool can_decrease_instances(int obj_idx = -1) const; bool can_set_instance_to_object() const; bool can_fix_through_netfabb() const; bool can_simplify() const; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index dc016f2141..9a56c17436 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -2145,6 +2145,16 @@ std::vector Selection::get_unselected_volume_idxs_from(const std:: return idxs; } +std::set Selection::get_object_idxs() const +{ + std::set idxs; + + for (unsigned int i : m_list) + idxs.emplace((*m_volumes)[i]->object_idx()); + + return idxs; +} + void Selection::update_valid() { m_valid = (m_volumes != nullptr) && (m_model != nullptr); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 29398eabfd..8a2ba1bfa1 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -453,6 +453,8 @@ public: std::vector get_missing_volume_idxs_from(const std::vector& volume_idxs) const; // returns the list of idxs of the volumes contained in the given list but not in the selection std::vector get_unselected_volume_idxs_from(const std::vector& volume_idxs) const; + // returns the list of idxs of the objects which are in the selection + std::set get_object_idxs() const; #if ENABLE_WORLD_COORDINATE_DEBUG void render_debug_window() const; From a9221c3c5b595506fe7ffdf9f2b375e040c533ff Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Feb 2023 09:40:36 +0100 Subject: [PATCH 5/7] Fix for #9692 - Configuration Update warning typo --- resources/localization/PrusaSlicer.pot | 2 +- resources/localization/ca/PrusaSlicer_ca.po | 2 +- resources/localization/cs/PrusaSlicer_cs.po | 2 +- resources/localization/de/PrusaSlicer_de.po | 2 +- resources/localization/en/PrusaSlicer_en.po | 2 +- resources/localization/es/PrusaSlicer_es.po | 2 +- resources/localization/fr/PrusaSlicer_fr.po | 2 +- resources/localization/hu/PrusaSlicer_hu.po | 2 +- resources/localization/it/PrusaSlicer_it.po | 2 +- resources/localization/ja/PrusaSlicer_ja.po | 2 +- resources/localization/ko/PrusaSlicer_ko_KR.po | 2 +- resources/localization/ko_KR/PrusaSlicer_ko.po | 2 +- resources/localization/ko_KR/PrusaSlicer_ko_KR.po | 2 +- resources/localization/nl/PrusaSlicer_nl.po | 2 +- resources/localization/pl/PrusaSlicer_pl.po | 2 +- resources/localization/pt_BR/PrusaSlicer_pt_BR.po | 2 +- resources/localization/ru/PrusaSlicer_ru.po | 2 +- resources/localization/tr/PrusaSlicer_tr.po | 2 +- resources/localization/uk/PrusaSlicer_uk.po | 2 +- resources/localization/zh_CN/PrusaSlicer_zh_CN.po | 2 +- resources/localization/zh_TW/PrusaSlicer_zh_TW.po | 2 +- src/slic3r/Utils/PresetUpdater.cpp | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/resources/localization/PrusaSlicer.pot b/resources/localization/PrusaSlicer.pot index 50e92a6e8b..7db135424a 100644 --- a/resources/localization/PrusaSlicer.pot +++ b/resources/localization/PrusaSlicer.pot @@ -11075,7 +11075,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/resources/localization/ca/PrusaSlicer_ca.po b/resources/localization/ca/PrusaSlicer_ca.po index 7eb6ac8b4d..1afe8110da 100644 --- a/resources/localization/ca/PrusaSlicer_ca.po +++ b/resources/localization/ca/PrusaSlicer_ca.po @@ -11845,7 +11845,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "L'actualització de la configuració fa que es perdi la modificació de la " diff --git a/resources/localization/cs/PrusaSlicer_cs.po b/resources/localization/cs/PrusaSlicer_cs.po index 64d7acf36f..f81773f876 100644 --- a/resources/localization/cs/PrusaSlicer_cs.po +++ b/resources/localization/cs/PrusaSlicer_cs.po @@ -2392,7 +2392,7 @@ msgstr "Zálohy konfigurace" #: src/slic3r/Utils/PresetUpdater.cpp:777 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Aktualizace konfigurace způsobí ztrátu změn v přednastaveních.\n" diff --git a/resources/localization/de/PrusaSlicer_de.po b/resources/localization/de/PrusaSlicer_de.po index 7da07ea90d..bfbbbbcc4e 100644 --- a/resources/localization/de/PrusaSlicer_de.po +++ b/resources/localization/de/PrusaSlicer_de.po @@ -2392,7 +2392,7 @@ msgstr "Konfigurations-Momentaufnahmen" #: src/slic3r/Utils/PresetUpdater.cpp:777 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Bei einer Konfigurationsaktualisierung gehen voreingestellte Änderungen " diff --git a/resources/localization/en/PrusaSlicer_en.po b/resources/localization/en/PrusaSlicer_en.po index 3c6f843472..823734cf1d 100644 --- a/resources/localization/en/PrusaSlicer_en.po +++ b/resources/localization/en/PrusaSlicer_en.po @@ -11084,7 +11084,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/resources/localization/es/PrusaSlicer_es.po b/resources/localization/es/PrusaSlicer_es.po index 3cf6271792..048b2ab4fe 100644 --- a/resources/localization/es/PrusaSlicer_es.po +++ b/resources/localization/es/PrusaSlicer_es.po @@ -2372,7 +2372,7 @@ msgstr "Instantáneas de la Configuración" #: src/slic3r/Utils/PresetUpdater.cpp:777 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "La actualización de la configuración hace que se pierda la modificación de " diff --git a/resources/localization/fr/PrusaSlicer_fr.po b/resources/localization/fr/PrusaSlicer_fr.po index a7b9fe626e..1f5aefbbc9 100644 --- a/resources/localization/fr/PrusaSlicer_fr.po +++ b/resources/localization/fr/PrusaSlicer_fr.po @@ -2399,7 +2399,7 @@ msgstr "Instantanés de Configuration capturés" #: src/slic3r/Utils/PresetUpdater.cpp:777 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Les mises à jour de configuration entraînent une perte de modification des " diff --git a/resources/localization/hu/PrusaSlicer_hu.po b/resources/localization/hu/PrusaSlicer_hu.po index 1fbb6b6bc0..4425b67f4c 100644 --- a/resources/localization/hu/PrusaSlicer_hu.po +++ b/resources/localization/hu/PrusaSlicer_hu.po @@ -11832,7 +11832,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "A Konfigurációs frissítések hatására az előre beállított módosítások " diff --git a/resources/localization/it/PrusaSlicer_it.po b/resources/localization/it/PrusaSlicer_it.po index edc1574d80..8f374d140c 100644 --- a/resources/localization/it/PrusaSlicer_it.po +++ b/resources/localization/it/PrusaSlicer_it.po @@ -2379,7 +2379,7 @@ msgstr "Istantanee di Configurazione" #: src/slic3r/Utils/PresetUpdater.cpp:777 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Gli aggiornamenti di configurazione causano la perdita della modifica del " diff --git a/resources/localization/ja/PrusaSlicer_ja.po b/resources/localization/ja/PrusaSlicer_ja.po index df0cde6174..8d93b06419 100644 --- a/resources/localization/ja/PrusaSlicer_ja.po +++ b/resources/localization/ja/PrusaSlicer_ja.po @@ -2338,7 +2338,7 @@ msgstr "設定のスナップショット" #: src/slic3r/Utils/PresetUpdater.cpp:777 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "構成のアップデートをすると、プリセットの変更が失われます。\n" diff --git a/resources/localization/ko/PrusaSlicer_ko_KR.po b/resources/localization/ko/PrusaSlicer_ko_KR.po index 566b0f321a..8d86b1c4a2 100644 --- a/resources/localization/ko/PrusaSlicer_ko_KR.po +++ b/resources/localization/ko/PrusaSlicer_ko_KR.po @@ -11257,7 +11257,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/resources/localization/ko_KR/PrusaSlicer_ko.po b/resources/localization/ko_KR/PrusaSlicer_ko.po index 4268bbac32..9332e89498 100644 --- a/resources/localization/ko_KR/PrusaSlicer_ko.po +++ b/resources/localization/ko_KR/PrusaSlicer_ko.po @@ -11398,7 +11398,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/resources/localization/ko_KR/PrusaSlicer_ko_KR.po b/resources/localization/ko_KR/PrusaSlicer_ko_KR.po index af5a19b781..5217816196 100644 --- a/resources/localization/ko_KR/PrusaSlicer_ko_KR.po +++ b/resources/localization/ko_KR/PrusaSlicer_ko_KR.po @@ -11398,7 +11398,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/resources/localization/nl/PrusaSlicer_nl.po b/resources/localization/nl/PrusaSlicer_nl.po index 13783c8c0d..ca01fdcb5d 100644 --- a/resources/localization/nl/PrusaSlicer_nl.po +++ b/resources/localization/nl/PrusaSlicer_nl.po @@ -11774,7 +11774,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Configuratie-updates veroorzaken een verlies van preset-aanpassingen.\n" diff --git a/resources/localization/pl/PrusaSlicer_pl.po b/resources/localization/pl/PrusaSlicer_pl.po index b6168a6f34..7e09abd1dd 100644 --- a/resources/localization/pl/PrusaSlicer_pl.po +++ b/resources/localization/pl/PrusaSlicer_pl.po @@ -2403,7 +2403,7 @@ msgstr "Zrzuty konfiguracji" #: src/slic3r/Utils/PresetUpdater.cpp:777 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Aktualizacja konfiguracji spowoduje utratę zmian w zestawach ustawień.\n" diff --git a/resources/localization/pt_BR/PrusaSlicer_pt_BR.po b/resources/localization/pt_BR/PrusaSlicer_pt_BR.po index ba19e980ba..b978c3f390 100644 --- a/resources/localization/pt_BR/PrusaSlicer_pt_BR.po +++ b/resources/localization/pt_BR/PrusaSlicer_pt_BR.po @@ -11769,7 +11769,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Atualizações de configuração causam perda de modificação predefinida.\n" diff --git a/resources/localization/ru/PrusaSlicer_ru.po b/resources/localization/ru/PrusaSlicer_ru.po index fa54c9db13..08a344cda2 100644 --- a/resources/localization/ru/PrusaSlicer_ru.po +++ b/resources/localization/ru/PrusaSlicer_ru.po @@ -11854,7 +11854,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "Обновление конфигурации приводит к потере изменённых профилей.\n" diff --git a/resources/localization/tr/PrusaSlicer_tr.po b/resources/localization/tr/PrusaSlicer_tr.po index 9e45c134d9..699ced6a16 100644 --- a/resources/localization/tr/PrusaSlicer_tr.po +++ b/resources/localization/tr/PrusaSlicer_tr.po @@ -11233,7 +11233,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/resources/localization/uk/PrusaSlicer_uk.po b/resources/localization/uk/PrusaSlicer_uk.po index 318d6009c4..fa64859db7 100644 --- a/resources/localization/uk/PrusaSlicer_uk.po +++ b/resources/localization/uk/PrusaSlicer_uk.po @@ -11543,7 +11543,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/resources/localization/zh_CN/PrusaSlicer_zh_CN.po b/resources/localization/zh_CN/PrusaSlicer_zh_CN.po index 6fba6321dd..d5570ca5c4 100644 --- a/resources/localization/zh_CN/PrusaSlicer_zh_CN.po +++ b/resources/localization/zh_CN/PrusaSlicer_zh_CN.po @@ -11363,7 +11363,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" "配置更新会导致预设修改丢失。\n" diff --git a/resources/localization/zh_TW/PrusaSlicer_zh_TW.po b/resources/localization/zh_TW/PrusaSlicer_zh_TW.po index 2580fee1ff..6df1fc778e 100644 --- a/resources/localization/zh_TW/PrusaSlicer_zh_TW.po +++ b/resources/localization/zh_TW/PrusaSlicer_zh_TW.po @@ -11083,7 +11083,7 @@ msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:1171 msgid "" -"Configuration Updates causes a lost of preset modification.\n" +"Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary." msgstr "" diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 2b69bff528..645be4a6b3 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -1168,7 +1168,7 @@ void PresetUpdater::slic3r_update_notify() static bool reload_configs_update_gui() { - wxString header = _L("Configuration Updates causes a lost of preset modification.\n" + wxString header = _L("Configuration Updates causes a loss of preset modification.\n" "So, check unsaved changes and save them if necessary."); if (!GUI::wxGetApp().check_and_save_current_preset_changes(_L("Updating"), header, false )) return false; From 4162689a6574b1ec932052b3f7c3299e44245070 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Feb 2023 10:18:06 +0100 Subject: [PATCH 6/7] Unify Tree/Organic terminology. + Implemented Enabling/Disabling for parameters of Organic support SPE-1478(https://dev.prusa3d.com/browse/SPE-1478) --- src/libslic3r/PrintConfig.cpp | 18 +++++++++--------- src/slic3r/GUI/ConfigManipulation.cpp | 7 +++++++ src/slic3r/GUI/Tab.cpp | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index f66bf7086e..9ba8d7cc74 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2786,7 +2786,7 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionBool(true)); def = this->add("support_tree_angle", coFloat); - def->label = L("Tree Support Maximum Branch Angle"); + def->label = L("Maximum Branch Angle"); def->category = L("Support material"); def->tooltip = L("The maximum angle of the branches, when the branches have to avoid the model. " "Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach."); @@ -2797,7 +2797,7 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloat(40)); def = this->add("support_tree_angle_slow", coFloat); - def->label = L("Tree Support Preferred Branch Angle"); + def->label = L("Preferred Branch Angle"); def->category = L("Support material"); def->tooltip = L("The preferred angle of the branches, when they do not have to avoid the model. " "Use a lower angle to make them more vertical and more stable. Use a higher angle for branches to merge faster."); @@ -2808,18 +2808,18 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloat(25)); def = this->add("support_tree_tip_diameter", coFloat); - def->label = L("Tree Support Tip Diameter"); + def->label = L("Tip Diameter"); def->category = L("Support material"); - def->tooltip = L("The diameter of the top of the tip of the branches of tree support."); + def->tooltip = L("The diameter of the top of the tip of the branches of organic support."); def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.8)); def = this->add("support_tree_branch_diameter", coFloat); - def->label = L("Tree Support Branch Diameter"); + def->label = L("Branch Diameter"); def->category = L("Support material"); - def->tooltip = L("The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. " + def->tooltip = L("The diameter of the thinnest branches of organic support. Thicker branches are more sturdy. " "Branches towards the base will be thicker than this."); def->sidetext = L("mm"); def->min = 0; @@ -2827,11 +2827,11 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloat(2)); def = this->add("support_tree_branch_diameter_angle", coFloat); - def->label = L("Tree Support Branch Diameter Angle"); + def->label = L("Branch Diameter Angle"); def->category = L("Support material"); def->tooltip = L("The angle of the branches' diameter as they gradually become thicker towards the bottom. " "An angle of 0 will cause the branches to have uniform thickness over their length. " - "A bit of an angle can increase stability of the tree support."); + "A bit of an angle can increase stability of the organic support."); def->sidetext = L("°"); def->min = 0; def->max = 15; @@ -2839,7 +2839,7 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloat(5)); def = this->add("support_tree_top_rate", coPercent); - def->label = L("Tree Support Branch Density"); + def->label = L("Branch Density"); def->category = L("Support material"); def->tooltip = L("Adjusts the density of the support structure used to generate the tips of the branches. " "A higher value results in better overhangs, but the supports are harder to remove. " diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 50ce249814..0cf85e2f37 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -292,6 +292,13 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) toggle_field("support_material_bottom_contact_distance", have_support_material && ! have_support_soluble); toggle_field("support_material_closing_radius", have_support_material && support_material_style == smsSnug); + const bool has_organic_supports = support_material_style == smsOrganic && + (config->opt_bool("support_material") || + config->opt_int("support_material_enforce_layers") > 0); + for (const std::string& key : { "support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter", + "support_tree_branch_diameter_angle", "support_tree_tip_diameter", "support_tree_top_rate" }) + toggle_field(key, has_organic_supports); + for (auto el : { "support_material_bottom_interface_layers", "support_material_interface_spacing", "support_material_interface_extruder", "support_material_interface_speed", "support_material_interface_contact_loops" }) toggle_field(el, have_support_material && have_support_interface); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 32dbd22320..9cc7d9b139 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1526,7 +1526,7 @@ void TabPrint::build() optgroup->append_single_option_line("dont_support_bridges", category_path + "dont-support-bridges"); optgroup->append_single_option_line("support_material_synchronize_layers", category_path + "synchronize-with-object-layers"); - optgroup = page->new_optgroup(L("Tree supports")); + optgroup = page->new_optgroup(L("Organic supports")); optgroup->append_single_option_line("support_tree_angle", category_path + "tree_angle"); optgroup->append_single_option_line("support_tree_angle_slow", category_path + "tree_angle_slow"); optgroup->append_single_option_line("support_tree_branch_diameter", category_path + "tree_branch_diameter"); From 026ca7b3c961660e3003125e792cfb131ffe7498 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 14 Feb 2023 14:02:40 +0100 Subject: [PATCH 7/7] Fixed wipe tower with no sparse layers (layers were missing) #9592 #9703 --- src/libslic3r/GCode.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 07209c8d1a..6cb9e8e358 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -230,6 +230,8 @@ namespace Slic3r { std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation); + gcode += gcodegen.writer().unlift(); // Make sure there is no z-hop (in most cases, there isn't). + double current_z = gcodegen.writer().get_position().z(); if (z == -1.) // in case no specific z was provided, print at current_z pos z = current_z;