diff --git a/src/ProjectFileManager.cpp b/src/ProjectFileManager.cpp index 2c5c63454..d2a122125 100644 --- a/src/ProjectFileManager.cpp +++ b/src/ProjectFileManager.cpp @@ -1231,15 +1231,23 @@ void ProjectFileManager::Compact() // Purpose of this is to remove the -wal file. projectFileIO.ReopenProject(); - auto currentTracks = TrackList::Create( nullptr ); - auto &tracks = TrackList::Get( project ); - for (auto t : tracks.Any()) - { - currentTracks->Add(t->Duplicate()); + auto savedState = undoManager.GetSavedState(); + if (savedState < 0) { + undoManager.StateSaved(); + savedState = undoManager.GetSavedState(); + if (savedState < 0) { + wxASSERT(false); + savedState = 0; + } } + std::vector trackLists; + undoManager.VisitStates( + [&](auto& elem){ trackLists.push_back(elem.state.tracks.get()); }, + savedState, + undoManager.GetCurrentState() + 1); int64_t total = projectFileIO.GetTotalUsage(); - int64_t used = projectFileIO.GetCurrentUsage({currentTracks.get()}); + int64_t used = projectFileIO.GetCurrentUsage(trackLists); auto before = wxFileName::GetSize(projectFileIO.GetFileName()); @@ -1256,27 +1264,21 @@ void ProjectFileManager::Compact() Internat::FormatSize(total - used))); if (isBatch || dlg.ShowModal() == wxYES) { - // Want to do this before removing the states so that it becomes the - // current state. - ProjectHistory::Get(project) - .PushState(XO("Compacted project file"), XO("Compact"), UndoPush::CONSOLIDATE); + // We can remove redo states. + undoManager.AbandonRedo(); - // Now we can remove all previous states. - auto numStates = undoManager.GetNumStates(); - undoManager.RemoveStates(0, numStates - 1); + // We can remove all states before the last saved. + undoManager.RemoveStates(0, savedState); // And clear the clipboard, if needed if (&mProject == clipboard.Project().lock().get()) clipboard.Clear(); - // This may also decrease some reference counts on blocks - mLastSavedTracks.reset(); - // Refresh the before space usage since it may have changed due to the // above actions. auto before = wxFileName::GetSize(projectFileIO.GetFileName()); - projectFileIO.Compact( { currentTracks.get() }, true); + projectFileIO.Compact(trackLists, true); auto after = wxFileName::GetSize(projectFileIO.GetFileName()); @@ -1288,6 +1290,4 @@ void ProjectFileManager::Compact() XO("Compact Project")); } } - - mLastSavedTracks = currentTracks; } diff --git a/src/UndoManager.cpp b/src/UndoManager.cpp index b9c4b2bf9..61f899083 100644 --- a/src/UndoManager.cpp +++ b/src/UndoManager.cpp @@ -321,11 +321,7 @@ void UndoManager::PushState(const TrackList * l, mayConsolidate = true; - // Abandon redo states - if (saved >= current) { - saved = -1; - } - RemoveStates( current + 1, stack.size() ); + AbandonRedo(); // Assume tags was duplicated before any changes. // Just save a NEW shared_ptr to it. @@ -343,6 +339,14 @@ void UndoManager::PushState(const TrackList * l, mProject.QueueEvent( safenew wxCommandEvent{ EVT_UNDO_PUSHED } ); } +void UndoManager::AbandonRedo() +{ + if (saved > current) { + saved = -1; + } + RemoveStates( current + 1, stack.size() ); +} + void UndoManager::SetStateTo(unsigned int n, const Consumer &consumer) { wxASSERT(n < stack.size()); @@ -438,6 +442,11 @@ void UndoManager::StateSaved() saved = current; } +int UndoManager::GetSavedState() const +{ + return saved; +} + // currently unused //void UndoManager::Debug() //{ diff --git a/src/UndoManager.h b/src/UndoManager.h index 9a1c57148..841d5788e 100644 --- a/src/UndoManager.h +++ b/src/UndoManager.h @@ -148,6 +148,7 @@ class AUDACITY_DLL_API UndoManager final UndoPush flags = UndoPush::NONE); void ModifyState(const TrackList * l, const SelectedRegion &selectedRegion, const std::shared_ptr &tags); + void AbandonRedo(); void ClearStates(); void RemoveStates( size_t begin, //!< inclusive start of range @@ -183,6 +184,7 @@ class AUDACITY_DLL_API UndoManager final bool RedoAvailable(); bool UnsavedChanges() const; + int GetSavedState() const; void StateSaved(); // Return value must first be calculated by CalculateSpaceUsage():