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 EnsureVisibleEvent (const std::shared_ptr< Track > &pTrack, bool modifyState)
 
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 982 of file Track.h.

Member Typedef Documentation

◆ const_iterator

Definition at line 1041 of file Track.h.

◆ const_reverse_iterator

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

Definition at line 1053 of file Track.h.

◆ iterator

Definition at line 1040 of file Track.h.

◆ reverse_iterator

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

Definition at line 1052 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 1418 of file Track.h.

◆ value_type

Definition at line 1043 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 364 of file Track.cpp.

365 : mOwner{ pOwner }
366{
367 if (mOwner)
368 mPendingUpdates = Temporary(nullptr);
369}
AudacityProject * mOwner
Definition: Track.h:1463
std::shared_ptr< TrackList > mPendingUpdates
Definition: Track.h:1468
static TrackListHolder Temporary(AudacityProject *pProject, const Track::Holder &left={}, const Track::Holder &right={})
Definition: Track.cpp:1435

References mOwner, mPendingUpdates, and Temporary().

Here is the call graph for this function:

◆ ~TrackList()

TrackList::~TrackList ( )
virtual

Definition at line 413 of file Track.cpp.

414{
415 Clear(false);
416}
void Clear(bool sendEvent=true)
Make the list empty.
Definition: Track.cpp:789

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 1195 of file Track.h.

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

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

Here is the caller graph for this function:

◆ AdditionEvent()

void TrackList::AdditionEvent ( TrackNodePointer  node)
private

Definition at line 508 of file Track.cpp.

509{
510 QueueEvent({ TrackListEvent::ADDITION, *node.first });
511}
void QueueEvent(TrackListEvent event)
Definition: Track.cpp:459
@ ADDITION
Posted when a track has been added to a tracklist. Also posted when one track replaces another.
Definition: Track.h:956

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 1191 of file Track.h.

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

◆ Any() [1/2]

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

Definition at line 1091 of file Track.h.

1093 {
1094 return Tracks< TrackType >( &Track::IsLeader );
1095 }
bool IsLeader() const override
Definition: Track.cpp:298

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(), LyricsPanel::DoUpdateLyrics(), 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(), VampEffect::Init(), MakeTransportTracks(), anonymous_namespace{ExportMIDI.cpp}::NoteTracksExistFlag(), ExportFilePanel::OnChannelsConfigure(), ExportAudioDialog::OnExport(), ScreenshotBigDialog::OnShortTracks(), 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 1098 of file Track.h.

1102 {
1103 return Tracks< TrackType >( &Track::IsLeader );
1104 }

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 1465 of file Track.cpp.

1466{
1467 auto iter = list.ListOfTracks::begin(),
1468 end = list.ListOfTracks::end();
1469 while (iter != end) {
1470 auto pTrack = *iter;
1471 iter = list.erase(iter);
1472 this->Add(pTrack);
1473 }
1474}
iterator end()
Definition: Track.h:1045
TrackKind * Add(const std::shared_ptr< TrackKind > &t)
Definition: Track.h:1195

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 1486 of file Track.cpp.

1487{
1488 auto iter = list.ListOfTracks::begin(),
1489 end = list.ListOfTracks::end();
1490 if (iter != end) {
1491 for (size_t nn = TrackList::NChannels(**iter); nn--;) {
1492 auto pTrack = *iter;
1493 iter = list.erase(iter);
1494 this->Add(pTrack);
1495 }
1496 }
1497}
size_t NChannels() const
Definition: Track.cpp:977

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 1109 of file Track.cpp.

1110{
1111 bool result = false;
1112
1113 ListOfTracks additions;
1114 auto updates = Temporary(nullptr);
1115 {
1116 // Always clear, even if one of the update functions throws
1117 auto cleanup = finally( [&] { ClearPendingTracks( &additions ); } );
1119 updates.swap(mPendingUpdates);
1120 }
1121
1122 // Remaining steps must be No-fail-guarantee so that this function
1123 // gives Strong-guarantee
1124
1125 std::vector< std::shared_ptr<Track> > reinstated;
1126
1127 if (updates)
1128 for (auto pendingTrack : static_cast<ListOfTracks &>(*updates))
1129 pendingTrack->AttachedTrackObjects::ForEach([&](auto &attachment){
1130 attachment.Reparent( pendingTrack );
1131 });
1132 while (updates && !updates->empty()) {
1133 auto iter = updates->ListOfTracks::begin();
1134 auto pendingTrack = *iter;
1135 auto src = FindById(pendingTrack->GetId());
1136 if (src) {
1137 this->ReplaceOne(*src, std::move(*updates));
1138 result = true;
1139 }
1140 else {
1141 // Perhaps a track marked for pending changes got deleted by
1142 // some other action. Recreate it so we don't lose the
1143 // accumulated changes.
1144 reinstated.push_back(pendingTrack);
1145 updates->ListOfTracks::erase(iter);
1146 }
1147 }
1148
1149 // If there are tracks to reinstate, append them to the list.
1150 for (auto &pendingTrack : reinstated)
1151 if (pendingTrack)
1152 this->Add( pendingTrack ), result = true;
1153
1154 // Put the pending added tracks back into the list, preserving their
1155 // positions.
1156 bool inserted = false;
1157 ListOfTracks::iterator first;
1158 for (auto &pendingTrack : additions) {
1159 if (pendingTrack) {
1160 auto iter = ListOfTracks::begin();
1161 std::advance( iter, pendingTrack->GetIndex() );
1162 iter = ListOfTracks::insert( iter, pendingTrack );
1163 pendingTrack->SetOwner( shared_from_this(), {iter, this} );
1164 pendingTrack->SetId( TrackId{ ++sCounter } );
1165 if (!inserted) {
1166 first = iter;
1167 inserted = true;
1168 }
1169 }
1170 }
1171 if (inserted) {
1172 TrackNodePointer node{first, this};
1173 RecalcPositions(node);
1174 AdditionEvent(node);
1175 result = true;
1176 }
1177
1178 return result;
1179}
std::pair< ListOfTracks::iterator, ListOfTracks * > TrackNodePointer
Pairs a std::list iterator and a pointer to a list, for comparison purposes.
Definition: Track.h:52
std::list< std::shared_ptr< Track > > ListOfTracks
Definition: Track.h:46
An in-session identifier of track objects across undo states. It does not persist between sessions.
Definition: Track.h:92
static long sCounter
Definition: Track.h:1413
void AdditionEvent(TrackNodePointer node)
Definition: Track.cpp:508
void RecalcPositions(TrackNodePointer node)
Definition: Track.cpp:436
TrackListHolder ReplaceOne(Track &t, TrackList &&with)
Definition: Track.cpp:654
void ClearPendingTracks(ListOfTracks *pAdded=nullptr)
Definition: Track.cpp:1067
void UpdatePendingTracks()
Definition: Track.cpp:1047
Track * FindById(TrackId id)
Definition: Track.cpp:605
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 1044 of file Track.h.

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

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 1080 of file Track.h.

1080{ 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 1046 of file Track.h.

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

◆ Begin() [2/2]

const_iterator TrackList::Begin ( ) const
inlineprivate

This private function still iterates channels not tracks.

Definition at line 1085 of file Track.h.

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

◆ CanMoveDown()

bool TrackList::CanMoveDown ( Track t) const

Definition at line 878 of file Track.cpp.

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

References GetNext().

Here is the call graph for this function:

◆ CanMoveUp()

bool TrackList::CanMoveUp ( Track t) const

Definition at line 873 of file Track.cpp.

874{
875 return GetPrev(t, true) != NULL;
876}
Track * GetPrev(Track *t, bool linked=false) const
Definition: Track.cpp:837

References GetPrev().

Here is the call graph for this function:

◆ cbegin()

const_iterator TrackList::cbegin ( ) const
inline

Definition at line 1048 of file Track.h.

1048{ return begin(); }
iterator begin()
Definition: Track.h:1044

References PackedArray::begin().

Here is the call graph for this function:

◆ cend()

const_iterator TrackList::cend ( ) const
inline

Definition at line 1049 of file Track.h.

1049{ 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 1158 of file Track.h.

1160 {
1161 return Channels_<TrackType>(pTrack->GetHolder()->Find(pTrack));
1162 }

Referenced by anonymous_namespace{WaveChannelView.cpp}::AnyAffordance(), WaveTrack::Append(), WaveTrack::ApplyStretchRatio(), WaveTrack::Clear(), WaveTrack::ClearAndAddCutLine(), WaveTrack::ClearAndPaste(), WaveTrack::Clone(), WaveTrack::CloseLock(), WaveTrack::ConvertToSampleFormat(), WaveTrack::Copy(), WaveTrack::CountBlocks(), WaveTrack::CreateWideClip(), DataEvent(), WaveTrack::DiscardTrimmed(), WaveChannelSubView::DoDetailedHitTest(), WaveTrack::DoGetChannel(), WaveTrack::DoOnProjectTempoChange(), TrackPanelResizerCell::Draw(), Track::Duplicate(), WaveTrack::ExpandCutLine(), WaveTrack::Flush(), WaveTrack::FormatConsistencyCheck(), WaveTrack::Get(), ChannelView::GetChannelGroupHeight(), WaveTrack::GetClipInterfaces(), WaveTrack::GetEnvelopeAtTime(), WaveTrack::GetEnvelopeValues(), WaveTrack::GetErrorOpening(), CommonChannelView::GetMinimizedHeight(), WaveTrack::GetSequenceSamplesCount(), TrackPanelResizeHandle::GetTrack(), WaveTrack::HasHiddenData(), WaveTrack::HasTrivialEnvelope(), WaveTrack::InsertSilence(), WaveTrack::Join(), WaveTrack::LinkConsistencyFix(), WaveTrack::MergeClips(), WaveTrack::MoveTo(), WaveTrack::PasteInto(), WaveTrack::PasteWaveTrack(), Permute(), WaveTrack::RateConsistencyCheck(), RegisterPendingChangedTrack(), WaveTrack::Reinit(), WaveTrack::RemoveCutLine(), ReplaceOne(), WaveTrack::Resample(), WaveTrack::Reverse(), 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 1136 of file Track.h.

1137 {
1138 // Assume iterator filters leader tracks
1139 if (*iter1) {
1140 return {
1141 iter1.Filter( &Track::Any )
1142 .template Filter<TrackType>(),
1143 (++iter1).Filter( &Track::Any )
1144 .template Filter<TrackType>()
1145 };
1146 }
1147 else
1148 // empty range
1149 return {
1150 iter1.template Filter<TrackType>(),
1151 iter1.template Filter<TrackType>()
1152 };
1153 }
bool Any() const
Definition: Track.cpp:292
TrackIter Filter(const Predicate2 &pred2) const
Return an iterator that replaces the predicate.
Definition: Track.h:681
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 789 of file Track.cpp.

790{
791 // Null out the back-pointers to this in tracks, in case there
792 // are outstanding shared_ptrs to those tracks, making them outlive
793 // the temporary ListOfTracks below.
794 for (auto pTrack: Tracks<Track>()) {
795 pTrack->SetOwner({}, {});
796
797 if (sendEvent)
798 DeletionEvent(pTrack->shared_from_this(), false);
799 }
800
801 if (mPendingUpdates)
802 for (auto pTrack: static_cast<ListOfTracks&>(*mPendingUpdates)) {
803 pTrack->SetOwner({}, {});
804 if (sendEvent)
805 DeletionEvent(pTrack, false);
806 }
807
808 ListOfTracks tempList;
809 tempList.swap( *this );
810
811 if (mPendingUpdates)
812 mPendingUpdates = Temporary(nullptr);
813
814 mUpdaters.clear();
815}
std::vector< Updater > mUpdaters
This is in correspondence with leader tracks in mPendingUpdates.
Definition: Track.h:1470
void DeletionEvent(std::weak_ptr< Track > node, bool duringReplace)
Definition: Track.cpp:502

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 1067 of file Track.cpp.

1068{
1069 assert(GetOwner()); // which implies mPendingUpdates is not null
1070 for (const auto &pTrack: static_cast<ListOfTracks&>(*mPendingUpdates))
1071 pTrack->SetOwner( {}, {} );
1072 mPendingUpdates->ListOfTracks::clear();
1073 mUpdaters.clear();
1074
1075 if (pAdded)
1076 pAdded->clear();
1077
1078 // To find the first node that remains after the first deleted one
1079 TrackNodePointer node;
1080 bool foundNode = false;
1081
1082 for (auto it = ListOfTracks::begin(), stop = ListOfTracks::end();
1083 it != stop;) {
1084 if (it->get()->GetId() == TrackId{}) {
1085 do {
1086 if (pAdded)
1087 pAdded->push_back( *it );
1088 (*it)->SetOwner( {}, {} );
1089 DeletionEvent(*it, false);
1090 it = erase( it );
1091 }
1092 while (it != stop && it->get()->GetId() == TrackId{});
1093
1094 if (!foundNode && it != stop) {
1095 node = (*it)->GetNode();
1096 foundNode = true;
1097 }
1098 }
1099 else
1100 ++it;
1101 }
1102
1103 if (!empty()) {
1105 }
1106}
bool empty() const
Definition: Track.cpp:972
TrackNodePointer getBegin() const
Definition: Track.h:1370
AudacityProject * GetOwner()
Definition: Track.h:1026
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 1058 of file Track.h.

1058{ return rbegin(); }
reverse_iterator rbegin()
Definition: Track.h:1054

◆ Create()

TrackListHolder TrackList::Create ( AudacityProject pOwner)
static

◆ crend()

const_reverse_iterator TrackList::crend ( ) const
inline

Definition at line 1059 of file Track.h.

1059{ return rend(); }
reverse_iterator rend()
Definition: Track.h:1055

◆ DataEvent()

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

Definition at line 474 of file Track.cpp.

476{
477 auto doQueueEvent = [this, code](const std::shared_ptr<Track> &theTrack){
479 };
480 if (allChannels)
481 for (auto channel : Channels(pTrack.get()))
482 doQueueEvent(channel->shared_from_this());
483 else
484 doQueueEvent(pTrack);
485}
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1158
@ TRACK_DATA_CHANGE
Posted when certain fields of a track change.
Definition: Track.h:943

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 502 of file Track.cpp.

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

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 628 of file Track.cpp.

629{
630 if (!ListOfTracks::empty()) {
631 auto &pLast = *ListOfTracks::rbegin();
632 if (auto pGroupData = pLast->FindGroupData()
633 ; pGroupData && pGroupData->mLinkType != Track::LinkType::None
634 ) {
635 // Assume the newly added track is intended to pair with the last
636 // Avoid upsetting assumptions in case this track had its own group
637 // data initialized during Duplicate()
638 t->DestroyGroupData();
639 }
640 }
641
642 push_back(t);
643
644 auto n = getPrev( getEnd() );
645
646 t->SetOwner(shared_from_this(), n);
647 if (mAssignsIds)
648 t->SetId(TrackId{ ++sCounter });
650 AdditionEvent(n);
651 return back().get();
652}
TrackNodePointer getEnd() const
Definition: Track.h:1367
bool mAssignsIds
Definition: Track.h:1473
TrackNodePointer getPrev(TrackNodePointer p) const
Move an iterator to the previous node, if any; else wrap to end.
Definition: Track.h:1385

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 616 of file Track.cpp.

617{
618 Track *pTrack = t.get();
619 push_front(ListOfTracks::value_type(t));
620 auto n = getBegin();
621 pTrack->SetOwner(shared_from_this(), n);
622 pTrack->SetId( TrackId{ ++sCounter } );
624 AdditionEvent(n);
625 return front().get();
626}
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:123
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:129
void SetId(TrackId id)
Definition: Track.h:153

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 528 of file Track.cpp.

529{
530 if (!pTrack || pTrack->GetHolder() != this)
531 return EndIterator<Track>();
532 else
533 return MakeTrackIterator<Track>(pTrack->GetNode());
534}
TrackNodePointer GetNode() const
Retrieve mNode with debug checks.
Definition: Track.cpp:122
TrackList * GetHolder() const
Definition: Track.h:1476

Referenced by RecalcPositions().

Here is the caller graph for this function:

◆ empty()

bool TrackList::empty ( ) const

Definition at line 972 of file Track.cpp.

973{
974 return Begin() == End();
975}
iterator Begin()
This private function still iterates channels not tracks.
Definition: Track.h:1080
iterator End()
This private function still iterates channels not tracks.
Definition: Track.h:1082

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 518 of file Track.cpp.

520{
521 auto it = const_cast<TrackList*>(this)->getEnd();
522 return {
523 { it, it, it, &Track::Any },
524 { it, it, it, &Track::Any }
525 };
526}
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:987

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

Here is the call graph for this function:

◆ end() [1/2]

iterator TrackList::end ( )
inline

Definition at line 1045 of file Track.h.

1045{ 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 1082 of file Track.h.

1082{ 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 1047 of file Track.h.

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

◆ End() [2/2]

const_iterator TrackList::End ( ) const
inlineprivate

This private function still iterates channels not tracks.

Definition at line 1087 of file Track.h.

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

◆ EndIterator()

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

Definition at line 1355 of file Track.h.

1356 {
1357 auto e = const_cast<TrackList*>(this)->getEnd();
1358 return { e, e, e };
1359 }

◆ EnsureVisibleEvent()

void TrackList::EnsureVisibleEvent ( const std::shared_ptr< Track > &  pTrack,
bool  modifyState 
)
private

Definition at line 487 of file Track.cpp.

489{
490 // Substitute leader track
491 const auto pLeader = *Find(pTrack.get());
493 pLeader ? pLeader->SharedPointer() : nullptr,
494 static_cast<int>(modifyState) });
495}
TrackIter< Track > Find(Track *pTrack)
Definition: Track.cpp:536
@ TRACK_REQUEST_VISIBLE
Posted when a track needs to be scrolled into view; leader track only.
Definition: Track.h:946

References Find(), QueueEvent(), and TrackListEvent::TRACK_REQUEST_VISIBLE.

Here is the call graph for this function:

◆ Find() [1/2]

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

Definition at line 1071 of file Track.h.

1072 {
1073 return const_cast<TrackList*>(this)->
1074 Find(const_cast<Track*>(pTrack)).Filter<const Track>();
1075 }

References ActiveProjects::Find().

Here is the call graph for this function:

◆ Find() [2/2]

auto TrackList::Find ( Track pTrack)

Definition at line 536 of file Track.cpp.

537{
538 auto iter = DoFind(pTrack);
539 while( *iter && ! ( *iter )->IsLeader() )
540 --iter;
541 return iter.Filter( &Track::IsLeader );
542}
TrackIter< Track > DoFind(Track *pTrack)
Definition: Track.cpp:528

References Track::IsLeader().

Referenced by SpectrumView::DoDraw(), WaveformView::DoDraw(), TimeShiftHandle::DoSlideVertical(), EnsureVisibleEvent(), 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 605 of file Track.cpp.

606{
607 // Linear search. Tracks in a project are usually very few.
608 // Search only the non-pending tracks.
609 auto it = std::find_if( ListOfTracks::begin(), ListOfTracks::end(),
610 [=](const ListOfTracks::value_type &ptr){ return ptr->GetId() == id; } );
611 if (it == ListOfTracks::end())
612 return {};
613 return it->get();
614}

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 1423 of file Track.cpp.

1424{
1425 auto &exts = state.state.extensions;
1426 auto end = exts.end(),
1427 iter = std::find_if(exts.begin(), end, [](auto &pExt){
1428 return dynamic_cast<TrackListRestorer*>(pExt.get());
1429 });
1430 if (iter != end)
1431 return static_cast<TrackListRestorer*>(iter->get())->mpTracks.get();
1432 return nullptr;
1433}
static const auto exts
Definition: ImportAUP.cpp:58
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 354 of file Track.cpp.

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

References key, and project.

Referenced by SelectUtilities::ActivatePlayRegion(), ProjectFileManager::AddImportedTracks(), SelectHandle::AdjustSelection(), AdornedRulerPanel::AdornedRulerPanel(), AnyTracksSelectedPred(), AppendItem(), SetTrackBase::Apply(), ImportCommand::Apply(), ScreenshotCommand::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(), 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(), 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(), LyricsPanel::DoUpdateLyrics(), ProjectWindow::DoZoomFit(), anonymous_namespace{ViewMenus.cpp}::DoZoomFitV(), 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(), GetInfoCommand::ExploreTrackPanel(), ExportAudioDialog::ExportAudioDialog(), cloud::audiocom::ShareAudioDialog::ExportProject(), anonymous_namespace{ClipMenus.cpp}::FindClipBoundaries(), anonymous_namespace{ClipMenus.cpp}::FindClips(), anonymous_namespace{EditMenus.cpp}::FindSourceTracks(), ProjectWindow::FixScrollbars(), SpectrumView::ForAll(), ProjectFileIO::GenerateDoc(), Get(), GetAllSeqBlocks(), FrequencyPlotDialog::GetAudio(), ContrastDialog::GetDB(), GetPropertiesOfSelected(), CompareAudioCommand::GetSelection(), SliderHandle::GetSlider(), ScreenshotCommand::GetTrackRect(), TrackPanelAx::GetTracks(), ProjectWindow::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(), PCMExportProcessor::Initialize(), WavPackExportProcessor::Initialize(), 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(), TimeTrack::New(), WaveTrack::New(), LabelTrack::New(), NoteTrack::New(), anonymous_namespace{ExportMIDI.cpp}::NoteTracksExistFlag(), anonymous_namespace{EditMenus.cpp}::NotificationScope(), ApplyMacroDialog::OnApplyToFiles(), ExportFilePanel::OnChannelsConfigure(), ProjectManager::OnCloseWindow(), ViewActions::Handler::OnCollapseAllTracks(), 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(), ViewActions::Handler::OnExpandAllTracks(), 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(), anonymous_namespace{Printing.cpp}::OnPrint(), 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(), ScreenshotBigDialog::OnShortTracks(), 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(), ProjectFileManager::ReadProjectFile(), RealtimeEffectPanel::RealtimeEffectPanel(), ProjectWindow::RedrawProject(), 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(), ProjectWindow::ScrollingLowerBoundTime(), anonymous_namespace{SelectMenus.cpp}::SeekWhenAudioInactive(), NoteTrackAffordanceHandle::SelectAt(), SelectUtilities::SelectNone(), GetInfoCommand::SendClips(), GetInfoCommand::SendEnvelopes(), GetInfoCommand::SendLabels(), GetInfoCommand::SendTracks(), TrackFocus::Set(), ScreenshotBigDialog::SizeTracks(), ProjectWindow::SkipEnd(), WaveTrackMenuTable::SplitStereo(), ProjectSelectionManager::SSBL_GetRate(), StereoRequiredFlag(), anonymous_namespace{Track.cpp}::TrackListRestorer::TrackListRestorer(), anonymous_namespace{ChannelView.cpp}::TrackPositioner::TrackPositioner(), TracksExistFlag(), ExportAudioDialog::UpdateLabelExportSettings(), ExportFilePanel::UpdateMaxChannels(), ProjectSettings::UpdatePrefs(), RealtimeEffectPanel::PrefsListenerHelper::UpdatePrefs(), ExportAudioDialog::UpdateTrackExportSettings(), AffordanceHandle::UpdateTrackSelection(), WaveTracksExistFlag(), WaveTracksSelectedFlag(), ProjectFileIO::WriteXML(), ProjectWindow::ZoomAfterImport(), ZoomInAvailableFlag(), and ZoomOutAvailableFlag().

◆ Get() [2/2]

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

Definition at line 359 of file Track.cpp.

360{
361 return Get( const_cast< AudacityProject & >( project ) );
362}
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:354

References Get(), and project.

Here is the call graph for this function:

◆ getBegin()

TrackNodePointer TrackList::getBegin ( ) const
inlineprivate

Definition at line 1370 of file Track.h.

1371 { return { const_cast<TrackList*>(this)->ListOfTracks::begin(),
1372 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 1367 of file Track.h.

1368 { return { const_cast<TrackList*>(this)->ListOfTracks::end(),
1369 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 1008 of file Track.cpp.

1009{
1010 return Accumulate(*this, &Track::GetEndTime,
1011 std::numeric_limits<double>::lowest(), std::max);
1012}
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:989

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 818 of file Track.cpp.

819{
820 if (t) {
821 auto node = t->GetNode();
822 if ( !isNull( node ) ) {
823 if ( linked && t->HasLinkedTrack() )
824 node = getNext( node );
825
826 if ( !isNull( node ) )
827 node = getNext( node );
828
829 if ( !isNull( node ) )
830 return node.first->get();
831 }
832 }
833
834 return nullptr;
835}
bool HasLinkedTrack() const noexcept
Returns true for leaders of multichannel groups.
Definition: Track.cpp:253
bool isNull(TrackNodePointer p) const
Definition: Track.h:1363
TrackNodePointer getNext(TrackNodePointer p) const
Move an iterator to the next node, if any; else stay at end.
Definition: Track.h:1375

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 1375 of file Track.h.

1376 {
1377 if ( isNull(p) )
1378 return p;
1379 auto q = p;
1380 ++q.first;
1381 return q;
1382 }

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 1026 of file Track.h.

1026{ 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 1027 of file Track.h.

1027{ return mOwner; }

◆ GetPrev()

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

Definition at line 837 of file Track.cpp.

838{
839 if (t) {
840 TrackNodePointer prev;
841 auto node = t->GetNode();
842 if ( !isNull( node ) ) {
843 // linked is true and input track second in team?
844 if (linked) {
845 prev = getPrev( node );
846 if( !isNull( prev ) &&
847 !t->HasLinkedTrack() && t->GetLinkedTrack() )
848 // Make it the first
849 node = prev;
850 }
851
852 prev = getPrev( node );
853 if ( !isNull( prev ) ) {
854 // Back up once
855 node = prev;
856
857 // Back up twice sometimes when linked is true
858 if (linked) {
859 prev = getPrev( node );
860 if( !isNull( prev ) &&
861 !(*node.first)->HasLinkedTrack() && (*node.first)->GetLinkedTrack() )
862 node = prev;
863 }
864
865 return node.first->get();
866 }
867 }
868 }
869
870 return nullptr;
871}
Track * GetLinkedTrack() const
Definition: Track.cpp:227

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 1385 of file Track.h.

1386 {
1387 if (p == getBegin())
1388 return getEnd();
1389 else {
1390 auto q = p;
1391 --q.first;
1392 return q;
1393 }
1394 }

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 1002 of file Track.cpp.

1003{
1004 return Accumulate(*this, &Track::GetStartTime,
1005 std::numeric_limits<double>::max(), std::min);
1006}
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 1286 of file Track.cpp.

1287{
1288 if (mPendingUpdates && !mPendingUpdates->empty())
1289 return true;
1290 if (End() != std::find_if(Begin(), End(), [](const Track *t){
1291 return t->GetId() == TrackId{};
1292 }))
1293 return true;
1294 return false;
1295}
TrackId GetId() const
Definition: Track.h:151

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 563 of file Track.cpp.

564{
565 assert(before == nullptr || (before->IsLeader() && Find(before) != EndIterator<const Track>()));
566
567 if(before == nullptr)
568 {
569 Append(std::move(trackList));
570 return;
571 }
572
573 std::vector<Track *> arr;
574 arr.reserve(Size() + trackList.Size());
575 for (const auto track : *this) {
576 if (track == before)
577 {
578 for(const auto addedTrack : trackList)
579 arr.push_back(addedTrack);
580 }
581 arr.push_back(track);
582 }
583 Append(std::move(trackList));
584 Permute(arr);
585}
void Permute(const std::vector< Track * > &tracks)
Definition: Track.cpp:587
void Append(TrackList &&list)
Remove all tracks from list and put them at the end of this
Definition: Track.cpp:1465
size_t Size() const
Definition: Track.h:1253

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 1363 of file Track.h.

1364 { return (p.second == this && p.first == ListOfTracks::end())
1365 || (mPendingUpdates && p.second == &*mPendingUpdates &&
1366 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 1240 of file Track.h.

1241 {
1242 auto pTrack = wTrack.lock();
1243 if (pTrack) {
1244 auto pList = pTrack->mList.lock();
1245 if (pTrack && this == pList.get())
1246 return pTrack;
1247 }
1248 return {};
1249 }

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 722 of file Track.cpp.

723{
724 if (nChannels != 2)
725 return false;
726
727 auto list = track.mList.lock();
728 if (list.get() == this) {
729 if (*list->Find(&track) != &track)
730 return false;
731
732 auto first = list->DoFind(&track);
733 auto canLink = [&]() -> bool {
734 int count = nChannels;
735 for (auto it = first, end = TrackList::End(); it != end && count; ++it)
736 {
737 if ((*it)->HasLinkedTrack())
738 return false;
739 --count;
740 }
741 return count == 0;
742 }();
743
744 if (!canLink)
745 return false;
746
747 (*first)->SetLinkType(Track::LinkType::Aligned);
748
749 //Cleanup the group data in all channels except the first
750 for(auto it = std::next(first), last = std::next(first, nChannels);
751 it != last;
752 ++it)
753 {
754 (*it)->DestroyGroupData();
755 }
756 }
757 else
759 return true;
760}
#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:494

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 1346 of file Track.h.

1347 {
1348 auto b = const_cast<TrackList*>(this)->getBegin();
1349 auto e = const_cast<TrackList*>(this)->getEnd();
1350 return { b, iter, e };
1351 }

◆ 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 418 of file Track.cpp.

419{
420 int n = 1;
421 while(true) {
422 auto name = wxString::Format("%s %d", baseTrackName, n++);
423
424 bool found {false};
425 for(const auto track : Tracks<const Track>()) {
426 if(track->GetName() == name) {
427 found = true;
428 break;
429 }
430 }
431 if(!found)
432 return name;
433 }
434}
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 1235 of file Track.h.

1235{ return up ? MoveUp(t) : MoveDown(t); }
bool MoveUp(Track *t)
Definition: Track.cpp:946
bool MoveDown(Track *t)
Definition: Track.cpp:959

◆ MoveDown()

bool TrackList::MoveDown ( Track t)

Definition at line 959 of file Track.cpp.

960{
961 if (t) {
962 Track *n = GetNext(t, true);
963 if (n) {
964 SwapNodes(t->GetNode(), n->GetNode());
965 return true;
966 }
967 }
968
969 return false;
970}
void SwapNodes(TrackNodePointer s1, TrackNodePointer s2)
Definition: Track.cpp:887

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

Here is the call graph for this function:

◆ MoveUp()

bool TrackList::MoveUp ( Track t)

Definition at line 946 of file Track.cpp.

947{
948 if (t) {
949 Track *p = GetPrev(t, true);
950 if (p) {
951 SwapNodes(p->GetNode(), t->GetNode());
952 return true;
953 }
954 }
955
956 return false;
957}

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 977 of file Track.cpp.

978{
979 int cnt = 0;
980
981 if (!empty())
982 cnt = getPrev( getEnd() ).first->get()->GetIndex() + 1;
983
984 return cnt;
985}

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 1165 of file Track.h.

1166 {
1167 return Channels(&track).size();
1168 }

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 497 of file Track.cpp.

498{
499 QueueEvent({ TrackListEvent::PERMUTED, *node.first });
500}
@ PERMUTED
Posted when tracks are reordered but otherwise unchanged.
Definition: Track.h:950

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 587 of file Track.cpp.

588{
589 std::vector<TrackNodePointer> permutation;
590 for (const auto pTrack : tracks)
591 for (const auto pChannel : Channels(pTrack))
592 permutation.push_back(pChannel->GetNode());
593 for (const auto iter : permutation) {
594 ListOfTracks::value_type track = *iter.first;
595 erase(iter.first);
596 Track *pTrack = track.get();
597 pTrack->SetOwner(shared_from_this(),
598 { insert(ListOfTracks::end(), track), this });
599 }
600 auto n = getBegin();
603}
const auto tracks
void PermutationEvent(TrackNodePointer node)
Definition: Track.cpp:497

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 459 of file Track.cpp.

460{
461 BasicUI::CallAfter( [wThis = weak_from_this(), event = std::move(event)]{
462 if (auto pThis = wThis.lock())
463 pThis->Publish(event);
464 } );
465}
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(), EnsureVisibleEvent(), PermutationEvent(), and ResizingEvent().

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 1054 of file Track.h.

1054{ 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 1056 of file Track.h.

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

◆ RecalcPositions()

void TrackList::RecalcPositions ( TrackNodePointer  node)
private

Definition at line 436 of file Track.cpp.

437{
438 if (isNull(node))
439 return;
440
441 Track *t;
442 int i = 0;
443
444 auto prev = getPrev(node);
445 if (!isNull(prev)) {
446 t = prev.first->get();
447 i = t->GetIndex() + 1;
448 }
449
450 const auto theEnd = End();
451 for (auto n = DoFind(node.first->get()); n != theEnd; ++n) {
452 t = *n;
453 t->SetIndex(i++);
454 }
455
457}
void SetIndex(int index)
Definition: Track.cpp:142
int GetIndex() const
Definition: Track.cpp:137

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 1015 of file Track.cpp.

1016{
1017 // This is only done on the TrackList belonging to a project
1018 assert(GetOwner()); // which implies mPendingUpdates is not null
1019 assert(src->IsLeader());
1020
1021 auto tracks = src->Clone(); // not duplicate
1022 assert(src->NChannels() == tracks->NChannels());
1023 {
1024 // Share the satellites with the original, though they do not point back
1025 // to the pending track
1026 const auto channels = TrackList::Channels(src);
1027 auto iter = TrackList::Channels(*tracks->begin()).begin();
1028 for (const auto pChannel : channels)
1029 ((AttachedTrackObjects&)**iter++) = *pChannel; // shallow copy
1030 }
1031
1032 const auto result = *tracks->begin();
1033 mUpdaters.push_back(updater);
1034 auto iter = tracks->ListOfTracks::begin(),
1035 end = tracks->ListOfTracks::end();
1036 while (iter != end) {
1037 auto pTrack = *iter;
1038 iter = tracks->erase(iter);
1039 mPendingUpdates->ListOfTracks::push_back(pTrack->SharedPointer());
1040 auto n = mPendingUpdates->ListOfTracks::end();
1041 --n;
1042 pTrack->SetOwner(shared_from_this(), {n, &*mPendingUpdates});
1043 }
1044 return result;
1045}
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:220
virtual TrackListHolder Clone() 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 1476 of file Track.cpp.

1477{
1478 for(auto it = list.ListOfTracks::begin(); it != list.ListOfTracks::end();)
1479 {
1480 Add(*it);
1481 (*it)->SetId({});
1482 it = list.erase(it);
1483 }
1484}

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 762 of file Track.cpp.

763{
764 assert(track.IsLeader());
765 auto *t = &track;
766 const size_t nChannels = NChannels(*t);
767 Track *nextT{};
768 for (size_t ii = 0; t != nullptr && ii < nChannels; ++ii, t = nextT) {
769 nextT = nullptr;
770 auto iter = getEnd();
771 auto node = t->GetNode();
772 t->SetOwner({}, {});
773
774 if (!isNull(node)) {
775 ListOfTracks::value_type holder = *node.first;
776
777 iter = getNext(node);
778 erase(node.first);
779 if (!isNull(iter)) {
780 RecalcPositions(iter);
781 nextT = iter.first->get();
782 }
783
784 DeletionEvent(t->shared_from_this(), false);
785 }
786 }
787}

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 1055 of file Track.h.

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

◆ rend() [2/2]

const_reverse_iterator TrackList::rend ( ) const
inline

Definition at line 1057 of file Track.h.

1057{ 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 654 of file Track.cpp.

655{
656 assert(t.IsLeader());
657 assert(t.GetOwner().get() == this);
658 auto nChannels = t.NChannels();
659
660 // TODO wide wave tracks: This won't matter, tracks will be 1 to 1
661 assert(nChannels >= (*with.begin())->NChannels());
662
663 TrackListHolder result = Temporary(nullptr);
664
665 auto iter = with.ListOfTracks::begin(),
666 end = with.ListOfTracks::end();
667 bool isLeader = true;
668 std::vector<Track*> saveChannels;
669 for (const auto pChannel : TrackList::Channels(&t))
670 saveChannels.push_back(pChannel);
671
672 // Because default constructor doesn't work
673 std::optional<TrackNodePointer> lastNode;
674
675 for (const auto pChannel : saveChannels) {
676 auto spChannel = pChannel->shared_from_this();
677
679 auto node = pChannel->GetNode();
680 pChannel->SetOwner({}, {});
681 result->Add(spChannel);
682
684 assert(isLeader == pChannel->IsLeader());
685 isLeader = false;
686
687 if (iter == end) {
688 node.second->erase(node.first);
689 RecalcPositions(*lastNode);
690 DeletionEvent(spChannel, true);
691 }
692 else {
693 lastNode.emplace(node);
695 const auto pTrack = *iter;
696 *node.first = pTrack;
697 iter = with.erase(iter);
698 pTrack->SetOwner(shared_from_this(), node);
699 pTrack->SetId(pChannel->GetId());
700 RecalcPositions(node);
701 DeletionEvent(spChannel, true);
702 AdditionEvent(node);
703 }
704 }
705 return result;
706}
std::shared_ptr< TrackList > TrackListHolder
Definition: Track.h:43
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:255

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 513 of file Track.cpp.

514{
515 QueueEvent({ TrackListEvent::RESIZING, *node.first });
516}
@ RESIZING
Posted when some track changed its height.
Definition: Track.h:953

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 1114 of file Track.h.

1116 {
1117 return Tracks<TrackType>(&Track::IsSelectedLeader);
1118 }

References Track::IsSelectedLeader().

Here is the call graph for this function:

◆ SelectionEvent()

void TrackList::SelectionEvent ( Track track)
private

Definition at line 467 of file Track.cpp.

468{
469 for (auto channel : Channels(&track))
470 QueueEvent({
471 TrackListEvent::SELECTION_CHANGE, channel->shared_from_this() });
472}
@ SELECTION_CHANGE
Posted when the set of selected tracks changes.
Definition: Track.h:940

◆ SingletonRange()

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

Definition at line 1122 of file Track.h.

1124 {
1125 return pTrack->GetOwner()->template Tracks<TrackType>()
1126 .StartingWith( pTrack ).EndingAfter( pTrack );
1127 }

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 1253 of file Track.h.

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

References Track::Any().

Referenced by ScreenshotCommand::Apply(), and 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 388 of file Track.cpp.

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

◆ 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 544 of file Track.cpp.

545{
546 if (!track.HasLinkedTrack())
547 return nullptr;
548 auto pOwner = track.GetOwner();
549 if (!pOwner)
550 return nullptr;
551 auto pPartner = pOwner->GetNext(&track, false);
552 if (!pPartner)
553 return nullptr;
554
555 // Swap channels, avoiding copying of GroupData
556 auto pData = track.DetachGroupData();
557 assert(pData);
558 pOwner->MoveUp(pPartner);
559 pPartner->AssignGroupData(move(pData));
560 return pPartner;
561}
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 887 of file Track.cpp.

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

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 1281 of file Track.h.

1284 {
1285 std::vector<Track::Holder> temp;
1286 static const auto convert = [](auto &pChannel){
1287 return std::static_pointer_cast<Track>(pChannel);
1288 };
1289 transform(channels.begin(), channels.end(), back_inserter(temp), convert);
1290 return Temporary(pProject, temp);
1291 }

◆ 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 1453 of file Track.cpp.

1455{
1456 auto nChannels = channels.size();
1457 auto tempList = Temporary(pProject,
1458 (nChannels > 0 ? channels[0] : nullptr),
1459 (nChannels > 1 ? channels[1] : nullptr));
1460 for (size_t iChannel = 2; iChannel < nChannels; ++iChannel)
1461 tempList->Add(channels[iChannel]);
1462 return tempList;
1463}

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 1435 of file Track.cpp.

1437{
1438 assert(left == nullptr || left->GetOwner() == nullptr);
1439 assert(right == nullptr || (left && right->GetOwner() == nullptr));
1440 // Make a well formed channel group from these tracks
1441 auto tempList = Create(pProject);
1442 if (left) {
1443 tempList->Add(left);
1444 if (right) {
1445 tempList->Add(right);
1446 tempList->MakeMultiChannelTrack(*left, 2);
1447 }
1448 }
1449 tempList->mAssignsIds = false;
1450 return tempList;
1451}
static TrackListHolder Create(AudacityProject *pOwner)
Definition: Track.cpp:372

References Create().

Referenced by ApplyPendingTracks(), Clear(), TimeTrack::Clone(), WaveTrack::Clone(), LabelTrack::Clone(), NoteTrack::Clone(), TimeTrack::Copy(), LabelTrack::Copy(), NoteTrack::Copy(), WaveTrackFactory::Create(), NoteTrack::Cut(), 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 1318 of file Track.h.

1318 {} )
1320 {
1321 auto b = getBegin(), e = getEnd();
1322 return { { b, b, e, pred }, { b, e, e, pred } };
1323 }
Range between two TrackIters, usable in range-for statements, and with Visit member functions.
Definition: Track.h:816

◆ 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 1331 of file Track.h.

1331 {} ) const
1332 -> std::enable_if_t< std::is_const_v<TrackType>,
1334 >
1335 {
1336 auto b = const_cast<TrackList*>(this)->getBegin();
1337 auto e = const_cast<TrackList*>(this)->getEnd();
1338 return { { b, b, e, pred }, { b, e, e, pred } };
1339 }

◆ UnlinkChannels()

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

Removes linkage if track belongs to a group.

Definition at line 708 of file Track.cpp.

709{
710 auto list = track.mList.lock();
711 if (list.get() == this)
712 {
713 auto channels = TrackList::Channels(&track);
714 for (auto c : channels)
715 c->SetLinkType(Track::LinkType::None);
716 return { channels.begin(), channels.end() };
717 }
718 else
720}
std::weak_ptr< TrackList > mList
Definition: Track.h:140

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 1047 of file Track.cpp.

1048{
1049 if (!mPendingUpdates)
1050 return;
1051 auto pUpdater = mUpdaters.begin();
1052 for (const auto &pendingTrack : *mPendingUpdates) {
1053 auto src = FindById(pendingTrack->GetId());
1054 // Copy just a part of the track state, according to the update
1055 // function
1056 const auto &updater = *pUpdater;
1057 if (pendingTrack && src) {
1058 if (updater)
1059 updater(*pendingTrack, *src);
1060 }
1061 ++pUpdater;
1062 pendingTrack->DoSetLinkType(src->GetLinkType());
1063 }
1064}
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 1174 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 1473 of file Track.h.

Referenced by DoAdd().

◆ mOwner

AudacityProject* TrackList::mOwner
private

Definition at line 1463 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 1468 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 1470 of file Track.h.

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

◆ sCounter

long TrackList::sCounter = -1
staticprivate

Definition at line 1413 of file Track.h.

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


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