Audacity 3.2.0
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
TrackList Class Referencefinal

A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list of tracks, event notifications. More...

#include <Track.h>

Inheritance diagram for TrackList:
[legend]
Collaboration diagram for TrackList:
[legend]

Public Types

using iterator = TrackIter< Track >
 
using const_iterator = TrackIter< const Track >
 
using value_type = Track *
 
using reverse_iterator = std::reverse_iterator< iterator >
 
using const_reverse_iterator = std::reverse_iterator< const_iterator >
 
using Updater = std::function< void(Track &dest, const Track &src)>
 
- Public Types inherited from Observer::Publisher< TrackListEvent >
using message_type = TrackListEvent
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const TrackListEvent &) >
 Type of functions that can be connected to the Publisher. More...
 

Public Member Functions

 TrackList (AudacityProject *pOwner)
 
void Swap (TrackList &that)
 
virtual ~TrackList ()
 
AudacityProjectGetOwner ()
 
const AudacityProjectGetOwner () const
 
wxString MakeUniqueTrackName (const wxString &baseTrackName) const
 Returns string that contains baseTrackName, but is guaranteed to be unique among other tracks in that list. More...
 
iterator begin ()
 
iterator end ()
 
const_iterator begin () const
 
const_iterator end () const
 
const_iterator cbegin () const
 
const_iterator cend () const
 
reverse_iterator rbegin ()
 
reverse_iterator rend ()
 
const_reverse_iterator rbegin () const
 
const_reverse_iterator rend () const
 
const_reverse_iterator crbegin () const
 
const_reverse_iterator crend () const
 
TrackIter< TrackDoFind (Track *pTrack)
 
TrackIter< TrackFind (Track *pTrack)
 
TrackIter< const TrackFind (const Track *pTrack) const
 
template<typename TrackType = Track>
auto Any () -> TrackIterRange< TrackType >
 
template<typename TrackType = const Track>
auto Any () const -> std::enable_if_t< std::is_const_v< TrackType >, TrackIterRange< TrackType > >
 
template<typename TrackType = Track>
auto Selected () -> TrackIterRange< TrackType >
 
template<typename TrackType = const Track>
auto Selected () const -> std::enable_if_t< std::is_const_v< TrackType >, TrackIterRange< TrackType > >
 
void Insert (const Track *before, TrackList &&trackList)
 Inserts tracks form trackList starting from position where before is located. If before is nullptr tracks are appended. More...
 
void Permute (const std::vector< Track * > &tracks)
 
TrackFindById (TrackId id)
 
template<typename TrackKind >
TrackKind * AddToHead (const std::shared_ptr< TrackKind > &t)
 Add a Track, giving it a fresh id. More...
 
template<typename TrackKind >
TrackKind * Add (const std::shared_ptr< TrackKind > &t)
 
std::vector< Track * > UnlinkChannels (Track &track)
 Removes linkage if track belongs to a group. More...
 
bool MakeMultiChannelTrack (Track &first, int nChannels)
 Converts channels to a multichannel track. More...
 
TrackListHolder ReplaceOne (Track &t, TrackList &&with)
 
void Remove (Track &track)
 Remove a channel group, given the leader. More...
 
void Clear (bool sendEvent=true)
 Make the list empty. More...
 
bool CanMoveUp (Track *t) const
 
bool CanMoveDown (Track *t) const
 
bool MoveUp (Track *t)
 
bool MoveDown (Track *t)
 
bool Move (Track *t, bool up)
 
template<typename Subclass >
std::shared_ptr< Subclass > Lock (const std::weak_ptr< Subclass > &wTrack)
 
bool empty () const
 
size_t NChannels () const
 
size_t Size () const
 
double GetStartTime () const
 Return the least start time of the tracks, or 0 when no tracks. More...
 
double GetEndTime () const
 Return the greatest end time of the tracks, or 0 when no tracks. More...
 
void Append (TrackList &&list)
 Remove all tracks from list and put them at the end of this More...
 
void RegisterPendingNewTracks (TrackList &&list)
 
void AppendOne (TrackList &&list)
 
TrackRegisterPendingChangedTrack (Updater updater, Track *src)
 
void UpdatePendingTracks ()
 
void ClearPendingTracks (ListOfTracks *pAdded=nullptr)
 
bool ApplyPendingTracks ()
 
bool HasPendingTracks () const
 
- Public Member Functions inherited from Observer::Publisher< TrackListEvent >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 
- Public Member Functions inherited from ClientData::Base
virtual ~Base ()
 

Static Public Member Functions

static TrackListGet (AudacityProject &project)
 
static const TrackListGet (const AudacityProject &project)
 
static TrackListFindUndoTracks (const UndoStackElem &state)
 
static TrackListHolder Create (AudacityProject *pOwner)
 
template<typename TrackType >
static auto SingletonRange (TrackType *pTrack) -> TrackIterRange< TrackType >
 
template<typename TrackType >
static auto Channels (TrackType *pTrack) -> TrackIterRange< TrackType >
 
static size_t NChannels (const Track &track)
 Count channels of a track. More...
 
static TrackSwapChannels (Track &track)
 
static TrackListHolder Temporary (AudacityProject *pProject, const Track::Holder &left={}, const Track::Holder &right={})
 
static TrackListHolder Temporary (AudacityProject *pProject, const std::vector< Track::Holder > &channels)
 
template<typename T >
static TrackListHolder Temporary (AudacityProject *pProject, const std::vector< std::shared_ptr< T > > &channels)
 

Private Member Functions

 TrackList (const TrackList &that)=delete
 
TrackListoperator= (const TrackList &)=delete
 
 TrackList (TrackList &&that)=delete
 
TrackListoperator= (TrackList &&)=delete
 
void clear ()=delete
 
iterator Begin ()
 This private function still iterates channels not tracks. More...
 
iterator End ()
 This private function still iterates channels not tracks. More...
 
const_iterator Begin () const
 This private function still iterates channels not tracks. More...
 
const_iterator End () const
 This private function still iterates channels not tracks. More...
 
TrackDoAddToHead (const std::shared_ptr< Track > &t)
 
TrackDoAdd (const std::shared_ptr< Track > &t)
 
template<typename TrackType = Track, typename Pred = typename TrackIterRange< TrackType >::iterator::FunctionType>
auto Tracks (const Pred &pred={}) -> TrackIterRange< TrackType >
 
template<typename TrackType = const Track, typename Pred = typename TrackIterRange< TrackType >::iterator::FunctionType>
auto Tracks (const Pred &pred={}) const -> std::enable_if_t< std::is_const_v< TrackType >, TrackIterRange< TrackType > >
 
TrackGetPrev (Track *t, bool linked=false) const
 
TrackGetNext (Track *t, bool linked=false) const
 Return a track in the list that comes after Track t. More...
 
template<typename TrackType >
TrackIter< TrackType > MakeTrackIterator (TrackNodePointer iter) const
 
template<typename TrackType >
TrackIter< TrackType > EndIterator () const
 
TrackIterRange< TrackEmptyRange () const
 
bool isNull (TrackNodePointer p) const
 
TrackNodePointer getEnd () const
 
TrackNodePointer getBegin () const
 
TrackNodePointer getNext (TrackNodePointer p) const
 Move an iterator to the next node, if any; else stay at end. More...
 
TrackNodePointer getPrev (TrackNodePointer p) const
 Move an iterator to the previous node, if any; else wrap to end. More...
 
void RecalcPositions (TrackNodePointer node)
 
void QueueEvent (TrackListEvent event)
 
void SelectionEvent (Track &track)
 
void PermutationEvent (TrackNodePointer node)
 
void DataEvent (const std::shared_ptr< Track > &pTrack, bool allChannels, int code)
 
void DeletionEvent (std::weak_ptr< Track > node, bool duringReplace)
 
void AdditionEvent (TrackNodePointer node)
 
void ResizingEvent (TrackNodePointer node)
 
void SwapNodes (TrackNodePointer s1, TrackNodePointer s2)
 

Static Private Member Functions

template<typename TrackType , typename InTrackType >
static TrackIterRange< TrackType > Channels_ (TrackIter< InTrackType > iter1)
 

Private Attributes

AudacityProjectmOwner
 
std::shared_ptr< TrackListmPendingUpdates
 
std::vector< UpdatermUpdaters
 This is in correspondence with leader tracks in mPendingUpdates. More...
 
bool mAssignsIds { true }
 

Static Private Attributes

static long sCounter = -1
 

Friends

class Track
 

Additional Inherited Members

- Static Public Attributes inherited from Observer::Publisher< TrackListEvent >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from Observer::Publisher< TrackListEvent >
CallbackReturn Publish (const TrackListEvent &message)
 Send a message to connected callbacks. More...
 

Detailed Description

A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list of tracks, event notifications.

Definition at line 988 of file Track.h.

Member Typedef Documentation

◆ const_iterator

Definition at line 1047 of file Track.h.

◆ const_reverse_iterator

using TrackList::const_reverse_iterator = std::reverse_iterator<const_iterator>

Definition at line 1059 of file Track.h.

◆ iterator

Definition at line 1046 of file Track.h.

◆ reverse_iterator

using TrackList::reverse_iterator = std::reverse_iterator<iterator>

Definition at line 1058 of file Track.h.

◆ Updater

using TrackList::Updater = std::function<void(Track &dest, const Track &src)>

The tracks supplied to this function will be leaders with the same number of channels

Definition at line 1422 of file Track.h.

◆ value_type

Definition at line 1049 of file Track.h.

Constructor & Destructor Documentation

◆ TrackList() [1/3]

TrackList::TrackList ( const TrackList that)
privatedelete

◆ TrackList() [2/3]

TrackList::TrackList ( TrackList &&  that)
privatedelete

◆ TrackList() [3/3]

TrackList::TrackList ( AudacityProject pOwner)
explicit

Definition at line 357 of file Track.cpp.

358 : mOwner{ pOwner }
359{
360 if (mOwner)
361 mPendingUpdates = Temporary(nullptr);
362}
AudacityProject * mOwner
Definition: Track.h:1467
std::shared_ptr< TrackList > mPendingUpdates
Definition: Track.h:1472
static TrackListHolder Temporary(AudacityProject *pProject, const Track::Holder &left={}, const Track::Holder &right={})
Definition: Track.cpp:1418

References mOwner, mPendingUpdates, and Temporary().

Here is the call graph for this function:

◆ ~TrackList()

TrackList::~TrackList ( )
virtual

Definition at line 406 of file Track.cpp.

407{
408 Clear(false);
409}
void Clear(bool sendEvent=true)
Make the list empty.
Definition: Track.cpp:772

References Clear().

Here is the call graph for this function:

Member Function Documentation

◆ Add()

template<typename TrackKind >
TrackKind * TrackList::Add ( const std::shared_ptr< TrackKind > &  t)
inline

Definition at line 1201 of file Track.h.

1202 { return static_cast< TrackKind* >( DoAdd( t ) ); }
Track * DoAdd(const std::shared_ptr< Track > &t)
Definition: Track.cpp:611

Referenced by Append(), AppendOne(), ApplyPendingTracks(), LabelTrack::Create(), AUPImportFileHandle::HandleLabelTrack(), AUPImportFileHandle::HandleNoteTrack(), AUPImportFileHandle::HandleTimeTrack(), AUPImportFileHandle::HandleWaveTrack(), NoteTrack::PasteInto(), TimeTrack::PasteInto(), WaveTrack::PasteInto(), LabelTrack::PasteInto(), RegisterPendingNewTracks(), and LabelDialog::TransferDataFromWindow().

Here is the caller graph for this function:

◆ AdditionEvent()

void TrackList::AdditionEvent ( TrackNodePointer  node)
private

Definition at line 491 of file Track.cpp.

492{
493 QueueEvent({ TrackListEvent::ADDITION, *node.first });
494}
void QueueEvent(TrackListEvent event)
Definition: Track.cpp:452
@ ADDITION
Posted when a track has been added to a tracklist. Also posted when one track replaces another.
Definition: Track.h:962

References TrackListEvent::ADDITION, and QueueEvent().

Referenced by ApplyPendingTracks(), DoAdd(), DoAddToHead(), and ReplaceOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddToHead()

template<typename TrackKind >
TrackKind * TrackList::AddToHead ( const std::shared_ptr< TrackKind > &  t)
inline

Add a Track, giving it a fresh id.

Definition at line 1197 of file Track.h.

1198 { return static_cast< TrackKind* >( DoAddToHead( t ) ); }
Track * DoAddToHead(const std::shared_ptr< Track > &t)
Definition: Track.cpp:599

◆ Any() [1/2]

template<typename TrackType = Track>
auto TrackList::Any ( ) -> TrackIterRange< TrackType >
inline

Definition at line 1097 of file Track.h.

1099 {
1100 return Tracks< TrackType >( &Track::IsLeader );
1101 }
bool IsLeader() const override
Definition: Track.cpp:291

References Track::IsLeader().

Referenced by anonymous_namespace{Track.cpp}::Accumulate(), cloud::audiocom::anonymous_namespace{ShareAudioDialog.cpp}::CalculateChannels(), WaveTrack::ClearAndPaste(), LabelDefaultClickHandle::Click(), anonymous_namespace{EditMenus.cpp}::CutCopyAvailableFlag(), LabelTrackView::DoKeyDown(), TimeShiftHandle::DoSlideVertical(), TrackPanel::DrawTracks(), EffectOutputTracks::EffectOutputTracks(), ControlToolBar::EnableDisableButtons(), TranscriptionToolBar::EnableDisableButtons(), anonymous_namespace{EditMenus.cpp}::EstimateCopiedBlocks(), anonymous_namespace{EditMenus.cpp}::EstimateCopyBytesCount(), LabelDialog::FindAllLabels(), anonymous_namespace{TimeShiftHandle.cpp}::FindCorrespondence(), anonymous_namespace{EditMenus.cpp}::FindCorrespondence(), ImportUtils::ForEachChannel(), EffectSilence::GenerateTrack(), GetAllSeqBlocks(), anonymous_namespace{EditMenus.cpp}::HasHiddenData(), MixerBoard::HasSolo(), ProjectFileManager::Import(), VampEffect::Init(), MakeTransportTracks(), anonymous_namespace{ExportMIDI.cpp}::NoteTracksExistFlag(), ExportFilePanel::OnChannelsConfigure(), ExportAudioDialog::OnExport(), TranscriptionToolBar::PlayAtSpeed(), TrackSelectHandle::Preview(), EffectFindClipping::Process(), NyquistEffect::Process(), NyquistEffect::ProcessOne(), PerTrackEffect::ProcessPass(), RealtimeEffectPanel::RealtimeEffectPanel(), TracksExistFlag(), LabelDialog::TransferDataFromWindow(), ExportFilePanel::UpdateMaxChannels(), MixerBoard::UpdateTrackClusters(), TrackPanel::UpdateVRulerSize(), WaveTracksExistFlag(), ZoomInAvailableFlag(), and ZoomOutAvailableFlag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Any() [2/2]

template<typename TrackType = const Track>
auto TrackList::Any ( ) const -> std::enable_if_t< std::is_const_v<TrackType>, TrackIterRange< TrackType > >
inline

Definition at line 1104 of file Track.h.

1108 {
1109 return Tracks< TrackType >( &Track::IsLeader );
1110 }

References Track::IsLeader().

Here is the call graph for this function:

◆ Append()

void TrackList::Append ( TrackList &&  list)

Remove all tracks from list and put them at the end of this

Definition at line 1449 of file Track.cpp.

1450{
1451 auto iter = list.ListOfTracks::begin(),
1452 end = list.ListOfTracks::end();
1453 while (iter != end) {
1454 auto pTrack = *iter;
1455 iter = list.erase(iter);
1456 this->Add(pTrack);
1457 }
1458}
iterator end()
Definition: Track.h:1051
TrackKind * Add(const std::shared_ptr< TrackKind > &t)
Definition: Track.h:1201

References Add(), and end().

Referenced by Insert(), and anonymous_namespace{Track.cpp}::TrackListRestorer::TrackListRestorer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AppendOne()

void TrackList::AppendOne ( TrackList &&  list)

Remove first channel group (if any) from list and put it at the end of this

Definition at line 1470 of file Track.cpp.

1471{
1472 auto iter = list.ListOfTracks::begin(),
1473 end = list.ListOfTracks::end();
1474 if (iter != end) {
1475 for (size_t nn = TrackList::NChannels(**iter); nn--;) {
1476 auto pTrack = *iter;
1477 iter = list.erase(iter);
1478 this->Add(pTrack);
1479 }
1480 }
1481}
size_t NChannels() const
Definition: Track.cpp:960

References Add(), end(), and NChannels().

Referenced by EffectOutputTracks::Commit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ApplyPendingTracks()

bool TrackList::ApplyPendingTracks ( )
Exception safety guarantee:
Strong

Definition at line 1092 of file Track.cpp.

1093{
1094 bool result = false;
1095
1096 ListOfTracks additions;
1097 auto updates = Temporary(nullptr);
1098 {
1099 // Always clear, even if one of the update functions throws
1100 auto cleanup = finally( [&] { ClearPendingTracks( &additions ); } );
1102 updates.swap(mPendingUpdates);
1103 }
1104
1105 // Remaining steps must be No-fail-guarantee so that this function
1106 // gives Strong-guarantee
1107
1108 std::vector< std::shared_ptr<Track> > reinstated;
1109
1110 if (updates)
1111 for (auto pendingTrack : static_cast<ListOfTracks &>(*updates))
1112 pendingTrack->AttachedTrackObjects::ForEach([&](auto &attachment){
1113 attachment.Reparent( pendingTrack );
1114 });
1115 while (updates && !updates->empty()) {
1116 auto iter = updates->ListOfTracks::begin();
1117 auto pendingTrack = *iter;
1118 auto src = FindById(pendingTrack->GetId());
1119 if (src) {
1120 this->ReplaceOne(*src, std::move(*updates));
1121 result = true;
1122 }
1123 else {
1124 // Perhaps a track marked for pending changes got deleted by
1125 // some other action. Recreate it so we don't lose the
1126 // accumulated changes.
1127 reinstated.push_back(pendingTrack);
1128 updates->ListOfTracks::erase(iter);
1129 }
1130 }
1131
1132 // If there are tracks to reinstate, append them to the list.
1133 for (auto &pendingTrack : reinstated)
1134 if (pendingTrack)
1135 this->Add( pendingTrack ), result = true;
1136
1137 // Put the pending added tracks back into the list, preserving their
1138 // positions.
1139 bool inserted = false;
1140 ListOfTracks::iterator first;
1141 for (auto &pendingTrack : additions) {
1142 if (pendingTrack) {
1143 auto iter = ListOfTracks::begin();
1144 std::advance( iter, pendingTrack->GetIndex() );
1145 iter = ListOfTracks::insert( iter, pendingTrack );
1146 pendingTrack->SetOwner( shared_from_this(), {iter, this} );
1147 pendingTrack->SetId( TrackId{ ++sCounter } );
1148 if (!inserted) {
1149 first = iter;
1150 inserted = true;
1151 }
1152 }
1153 }
1154 if (inserted) {
1155 TrackNodePointer node{first, this};
1156 RecalcPositions(node);
1157 AdditionEvent(node);
1158 result = true;
1159 }
1160
1161 return result;
1162}
std::pair< ListOfTracks::iterator, ListOfTracks * > TrackNodePointer
Pairs a std::list iterator and a pointer to a list, for comparison purposes.
Definition: Track.h:51
std::list< std::shared_ptr< Track > > ListOfTracks
Definition: Track.h:45
An in-session identifier of track objects across undo states. It does not persist between sessions.
Definition: Track.h:91
static long sCounter
Definition: Track.h:1417
void AdditionEvent(TrackNodePointer node)
Definition: Track.cpp:491
void RecalcPositions(TrackNodePointer node)
Definition: Track.cpp:429
TrackListHolder ReplaceOne(Track &t, TrackList &&with)
Definition: Track.cpp:637
void ClearPendingTracks(ListOfTracks *pAdded=nullptr)
Definition: Track.cpp:1050
void UpdatePendingTracks()
Definition: Track.cpp:1030
Track * FindById(TrackId id)
Definition: Track.cpp:588
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150

References Add(), AdditionEvent(), PackedArray::begin(), ClearPendingTracks(), FindById(), mPendingUpdates, RecalcPositions(), ReplaceOne(), sCounter, Temporary(), and UpdatePendingTracks().

Referenced by ProjectAudioManager::OnCommitRecording().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ begin() [1/2]

iterator TrackList::begin ( )
inline

Definition at line 1050 of file Track.h.

1050{ return Any().begin(); }
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1097

Referenced by Track::Paste().

Here is the caller graph for this function:

◆ Begin() [1/2]

iterator TrackList::Begin ( )
inlineprivate

This private function still iterates channels not tracks.

Definition at line 1086 of file Track.h.

1086{ return Tracks<Track>().begin(); }

Referenced by empty(), and HasPendingTracks().

Here is the caller graph for this function:

◆ begin() [2/2]

const_iterator TrackList::begin ( ) const
inline

Definition at line 1052 of file Track.h.

1052{ return Any().begin(); }

◆ Begin() [2/2]

const_iterator TrackList::Begin ( ) const
inlineprivate

This private function still iterates channels not tracks.

Definition at line 1091 of file Track.h.

1091{ return Tracks<const Track>().begin(); }

◆ CanMoveDown()

bool TrackList::CanMoveDown ( Track t) const

Definition at line 861 of file Track.cpp.

862{
863 return GetNext(t, true) != NULL;
864}
Track * GetNext(Track *t, bool linked=false) const
Return a track in the list that comes after Track t.
Definition: Track.cpp:801

References GetNext().

Here is the call graph for this function:

◆ CanMoveUp()

bool TrackList::CanMoveUp ( Track t) const

Definition at line 856 of file Track.cpp.

857{
858 return GetPrev(t, true) != NULL;
859}
Track * GetPrev(Track *t, bool linked=false) const
Definition: Track.cpp:820

References GetPrev().

Here is the call graph for this function:

◆ cbegin()

const_iterator TrackList::cbegin ( ) const
inline

Definition at line 1054 of file Track.h.

1054{ return begin(); }
iterator begin()
Definition: Track.h:1050

References PackedArray::begin().

Here is the call graph for this function:

◆ cend()

const_iterator TrackList::cend ( ) const
inline

Definition at line 1055 of file Track.h.

1055{ return end(); }

References PackedArray::end().

Here is the call graph for this function:

◆ Channels()

template<typename TrackType >
static auto TrackList::Channels ( TrackType *  pTrack) -> TrackIterRange< TrackType >
inlinestatic

Definition at line 1164 of file Track.h.

1166 {
1167 return Channels_<TrackType>(pTrack->GetHolder()->Find(pTrack));
1168 }

Referenced by anonymous_namespace{WaveChannelView.cpp}::AnyAffordance(), WaveTrack::Append(), WaveTrack::Clear(), WaveTrack::ClearAndAddCutLine(), WaveTrack::ClearAndPasteAtSameTempo(), WaveTrack::Clone(), WaveTrack::CloseLock(), WaveTrack::ConvertToSampleFormat(), WaveTrack::Copy(), WaveTrack::CopyClipEnvelopes(), WaveTrack::CountBlocks(), WaveTrack::CreateWideClip(), DataEvent(), WaveTrack::DiscardTrimmed(), WaveChannelSubView::DoDetailedHitTest(), WaveTrack::DoGet(), WaveTrack::DoGetChannel(), WaveTrack::DoOnProjectTempoChange(), TrackPanelResizerCell::Draw(), Track::Duplicate(), WaveTrack::ExpandCutLine(), anonymous_namespace{PendingTracks.cpp}::finder(), WaveTrack::Flush(), WaveTrack::FormatConsistencyCheck(), ChannelView::GetChannelGroupHeight(), WaveTrack::GetClipInterfaces(), WaveTrack::GetEnvelopeAtTime(), WaveTrack::GetEnvelopeValues(), WaveTrack::GetErrorOpening(), CommonChannelView::GetMinimizedHeight(), WaveTrack::GetSequenceSamplesCount(), TrackPanelResizeHandle::GetTrack(), WaveTrack::HasHiddenData(), WaveTrack::HasTrivialEnvelope(), WaveTrack::InsertInterval(), WaveTrack::InsertSilence(), WaveTrack::Join(), WaveTrack::LinkConsistencyFix(), WaveTrack::MergeClips(), WaveTrack::MoveTo(), WaveTrack::PasteInto(), WaveTrack::PasteWaveTrackAtSameTempo(), Permute(), WaveTrack::RateConsistencyCheck(), RegisterPendingChangedTrack(), WaveTrack::Reinit(), WaveTrack::RemoveCutLine(), WaveTrack::RemoveInterval(), ReplaceOne(), WaveTrack::Resample(), WaveTrack::Reverse(), SelectionEvent(), ChannelView::SetMinimized(), WaveTrack::SetWaveColorIndex(), WaveTrack::Silence(), WaveTrack::Split(), WaveTrack::SplitDelete(), WaveTrack::SyncLockAdjust(), WaveTrack::Trim(), UnlinkChannels(), TrackPanel::UpdateVRuler(), VisitBlocks(), WaveTrack::WideEmptyCopy(), WaveTrack::WidestEffectiveFormat(), and WaveTrack::WriteXML().

◆ Channels_()

template<typename TrackType , typename InTrackType >
static TrackIterRange< TrackType > TrackList::Channels_ ( TrackIter< InTrackType >  iter1)
inlinestaticprivate

Definition at line 1142 of file Track.h.

1143 {
1144 // Assume iterator filters leader tracks
1145 if (*iter1) {
1146 return {
1147 iter1.Filter( &Track::Any )
1148 .template Filter<TrackType>(),
1149 (++iter1).Filter( &Track::Any )
1150 .template Filter<TrackType>()
1151 };
1152 }
1153 else
1154 // empty range
1155 return {
1156 iter1.template Filter<TrackType>(),
1157 iter1.template Filter<TrackType>()
1158 };
1159 }
bool Any() const
Definition: Track.cpp:285
TrackIter Filter(const Predicate2 &pred2) const
Return an iterator that replaces the predicate.
Definition: Track.h:690
Select only the subsequence of the type list satisfying the predicate.
Definition: TypeList.h:500

References Track::Any(), and TrackIter< TrackType >::Filter().

Here is the call graph for this function:

◆ clear()

void TrackList::clear ( )
privatedelete

◆ Clear()

void TrackList::Clear ( bool  sendEvent = true)

Make the list empty.

Definition at line 772 of file Track.cpp.

773{
774 // Null out the back-pointers to this in tracks, in case there
775 // are outstanding shared_ptrs to those tracks, making them outlive
776 // the temporary ListOfTracks below.
777 for (auto pTrack: Tracks<Track>()) {
778 pTrack->SetOwner({}, {});
779
780 if (sendEvent)
781 DeletionEvent(pTrack->shared_from_this(), false);
782 }
783
784 if (mPendingUpdates)
785 for (auto pTrack: static_cast<ListOfTracks&>(*mPendingUpdates)) {
786 pTrack->SetOwner({}, {});
787 if (sendEvent)
788 DeletionEvent(pTrack, false);
789 }
790
791 ListOfTracks tempList;
792 tempList.swap( *this );
793
794 if (mPendingUpdates)
795 mPendingUpdates = Temporary(nullptr);
796
797 mUpdaters.clear();
798}
std::vector< Updater > mUpdaters
This is in correspondence with leader tracks in mPendingUpdates.
Definition: Track.h:1474
void DeletionEvent(std::weak_ptr< Track > node, bool duringReplace)
Definition: Track.cpp:485

References DeletionEvent(), mPendingUpdates, mUpdaters, and Temporary().

Referenced by ~TrackList().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearPendingTracks()

void TrackList::ClearPendingTracks ( ListOfTracks pAdded = nullptr)
Exception safety guarantee:
No-fail

Definition at line 1050 of file Track.cpp.

1051{
1052 assert(GetOwner()); // which implies mPendingUpdates is not null
1053 for (const auto &pTrack: static_cast<ListOfTracks&>(*mPendingUpdates))
1054 pTrack->SetOwner( {}, {} );
1055 mPendingUpdates->ListOfTracks::clear();
1056 mUpdaters.clear();
1057
1058 if (pAdded)
1059 pAdded->clear();
1060
1061 // To find the first node that remains after the first deleted one
1062 TrackNodePointer node;
1063 bool foundNode = false;
1064
1065 for (auto it = ListOfTracks::begin(), stop = ListOfTracks::end();
1066 it != stop;) {
1067 if (it->get()->GetId() == TrackId{}) {
1068 do {
1069 if (pAdded)
1070 pAdded->push_back( *it );
1071 (*it)->SetOwner( {}, {} );
1072 DeletionEvent(*it, false);
1073 it = erase( it );
1074 }
1075 while (it != stop && it->get()->GetId() == TrackId{});
1076
1077 if (!foundNode && it != stop) {
1078 node = (*it)->GetNode();
1079 foundNode = true;
1080 }
1081 }
1082 else
1083 ++it;
1084 }
1085
1086 if (!empty()) {
1088 }
1089}
bool empty() const
Definition: Track.cpp:955
TrackNodePointer getBegin() const
Definition: Track.h:1376
AudacityProject * GetOwner()
Definition: Track.h:1032
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159

References PackedArray::begin(), DeletionEvent(), empty(), PackedArray::end(), getBegin(), GetOwner(), mPendingUpdates, mUpdaters, and RecalcPositions().

Referenced by ApplyPendingTracks(), ProjectAudioManager::CancelRecording(), and AudacityApp::OnExceptionInMainLoop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ crbegin()

const_reverse_iterator TrackList::crbegin ( ) const
inline

Definition at line 1064 of file Track.h.

1064{ return rbegin(); }
reverse_iterator rbegin()
Definition: Track.h:1060

◆ Create()

TrackListHolder TrackList::Create ( AudacityProject pOwner)
static

◆ crend()

const_reverse_iterator TrackList::crend ( ) const
inline

Definition at line 1065 of file Track.h.

1065{ return rend(); }
reverse_iterator rend()
Definition: Track.h:1061

◆ DataEvent()

void TrackList::DataEvent ( const std::shared_ptr< Track > &  pTrack,
bool  allChannels,
int  code 
)
private

Definition at line 467 of file Track.cpp.

469{
470 auto doQueueEvent = [this, code](const std::shared_ptr<Track> &theTrack){
472 };
473 if (allChannels)
474 for (auto channel : Channels(pTrack.get()))
475 doQueueEvent(channel->shared_from_this());
476 else
477 doQueueEvent(pTrack);
478}
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1164
@ TRACK_DATA_CHANGE
Posted when certain fields of a track change.
Definition: Track.h:952

References Channels(), QueueEvent(), and TrackListEvent::TRACK_DATA_CHANGE.

Here is the call graph for this function:

◆ DeletionEvent()

void TrackList::DeletionEvent ( std::weak_ptr< Track node,
bool  duringReplace 
)
private

Definition at line 485 of file Track.cpp.

486{
488 { TrackListEvent::DELETION, std::move(node), duringReplace ? 1 : 0 });
489}
@ DELETION
Posted when a track has been deleted from a tracklist. Also posted when one track replaces another.
Definition: Track.h:968

References TrackListEvent::DELETION, and QueueEvent().

Referenced by Clear(), ClearPendingTracks(), Remove(), and ReplaceOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoAdd()

Track * TrackList::DoAdd ( const std::shared_ptr< Track > &  t)
private

Definition at line 611 of file Track.cpp.

612{
613 if (!ListOfTracks::empty()) {
614 auto &pLast = *ListOfTracks::rbegin();
615 if (auto pGroupData = pLast->FindGroupData()
616 ; pGroupData && pGroupData->mLinkType != Track::LinkType::None
617 ) {
618 // Assume the newly added track is intended to pair with the last
619 // Avoid upsetting assumptions in case this track had its own group
620 // data initialized during Duplicate()
621 t->DestroyGroupData();
622 }
623 }
624
625 push_back(t);
626
627 auto n = getPrev( getEnd() );
628
629 t->SetOwner(shared_from_this(), n);
630 if (mAssignsIds)
631 t->SetId(TrackId{ ++sCounter });
633 AdditionEvent(n);
634 return back().get();
635}
TrackNodePointer getEnd() const
Definition: Track.h:1373
bool mAssignsIds
Definition: Track.h:1477
TrackNodePointer getPrev(TrackNodePointer p) const
Move an iterator to the previous node, if any; else wrap to end.
Definition: Track.h:1391

References AdditionEvent(), getEnd(), getPrev(), mAssignsIds, ChannelGroup::None, RecalcPositions(), and sCounter.

Here is the call graph for this function:

◆ DoAddToHead()

Track * TrackList::DoAddToHead ( const std::shared_ptr< Track > &  t)
private

Definition at line 599 of file Track.cpp.

600{
601 Track *pTrack = t.get();
602 push_front(ListOfTracks::value_type(t));
603 auto n = getBegin();
604 pTrack->SetOwner(shared_from_this(), n);
605 pTrack->SetId( TrackId{ ++sCounter } );
607 AdditionEvent(n);
608 return front().get();
609}
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:122
void SetOwner(const std::weak_ptr< TrackList > &list, TrackNodePointer node)
Update mNode when Track is added to TrackList, or removed from it.
Definition: Track.cpp:122
void SetId(TrackId id)
Definition: Track.h:152

References AdditionEvent(), getBegin(), RecalcPositions(), sCounter, Track::SetId(), and Track::SetOwner().

Here is the call graph for this function:

◆ DoFind()

auto TrackList::DoFind ( Track pTrack)

Turn a pointer into a TrackIter (constant time); get end iterator if this does not own the track

Definition at line 511 of file Track.cpp.

512{
513 if (!pTrack || pTrack->GetHolder() != this)
514 return EndIterator<Track>();
515 else
516 return MakeTrackIterator<Track>(pTrack->GetNode());
517}
TrackNodePointer GetNode() const
Retrieve mNode with debug checks.
Definition: Track.cpp:115
TrackList * GetHolder() const
Definition: Track.h:1480

Referenced by RecalcPositions().

Here is the caller graph for this function:

◆ empty()

bool TrackList::empty ( ) const

Definition at line 955 of file Track.cpp.

956{
957 return Begin() == End();
958}
iterator Begin()
This private function still iterates channels not tracks.
Definition: Track.h:1086
iterator End()
This private function still iterates channels not tracks.
Definition: Track.h:1088

References Begin(), and End().

Referenced by anonymous_namespace{Track.cpp}::Accumulate(), ImportCommand::Apply(), ClearPendingTracks(), ProjectFileManager::Import(), NChannels(), ApplyMacroDialog::OnApplyToFiles(), and anonymous_namespace{TimerRecordDialog.cpp}::OnTimerRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EmptyRange()

auto TrackList::EmptyRange ( ) const
private

Definition at line 501 of file Track.cpp.

503{
504 auto it = const_cast<TrackList*>(this)->getEnd();
505 return {
506 { it, it, it, &Track::Any },
507 { it, it, it, &Track::Any }
508 };
509}
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:993

References Track::Any(), and getEnd().

Here is the call graph for this function:

◆ end() [1/2]

iterator TrackList::end ( )
inline

Definition at line 1051 of file Track.h.

1051{ return Any().end(); }

Referenced by Append(), AppendOne(), FindUndoTracks(), MakeMultiChannelTrack(), RegisterPendingChangedTrack(), and ReplaceOne().

Here is the caller graph for this function:

◆ End() [1/2]

iterator TrackList::End ( )
inlineprivate

This private function still iterates channels not tracks.

Definition at line 1088 of file Track.h.

1088{ return Tracks<Track>().end(); }

Referenced by empty(), HasPendingTracks(), MakeMultiChannelTrack(), and RecalcPositions().

Here is the caller graph for this function:

◆ end() [2/2]

const_iterator TrackList::end ( ) const
inline

Definition at line 1053 of file Track.h.

1053{ return Any().end(); }

◆ End() [2/2]

const_iterator TrackList::End ( ) const
inlineprivate

This private function still iterates channels not tracks.

Definition at line 1093 of file Track.h.

1093{ return Tracks<const Track>().end(); }

◆ EndIterator()

template<typename TrackType >
TrackIter< TrackType > TrackList::EndIterator ( ) const
inlineprivate

Definition at line 1361 of file Track.h.

1362 {
1363 auto e = const_cast<TrackList*>(this)->getEnd();
1364 return { e, e, e };
1365 }

◆ Find() [1/2]

TrackIter< const Track > TrackList::Find ( const Track pTrack) const
inline

Definition at line 1077 of file Track.h.

1078 {
1079 return const_cast<TrackList*>(this)->
1080 Find(const_cast<Track*>(pTrack)).Filter<const Track>();
1081 }
TrackIter< Track > Find(Track *pTrack)
Definition: Track.cpp:519

References ActiveProjects::Find().

Here is the call graph for this function:

◆ Find() [2/2]

auto TrackList::Find ( Track pTrack)

Definition at line 519 of file Track.cpp.

520{
521 auto iter = DoFind(pTrack);
522 while( *iter && ! ( *iter )->IsLeader() )
523 --iter;
524 return iter.Filter( &Track::IsLeader );
525}
TrackIter< Track > DoFind(Track *pTrack)
Definition: Track.cpp:511

References Track::IsLeader().

Referenced by SpectrumView::DoDraw(), WaveformView::DoDraw(), TimeShiftHandle::DoSlideVertical(), anonymous_namespace{TimeShiftHandle.cpp}::FindCorrespondence(), TrackPanel::FindTrackRect(), Insert(), anonymous_namespace{ChannelView.cpp}::TrackPositioner::OnUpdate(), ProjectTempoListener::ProjectTempoListener(), TrackPanel::RefreshTrack(), TrackFocus::Set(), and SwapNodes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindById()

Track * TrackList::FindById ( TrackId  id)

Definition at line 588 of file Track.cpp.

589{
590 // Linear search. Tracks in a project are usually very few.
591 // Search only the non-pending tracks.
592 auto it = std::find_if( ListOfTracks::begin(), ListOfTracks::end(),
593 [=](const ListOfTracks::value_type &ptr){ return ptr->GetId() == id; } );
594 if (it == ListOfTracks::end())
595 return {};
596 return it->get();
597}

References PackedArray::begin(), and PackedArray::end().

Referenced by ApplyPendingTracks(), and UpdatePendingTracks().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindUndoTracks()

TrackList * TrackList::FindUndoTracks ( const UndoStackElem state)
static

Definition at line 1406 of file Track.cpp.

1407{
1408 auto &exts = state.state.extensions;
1409 auto end = exts.end(),
1410 iter = std::find_if(exts.begin(), end, [](auto &pExt){
1411 return dynamic_cast<TrackListRestorer*>(pExt.get());
1412 });
1413 if (iter != end)
1414 return static_cast<TrackListRestorer*>(iter->get())->mpTracks.get();
1415 return nullptr;
1416}
static const auto exts
Definition: ImportAUP.cpp:56
UndoState state
Definition: UndoManager.h:128
Extensions extensions
Definition: UndoManager.h:114

References end(), UndoState::extensions, exts, and UndoStackElem::state.

Referenced by anonymous_namespace{HistoryWindow.cpp}::SpaceUsageCalculator::Calculate(), ProjectFileManager::Compact(), and EstimateRemovedBlocks().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Get() [1/2]

TrackList & TrackList::Get ( AudacityProject project)
static

Definition at line 347 of file Track.cpp.

348{
349 return project.AttachedObjects::Get< TrackList >( key );
350}
const auto project
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: Track.cpp:343

References key, and project.

Referenced by SelectUtilities::ActivatePlayRegion(), ProjectFileManager::AddImportedTracks(), SelectHandle::AdjustSelection(), AdornedRulerPanel::AdornedRulerPanel(), AnyTracksSelectedPred(), AppendItem(), SetTrackBase::Apply(), ImportCommand::Apply(), SelectTimeCommand::Apply(), SelectTracksCommand::Apply(), SetClipCommand::Apply(), SetLabelCommand::Apply(), BrushHandleHitTest(), TrackSelectHandle::CalculateRearrangingThresholds(), TrackPanelResizeHandle::Cancel(), ProjectAudioManager::CancelRecording(), anonymous_namespace{Track.cpp}::TrackListRestorer::CanUndoOrRedo(), ProjectAudioManager::ChooseExistingRecordingTracks(), ButtonHandle::Click(), TrackPanelResizeHandle::Click(), LabelDefaultClickHandle::Click(), LabelGlyphHandle::Click(), BrushHandle::Click(), SelectHandle::Click(), TimeShiftHandle::Click(), BackgroundHandle::Click(), Viewport::CollapseAllTracks(), anonymous_namespace{EditMenus.cpp}::CutCopyAvailableFlag(), anonymous_namespace{LabelMenus.cpp}::DoAddLabel(), anonymous_namespace{TrackMenus.cpp}::DoAlign(), anonymous_namespace{SelectMenus.cpp}::DoBoundaryMove(), anonymous_namespace{ClipMenus.cpp}::DoClipLeftOrRight(), LOFImportFileHandle::doDurationAndScrollOffset(), LabelTrackView::DoEditLabels(), EffectUI::DoEffect(), anonymous_namespace{FileMenus.cpp}::DoExport(), ExportAudioDialog::DoExportSplitByTracks(), anonymous_namespace{ImportMIDI.cpp}::DoImportMIDI(), LabelTrackView::DoKeyDown(), SelectUtilities::DoListSelection(), anonymous_namespace{TrackMenus.cpp}::DoMixAndRender(), anonymous_namespace{TransportMenus.cpp}::DoMoveToLabel(), TrackUtilities::DoMoveTrack(), anonymous_namespace{NavigationMenus.cpp}::DoNextTrack(), anonymous_namespace{TrackMenus.cpp}::DoPanTracks(), anonymous_namespace{EditMenus.cpp}::DoPasteNothingSelected(), anonymous_namespace{EditMenus.cpp}::DoPasteText(), anonymous_namespace{NavigationMenus.cpp}::DoPrevTrack(), ProjectAudioManager::DoRecord(), TrackUtilities::DoRemoveTrack(), TrackUtilities::DoRemoveTracks(), ProjectFileManager::DoSave(), SelectUtilities::DoSelectSomething(), anonymous_namespace{SelectUtilities.cpp}::DoSelectTimeAndAudioTracks(), SelectUtilities::DoSelectTimeAndTracks(), anonymous_namespace{TrackMenus.cpp}::DoSortTracks(), TrackUtilities::DoTrackMute(), TrackUtilities::DoTrackSolo(), ButtonHandle::Drag(), TrackPanelResizeHandle::Drag(), LabelTextHandle::Drag(), NoteTrackVZoomHandle::Drag(), SpectrumVZoomHandle::Drag(), WaveformVZoomHandle::Drag(), TimeTrackVZoomHandle::Drag(), BrushHandle::Drag(), SelectHandle::Drag(), TimeShiftHandle::Drag(), TrackSelectHandle::Drag(), anonymous_namespace{DropoutDetector.cpp}::DropoutSubscription::DropoutSubscription(), EditableTracksSelectedPred(), cloud::ShareAudioToolbar::EnableDisableButtons(), ControlToolBar::EnableDisableButtons(), TranscriptionToolBar::EnableDisableButtons(), EstimateRemovedBlocks(), TimerRecordDialog::ExecutePostRecordActions(), Viewport::ExpandAllTracks(), GetInfoCommand::ExploreTrackPanel(), ExportAudioDialog::ExportAudioDialog(), cloud::audiocom::ShareAudioDialog::ExportProject(), anonymous_namespace{ClipMenus.cpp}::FindClipBoundaries(), anonymous_namespace{ClipMenus.cpp}::FindClips(), anonymous_namespace{EditMenus.cpp}::FindSourceTracks(), TrackFocus::FindTrack(), SpectrumView::ForAll(), ProjectFileIO::GenerateDoc(), Get(), GetAllSeqBlocks(), FrequencyPlotDialog::GetAudio(), ContrastDialog::GetDB(), GetPropertiesOfSelected(), CompareAudioCommand::GetSelection(), SliderHandle::GetSlider(), TrackFocus::GetTracks(), Viewport::GetZoomOfToFit(), LabelGlyphHandle::HandleGlyphDragRelease(), AUPImportFileHandle::HandleImport(), AUPImportFileHandle::HandleLabelTrack(), AUPImportFileHandle::HandleNoteTrack(), AUPImportFileHandle::HandleTimeTrack(), AUPImportFileHandle::HandleWaveTrack(), SelectHandle::HitTest(), ProjectFileManager::Import(), AUPImportFileHandle::Import(), anonymous_namespace{ProjectFileManager.cpp}::ImportProject(), EffectEqualization::Init(), NyquistEffect::Init(), ExportFilePanel::Init(), CLExportProcessor::Initialize(), FLACExportProcessor::Initialize(), FFmpegExportProcessor::Initialize(), MP2ExportProcessor::Initialize(), MP3ExportProcessor::Initialize(), OGGExportProcessor::Initialize(), OpusExportProcessor::Initialize(), PCMExportProcessor::Initialize(), WavPackExportProcessor::Initialize(), anonymous_namespace{EditMenus.cpp}::JoinClipsAvailableFlag(), anonymous_namespace{LabelMenus.cpp}::LabelsSelectedFlag(), LabelTracksExistFlag(), LOFImportFileHandle::lofOpenFiles(), MixerBoard::MixerBoard(), anonymous_namespace{SelectMenus.cpp}::MoveWhenAudioInactive(), anonymous_namespace{TrackMenus.cpp}::MuteTracks(), anonymous_namespace{SelectMenus.cpp}::NearestZeroCrossing(), NoteTrack::New(), TimeTrack::New(), WaveTrack::New(), LabelTrack::New(), anonymous_namespace{ExportMIDI.cpp}::NoteTracksExistFlag(), anonymous_namespace{EditMenus.cpp}::NotificationScope(), ApplyMacroDialog::OnApplyToFiles(), ExportFilePanel::OnChannelsConfigure(), ProjectManager::OnCloseWindow(), ProjectAudioManager::OnCommitRecording(), anonymous_namespace{EditMenus.cpp}::OnCopy(), anonymous_namespace{LabelMenus.cpp}::OnCopyLabels(), SelectActions::Handler::OnCursorTrackEnd(), SelectActions::Handler::OnCursorTrackStart(), anonymous_namespace{EditMenus.cpp}::OnCut(), anonymous_namespace{LabelMenus.cpp}::OnCutLabels(), anonymous_namespace{EditMenus.cpp}::OnDelete(), anonymous_namespace{LabelMenus.cpp}::OnDeleteLabels(), anonymous_namespace{EditMenus.cpp}::OnDisjoin(), anonymous_namespace{LabelMenus.cpp}::OnDisjoinLabels(), anonymous_namespace{EditMenus.cpp}::OnDuplicate(), AudacityApp::OnExceptionInMainLoop(), ExportAudioDialog::OnExport(), anonymous_namespace{FileMenus.cpp}::OnExportLabels(), anonymous_namespace{ExportMIDI.cpp}::OnExportMIDI(), NavigationActions::Handler::OnFirstTrack(), ContrastDialog::OnGetBackground(), ContrastDialog::OnGetForeground(), anonymous_namespace{FileMenus.cpp}::OnImportLabels(), anonymous_namespace{EditMenus.cpp}::OnJoin(), anonymous_namespace{LabelMenus.cpp}::OnJoinLabels(), NavigationActions::Handler::OnLastTrack(), WaveTrackMenuTable::OnMergeStereo(), anonymous_namespace{LabelMenus.cpp}::OnNewLabelTrack(), anonymous_namespace{WaveTrackMenuItems.cpp}::OnNewStereoTrack(), anonymous_namespace{TimeTrackMenuItems.cpp}::OnNewTimeTrack(), anonymous_namespace{WaveTrackMenuItems.cpp}::OnNewWaveTrack(), anonymous_namespace{FileMenus.cpp}::OnOpen(), anonymous_namespace{EditMenus.cpp}::OnPaste(), anonymous_namespace{LabelMenus.cpp}::OnPasteNewLabel(), ProjectAudioManager::OnRecord(), anonymous_namespace{EditMenus.cpp}::OnRedo(), anonymous_namespace{TrackMenus.cpp}::OnResample(), SelectActions::Handler::OnSelectAll(), SelectActions::Handler::OnSelectCursorEnd(), SelectActions::Handler::OnSelectStartCursor(), SelectActions::Handler::OnSelectSyncLockSel(), SelectActions::Handler::OnSelectTrackStartToEnd(), anonymous_namespace{EditMenus.cpp}::OnSilence(), anonymous_namespace{LabelMenus.cpp}::OnSilenceLabels(), anonymous_namespace{EditMenus.cpp}::OnSplit(), anonymous_namespace{EditMenus.cpp}::OnSplitCut(), anonymous_namespace{LabelMenus.cpp}::OnSplitCutLabels(), anonymous_namespace{EditMenus.cpp}::OnSplitDelete(), anonymous_namespace{LabelMenus.cpp}::OnSplitDeleteLabels(), anonymous_namespace{LabelMenus.cpp}::OnSplitLabels(), anonymous_namespace{EditMenus.cpp}::OnSplitNew(), anonymous_namespace{TimerRecordDialog.cpp}::OnTimerRecord(), anonymous_namespace{TrackMenus.cpp}::OnTrackMoveBottom(), anonymous_namespace{TrackMenus.cpp}::OnTrackMoveDown(), anonymous_namespace{TrackMenus.cpp}::OnTrackMoveTop(), anonymous_namespace{TrackMenus.cpp}::OnTrackMoveUp(), anonymous_namespace{EditMenus.cpp}::OnTrim(), anonymous_namespace{EditMenus.cpp}::OnUndo(), anonymous_namespace{ChannelView.cpp}::TrackPositioner::OnUpdate(), SelectActions::Handler::OnZeroCrossing(), ProjectFileManager::OpenProjectFile(), TimeTrack::PasteInto(), anonymous_namespace{MixerBoard.cpp}::PlayableTracksExistFlag(), TranscriptionToolBar::PlayAtSpeed(), ProjectAudioManager::PlayPlayRegion(), TrackSelectHandle::Preview(), NyquistEffect::Process(), EffectTwoPassSimpleMono::Process(), SpectralDataManager::ProcessTracks(), TrackPanel::ProcessUIHandleResult(), WaveTrack::ProjectNyquistFrequency(), ProjectFileManager::ReadProjectFile(), RealtimeEffectPanel::RealtimeEffectPanel(), ButtonHandle::Release(), LabelTextHandle::Release(), NoteTrackButtonHandle::Release(), NoteTrackVZoomHandle::Release(), SpectrumVZoomHandle::Release(), WaveformVZoomHandle::Release(), TimeTrackVZoomHandle::Release(), LabelDefaultClickHandle::RestoreState(), anonymous_namespace{Track.cpp}::TrackListRestorer::RestoreUndoRedoState(), ProjectManager::SafeToOpenProjectInto(), ProjectFileIO::SaveCopy(), LabelDefaultClickHandle::SaveState(), Viewport::ScrollToBottom(), Viewport::ScrollToEnd(), anonymous_namespace{SelectMenus.cpp}::SeekWhenAudioInactive(), NoteTrackAffordanceHandle::SelectAt(), SelectUtilities::SelectNone(), GetInfoCommand::SendClips(), GetInfoCommand::SendEnvelopes(), GetInfoCommand::SendLabels(), GetInfoCommand::SendTracks(), TrackFocus::Set(), Viewport::ShowTrack(), WaveTrackMenuTable::SplitStereo(), StereoRequiredFlag(), anonymous_namespace{Track.cpp}::TrackListRestorer::TrackListRestorer(), anonymous_namespace{ChannelView.cpp}::TrackPositioner::TrackPositioner(), TracksExistFlag(), ExportAudioDialog::UpdateLabelExportSettings(), ExportFilePanel::UpdateMaxChannels(), ProjectSettings::UpdatePrefs(), RealtimeEffectPanel::PrefsListenerHelper::UpdatePrefs(), Viewport::UpdateScrollbarsForTracks(), ExportAudioDialog::UpdateTrackExportSettings(), HighlitClipButtonHandle::UpdateTrackSelection(), AffordanceHandle::UpdateTrackSelection(), WaveTracksExistFlag(), WaveTracksSelectedFlag(), ProjectFileIO::WriteXML(), Viewport::ZoomFitHorizontally(), Viewport::ZoomFitHorizontallyAndShowTrack(), Viewport::ZoomFitVertically(), ZoomInAvailableFlag(), and ZoomOutAvailableFlag().

◆ Get() [2/2]

const TrackList & TrackList::Get ( const AudacityProject project)
static

Definition at line 352 of file Track.cpp.

353{
354 return Get( const_cast< AudacityProject & >( project ) );
355}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:347

References Get(), and project.

Here is the call graph for this function:

◆ getBegin()

TrackNodePointer TrackList::getBegin ( ) const
inlineprivate

Definition at line 1376 of file Track.h.

1377 { return { const_cast<TrackList*>(this)->ListOfTracks::begin(),
1378 const_cast<TrackList*>(this)}; }

References PackedArray::begin().

Referenced by ClearPendingTracks(), DoAddToHead(), and Permute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getEnd()

TrackNodePointer TrackList::getEnd ( ) const
inlineprivate

Definition at line 1373 of file Track.h.

1374 { return { const_cast<TrackList*>(this)->ListOfTracks::end(),
1375 const_cast<TrackList*>(this)}; }

References PackedArray::end().

Referenced by DoAdd(), EmptyRange(), NChannels(), and Remove().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetEndTime()

double TrackList::GetEndTime ( ) const

Return the greatest end time of the tracks, or 0 when no tracks.

Definition at line 991 of file Track.cpp.

992{
993 return Accumulate(*this, &Track::GetEndTime,
994 std::numeric_limits<double>::lowest(), std::max);
995}
double GetEndTime() const
Get the maximum of End() values of intervals, or 0 when none.
Definition: Channel.cpp:135
double Accumulate(const TrackList &list, double(Track::*memfn)() const, double ident, const double &(*combine)(const double &, const double &))
Definition: Track.cpp:972

References anonymous_namespace{Track.cpp}::Accumulate(), and ChannelGroup::GetEndTime().

Referenced by SelectTimeCommand::Apply(), LOFImportFileHandle::doDurationAndScrollOffset(), ExportAudioDialog::OnExport(), and AdornedRulerPanel::StartQPPlay().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetNext()

Track * TrackList::GetNext ( Track t,
bool  linked = false 
) const
private

Return a track in the list that comes after Track t.

Definition at line 801 of file Track.cpp.

802{
803 if (t) {
804 auto node = t->GetNode();
805 if ( !isNull( node ) ) {
806 if ( linked && t->HasLinkedTrack() )
807 node = getNext( node );
808
809 if ( !isNull( node ) )
810 node = getNext( node );
811
812 if ( !isNull( node ) )
813 return node.first->get();
814 }
815 }
816
817 return nullptr;
818}
bool HasLinkedTrack() const noexcept
Returns true for leaders of multichannel groups.
Definition: Track.cpp:246
bool isNull(TrackNodePointer p) const
Definition: Track.h:1369
TrackNodePointer getNext(TrackNodePointer p) const
Move an iterator to the next node, if any; else stay at end.
Definition: Track.h:1381

References getNext(), Track::GetNode(), Track::HasLinkedTrack(), and isNull().

Referenced by CanMoveDown(), and MoveDown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getNext()

TrackNodePointer TrackList::getNext ( TrackNodePointer  p) const
inlineprivate

Move an iterator to the next node, if any; else stay at end.

Definition at line 1381 of file Track.h.

1382 {
1383 if ( isNull(p) )
1384 return p;
1385 auto q = p;
1386 ++q.first;
1387 return q;
1388 }

Referenced by Track::GetLinkedTrack(), GetNext(), and Remove().

Here is the caller graph for this function:

◆ GetOwner() [1/2]

AudacityProject * TrackList::GetOwner ( )
inline

Definition at line 1032 of file Track.h.

1032{ return mOwner; }

Referenced by ClearPendingTracks(), EffectOutputTracks::EffectOutputTracks(), EffectBase::FindProject(), EffectStereoToMono::ProcessOne(), and RegisterPendingChangedTrack().

Here is the caller graph for this function:

◆ GetOwner() [2/2]

const AudacityProject * TrackList::GetOwner ( ) const
inline

Definition at line 1033 of file Track.h.

1033{ return mOwner; }

◆ GetPrev()

Track * TrackList::GetPrev ( Track t,
bool  linked = false 
) const
private

Definition at line 820 of file Track.cpp.

821{
822 if (t) {
823 TrackNodePointer prev;
824 auto node = t->GetNode();
825 if ( !isNull( node ) ) {
826 // linked is true and input track second in team?
827 if (linked) {
828 prev = getPrev( node );
829 if( !isNull( prev ) &&
830 !t->HasLinkedTrack() && t->GetLinkedTrack() )
831 // Make it the first
832 node = prev;
833 }
834
835 prev = getPrev( node );
836 if ( !isNull( prev ) ) {
837 // Back up once
838 node = prev;
839
840 // Back up twice sometimes when linked is true
841 if (linked) {
842 prev = getPrev( node );
843 if( !isNull( prev ) &&
844 !(*node.first)->HasLinkedTrack() && (*node.first)->GetLinkedTrack() )
845 node = prev;
846 }
847
848 return node.first->get();
849 }
850 }
851 }
852
853 return nullptr;
854}
Track * GetLinkedTrack() const
Definition: Track.cpp:220

References Track::GetLinkedTrack(), Track::GetNode(), getPrev(), Track::HasLinkedTrack(), and isNull().

Referenced by CanMoveUp(), and MoveUp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getPrev()

TrackNodePointer TrackList::getPrev ( TrackNodePointer  p) const
inlineprivate

Move an iterator to the previous node, if any; else wrap to end.

Definition at line 1391 of file Track.h.

1392 {
1393 if (p == getBegin())
1394 return getEnd();
1395 else {
1396 auto q = p;
1397 --q.first;
1398 return q;
1399 }
1400 }

Referenced by DoAdd(), GetPrev(), NChannels(), and RecalcPositions().

Here is the caller graph for this function:

◆ GetStartTime()

double TrackList::GetStartTime ( ) const

Return the least start time of the tracks, or 0 when no tracks.

Definition at line 985 of file Track.cpp.

986{
987 return Accumulate(*this, &Track::GetStartTime,
988 std::numeric_limits<double>::max(), std::min);
989}
int min(int a, int b)
double GetStartTime() const
Get the minimum of Start() values of intervals, or 0 when none.
Definition: Channel.cpp:124

References anonymous_namespace{Track.cpp}::Accumulate(), ChannelGroup::GetStartTime(), and min().

Referenced by AdornedRulerPanel::StartQPPlay().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HasPendingTracks()

bool TrackList::HasPendingTracks ( ) const

Definition at line 1269 of file Track.cpp.

1270{
1271 if (mPendingUpdates && !mPendingUpdates->empty())
1272 return true;
1273 if (End() != std::find_if(Begin(), End(), [](const Track *t){
1274 return t->GetId() == TrackId{};
1275 }))
1276 return true;
1277 return false;
1278}
TrackId GetId() const
Definition: Track.h:150

References Begin(), End(), Track::GetId(), and mPendingUpdates.

Referenced by anonymous_namespace{Track.cpp}::TrackListRestorer::CanUndoOrRedo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Insert()

void TrackList::Insert ( const Track before,
TrackList &&  trackList 
)

Inserts tracks form trackList starting from position where before is located. If before is nullptr tracks are appended.

Precondition
before == nullptr || (before->IsLeader() && Find(before) != EndIterator<const Track>())

Definition at line 546 of file Track.cpp.

547{
548 assert(before == nullptr || (before->IsLeader() && Find(before) != EndIterator<const Track>()));
549
550 if(before == nullptr)
551 {
552 Append(std::move(trackList));
553 return;
554 }
555
556 std::vector<Track *> arr;
557 arr.reserve(Size() + trackList.Size());
558 for (const auto track : *this) {
559 if (track == before)
560 {
561 for(const auto addedTrack : trackList)
562 arr.push_back(addedTrack);
563 }
564 arr.push_back(track);
565 }
566 Append(std::move(trackList));
567 Permute(arr);
568}
void Permute(const std::vector< Track * > &tracks)
Definition: Track.cpp:570
void Append(TrackList &&list)
Remove all tracks from list and put them at the end of this
Definition: Track.cpp:1449
size_t Size() const
Definition: Track.h:1259

References Append(), Find(), Track::IsLeader(), Permute(), and Size().

Here is the call graph for this function:

◆ isNull()

bool TrackList::isNull ( TrackNodePointer  p) const
inlineprivate

Definition at line 1369 of file Track.h.

1370 { return (p.second == this && p.first == ListOfTracks::end())
1371 || (mPendingUpdates && p.second == &*mPendingUpdates &&
1372 p.first == mPendingUpdates->ListOfTracks::end()); }

References PackedArray::end().

Referenced by GetNext(), GetPrev(), RecalcPositions(), Remove(), and SwapNodes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Lock()

template<typename Subclass >
std::shared_ptr< Subclass > TrackList::Lock ( const std::weak_ptr< Subclass > &  wTrack)
inline

Definition at line 1246 of file Track.h.

1247 {
1248 auto pTrack = wTrack.lock();
1249 if (pTrack) {
1250 auto pList = pTrack->mList.lock();
1251 if (pTrack && this == pList.get())
1252 return pTrack;
1253 }
1254 return {};
1255 }

Referenced by SelectHandle::AdjustSelection(), ButtonHandle::Click(), BrushHandle::Click(), ButtonHandle::Drag(), LabelTextHandle::Drag(), NoteTrackVZoomHandle::Drag(), SpectrumVZoomHandle::Drag(), WaveformVZoomHandle::Drag(), TimeTrackVZoomHandle::Drag(), BrushHandle::Drag(), SelectHandle::Drag(), SliderHandle::GetSlider(), TrackPanel::ProcessUIHandleResult(), ButtonHandle::Release(), LabelTextHandle::Release(), NoteTrackButtonHandle::Release(), NoteTrackVZoomHandle::Release(), SpectrumVZoomHandle::Release(), WaveformVZoomHandle::Release(), TimeTrackVZoomHandle::Release(), LabelDefaultClickHandle::RestoreState(), and NoteTrackAffordanceHandle::SelectAt().

Here is the caller graph for this function:

◆ MakeMultiChannelTrack()

bool TrackList::MakeMultiChannelTrack ( Track first,
int  nChannels 
)

Converts channels to a multichannel track.

Parameters
firstand the following must be in this list. Tracks should not be a part of another group (not linked)
nChannelsnumber of channels, for now only 2 channels supported
Returns
true on success, false if some prerequisites do not met

Definition at line 705 of file Track.cpp.

706{
707 if (nChannels != 2)
708 return false;
709
710 auto list = track.mList.lock();
711 if (list.get() == this) {
712 if (*list->Find(&track) != &track)
713 return false;
714
715 auto first = list->DoFind(&track);
716 auto canLink = [&]() -> bool {
717 int count = nChannels;
718 for (auto it = first, end = TrackList::End(); it != end && count; ++it)
719 {
720 if ((*it)->HasLinkedTrack())
721 return false;
722 --count;
723 }
724 return count == 0;
725 }();
726
727 if (!canLink)
728 return false;
729
730 (*first)->SetLinkType(Track::LinkType::Aligned);
731
732 //Cleanup the group data in all channels except the first
733 for(auto it = std::next(first), last = std::next(first, nChannels);
734 it != last;
735 ++it)
736 {
737 (*it)->DestroyGroupData();
738 }
739 }
740 else
742 return true;
743}
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
@ Aligned
Tracks are grouped and changes should be synchronized.
Subclass * DoFind(Locked< DataContainer > &data, const RegisteredFactory &key)
Definition: ClientData.h:502

References ChannelGroup::Aligned, end(), End(), Track::mList, and THROW_INCONSISTENCY_EXCEPTION.

Here is the call graph for this function:

◆ MakeTrackIterator()

template<typename TrackType >
TrackIter< TrackType > TrackList::MakeTrackIterator ( TrackNodePointer  iter) const
inlineprivate

Definition at line 1352 of file Track.h.

1353 {
1354 auto b = const_cast<TrackList*>(this)->getBegin();
1355 auto e = const_cast<TrackList*>(this)->getEnd();
1356 return { b, iter, e };
1357 }

◆ MakeUniqueTrackName()

wxString TrackList::MakeUniqueTrackName ( const wxString &  baseTrackName) const

Returns string that contains baseTrackName, but is guaranteed to be unique among other tracks in that list.

Parameters
baseTrackNameString to be put into the template
Returns
Formatted string: "[baseTrackName] [N]"

Definition at line 411 of file Track.cpp.

412{
413 int n = 1;
414 while(true) {
415 auto name = wxString::Format("%s %d", baseTrackName, n++);
416
417 bool found {false};
418 for(const auto track : Tracks<const Track>()) {
419 if(track->GetName() == name) {
420 found = true;
421 break;
422 }
423 }
424 if(!found)
425 return name;
426 }
427}
const TranslatableString name
Definition: Distortion.cpp:76

References name.

Referenced by LabelTrack::Create().

Here is the caller graph for this function:

◆ Move()

bool TrackList::Move ( Track t,
bool  up 
)
inline

Definition at line 1241 of file Track.h.

1241{ return up ? MoveUp(t) : MoveDown(t); }
bool MoveUp(Track *t)
Definition: Track.cpp:929
bool MoveDown(Track *t)
Definition: Track.cpp:942

◆ MoveDown()

bool TrackList::MoveDown ( Track t)

Definition at line 942 of file Track.cpp.

943{
944 if (t) {
945 Track *n = GetNext(t, true);
946 if (n) {
947 SwapNodes(t->GetNode(), n->GetNode());
948 return true;
949 }
950 }
951
952 return false;
953}
void SwapNodes(TrackNodePointer s1, TrackNodePointer s2)
Definition: Track.cpp:870

References GetNext(), Track::GetNode(), and SwapNodes().

Here is the call graph for this function:

◆ MoveUp()

bool TrackList::MoveUp ( Track t)

Definition at line 929 of file Track.cpp.

930{
931 if (t) {
932 Track *p = GetPrev(t, true);
933 if (p) {
934 SwapNodes(p->GetNode(), t->GetNode());
935 return true;
936 }
937 }
938
939 return false;
940}

References Track::GetNode(), GetPrev(), and SwapNodes().

Here is the call graph for this function:

◆ NChannels() [1/2]

size_t TrackList::NChannels ( ) const

Definition at line 960 of file Track.cpp.

961{
962 int cnt = 0;
963
964 if (!empty())
965 cnt = getPrev( getEnd() ).first->get()->GetIndex() + 1;
966
967 return cnt;
968}

References empty(), getEnd(), and getPrev().

Referenced by AppendItem(), AppendOne(), anonymous_namespace{EditMenus.cpp}::FitsInto(), WaveTrack::GetChannelType(), CompareAudioCommand::GetSelection(), ExportFilePanel::Init(), MixAndRender(), WaveTrack::NChannels(), EffectNormalize::Process(), Remove(), GetInfoCommand::SendTracks(), anonymous_namespace{WaveTrackControls.cpp}::Status1DrawFunction(), and SwapNodes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ NChannels() [2/2]

static size_t TrackList::NChannels ( const Track track)
inlinestatic

Count channels of a track.

Definition at line 1171 of file Track.h.

1172 {
1173 return Channels(&track).size();
1174 }

References ChannelGroup::Channels().

Here is the call graph for this function:

◆ operator=() [1/2]

TrackList & TrackList::operator= ( const TrackList )
privatedelete

◆ operator=() [2/2]

TrackList & TrackList::operator= ( TrackList &&  )
privatedelete

◆ PermutationEvent()

void TrackList::PermutationEvent ( TrackNodePointer  node)
private

Definition at line 480 of file Track.cpp.

481{
482 QueueEvent({ TrackListEvent::PERMUTED, *node.first });
483}
@ PERMUTED
Posted when tracks are reordered but otherwise unchanged.
Definition: Track.h:956

References TrackListEvent::PERMUTED, and QueueEvent().

Referenced by Permute(), and SwapNodes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Permute()

void TrackList::Permute ( const std::vector< Track * > &  tracks)
Precondition
tracks contains pointers only to leader tracks of this, and each of them exactly once

Definition at line 570 of file Track.cpp.

571{
572 std::vector<TrackNodePointer> permutation;
573 for (const auto pTrack : tracks)
574 for (const auto pChannel : Channels(pTrack))
575 permutation.push_back(pChannel->GetNode());
576 for (const auto iter : permutation) {
577 ListOfTracks::value_type track = *iter.first;
578 erase(iter.first);
579 Track *pTrack = track.get();
580 pTrack->SetOwner(shared_from_this(),
581 { insert(ListOfTracks::end(), track), this });
582 }
583 auto n = getBegin();
586}
const auto tracks
void PermutationEvent(TrackNodePointer node)
Definition: Track.cpp:480

References Channels(), PackedArray::end(), getBegin(), PermutationEvent(), RecalcPositions(), Track::SetOwner(), and tracks.

Referenced by Insert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ QueueEvent()

void TrackList::QueueEvent ( TrackListEvent  event)
private

Definition at line 452 of file Track.cpp.

453{
454 BasicUI::CallAfter( [wThis = weak_from_this(), event = std::move(event)]{
455 if (auto pThis = wThis.lock())
456 pThis->Publish(event);
457 } );
458}
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
Definition: BasicUI.cpp:208

References BasicUI::CallAfter().

Referenced by AdditionEvent(), DataEvent(), DeletionEvent(), PermutationEvent(), ResizingEvent(), and SelectionEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rbegin() [1/2]

reverse_iterator TrackList::rbegin ( )
inline

Definition at line 1060 of file Track.h.

1060{ return Any().rbegin(); }

Referenced by ChannelView::GetTotalHeight().

Here is the caller graph for this function:

◆ rbegin() [2/2]

const_reverse_iterator TrackList::rbegin ( ) const
inline

Definition at line 1062 of file Track.h.

1062{ return Any().rbegin(); }

◆ RecalcPositions()

void TrackList::RecalcPositions ( TrackNodePointer  node)
private

Definition at line 429 of file Track.cpp.

430{
431 if (isNull(node))
432 return;
433
434 Track *t;
435 int i = 0;
436
437 auto prev = getPrev(node);
438 if (!isNull(prev)) {
439 t = prev.first->get();
440 i = t->GetIndex() + 1;
441 }
442
443 const auto theEnd = End();
444 for (auto n = DoFind(node.first->get()); n != theEnd; ++n) {
445 t = *n;
446 t->SetIndex(i++);
447 }
448
450}
void SetIndex(int index)
Definition: Track.cpp:135
int GetIndex() const
Definition: Track.cpp:130

References DoFind(), End(), Track::GetIndex(), getPrev(), isNull(), Track::SetIndex(), and UpdatePendingTracks().

Referenced by ApplyPendingTracks(), ClearPendingTracks(), DoAdd(), DoAddToHead(), Permute(), Remove(), ReplaceOne(), and SwapNodes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RegisterPendingChangedTrack()

Track * TrackList::RegisterPendingChangedTrack ( Updater  updater,
Track src 
)
Precondition
GetOwner()
src->IsLeader()
Postcondition
result: src->NChannels() == result.size()

Definition at line 998 of file Track.cpp.

999{
1000 // This is only done on the TrackList belonging to a project
1001 assert(GetOwner()); // which implies mPendingUpdates is not null
1002 assert(src->IsLeader());
1003
1004 auto tracks = src->Clone(false); // not duplicate
1005 assert(src->NChannels() == tracks->NChannels());
1006 {
1007 // Share the satellites with the original, though they do not point back
1008 // to the pending track
1009 const auto channels = TrackList::Channels(src);
1010 auto iter = TrackList::Channels(*tracks->begin()).begin();
1011 for (const auto pChannel : channels)
1012 ((AttachedTrackObjects&)**iter++) = *pChannel; // shallow copy
1013 }
1014
1015 const auto result = *tracks->begin();
1016 mUpdaters.push_back(updater);
1017 auto iter = tracks->ListOfTracks::begin(),
1018 end = tracks->ListOfTracks::end();
1019 while (iter != end) {
1020 auto pTrack = *iter;
1021 iter = tracks->erase(iter);
1022 mPendingUpdates->ListOfTracks::push_back(pTrack->SharedPointer());
1023 auto n = mPendingUpdates->ListOfTracks::end();
1024 --n;
1025 pTrack->SetOwner(shared_from_this(), {n, &*mPendingUpdates});
1026 }
1027 return result;
1028}
static CustomUpdaterValue updater
virtual size_t NChannels() const =0
Report the number of channels.
Utility to register hooks into a host class that attach client data.
Definition: ClientData.h:228
virtual TrackListHolder Clone(bool backup) const =0

References Channels(), Track::Clone(), end(), GetOwner(), Track::IsLeader(), mPendingUpdates, mUpdaters, ChannelGroup::NChannels(), tracks, and updater.

Here is the call graph for this function:

◆ RegisterPendingNewTracks()

void TrackList::RegisterPendingNewTracks ( TrackList &&  list)

Definition at line 1460 of file Track.cpp.

1461{
1462 for(auto it = list.ListOfTracks::begin(); it != list.ListOfTracks::end();)
1463 {
1464 Add(*it);
1465 (*it)->SetId({});
1466 it = list.erase(it);
1467 }
1468}

References Add().

Here is the call graph for this function:

◆ Remove()

void TrackList::Remove ( Track track)

Remove a channel group, given the leader.

Precondition
track.IsLeader()

Definition at line 745 of file Track.cpp.

746{
747 assert(track.IsLeader());
748 auto *t = &track;
749 const size_t nChannels = NChannels(*t);
750 Track *nextT{};
751 for (size_t ii = 0; t != nullptr && ii < nChannels; ++ii, t = nextT) {
752 nextT = nullptr;
753 auto iter = getEnd();
754 auto node = t->GetNode();
755 t->SetOwner({}, {});
756
757 if (!isNull(node)) {
758 ListOfTracks::value_type holder = *node.first;
759
760 iter = getNext(node);
761 erase(node.first);
762 if (!isNull(iter)) {
763 RecalcPositions(iter);
764 nextT = iter.first->get();
765 }
766
767 DeletionEvent(t->shared_from_this(), false);
768 }
769 }
770}

References DeletionEvent(), getEnd(), getNext(), Track::IsLeader(), isNull(), NChannels(), and RecalcPositions().

Referenced by EffectOutputTracks::Commit(), and EffectStereoToMono::ProcessOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rend() [1/2]

reverse_iterator TrackList::rend ( )
inline

Definition at line 1061 of file Track.h.

1061{ return Any().rend(); }

◆ rend() [2/2]

const_reverse_iterator TrackList::rend ( ) const
inline

Definition at line 1063 of file Track.h.

1063{ return Any().rend(); }

◆ ReplaceOne()

TrackListHolder TrackList::ReplaceOne ( Track t,
TrackList &&  with 
)

Replace channel group t with the first group in the given list, return a temporary list of the removed tracks, modify given list by removing group

Replacements may have fewer channels Give the replacements the same ids as the replaced

Precondition
t.IsLeader()
t.GetOwner().get() == this
t.NChannels() >= (*with.begin())->NChannels()

Move one channel to the temporary list

Be sure it preserves leader-ness

Redirect the list element of this

Definition at line 637 of file Track.cpp.

638{
639 assert(t.IsLeader());
640 assert(t.GetOwner().get() == this);
641 auto nChannels = t.NChannels();
642
643 // TODO wide wave tracks: This won't matter, tracks will be 1 to 1
644 assert(nChannels >= (*with.begin())->NChannels());
645
646 TrackListHolder result = Temporary(nullptr);
647
648 auto iter = with.ListOfTracks::begin(),
649 end = with.ListOfTracks::end();
650 bool isLeader = true;
651 std::vector<Track*> saveChannels;
652 for (const auto pChannel : TrackList::Channels(&t))
653 saveChannels.push_back(pChannel);
654
655 // Because default constructor doesn't work
656 std::optional<TrackNodePointer> lastNode;
657
658 for (const auto pChannel : saveChannels) {
659 auto spChannel = pChannel->shared_from_this();
660
662 auto node = pChannel->GetNode();
663 pChannel->SetOwner({}, {});
664 result->Add(spChannel);
665
667 assert(isLeader == pChannel->IsLeader());
668 isLeader = false;
669
670 if (iter == end) {
671 node.second->erase(node.first);
672 RecalcPositions(*lastNode);
673 DeletionEvent(spChannel, true);
674 }
675 else {
676 lastNode.emplace(node);
678 const auto pTrack = *iter;
679 *node.first = pTrack;
680 iter = with.erase(iter);
681 pTrack->SetOwner(shared_from_this(), node);
682 pTrack->SetId(pChannel->GetId());
683 RecalcPositions(node);
684 DeletionEvent(spChannel, true);
685 AdditionEvent(node);
686 }
687 }
688 return result;
689}
std::shared_ptr< TrackList > TrackListHolder
Definition: Track.h:42
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:254

References AdditionEvent(), Channels(), DeletionEvent(), end(), Track::GetOwner(), Track::IsLeader(), ChannelGroup::NChannels(), RecalcPositions(), and Temporary().

Referenced by ApplyPendingTracks(), and EffectOutputTracks::Commit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ResizingEvent()

void TrackList::ResizingEvent ( TrackNodePointer  node)
private

Definition at line 496 of file Track.cpp.

497{
498 QueueEvent({ TrackListEvent::RESIZING, *node.first });
499}
@ RESIZING
Posted when some track changed its height.
Definition: Track.h:959

References QueueEvent(), and TrackListEvent::RESIZING.

Here is the call graph for this function:

◆ Selected() [1/2]

template<typename TrackType = Track>
auto TrackList::Selected ( ) -> TrackIterRange<TrackType>
inline

◆ Selected() [2/2]

template<typename TrackType = const Track>
auto TrackList::Selected ( ) const -> std::enable_if_t<std::is_const_v<TrackType>, TrackIterRange<TrackType>>
inline

Definition at line 1120 of file Track.h.

1122 {
1123 return Tracks<TrackType>(&Track::IsSelectedLeader);
1124 }

References Track::IsSelectedLeader().

Here is the call graph for this function:

◆ SelectionEvent()

void TrackList::SelectionEvent ( Track track)
private

Definition at line 460 of file Track.cpp.

461{
462 for (auto channel : Channels(&track))
463 QueueEvent({
464 TrackListEvent::SELECTION_CHANGE, channel->shared_from_this() });
465}
@ SELECTION_CHANGE
Posted when the set of selected tracks changes.
Definition: Track.h:949

References Channels(), QueueEvent(), and TrackListEvent::SELECTION_CHANGE.

Here is the call graph for this function:

◆ SingletonRange()

template<typename TrackType >
static auto TrackList::SingletonRange ( TrackType *  pTrack) -> TrackIterRange< TrackType >
inlinestatic

Definition at line 1128 of file Track.h.

1130 {
1131 return pTrack->GetOwner()->template Tracks<TrackType>()
1132 .StartingWith( pTrack ).EndingAfter( pTrack );
1133 }

References TrackIterRange< TrackType >::EndingAfter(), and TrackIterRange< TrackType >::StartingWith().

Referenced by EffectTruncSilence::ProcessIndependently(), and SelectionState::SelectTrackLength().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Size()

size_t TrackList::Size ( ) const
inline

Definition at line 1259 of file Track.h.

1259{ return Any().size(); }

References Track::Any().

Referenced by Insert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Swap()

void TrackList::Swap ( TrackList that)
Precondition
!GetOwner() && !that.GetOwner()

Definition at line 381 of file Track.cpp.

382{
383 auto SwapLOTs = [](
384 ListOfTracks &a, const std::weak_ptr< TrackList > &aSelf,
385 ListOfTracks &b, const std::weak_ptr< TrackList > &bSelf )
386 {
387 a.swap(b);
388 for (auto it = a.begin(), last = a.end(); it != last; ++it)
389 (*it)->SetOwner(aSelf, {it, &a});
390 for (auto it = b.begin(), last = b.end(); it != last; ++it)
391 (*it)->SetOwner(bSelf, {it, &b});
392 };
393
394 const auto self = shared_from_this();
395 const auto otherSelf = that.shared_from_this();
396 SwapLOTs( *this, self, that, otherSelf );
397
398 assert(!GetOwner() && !that.GetOwner()); // precondition
399 // which implies (see constructor)
400 assert(!this->mPendingUpdates);
401 assert(!that.mPendingUpdates);
402
403 mUpdaters.swap(that.mUpdaters);
404}

◆ SwapChannels()

Track * TrackList::SwapChannels ( Track track)
static

If the given track is one of a pair of channels, swap them

Returns
New left track on success

Definition at line 527 of file Track.cpp.

528{
529 if (!track.HasLinkedTrack())
530 return nullptr;
531 auto pOwner = track.GetOwner();
532 if (!pOwner)
533 return nullptr;
534 auto pPartner = pOwner->GetNext(&track, false);
535 if (!pPartner)
536 return nullptr;
537
538 // Swap channels, avoiding copying of GroupData
539 auto pData = track.DetachGroupData();
540 assert(pData);
541 pOwner->MoveUp(pPartner);
542 pPartner->AssignGroupData(move(pData));
543 return pPartner;
544}
std::unique_ptr< ChannelGroupData > DetachGroupData()
Move attachments out.
Definition: Channel.cpp:101

References ChannelGroup::DetachGroupData(), Track::GetOwner(), and Track::HasLinkedTrack().

Referenced by WaveTrackMenuTable::OnSwapChannels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SwapNodes()

void TrackList::SwapNodes ( TrackNodePointer  s1,
TrackNodePointer  s2 
)
private

Definition at line 870 of file Track.cpp.

871{
872 // if a null pointer is passed in, we want to know about it
873 wxASSERT(!isNull(s1));
874 wxASSERT(!isNull(s2));
875
876 // Deal with first track in each team
877 s1 = ( * Find( s1.first->get() ) )->GetNode();
878 s2 = ( * Find( s2.first->get() ) )->GetNode();
879
880 // Safety check...
881 if (s1 == s2)
882 return;
883
884 // Be sure s1 is the earlier iterator
885 if ((*s1.first)->GetIndex() >= (*s2.first)->GetIndex())
886 std::swap(s1, s2);
887
888 // For saving the removed tracks
889 using Saved = std::vector< ListOfTracks::value_type >;
890 Saved saved1, saved2;
891
892 auto doSave = [&] ( Saved &saved, TrackNodePointer &s ) {
893 size_t nn = NChannels(**s.first);
894 saved.resize( nn );
895 // Save them in backwards order
896 while( nn-- )
897 saved[nn] = *s.first, s.first = erase(s.first);
898 };
899
900 doSave( saved1, s1 );
901 // The two ranges are assumed to be disjoint but might abut
902 const bool same = (s1 == s2);
903 doSave( saved2, s2 );
904 if (same)
905 // Careful, we invalidated s1 in the second doSave!
906 s1 = s2;
907
908 // Reinsert them
909 auto doInsert = [&] ( Saved &saved, TrackNodePointer &s ) {
910 Track *pTrack;
911 for (auto & pointer : saved)
912 pTrack = pointer.get(),
913 // Insert before s, and reassign s to point at the new node before
914 // old s; which is why we saved pointers in backwards order
915 pTrack->SetOwner(shared_from_this(),
916 s = { insert(s.first, pointer), this } );
917 };
918 // This does not invalidate s2 even when it equals s1:
919 doInsert( saved2, s1 );
920 // Even if s2 was same as s1, this correctly inserts the saved1 range
921 // after the saved2 range, when done after:
922 doInsert( saved1, s2 );
923
924 // Now correct the Index in the tracks, and other things
925 RecalcPositions(s1);
927}
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:645

References Find(), isNull(), NChannels(), PermutationEvent(), RecalcPositions(), Track::SetOwner(), and anonymous_namespace{NoteTrack.cpp}::swap().

Referenced by MoveDown(), and MoveUp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Temporary() [1/3]

template<typename T >
static TrackListHolder TrackList::Temporary ( AudacityProject pProject,
const std::vector< std::shared_ptr< T > > &  channels 
)
inlinestatic

Construct a temporary list whose first channel group contains the given channels, up to the limit of channel group size; excess channels go each into a separate group Overload allowing shared pointers to some subclass of Track

Definition at line 1287 of file Track.h.

1290 {
1291 std::vector<Track::Holder> temp;
1292 static const auto convert = [](auto &pChannel){
1293 return std::static_pointer_cast<Track>(pChannel);
1294 };
1295 transform(channels.begin(), channels.end(), back_inserter(temp), convert);
1296 return Temporary(pProject, temp);
1297 }

◆ Temporary() [2/3]

TrackListHolder TrackList::Temporary ( AudacityProject pProject,
const std::vector< Track::Holder > &  channels 
)
static

Construct a temporary list whose first channel group contains the given channels, up to the limit of channel group size; excess channels go each into a separate group

Definition at line 1436 of file Track.cpp.

1438{
1439 size_t iChannel = 0;
1440 auto nChannels = channels.size();
1441 auto left = (nChannels == 2 ? channels[iChannel++] : nullptr);
1442 auto right = (nChannels == 2 ? channels[iChannel++] : nullptr);
1443 auto tempList = Temporary(pProject, left, right);
1444 for (; iChannel < nChannels; ++iChannel)
1445 tempList->Add(channels[iChannel]);
1446 return tempList;
1447}

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, and Temporary().

Here is the call graph for this function:

◆ Temporary() [3/3]

TrackListHolder TrackList::Temporary ( AudacityProject pProject,
const Track::Holder left = {},
const Track::Holder right = {} 
)
static

Construct a temporary list owned by pProject (if that is not null) so that TrackList::Channels(left.get()) will enumerate the given tracks

Precondition
left == nullptr || left->GetOwner() == nullptr
right == nullptr || (left && right->GetOwner() == nullptr)

Definition at line 1418 of file Track.cpp.

1420{
1421 assert(left == nullptr || left->GetOwner() == nullptr);
1422 assert(right == nullptr || (left && right->GetOwner() == nullptr));
1423 // Make a well formed channel group from these tracks
1424 auto tempList = Create(pProject);
1425 if (left) {
1426 tempList->Add(left);
1427 if (right) {
1428 tempList->Add(right);
1429 tempList->MakeMultiChannelTrack(*left, 2);
1430 }
1431 }
1432 tempList->mAssignsIds = false;
1433 return tempList;
1434}
static TrackListHolder Create(AudacityProject *pOwner)
Definition: Track.cpp:365

References Create().

Referenced by ApplyPendingTracks(), Clear(), NoteTrack::Clone(), TimeTrack::Clone(), WaveTrack::Clone(), LabelTrack::Clone(), TimeTrack::Copy(), NoteTrack::Copy(), LabelTrack::Copy(), WaveTrackFactory::Create(), NoteTrack::Cut(), anonymous_namespace{ImportMIDI.cpp}::MIDIImportFileHandle::Import(), BenchmarkDialog::OnRun(), EffectStereoToMono::ProcessOne(), PerTrackEffect::ProcessPass(), ReplaceOne(), WaveTrack::SyncLockAdjust(), Temporary(), TrackList(), and WaveTrack::WideEmptyCopy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Tracks() [1/2]

template<typename TrackType = Track, typename Pred = typename TrackIterRange< TrackType >::iterator::FunctionType>
auto TrackList::Tracks ( const Pred &  pred = {}) -> TrackIterRange< TrackType >
inlineprivate

Definition at line 1324 of file Track.h.

1324 {} )
1326 {
1327 auto b = getBegin(), e = getEnd();
1328 return { { b, b, e, pred }, { b, e, e, pred } };
1329 }
Range between two TrackIters, usable in range-for statements, and with Visit member functions.
Definition: Track.h:825

◆ Tracks() [2/2]

template<typename TrackType = const Track, typename Pred = typename TrackIterRange< TrackType >::iterator::FunctionType>
auto TrackList::Tracks ( const Pred &  pred = {}) const -> std::enable_if_t< std::is_const_v<TrackType>, TrackIterRange< TrackType > >
inlineprivate

Definition at line 1337 of file Track.h.

1337 {} ) const
1338 -> std::enable_if_t< std::is_const_v<TrackType>,
1340 >
1341 {
1342 auto b = const_cast<TrackList*>(this)->getBegin();
1343 auto e = const_cast<TrackList*>(this)->getEnd();
1344 return { { b, b, e, pred }, { b, e, e, pred } };
1345 }

◆ UnlinkChannels()

std::vector< Track * > TrackList::UnlinkChannels ( Track track)

Removes linkage if track belongs to a group.

Definition at line 691 of file Track.cpp.

692{
693 auto list = track.mList.lock();
694 if (list.get() == this)
695 {
696 auto channels = TrackList::Channels(&track);
697 for (auto c : channels)
698 c->SetLinkType(Track::LinkType::None);
699 return { channels.begin(), channels.end() };
700 }
701 else
703}
std::weak_ptr< TrackList > mList
Definition: Track.h:139

References Channels(), Track::mList, ChannelGroup::None, and THROW_INCONSISTENCY_EXCEPTION.

Referenced by EffectStereoToMono::ProcessOne(), and WaveTrackMenuTable::SplitStereo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdatePendingTracks()

void TrackList::UpdatePendingTracks ( )

Definition at line 1030 of file Track.cpp.

1031{
1032 if (!mPendingUpdates)
1033 return;
1034 auto pUpdater = mUpdaters.begin();
1035 for (const auto &pendingTrack : *mPendingUpdates) {
1036 auto src = FindById(pendingTrack->GetId());
1037 // Copy just a part of the track state, according to the update
1038 // function
1039 const auto &updater = *pUpdater;
1040 if (pendingTrack && src) {
1041 if (updater)
1042 updater(*pendingTrack, *src);
1043 }
1044 ++pUpdater;
1045 pendingTrack->DoSetLinkType(src->GetLinkType());
1046 }
1047}
std::optional< LogWindowUpdater > pUpdater
Definition: LogWindow.cpp:53

References FindById(), mPendingUpdates, mUpdaters, anonymous_namespace{LogWindow.cpp}::pUpdater, and updater.

Referenced by ApplyPendingTracks(), TrackPanel::ProcessUIHandleResult(), and RecalcPositions().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ Track

friend class Track
friend

Definition at line 1180 of file Track.h.

Member Data Documentation

◆ mAssignsIds

bool TrackList::mAssignsIds { true }
private

Whether the list assigns unique ids to added tracks; false for temporaries

Definition at line 1477 of file Track.h.

Referenced by DoAdd().

◆ mOwner

AudacityProject* TrackList::mOwner
private

Definition at line 1467 of file Track.h.

Referenced by TrackList().

◆ mPendingUpdates

std::shared_ptr<TrackList> TrackList::mPendingUpdates
private

Shadow tracks holding append-recording in progress; need to put them into a list so that channel grouping works

Beware, they are in a disjoint iteration sequence from ordinary tracks

Definition at line 1472 of file Track.h.

Referenced by ApplyPendingTracks(), Clear(), ClearPendingTracks(), HasPendingTracks(), RegisterPendingChangedTrack(), TrackList(), and UpdatePendingTracks().

◆ mUpdaters

std::vector< Updater > TrackList::mUpdaters
private

This is in correspondence with leader tracks in mPendingUpdates.

Definition at line 1474 of file Track.h.

Referenced by Clear(), ClearPendingTracks(), RegisterPendingChangedTrack(), and UpdatePendingTracks().

◆ sCounter

long TrackList::sCounter = -1
staticprivate

Definition at line 1417 of file Track.h.

Referenced by ApplyPendingTracks(), DoAdd(), and DoAddToHead().


The documentation for this class was generated from the following files: