Check unsaved changes (#6991)

* Check Unsaved changes (partially related to #5903)
 + Allow create new project when Plater is empty, but some of presets are modified (related to #5903)
 + When creating new project allow Keep or Discard modification from previous project
 + Added check of changes:
    * before any load project (including DnD and "Load From Recent Projects")
    * before preset updater
    * when configuration is changing from the ConfigWizard
 + Dialog caption is added for each check

 + Create/Destroy ConfigWizard every time when it's called

* Check Unsaved changes: Next Improvements
 + For dialog "Save project changes" added a reason of saving and name of the current project (or "Untitled")
 + UnsavedChangesDialog: Headers are extended to better explain the reason
 + Preferences: Fixed tooltiops for "Always ask for unsaved changes when..."
 + Suppress "Remember my choice" checkbox for actions which are not frequently used

* Fixed behavior of the application when try to save changed project but "Cancel" button is selected in "Save file as..." dialog

* Check unsaved changes: Improvements for Config Wizard - Check all cases when presets should be updated
 + Fixed info line for Materials pages. Text of the info relates to the printer technology now

* Improved suggested name for a project when Application is closing

* Fixed Linux/OSX build warnings
This commit is contained in:
Oleksandra Yushchenko 2021-09-22 12:44:13 +02:00 committed by GitHub
parent 846b868215
commit 8f064dd155
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 462 additions and 178 deletions

View file

@ -222,13 +222,14 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
}
if (m_plater != nullptr) {
int saved_project = m_plater->save_project_if_dirty();
int saved_project = m_plater->save_project_if_dirty(_L("Closing PrusaSlicer. Current project is modified."));
if (saved_project == wxID_CANCEL) {
event.Veto();
return;
}
// check unsaved changes only if project wasn't saved
else if (saved_project == wxID_NO && event.CanVeto() && !wxGetApp().check_and_save_current_preset_changes()) {
else if (saved_project == wxID_NO && event.CanVeto() &&
!wxGetApp().check_and_save_current_preset_changes(_L("PrusaSlicer is closing"), _L("Closing PrusaSlicer while some presets are modified."))) {
event.Veto();
return;
}
@ -820,7 +821,10 @@ bool MainFrame::is_active_and_shown_tab(Tab* tab)
bool MainFrame::can_start_new_project() const
{
return (m_plater != nullptr) && (!m_plater->get_project_filename(".3mf").IsEmpty() || GetTitle().StartsWith('*') || !m_plater->model().objects.empty());
return m_plater && (!m_plater->get_project_filename(".3mf").IsEmpty() ||
GetTitle().StartsWith('*')||
wxGetApp().has_current_preset_changes() ||
!m_plater->model().objects.empty() );
}
bool MainFrame::can_save() const
@ -852,13 +856,14 @@ void MainFrame::save_project()
save_project_as(m_plater->get_project_filename(".3mf"));
}
void MainFrame::save_project_as(const wxString& filename)
bool MainFrame::save_project_as(const wxString& filename)
{
bool ret = (m_plater != nullptr) ? m_plater->export_3mf(into_path(filename)) : false;
if (ret) {
// wxGetApp().update_saved_preset_from_current_preset();
m_plater->reset_project_dirty_after_save();
}
return ret;
}
bool MainFrame::can_export_model() const
@ -1151,8 +1156,10 @@ void MainFrame::init_menubar_as_editor()
Bind(wxEVT_MENU, [this](wxCommandEvent& evt) {
size_t file_id = evt.GetId() - wxID_FILE1;
wxString filename = m_recent_projects.GetHistoryFile(file_id);
if (wxFileExists(filename))
m_plater->load_project(filename);
if (wxFileExists(filename)) {
if (wxGetApp().can_load_project())
m_plater->load_project(filename);
}
else
{
//wxMessageDialog msg(this, _L("The selected project is no longer available.\nDo you want to remove it from the recent projects list?"), _L("Error"), wxYES_NO | wxYES_DEFAULT);
@ -1772,7 +1779,7 @@ void MainFrame::export_config()
// Load a config file containing a Print, Filament & Printer preset.
void MainFrame::load_config_file()
{
if (!wxGetApp().check_and_save_current_preset_changes())
if (!wxGetApp().check_and_save_current_preset_changes(_L("Loading of a configuration file"), "", false))
return;
wxFileDialog dlg(this, _L("Select configuration to load:"),
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
@ -1803,7 +1810,8 @@ bool MainFrame::load_config_file(const std::string &path)
void MainFrame::export_configbundle(bool export_physical_printers /*= false*/)
{
if (!wxGetApp().check_and_save_current_preset_changes())
if (!wxGetApp().check_and_save_current_preset_changes(_L("Exporting configuration bundle"),
_L("Some presets are modified and the unsaved changes will not be exported into configuration bundle."), false, true))
return;
// validate current configuration in case it's dirty
auto err = wxGetApp().preset_bundle->full_config().validate();
@ -1835,7 +1843,7 @@ void MainFrame::export_configbundle(bool export_physical_printers /*= false*/)
// but that behavior was not documented and likely buggy.
void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool reset_user_profile*/)
{
if (!wxGetApp().check_and_save_current_preset_changes())
if (!wxGetApp().check_and_save_current_preset_changes(_L("Loading of a configuration bundle"), "", false))
return;
if (file.IsEmpty()) {
wxFileDialog dlg(this, _L("Select configuration to load:"),