Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/slic3r/GUI/GUI_App.cpp')
-rw-r--r--src/slic3r/GUI/GUI_App.cpp299
1 files changed, 154 insertions, 145 deletions
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index bda7394ed..5ebd5300a 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -862,9 +862,9 @@ static boost::optional<Semver> parse_semver_from_ini(std::string path)
void GUI_App::init_app_config()
{
// Profiles for the alpha are stored into the PrusaSlicer-alpha directory to not mix with the current release.
-// SetAppName(SLIC3R_APP_KEY);
+ SetAppName(SLIC3R_APP_KEY);
// SetAppName(SLIC3R_APP_KEY "-alpha");
- SetAppName(SLIC3R_APP_KEY "-beta");
+// SetAppName(SLIC3R_APP_KEY "-beta");
// SetAppDisplayName(SLIC3R_APP_NAME);
// Set the Slic3r data directory at the Slic3r XS module.
@@ -909,17 +909,18 @@ void GUI_App::init_app_config()
"\n\n" + app_config->config_path() + "\n\n" + error);
}
}
- // Save orig_version here, so its empty if no app_config existed before this run.
- m_last_config_version = app_config->orig_version();//parse_semver_from_ini(app_config->config_path());
}
}
-// returns true if found newer version and user agreed to use it
-bool GUI_App::check_older_app_config(Semver current_version, bool backup)
+// returns old config path to copy from if such exists,
+// returns an empty string if such config path does not exists or if it cannot be loaded.
+std::string GUI_App::check_older_app_config(Semver current_version, bool backup)
{
+ std::string older_data_dir_path;
+
// If the config folder is redefined - do not check
if (m_datadir_redefined)
- return false;
+ return {};
// find other version app config (alpha / beta / release)
std::string config_path = app_config->config_path();
@@ -940,55 +941,57 @@ bool GUI_App::check_older_app_config(Semver current_version, bool backup)
boost::optional<Semver>other_semver = parse_semver_from_ini(candidate.string());
if (other_semver && *other_semver > last_semver) {
last_semver = *other_semver;
- m_older_data_dir_path = candidate.parent_path().string();
+ older_data_dir_path = candidate.parent_path().string();
}
}
}
- if (m_older_data_dir_path.empty())
- return false;
- BOOST_LOG_TRIVIAL(info) << "last app config file used: " << m_older_data_dir_path;
+ if (older_data_dir_path.empty())
+ return {};
+ BOOST_LOG_TRIVIAL(info) << "last app config file used: " << older_data_dir_path;
// ask about using older data folder
- RichMessageDialog msg(nullptr, backup ?
- wxString::Format(_L("PrusaSlicer detected another configuration folder at %s."
- "\nIts version is %s."
- "\nLast version you used in current configuration folder is %s."
- "\nPlease note that PrusaSlicer uses different folders to save configuration of alpha, beta and full release versions."
- "\nWould you like to copy found configuration to your current configuration folder?"
-
- "\n\nIf you select yes, PrusaSlicer will copy all profiles and other files from found folder to the current one. Overwriting any existing file with matching name."
- "\nIf you select no, you will continue with current configuration.")
- , m_older_data_dir_path, last_semver.to_string(), current_version.to_string())
- : wxString::Format(_L("PrusaSlicer detected another configuration folder at %s."
- "\nIts version is %s."
- "\nThere is no configuration file in current configuration folder."
- "\nPlease note that PrusaSlicer uses different folders to save configuration of alpha, beta and full release versions."
- "\nWould you like to copy found configuration to your current configuration folder?"
-
- "\n\nIf you select yes, PrusaSlicer will copy all profiles and other files from found folder to the current one."
- "\nIf you select no, you will start with clean installation with configuration wizard.")
- , m_older_data_dir_path, last_semver.to_string())
- , _L("PrusaSlicer"), /*wxICON_QUESTION | */wxYES_NO);
+
+ InfoDialog msg(nullptr
+ , format_wxstr(_L("You are opening %1% version %2%."), SLIC3R_APP_NAME, SLIC3R_VERSION)
+ , backup ?
+ format_wxstr(_L(
+ "The active configuration was created by <b>%1% %2%</b>,"
+ "\nwhile a newer configuration was found in <b>%3%</b>"
+ "\ncreated by <b>%1% %4%</b>."
+ "\n\nShall the newer configuration be imported?"
+ "\nIf so, your active configuration will be backed up before importing the new configuration."
+ )
+ , SLIC3R_APP_NAME, current_version.to_string(), older_data_dir_path, last_semver.to_string())
+ : format_wxstr(_L(
+ "An existing configuration was found in <b>%3%</b>"
+ "\ncreated by <b>%1% %2%</b>."
+ "\n\nShall this configuration be imported?"
+ )
+ , SLIC3R_APP_NAME, last_semver.to_string(), older_data_dir_path)
+ , true, wxYES_NO);
+
+ if (backup) {
+ msg.SetButtonLabel(wxID_YES, _L("Import"));
+ msg.SetButtonLabel(wxID_NO, _L("Don't import"));
+ }
+
if (msg.ShowModal() == wxID_YES) {
std::string snapshot_id;
if (backup) {
- // configuration snapshot
- std::string comment;
- if (const Config::Snapshot* snapshot = Config::take_config_snapshot_report_error(
- *app_config,
- Config::Snapshot::SNAPSHOT_USER,
- comment);
- snapshot != nullptr)
- // Is thos correct? Save snapshot id for later, when new app config is loaded.
+ const Config::Snapshot* snapshot{ nullptr };
+ if (! GUI::Config::take_config_snapshot_cancel_on_error(*app_config, Config::Snapshot::SNAPSHOT_USER, "",
+ _u8L("Continue and import newer configuration?"), &snapshot))
+ return {};
+ if (snapshot) {
+ // Save snapshot ID before loading the alternate AppConfig, as loading the alternate AppConfig may fail.
snapshot_id = snapshot->id;
- else
- BOOST_LOG_TRIVIAL(error) << "Failed to take congiguration snapshot: ";
+ assert(! snapshot_id.empty());
+ app_config->set("on_snapshot", snapshot_id);
+ } else
+ BOOST_LOG_TRIVIAL(error) << "Failed to take congiguration snapshot";
}
- // This will tell later (when config folder structure is sure to exists) to copy files from m_older_data_dir_path
- m_init_app_config_from_older = true;
// load app config from older file
- app_config->set_loading_path((boost::filesystem::path(m_older_data_dir_path) / filename).string());
- std::string error = app_config->load();
+ std::string error = app_config->load((boost::filesystem::path(older_data_dir_path) / filename).string());
if (!error.empty()) {
// Error while parsing config file. We'll customize the error message and rethrow to be displayed.
if (is_editor()) {
@@ -1007,14 +1010,9 @@ bool GUI_App::check_older_app_config(Semver current_version, bool backup)
if (!snapshot_id.empty())
app_config->set("on_snapshot", snapshot_id);
m_app_conf_exists = true;
- return true;
+ return older_data_dir_path;
}
- return false;
-}
-
-void GUI_App::copy_older_config()
-{
- preset_bundle->copy_files(m_older_data_dir_path);
+ return {};
}
void GUI_App::init_single_instance_checker(const std::string &name, const std::string &path)
@@ -1035,6 +1033,9 @@ bool GUI_App::OnInit()
bool GUI_App::on_init_inner()
{
+ // Set initialization of image handlers before any UI actions - See GH issue #7469
+ wxInitAllImageHandlers();
+
#if defined(_WIN32) && ! defined(_WIN64)
// Win32 32bit build.
if (wxPlatformInfo::Get().GetArchName().substr(0, 2) == "64") {
@@ -1077,6 +1078,42 @@ bool GUI_App::on_init_inner()
// Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION;
+ // !!! Initialization of UI settings as a language, application color mode, fonts... have to be done before first UI action.
+ // Like here, before the show InfoDialog in check_older_app_config()
+
+ // 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";
+ NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled);
+#endif
+ // initialize label colors and fonts
+ init_label_colours();
+ init_fonts();
+
+ std::string older_data_dir_path;
+ if (m_app_conf_exists) {
+ if (app_config->orig_version().valid() && app_config->orig_version() < *Semver::parse(SLIC3R_VERSION))
+ // Only copying configuration if it was saved with a newer slicer than the one currently running.
+ older_data_dir_path = check_older_app_config(app_config->orig_version(), true);
+ } else {
+ // No AppConfig exists, fresh install. Always try to copy from an alternate location, don't make backup of the current configuration.
+ older_data_dir_path = check_older_app_config(Semver(), false);
+ }
+
+#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";
+ init_dark_color_mode != new_dark_color_mode) {
+ NppDarkMode::SetDarkMode(new_dark_color_mode);
+ init_label_colours();
+ update_label_colours_from_appconfig();
+ }
+ if (bool new_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1";
+ init_sys_menu_enabled != new_sys_menu_enabled)
+ NppDarkMode::SetSystemMenuForApp(new_sys_menu_enabled);
+#endif
if (is_editor()) {
std::string msg = Http::tls_global_init();
@@ -1098,24 +1135,6 @@ bool GUI_App::on_init_inner()
}
}
- if (m_last_config_version) {
- if (*m_last_config_version < *Semver::parse(SLIC3R_VERSION))
- check_older_app_config(*m_last_config_version, true);
- } else {
- check_older_app_config(Semver(), false);
- }
-
- app_config->set("version", SLIC3R_VERSION);
- app_config->save();
-
- // If load_language() fails, the application closes.
- load_language(wxString(), true);
-
- wxInitAllImageHandlers();
-
-#ifdef _MSW_DARK_MODE
- NppDarkMode::InitDarkMode(app_config->get("dark_color_mode") == "1", app_config->get("sys_menu_enabled") == "1");
-#endif
SplashScreen* scrn = nullptr;
if (app_config->get("show_splash_screen") == "1") {
// make a bitmap with dark grey banner on the left side
@@ -1139,17 +1158,18 @@ bool GUI_App::on_init_inner()
scrn->SetText(_L("Loading configuration")+ dots);
}
-
-
preset_bundle = new PresetBundle();
// just checking for existence of Slic3r::data_dir is not enough : it may be an empty directory
// supplied as argument to --datadir; in that case we should still run the wizard
preset_bundle->setup_directories();
-
- if (m_init_app_config_from_older)
- copy_older_config();
+ if (! older_data_dir_path.empty())
+ preset_bundle->import_newer_configs(older_data_dir_path);
+
+ // Save PrusaSlicer.ini after possibly copying the config from the alternate location and after all the configs from the alternate location were copied.
+ app_config->set("version", SLIC3R_VERSION);
+ app_config->save();
if (is_editor()) {
#ifdef __WXMSW__
@@ -1198,10 +1218,6 @@ bool GUI_App::on_init_inner()
#endif // __WXMSW__
}
- // initialize label colors and fonts
- init_label_colours();
- init_fonts();
-
// Suppress the '- default -' presets.
preset_bundle->set_default_suppressed(app_config->get("no_defaults") == "1");
try {
@@ -1372,24 +1388,41 @@ void GUI_App::update_label_colours()
tab->update_label_colours();
}
+static bool is_focused(HWND hWnd)
+{
+ HWND hFocusedWnd = ::GetFocus();
+ return hFocusedWnd && hWnd == hFocusedWnd;
+}
+
void GUI_App::UpdateDarkUI(wxWindow* window, bool highlited/* = false*/, bool just_font/* = false*/)
{
#ifdef _WIN32
+ bool is_focused_button = false;
if (wxButton* btn = dynamic_cast<wxButton*>(window)) {
if (!(btn->GetWindowStyle() & wxNO_BORDER)) {
btn->SetWindowStyle(btn->GetWindowStyle() | wxNO_BORDER);
highlited = true;
}
- // hovering for buttons
+ // button marking
{
- auto focus_button = [this, btn](const bool focus) {
- btn->SetForegroundColour(focus ? m_color_hovered_btn_label : m_color_label_default);
+ auto mark_button = [this, btn, highlited](const bool mark) {
+ if (btn->GetLabel().IsEmpty())
+ btn->SetBackgroundColour(mark ? m_color_selected_btn_bg : highlited ? m_color_highlight_default : m_color_window_default);
+ else
+ btn->SetForegroundColour(mark ? m_color_hovered_btn_label : m_color_label_default);
btn->Refresh();
btn->Update();
};
- btn->Bind(wxEVT_ENTER_WINDOW, [focus_button](wxMouseEvent& event) { focus_button(true); event.Skip(); });
- btn->Bind(wxEVT_LEAVE_WINDOW, [focus_button](wxMouseEvent& event) { focus_button(false); event.Skip(); });
+ // hovering
+ btn->Bind(wxEVT_ENTER_WINDOW, [mark_button](wxMouseEvent& event) { mark_button(true); event.Skip(); });
+ btn->Bind(wxEVT_LEAVE_WINDOW, [mark_button, btn](wxMouseEvent& event) { mark_button(is_focused(btn->GetHWND())); event.Skip(); });
+ // focusing
+ btn->Bind(wxEVT_SET_FOCUS, [mark_button](wxFocusEvent& event) { mark_button(true); event.Skip(); });
+ btn->Bind(wxEVT_KILL_FOCUS, [mark_button](wxFocusEvent& event) { mark_button(false); event.Skip(); });
+
+ if (is_focused_button = is_focused(btn->GetHWND()))
+ mark_button(true);
}
}
else if (wxTextCtrl* text = dynamic_cast<wxTextCtrl*>(window)) {
@@ -1411,7 +1444,8 @@ void GUI_App::UpdateDarkUI(wxWindow* window, bool highlited/* = false*/, bool ju
if (!just_font)
window->SetBackgroundColour(highlited ? m_color_highlight_default : m_color_window_default);
- window->SetForegroundColour(m_color_label_default);
+ if (!is_focused_button)
+ window->SetForegroundColour(m_color_label_default);
#endif
}
@@ -1702,6 +1736,7 @@ void GUI_App::force_colors_update()
if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl())
NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND);
NppDarkMode::SetDarkTitleBar(mainframe->GetHWND());
+ NppDarkMode::SetDarkTitleBar(mainframe->m_settings_dialog.GetHWND());
#endif //_MSW_DARK_MODE
m_force_colors_update = true;
}
@@ -1718,9 +1753,18 @@ void GUI_App::update_ui_from_settings()
m_force_colors_update = false;
mainframe->force_color_changed();
mainframe->diff_dialog.force_color_changed();
+ mainframe->preferences_dialog->force_color_changed();
mainframe->printhost_queue_dlg()->force_color_changed();
#ifdef _MSW_DARK_MODE
update_scrolls(mainframe);
+ if (mainframe->is_dlg_layout()) {
+ // update for tabs bar
+ UpdateDarkUI(&mainframe->m_settings_dialog);
+ mainframe->m_settings_dialog.Fit();
+ mainframe->m_settings_dialog.Refresh();
+ // update scrollbars
+ update_scrolls(&mainframe->m_settings_dialog);
+ }
#endif //_MSW_DARK_MODE
}
#endif
@@ -2162,9 +2206,9 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
local_menu->Append(config_id_base + ConfigMenuLanguage, _L("&Language"));
if (is_editor()) {
local_menu->AppendSeparator();
- local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _L("Flash printer &firmware"), _L("Upload a firmware image into an Arduino based printer"));
+ local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _L("Flash Printer &Firmware"), _L("Upload a firmware image into an Arduino based printer"));
// TODO: for when we're able to flash dictionaries
- // local_menu->Append(config_id_base + FirmwareMenuDict, _L("Flash language file"), _L("Upload a language dictionary file into a Prusa printer"));
+ // local_menu->Append(config_id_base + FirmwareMenuDict, _L("Flash Language File"), _L("Upload a language dictionary file into a Prusa printer"));
}
local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) {
@@ -2230,40 +2274,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
break;
case ConfigMenuPreferences:
{
- bool app_layout_changed = false;
- {
- // the dialog needs to be destroyed before the call to recreate_GUI()
- // or sometimes the application crashes into wxDialogBase() destructor
- // so we put it into an inner scope
- PreferencesDialog dlg(mainframe);
- dlg.ShowModal();
- app_layout_changed = dlg.settings_layout_changed();
- if (dlg.seq_top_layer_only_changed())
- this->plater_->refresh_print();
-
- if (dlg.recreate_GUI()) {
- recreate_GUI(_L("Restart application") + dots);
- return;
- }
-#ifdef _WIN32
- if (is_editor()) {
- if (app_config->get("associate_3mf") == "1")
- associate_3mf_files();
- if (app_config->get("associate_stl") == "1")
- associate_stl_files();
- }
- else {
- if (app_config->get("associate_gcode") == "1")
- associate_gcode_files();
- }
-#endif // _WIN32
- }
- if (app_layout_changed) {
- // hide full main_sizer for mainFrame
- mainframe->GetSizer()->Show(false);
- mainframe->update_layout();
- mainframe->select_tab(size_t(0));
- }
+ open_preferences();
break;
}
case ConfigMenuLanguage:
@@ -2311,36 +2322,34 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
menu->Append(local_menu, _L("&Configuration"));
}
-void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_option)
+void GUI_App::open_preferences(const std::string& highlight_option /*= std::string()*/, const std::string& tab_name/*= std::string()*/)
{
- bool app_layout_changed = false;
- {
- // the dialog needs to be destroyed before the call to recreate_GUI()
- // or sometimes the application crashes into wxDialogBase() destructor
- // so we put it into an inner scope
- PreferencesDialog dlg(mainframe, open_on_tab, highlight_option);
- dlg.ShowModal();
- app_layout_changed = dlg.settings_layout_changed();
+ mainframe->preferences_dialog->show(highlight_option, tab_name);
+
+ if (mainframe->preferences_dialog->recreate_GUI())
+ recreate_GUI(_L("Restart application") + dots);
+
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
- if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
+ if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
#else
- if (dlg.seq_top_layer_only_changed())
+ if (mainframe->preferences_dialog->seq_top_layer_only_changed())
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
- this->plater_->refresh_print();
+ this->plater_->refresh_print();
+
#ifdef _WIN32
- if (is_editor()) {
- if (app_config->get("associate_3mf") == "1")
- associate_3mf_files();
- if (app_config->get("associate_stl") == "1")
- associate_stl_files();
- }
- else {
- if (app_config->get("associate_gcode") == "1")
- associate_gcode_files();
- }
-#endif // _WIN32
+ if (is_editor()) {
+ if (app_config->get("associate_3mf") == "1")
+ associate_3mf_files();
+ if (app_config->get("associate_stl") == "1")
+ associate_stl_files();
}
- if (app_layout_changed) {
+ else {
+ if (app_config->get("associate_gcode") == "1")
+ associate_gcode_files();
+ }
+#endif // _WIN32
+
+ if (mainframe->preferences_dialog->settings_layout_changed()) {
// hide full main_sizer for mainFrame
mainframe->GetSizer()->Show(false);
mainframe->update_layout();