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
17 [](AudacityProject &){ return std::make_shared< SelectionState >(); }
18};
19
21{
22 return project.AttachedObjects::Get< SelectionState >( key );
23}
24
26{
27 return Get( const_cast< AudacityProject & >( project ) );
28}
29
30// Set selection length to the length of a track -- but if sync-lock is turned
31// on, use the largest possible selection in the sync-lock group.
32// If it's a stereo track, do the same for the stereo channels.
34( ViewInfo &viewInfo, Track &track, bool syncLocked )
35{
36 auto trackRange = syncLocked
37 // If we have a sync-lock group and sync-lock linking is on,
38 // check the sync-lock group tracks.
39 ? SyncLock::Group(&track)
40
41 // Otherwise, check for a stereo pair
42 : TrackList::Channels(&track);
43
44 auto minOffset = trackRange.min( &Track::GetOffset );
45 auto maxEnd = trackRange.max( &Track::GetEndTime );
46
47 // PRL: double click or click on track control.
48 // should this select all frequencies too? I think not.
49 viewInfo.selectedRegion.setTimes(minOffset, maxEnd);
50}
51
53 Track &track, bool selected, bool updateLastPicked )
54{
55 //bool wasCorrect = (selected == track.GetSelected());
56
57 track.SetSelected(selected);
58
59 if (updateLastPicked)
61
62//The older code below avoids an anchor on an unselected track.
63
64 /*
65 if (selected) {
66 // This handles the case of linked tracks, selecting all channels
67 mTracks->Select(pTrack, true);
68 if (updateLastPicked)
69 mLastPickedTrack = Track::Pointer( pTrack );
70 }
71 else {
72 mTracks->Select(pTrack, false);
73 if (updateLastPicked && pTrack == mLastPickedTrack.lock().get())
74 mLastPickedTrack.reset();
75 }
76*/
77}
78
80( TrackList &tracks, Track &rsTrack, Track &reTrack )
81{
82 Track *sTrack = &rsTrack, *eTrack = &reTrack;
83 // Swap the track pointers if needed
84 if (eTrack->GetIndex() < sTrack->GetIndex())
85 std::swap(sTrack, eTrack);
86
87 for (auto track :
88 tracks.Any().StartingWith(sTrack).EndingAfter(eTrack))
89 SelectTrack(*track, true, false);
90}
91
93{
94 for (auto t : tracks.Any())
95 SelectTrack( *t, false, false );
96}
97
99( TrackList &tracks, Track &track )
100{
101 // We will either extend from the first or from the last.
102 auto pExtendFrom = tracks.Lock(mLastPickedTrack);
103
104 if( !pExtendFrom ) {
105 auto trackRange = tracks.Selected();
106 auto pFirst = *trackRange.begin();
107
108 // If our track is at or after the first, extend from the first.
109 if( pFirst && track.GetIndex() >= pFirst->GetIndex() )
110 pExtendFrom = pFirst->SharedPointer();
111
112 // Our track was earlier than the first. Extend from the last.
113 if( !pExtendFrom )
114 pExtendFrom = Track::SharedPointer( *trackRange.rbegin() );
115 }
116
117 SelectNone( tracks );
118 if( pExtendFrom )
119 SelectRangeOfTracks( tracks, track, *pExtendFrom );
120 else
121 SelectTrack( track, true, true );
122 mLastPickedTrack = pExtendFrom;
123}
124
126( TrackList &tracks, ViewInfo &viewInfo,
127 Track &track, bool shift, bool ctrl, bool syncLocked )
128{
129 // AS: If the shift button is being held down, invert
130 // the selection on this track.
131 if (ctrl)
132 SelectTrack( track, !track.GetSelected(), true );
133 else {
134 if (shift && mLastPickedTrack.lock())
135 ChangeSelectionOnShiftClick( tracks, track );
136 else {
137 SelectNone( tracks );
138 SelectTrack( track, true, true );
139 SelectTrackLength( viewInfo, track, syncLocked );
140 }
141 }
142}
143
145( SelectionState &state, TrackList &tracks )
146 : mpState{ &state }
147 , mTracks{ tracks }
148 , mInitialLastPickedTrack{ state.mLastPickedTrack }
149{
150 // Save initial state of track selections
151 const auto range = tracks.Leaders();
153 mInitialTrackSelection.reserve(range.size());
154 for (const auto track : range) {
155 const bool isSelected = track->GetSelected();
156 mInitialTrackSelection.push_back(isSelected);
157 }
158}
159
161{
162 if ( mpState ) {
163 // roll back changes
165 std::vector<bool>::const_iterator
166 it = mInitialTrackSelection.begin(),
168
169 for (auto track : mTracks.Leaders()) {
170 if (it == end)
171 break;
172 track->SetSelected( *it++ );
173 }
174 }
175}
176
178{
179 mpState = nullptr;
180}
static const AudacityProject::AttachedObjects::RegisteredFactory key
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
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:266
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 *pTrack)
Definition: SyncLock.cpp:161
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:162
bool GetSelected() const
Selectedness is always the same for all channels of a group.
Definition: Track.cpp:82
virtual void SetSelected(bool s)
Definition: Track.cpp:87
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:232
virtual double GetOffset() const =0
virtual double GetEndTime() const =0
int GetIndex() const
Definition: Track.cpp:138
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1212
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:1485
auto Leaders() -> TrackIterRange< TrackType >
Definition: Track.h:1347
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1313
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1330
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1417
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:219
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:752