From 68c726918b6eb8d2af67527d95f2895043ecb428 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 17 Dec 2016 10:05:15 -0500 Subject: [PATCH] If exception in cut/copy, leave clipboard clear (no partial results) --- src/Menus.cpp | 27 ++++++++++++++++++++++++--- src/Project.cpp | 8 +++++++- src/Track.h | 3 +++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index dbcf5d95f..52a3b0e9c 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -4149,6 +4149,9 @@ void AudacityProject::OnCut() } ClearClipboard(); + + TrackList newClipboard; + n = iter.First(); while (n) { if (n->GetSelected()) { @@ -4164,11 +4167,17 @@ void AudacityProject::OnCut() mViewInfo.selectedRegion.t1()); if (dest) - FinishCopy(n, std::move(dest), *msClipboard); + FinishCopy(n, std::move(dest), newClipboard); } n = iter.Next(); } + // Survived possibility of exceptions. Commit changes to the clipboard now. + newClipboard.Swap(*msClipboard); + + // Proceed to change the project. If this throws, the project will be + // rolled back by the top level handler. + n = iter.First(); while (n) { // We clear from selected and sync-lock selected tracks. @@ -4220,6 +4229,9 @@ void AudacityProject::OnSplitCut() Track *n = iter.First(); ClearClipboard(); + + TrackList newClipboard; + while (n) { if (n->GetSelected()) { Track::Holder dest; @@ -4237,11 +4249,14 @@ void AudacityProject::OnSplitCut() mViewInfo.selectedRegion.t1()); } if (dest) - FinishCopy(n, std::move(dest), *msClipboard); + FinishCopy(n, std::move(dest), newClipboard); } n = iter.Next(); } + // Survived possibility of exceptions. Commit changes to the clipboard now. + newClipboard.Swap(*msClipboard); + msClipT0 = mViewInfo.selectedRegion.t0(); msClipT1 = mViewInfo.selectedRegion.t1(); msClipProject = this; @@ -4275,17 +4290,23 @@ void AudacityProject::OnCopy() } ClearClipboard(); + + TrackList newClipboard; + n = iter.First(); while (n) { if (n->GetSelected()) { auto dest = n->Copy(mViewInfo.selectedRegion.t0(), mViewInfo.selectedRegion.t1()); if (dest) - FinishCopy(n, std::move(dest), *msClipboard); + FinishCopy(n, std::move(dest), newClipboard); } n = iter.Next(); } + // Survived possibility of exceptions. Commit changes to the clipboard now. + newClipboard.Swap(*msClipboard); + msClipT0 = mViewInfo.selectedRegion.t0(); msClipT1 = mViewInfo.selectedRegion.t1(); msClipProject = this; diff --git a/src/Project.cpp b/src/Project.cpp index 346c39557..fdda5a74d 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -4917,6 +4917,9 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) } ClearClipboard(); + + TrackList newClipboard; + //Apply action on wavetracks starting from //labeled regions in the end. This is to correctly perform //actions like 'Cut' which collapse the track area. @@ -4961,10 +4964,13 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) regions.at(i + 1).start - region.end); } if( merged ) - msClipboard->Add( std::move(merged) ); + newClipboard.Add( std::move(merged) ); } } + // Survived possibility of exceptions. Commit changes to the clipboard now. + newClipboard.Swap(*msClipboard); + msClipT0 = regions.front().start; msClipT1 = regions.back().end; diff --git a/src/Track.h b/src/Track.h index 64a8fe05a..8e2bc533f 100644 --- a/src/Track.h +++ b/src/Track.h @@ -408,6 +408,9 @@ DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_UPDATED, -1); class TrackList final : public wxEvtHandler, public ListOfTracks { + // privatize this, make you use Swap instead: + using ListOfTracks::swap; + public: // Create an empty TrackList TrackList();