Audacity 3.2.0
SelectionState.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 SelectionState.h
6
7 **********************************************************************/
8
9#include "SelectionState.h"
10
11#include "ViewInfo.h"
12#include "SyncLock.h"
13#include "Track.h"
14#include "Project.h"
15
16#include <cassert>
17
19 [](AudacityProject &){ return std::make_shared< SelectionState >(); }
20};
21
23{
24 return project.AttachedObjects::Get< SelectionState >( key );
25}
26
28{
29 return Get( const_cast< AudacityProject & >( project ) );
30}
31
33 ViewInfo &viewInfo, Track &track, bool syncLocked)
34{
35 auto trackRange = syncLocked
36 // If we have a sync-lock group and sync-lock linking is on,
37 // check the sync-lock group tracks.
38 ? SyncLock::Group(track)
39
40 // Otherwise, check for one track
42
43 auto minOffset = trackRange.min(&Track::GetStartTime);
44 auto maxEnd = trackRange.max(&Track::GetEndTime);
45
46 // PRL: double click or click on track control.
47 // should this select all frequencies too? I think not.
48 viewInfo.selectedRegion.setTimes(minOffset, maxEnd);
49}
50
52 Track &track, bool selected, bool updateLastPicked)
53{
54 //bool wasCorrect = (selected == track.GetSelected());
55
56 track.SetSelected(selected);
57
58 if (updateLastPicked)
60
61//The older code below avoids an anchor on an unselected track.
62
63 /*
64 if (selected) {
65 // This handles the case of linked tracks, selecting all channels
66 mTracks->Select(pTrack, true);
67 if (updateLastPicked)
68 mLastPickedTrack = Track::Pointer( pTrack );
69 }
70 else {
71 mTracks->Select(pTrack, false);
72 if (updateLastPicked && pTrack == mLastPickedTrack.lock().get())
73 mLastPickedTrack.reset();
74 }
75*/
76}
77
79 TrackList &tracks, Track &rsTrack, Track &reTrack)
80{
81 Track *sTrack = &rsTrack, *eTrack = &reTrack;
82 // Swap the track pointers if needed
83 auto begin = tracks.begin(),
84 iterS = tracks.Find(sTrack),
85 iterE = tracks.Find(eTrack);
86 auto indS = std::distance(begin, iterS),
87 indE = std::distance(begin, iterE);
88 if (indE < indS)
89 std::swap(sTrack, eTrack);
90
91 for (auto track :
92 tracks.Any().StartingWith(sTrack).EndingAfter(eTrack))
93 SelectTrack(*track, true, false);
94}
95
97{
98 for (auto t : tracks)
99 SelectTrack(*t, false, false);
100}
101
103 TrackList &tracks, Track &track)
104{
105 // We will either extend from the first or from the last.
106 auto pExtendFrom = tracks.Lock(mLastPickedTrack);
107
108 if (!pExtendFrom) {
109 auto trackRange = tracks.Selected();
110 auto pFirst = *trackRange.begin();
111
112 // If our track is at or after the first, extend from the first.
113 if (pFirst) {
114 auto begin = tracks.begin(),
115 iterT = tracks.Find(&track),
116 iterF = tracks.Find(pFirst);
117 auto indT = std::distance(begin, iterT),
118 indF = std::distance(begin, iterF);
119 if (indT >= indF)
120 pExtendFrom = pFirst->SharedPointer();
121 }
122
123 // Our track was earlier than the first. Extend from the last.
124 if (!pExtendFrom)
125 pExtendFrom = Track::SharedPointer(*trackRange.rbegin());
126 }
127
129 if (pExtendFrom)
130 SelectRangeOfTracks(tracks, track, *pExtendFrom);
131 else
132 SelectTrack(track, true, true);
133 mLastPickedTrack = pExtendFrom;
134}
135
137 Track &track, bool shift, bool ctrl, bool syncLocked)
138{
139 // AS: If the shift button is being held down, invert
140 // the selection on this track.
141 if (ctrl)
142 SelectTrack(track, !track.GetSelected(), true);
143 else {
144 if (shift && mLastPickedTrack.lock())
146 else {
148 SelectTrack(track, true, true);
149 SelectTrackLength(viewInfo, track, syncLocked);
150 }
151 }
152}
153
156 : mpState{ &state }
157 , mTracks{ tracks }
158 , mInitialLastPickedTrack{ state.mLastPickedTrack }
159{
160 // Save initial state of track selections
161 const auto range = tracks.Any();
163 mInitialTrackSelection.reserve(range.size());
164 for (const auto track : range) {
165 const bool isSelected = track->GetSelected();
166 mInitialTrackSelection.push_back(isSelected);
167 }
168}
169
171{
172 if ( mpState ) {
173 // roll back changes
175 std::vector<bool>::const_iterator
176 it = mInitialTrackSelection.begin(),
178
179 for (auto track : mTracks) {
180 if (it == end)
181 break;
182 track->SetSelected( *it++ );
183 }
184 }
185}
186
188{
189 mpState = nullptr;
190}
static const AudacityProject::AttachedObjects::RegisteredFactory key
const auto tracks
const auto project
declares abstract base class Track, TrackList, and iterators over TrackList
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
double GetEndTime() const
Get the maximum of End() values of intervals, or 0 when none.
Definition: Channel.cpp:61
double GetStartTime() const
Get the minimum of Start() values of intervals, or 0 when none.
Definition: Channel.cpp:50
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:275
bool setTimes(double t0, double t1)
Definition: ViewInfo.cpp:51
SelectionState * mpState
SelectionStateChanger(SelectionState &state, TrackList &tracks)
std::vector< bool > mInitialTrackSelection
std::weak_ptr< Track > mInitialLastPickedTrack
std::weak_ptr< Track > mLastPickedTrack
void HandleListSelection(TrackList &tracks, ViewInfo &viewInfo, Track &track, bool shift, bool ctrl, bool syncLocked)
void ChangeSelectionOnShiftClick(TrackList &tracks, Track &track)
static void SelectTrackLength(ViewInfo &viewInfo, Track &track, bool syncLocked)
void SelectRangeOfTracks(TrackList &tracks, Track &sTrack, Track &eTrack)
void SelectNone(TrackList &tracks)
static SelectionState & Get(AudacityProject &project)
void SelectTrack(Track &track, bool selected, bool updateLastPicked)
static TrackIterRange< Track > Group(Track &track)
Definition: SyncLock.cpp:150
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:110
bool GetSelected() const
Selectedness is always the same for all channels of a group.
Definition: Track.cpp:78
virtual void SetSelected(bool s)
Definition: Track.cpp:83
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:146
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:850
static auto SingletonRange(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:981
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:215
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:628
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101