From 1bb34e703e2664d07286742d0e48c044accd43a1 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 28 Aug 2020 14:03:35 -0400 Subject: [PATCH] Bug2529: don't lose data when closing without saving on small drive (#650) --- src/ProjectFileIO.cpp | 29 +++++++++++++++++++---------- src/ProjectFileIO.h | 1 + src/ProjectFileManager.cpp | 13 +++++++++++-- src/ProjectFileManager.h | 2 +- src/ProjectManager.cpp | 2 +- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/ProjectFileIO.cpp b/src/ProjectFileIO.cpp index c4be71f1f..30054ff46 100644 --- a/src/ProjectFileIO.cpp +++ b/src/ProjectFileIO.cpp @@ -1885,6 +1885,24 @@ bool ProjectFileIO::LoadProject(const FilePath &fileName) return true; } +bool ProjectFileIO::UpdateSaved( + const std::shared_ptr &tracks) +{ + ProjectSerializer doc; + WriteXMLHeader(doc); + WriteXML(doc, false, tracks); + + if (!WriteDoc("project", doc)) + { + return false; + } + + // Autosave no longer needed + AutoSaveDelete(); + + return true; +} + bool ProjectFileIO::SaveProject(const FilePath &fileName, const std::shared_ptr &lastSaved) { // In the case where we're saving a temporary project to a permanent project, @@ -1986,17 +2004,8 @@ bool ProjectFileIO::SaveProject(const FilePath &fileName, const std::shared_ptr< } else { - ProjectSerializer doc; - WriteXMLHeader(doc); - WriteXML(doc); - - if (!WriteDoc("project", doc)) - { + if ( !UpdateSaved( nullptr ) ) return false; - } - - // Autosave no longer needed - AutoSaveDelete(); } // Reaching this point defines success and all the rest are no-fail diff --git a/src/ProjectFileIO.h b/src/ProjectFileIO.h index c09464d0c..7de85ed45 100644 --- a/src/ProjectFileIO.h +++ b/src/ProjectFileIO.h @@ -84,6 +84,7 @@ public: bool ImportProject(const FilePath &fileName); bool LoadProject(const FilePath &fileName); + bool UpdateSaved(const std::shared_ptr &tracks = nullptr); bool SaveProject(const FilePath &fileName, const std::shared_ptr &lastSaved); bool SaveCopy(const FilePath& fileName); diff --git a/src/ProjectFileManager.cpp b/src/ProjectFileManager.cpp index ba9104f68..7eee74606 100644 --- a/src/ProjectFileManager.cpp +++ b/src/ProjectFileManager.cpp @@ -654,7 +654,7 @@ bool ProjectFileManager::SaveFromTimerRecording(wxFileName fnFile) return success; } -void ProjectFileManager::CompactProject() +void ProjectFileManager::CompactProjectOnClose() { auto &project = mProject; auto &projectFileIO = ProjectFileIO::Get(project); @@ -671,6 +671,15 @@ void ProjectFileManager::CompactProject() // Attempt to compact the project projectFileIO.Compact(mLastSavedTracks); + + if ( !projectFileIO.WasCompacted() && + UndoManager::Get( project ).UnsavedChanges() ) { + // If compaction failed, we must do some work in case of close + // without save. Don't leave the document blob from the last + // push of undo history, when that undo state may get purged + // with deletion of some new sample blocks. + projectFileIO.UpdateSaved( mLastSavedTracks ); + } } } @@ -689,7 +698,7 @@ void ProjectFileManager::CloseProject() projectFileIO.CloseProject(); - // Blocks were locked in CompactProject, so DELETE the data structure so that + // Blocks were locked in CompactProjectOnClose, so DELETE the data structure so that // there's no memory leak. if (mLastSavedTracks) { diff --git a/src/ProjectFileManager.h b/src/ProjectFileManager.h index 1392630fa..f2965dc8b 100644 --- a/src/ProjectFileManager.h +++ b/src/ProjectFileManager.h @@ -53,7 +53,7 @@ public: bool OpenProject(); void CloseProject(); - void CompactProject(); + void CompactProjectOnClose(); bool Save(); bool SaveAs(); diff --git a/src/ProjectManager.cpp b/src/ProjectManager.cpp index 58c3d8452..e8e249252 100644 --- a/src/ProjectManager.cpp +++ b/src/ProjectManager.cpp @@ -733,7 +733,7 @@ void ProjectManager::OnCloseWindow(wxCloseEvent & event) // SetMenuBar(NULL); // Compact the project. - projectFileManager.CompactProject(); + projectFileManager.CompactProjectOnClose(); // Set (or not) the bypass flag to indicate that deletes that would happen during // the UndoManager::ClearStates() below are not necessary.