From 25619fb46e9d691d6b9de475e84da93eafb5fbc5 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 26 Nov 2016 08:48:08 -0500 Subject: [PATCH] Don't create placeholder clips in Duplicate command ... ... when there is no clip at the right edge of the selection. --- src/LabelTrack.cpp | 2 +- src/LabelTrack.h | 6 +----- src/Menus.cpp | 3 ++- src/NoteTrack.cpp | 2 +- src/NoteTrack.h | 2 +- src/Project.cpp | 6 ++++++ src/Track.h | 6 +++++- src/WaveTrack.cpp | 7 +++++-- src/WaveTrack.h | 8 +++++++- 9 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/LabelTrack.cpp b/src/LabelTrack.cpp index 57a22d7ae..92280ed17 100644 --- a/src/LabelTrack.cpp +++ b/src/LabelTrack.cpp @@ -2361,7 +2361,7 @@ Track::Holder LabelTrack::SplitCut(double t0, double t1) } #endif -Track::Holder LabelTrack::Copy(double t0, double t1) const +Track::Holder LabelTrack::Copy(double t0, double t1, bool) const { auto tmp = std::make_unique(GetDirManager()); const auto lt = static_cast(tmp.get()); diff --git a/src/LabelTrack.h b/src/LabelTrack.h index 053ea12d4..1f9b1fd9c 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -155,11 +155,7 @@ class AUDACITY_DLL_API LabelTrack final : public Track #endif Track::Holder Cut (double t0, double t1) override; - // JKC Do not add the const modifier to Copy(), Clear() - // or Paste() because then it - // is no longer recognised as a virtual function matching the - // one in Track. - Track::Holder Copy (double t0, double t1) const override; + Track::Holder Copy (double t0, double t1, bool forClipboard = true) const override; bool Clear(double t0, double t1) override; bool Paste(double t, const Track * src) override; bool Repeat(double t0, double t1, int n); diff --git a/src/Menus.cpp b/src/Menus.cpp index e5ba71083..a7d81acf7 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -4789,8 +4789,9 @@ void AudacityProject::OnDuplicate() while (n) { if (n->GetSelected()) { + // Make copies not for clipboard but for direct addition to the project auto dest = n->Copy(mViewInfo.selectedRegion.t0(), - mViewInfo.selectedRegion.t1()); + mViewInfo.selectedRegion.t1(), false); if (dest) { dest->Init(*n); dest->SetOffset(wxMax(mViewInfo.selectedRegion.t0(), n->GetOffset())); diff --git a/src/NoteTrack.cpp b/src/NoteTrack.cpp index 5e6f97d82..3bcf57e6b 100644 --- a/src/NoteTrack.cpp +++ b/src/NoteTrack.cpp @@ -454,7 +454,7 @@ Track::Holder NoteTrack::Cut(double t0, double t1) return std::move(newTrack); } -Track::Holder NoteTrack::Copy(double t0, double t1) const +Track::Holder NoteTrack::Copy(double t0, double t1, bool) const { if (t1 <= t0) return{}; diff --git a/src/NoteTrack.h b/src/NoteTrack.h index fafdb6dff..30a034f22 100644 --- a/src/NoteTrack.h +++ b/src/NoteTrack.h @@ -91,7 +91,7 @@ class AUDACITY_DLL_API NoteTrack final : public Track { // High-level editing Track::Holder Cut (double t0, double t1) override; - Track::Holder Copy (double t0, double t1) const override; + Track::Holder Copy (double t0, double t1, bool forClipboard = true) const override; bool Trim (double t0, double t1) /* not override */; bool Clear(double t0, double t1) override; bool Paste(double t, const Track *src) override; diff --git a/src/Project.cpp b/src/Project.cpp index 7517e4df0..4804d040e 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -4905,6 +4905,7 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) if( n->GetKind() == Track::Wave && ( allTracks || n->GetSelected() ) ) { WaveTrack *wt = ( WaveTrack* )n; + // This track accumulates the needed clips, right to left: Track::Holder merged; for( int i = (int)regions.size() - 1; i >= 0; i-- ) { @@ -4923,6 +4924,11 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) merged->Offset( regions.at(i + 1).start - region.end); + // dest may have a placeholder clip at the end that is + // removed when pasting, which is okay because we proceed + // right to left. Any placeholder already in merged is kept. + // Only the rightmost placeholder is important in the final + // result. bool bResult = merged->Paste( 0.0 , dest.get() ); wxASSERT(bResult); // TO DO: Actually handle this. wxUnusedVar(bResult); diff --git a/src/Track.h b/src/Track.h index cc18b309b..64a8fe05a 100644 --- a/src/Track.h +++ b/src/Track.h @@ -216,7 +216,11 @@ class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler virtual Holder Cut(double WXUNUSED(t0), double WXUNUSED(t1)) { return{}; } // Create a NEW track and don't modify this track (or return null for failure) - virtual Holder Copy(double WXUNUSED(t0), double WXUNUSED(t1)) const { return{}; } + // Note that subclasses may want to distinguish tracks stored in a clipboard + // from those stored in a project + virtual Holder Copy + (double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard = true) const + { return{}; } // Return true for success virtual bool Clear(double WXUNUSED(t0), double WXUNUSED(t1)) {return false;} diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index f0192fdc7..9afb03b48 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -630,7 +630,7 @@ bool WaveTrack::Trim (double t0, double t1) -Track::Holder WaveTrack::Copy(double t0, double t1) const +Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const { if (t1 <= t0) return{}; @@ -695,7 +695,10 @@ Track::Holder WaveTrack::Copy(double t0, double t1) const // AWD, Oct 2009: If the selection ends in whitespace, create a placeholder // clip representing that whitespace - if (newTrack->GetEndTime() + 1.0 / newTrack->GetRate() < t1 - t0) + // PRL: Only if we want the track for pasting into other tracks. Not if it + // goes directly into a project as in the Duplicate command. + if (forClipboard && + newTrack->GetEndTime() + 1.0 / newTrack->GetRate() < t1 - t0) { auto placeholder = make_movable(mDirManager, newTrack->GetSampleFormat(), diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 2fbb03ed5..977ca6474 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -167,8 +167,14 @@ class AUDACITY_DLL_API WaveTrack final : public Track { // Track::Holder Cut(double t0, double t1) override; - Track::Holder Copy(double t0, double t1) const override; + + // If forClipboard is true, + // and there is no clip at the end time of the selection, then the result + // will contain a "placeholder" clip whose only purpose is to make + // GetEndTime() correct. This clip is not re-copied when pasting. + Track::Holder Copy(double t0, double t1, bool forClipboard = true) const override; Track::Holder CopyNonconst(double t0, double t1) /* not override */; + bool Clear(double t0, double t1) override; bool Paste(double t0, const Track *src) override; bool ClearAndPaste(double t0, double t1,