From 15313a27f7611e161711dfac2a20c9a248442184 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 29 Jan 2021 00:25:33 -0500 Subject: [PATCH] Define virtual Track::PasteInto to simplfy Paste... ... Also making EditMenus not dependent on TimeTrack --- src/LabelTrack.cpp | 7 +++++++ src/LabelTrack.h | 2 ++ src/NoteTrack.cpp | 7 +++++++ src/NoteTrack.h | 2 ++ src/TimeTrack.cpp | 12 ++++++++++++ src/TimeTrack.h | 2 ++ src/Track.h | 7 ++++++- src/WaveTrack.cpp | 9 +++++++++ src/WaveTrack.h | 2 ++ src/menus/EditMenus.cpp | 41 ++++++----------------------------------- 10 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/LabelTrack.cpp b/src/LabelTrack.cpp index 61a6e9e02..0d901b900 100644 --- a/src/LabelTrack.cpp +++ b/src/LabelTrack.cpp @@ -85,6 +85,13 @@ LabelTrack::LabelTrack(const LabelTrack &orig) : } } +Track::Holder LabelTrack::PasteInto( AudacityProject & ) const +{ + auto pNewTrack = std::make_shared(); + pNewTrack->Paste(0.0, this); + return pNewTrack; +} + template static IntervalType DoMakeInterval(const LabelStruct &label, size_t index) { diff --git a/src/LabelTrack.h b/src/LabelTrack.h index b10f12c81..476db8861 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -155,6 +155,8 @@ public: int FindNextLabel(const SelectedRegion& currentSelection); int FindPrevLabel(const SelectedRegion& currentSelection); + Track::Holder PasteInto( AudacityProject & ) const override; + struct IntervalData final : Track::IntervalData { size_t index; explicit IntervalData(size_t index) : index{index} {}; diff --git a/src/NoteTrack.cpp b/src/NoteTrack.cpp index 789a1ff8e..c73d4b83a 100644 --- a/src/NoteTrack.cpp +++ b/src/NoteTrack.cpp @@ -683,6 +683,13 @@ QuantizedTimeAndBeat NoteTrack::NearestBeatTime( double time ) const return { seq_time + GetOffset(), beat }; } +Track::Holder NoteTrack::PasteInto( AudacityProject & ) const +{ + auto pNewTrack = std::make_shared(); + pNewTrack->Paste(0.0, this); + return pNewTrack; +} + auto NoteTrack::GetIntervals() const -> ConstIntervals { ConstIntervals results; diff --git a/src/NoteTrack.h b/src/NoteTrack.h index f1cf21658..ceb7c0c0f 100644 --- a/src/NoteTrack.h +++ b/src/NoteTrack.h @@ -185,6 +185,8 @@ public: mVisibleChannels = CHANNEL_BIT(c); } + Track::Holder PasteInto( AudacityProject & ) const override; + ConstIntervals GetIntervals() const override; Intervals GetIntervals() override; diff --git a/src/TimeTrack.cpp b/src/TimeTrack.cpp index 2863ecbb8..11703b691 100644 --- a/src/TimeTrack.cpp +++ b/src/TimeTrack.cpp @@ -136,6 +136,18 @@ bool TimeTrack::SupportsBasicEditing() const return false; } +Track::Holder TimeTrack::PasteInto( AudacityProject &project ) const +{ + // Maintain uniqueness of the time track! + std::shared_ptr pNewTrack; + if( auto pTrack = *TrackList::Get( project ).Any().begin() ) + pNewTrack = pTrack->SharedPointer(); + else + pNewTrack = std::make_shared( &ViewInfo::Get( project ) ); + pNewTrack->Paste(0.0, this); + return pNewTrack; +} + Track::Holder TimeTrack::Cut( double t0, double t1 ) { auto result = Copy( t0, t1, false ); diff --git a/src/TimeTrack.h b/src/TimeTrack.h index aa04bb424..041a2da71 100644 --- a/src/TimeTrack.h +++ b/src/TimeTrack.h @@ -42,6 +42,8 @@ class TimeTrack final : public Track { bool SupportsBasicEditing() const override; + Holder PasteInto( AudacityProject & ) const override; + Holder Cut( double t0, double t1 ) override; Holder Copy( double t0, double t1, bool forClipboard ) const override; void Clear(double t0, double t1) override; diff --git a/src/Track.h b/src/Track.h index e3440f290..3adbf1b5a 100644 --- a/src/Track.h +++ b/src/Track.h @@ -321,6 +321,12 @@ class AUDACITY_DLL_API Track /* not final */ //! Whether this track type implements cut-copy-paste; by default, true virtual bool SupportsBasicEditing() const; + using Holder = std::shared_ptr; + + //! Find or create the destination track for a paste, maybe in a different project + /*! @return A smart pointer to the track; its `use_count()` can tell whether it is new */ + virtual Holder PasteInto( AudacityProject & ) const = 0; + //! Report times on the track where important intervals begin and end, for UI to snap to /*! Some intervals may be empty, and no ordering of the intervals is assumed. @@ -393,7 +399,6 @@ private: void Init(const Track &orig); - using Holder = std::shared_ptr; // public nonvirtual duplication function that invokes Clone(): virtual Holder Duplicate() const; diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 9d697f73c..e5d794916 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -334,6 +334,15 @@ static Container MakeIntervals(const std::vector &clips) return result; } +Track::Holder WaveTrack::PasteInto( AudacityProject &project ) const +{ + auto &trackFactory = WaveTrackFactory::Get( project ); + auto &pSampleBlockFactory = trackFactory.GetSampleBlockFactory(); + auto pNewTrack = EmptyCopy( pSampleBlockFactory ); + pNewTrack->Paste(0.0, this); + return pNewTrack; +} + auto WaveTrack::GetIntervals() const -> ConstIntervals { return MakeIntervals( mClips ); diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 370c1ff73..97e8c2e53 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -537,6 +537,8 @@ private: std::shared_ptr pClip; }; + Track::Holder PasteInto( AudacityProject & ) const override; + ConstIntervals GetIntervals() const override; Intervals GetIntervals() override; diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index 3dd92d89d..169873416 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -11,7 +11,6 @@ #include "../ProjectSettings.h" #include "../ProjectWindow.h" #include "../SelectUtilities.h" -#include "../TimeTrack.h" #include "../TrackPanel.h" #include "../TrackPanelAx.h" #include "../UndoManager.h" @@ -76,8 +75,6 @@ bool DoPasteText(AudacityProject &project) bool DoPasteNothingSelected(AudacityProject &project) { auto &tracks = TrackList::Get( project ); - auto &trackFactory = WaveTrackFactory::Get( project ); - auto &pSampleBlockFactory = trackFactory.GetSampleBlockFactory(); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; auto &viewInfo = ViewInfo::Get( project ); auto &window = ProjectWindow::Get( project ); @@ -94,44 +91,18 @@ bool DoPasteNothingSelected(AudacityProject &project) Track* pFirstNewTrack = NULL; for (auto pClip : clipTrackRange) { - Track::Holder uNewTrack; - Track *pNewTrack; - pClip->TypeSwitch( - [&](const WaveTrack *wc) { - uNewTrack = wc->EmptyCopy( pSampleBlockFactory ); - pNewTrack = uNewTrack.get(); - }, -#ifdef USE_MIDI - [&](const NoteTrack *) { - uNewTrack = std::make_shared(), - pNewTrack = uNewTrack.get(); - }, -#endif - [&](const LabelTrack *) { - uNewTrack = std::make_shared(), - pNewTrack = uNewTrack.get(); - }, - [&](const TimeTrack *) { - // Maintain uniqueness of the time track! - pNewTrack = *tracks.Any().begin(); - if (!pNewTrack) - uNewTrack = std::make_shared( &viewInfo ), - pNewTrack = uNewTrack.get(); - } - ); - + auto pNewTrack = pClip->PasteInto( project ); + bool newTrack = (pNewTrack.use_count() == 1); wxASSERT(pClip); - pNewTrack->Paste(0.0, pClip); - if (!pFirstNewTrack) - pFirstNewTrack = pNewTrack; + pFirstNewTrack = pNewTrack.get(); pNewTrack->SetSelected(true); - if (uNewTrack) - FinishCopy(pClip, uNewTrack, tracks); + if (newTrack) + FinishCopy(pClip, pNewTrack, tracks); else - Track::FinishCopy(pClip, pNewTrack); + Track::FinishCopy(pClip, pNewTrack.get()); } // Select some pasted samples, which is probably impossible to get right