Audacity 3.2.0
SyncLock.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5@file SyncLock.cpp
6@brief implements sync-lock logic
7
8Paul Licameli split from Track.cpp
9
10**********************************************************************/
11
12#include "SyncLock.h"
13
14#include "ProjectSettings.h"
15#include "Track.h"
16
17namespace {
18inline bool IsSyncLockableNonSeparatorTrack( const Track *pTrack )
19{
20 return pTrack && GetSyncLockPolicy::Call(*pTrack) == SyncLockPolicy::Grouped;
21}
22
23inline bool IsSeparatorTrack( const Track *pTrack )
24{
25 return pTrack &&
27}
28
29bool IsGoodNextSyncLockTrack(const Track *t, bool inSeparatorSection)
30{
31 if (!t)
32 return false;
33 const bool isSeparator = IsSeparatorTrack(t);
34 if (inSeparatorSection)
35 return isSeparator;
36 else if (isSeparator)
37 return true;
38 else
40}
41}
42
44{
45 if (!pTrack)
46 return false;
47 auto pList = pTrack->GetOwner();
48 if (!pList)
49 return false;
50
51 auto p = pList->GetOwner();
52 if (!p || !ProjectSettings::Get( *p ).IsSyncLocked())
53 return false;
54
55 auto shTrack = pTrack->SubstituteOriginalTrack();
56 if (!shTrack)
57 return false;
58
59 const auto pOrigTrack = shTrack.get();
60 auto trackRange = Group( pOrigTrack );
61
62 if (trackRange.size() <= 1) {
63 // Not in a sync-locked group.
64 // Return true iff selected and of a sync-lockable type.
65 return (IsSyncLockableNonSeparatorTrack( pOrigTrack ) ||
66 IsSeparatorTrack( pOrigTrack )) && pTrack->GetSelected();
67 }
68
69 // Return true iff any track in the group is selected.
70 return *(trackRange + &Track::IsSelected).begin();
71}
72
74{
75 return pTrack && (pTrack->IsSelected() || IsSyncLockSelected(pTrack));
76}
77
78namespace {
79std::pair<Track *, Track *> FindSyncLockGroup( Track *pMember)
80{
81 if (!pMember)
82 return { nullptr, nullptr };
83
84 // A non-trivial sync-locked group is a maximal sub-sequence of the tracks
85 // consisting of any positive number of audio tracks followed by zero or
86 // more label tracks.
87
88 // Step back through any label tracks.
89 auto pList = pMember->GetOwner();
90 auto member = pList->Find(pMember);
91 while (*member && IsSeparatorTrack(*member) )
92 --member;
93
94 // Step back through the wave and note tracks before the label tracks.
95 Track *first = nullptr;
96 while (*member && IsSyncLockableNonSeparatorTrack(*member)) {
97 first = *member;
98 --member;
99 }
100
101 if (!first)
102 // Can't meet the criteria described above. In that case,
103 // consider the track to be the sole member of a group.
104 return { pMember, pMember };
105
106 auto last = pList->Find(first);
107 auto next = last;
108 bool inLabels = false;
109
110 while (*++next) {
111 if ( ! IsGoodNextSyncLockTrack(*next, inLabels) )
112 break;
113 last = next;
114 inLabels = IsSeparatorTrack(*last);
115 }
116
117 return { first, *last };
118}
119
120}
121
123{
124 auto pList = pTrack->GetOwner();
125 auto tracks = FindSyncLockGroup(const_cast<Track*>( pTrack ) );
126 return pList->Any().StartingWith(tracks.first).EndingAfter(tracks.second);
127}
128
130 return [](auto&){ return SyncLockPolicy::Isolated; };
131}
DEFINE_ATTACHED_VIRTUAL(GetSyncLockPolicy)
Definition: SyncLock.cpp:129
@ EndSeparator
Delimits the end of a group (of which it is a part)
@ Grouped
Can be part of a group.
@ Isolated
Never part of a group.
declares abstract base class Track, TrackList, and iterators over TrackList
Class template generates single-dispatch, open method registry tables.
static Return Call(This &obj, Arguments &&...arguments)
Invoke the method – but only after static initialization time.
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Definition: ClientData.h:333
static ProjectSettings & Get(AudacityProject &project)
bool IsSyncLocked() const
static bool IsSelectedOrSyncLockSelected(const Track *pTrack)
Definition: SyncLock.cpp:73
static bool IsSyncLockSelected(const Track *pTrack)
Definition: SyncLock.cpp:43
static TrackIterRange< Track > Group(Track *pTrack)
Definition: SyncLock.cpp:122
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
bool GetSelected() const
Definition: Track.h:461
bool IsSelected() const
Definition: Track.cpp:384
std::shared_ptr< const Track > SubstituteOriginalTrack() const
Definition: Track.cpp:1209
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:402
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
bool IsSeparatorTrack(const Track *pTrack)
Definition: SyncLock.cpp:23
bool IsSyncLockableNonSeparatorTrack(const Track *pTrack)
Definition: SyncLock.cpp:18
std::pair< Track *, Track * > FindSyncLockGroup(Track *pMember)
Definition: SyncLock.cpp:79
bool IsGoodNextSyncLockTrack(const Track *t, bool inSeparatorSection)
Definition: SyncLock.cpp:29
Range between two TrackIters, usable in range-for statements, and with Visit member functions.
Definition: Track.h:1161