Audacity  3.0.3
SelectMenus.cpp
Go to the documentation of this file.
1 
2 
3 #include "../AdornedRulerPanel.h"
4 #include "../AudioIO.h"
5 #include "../CommonCommandFlags.h"
6 #include "../SpectrumAnalyst.h"
7 #include "Prefs.h"
8 #include "Project.h"
9 #include "../ProjectAudioIO.h"
10 #include "../ProjectAudioManager.h"
11 #include "../ProjectHistory.h"
12 #include "ProjectRate.h"
13 #include "../ProjectSelectionManager.h"
14 #include "../ProjectSettings.h"
15 #include "../ProjectWindow.h"
16 #include "../ProjectWindows.h"
17 #include "../SelectUtilities.h"
18 #include "../TimeDialog.h"
19 #include "../TrackPanel.h"
20 #include "../WaveTrack.h"
21 #include "../commands/CommandContext.h"
22 #include "../commands/CommandManager.h"
23 #include "../toolbars/ControlToolBar.h"
24 #include "../tracks/ui/SelectHandle.h"
25 #include "../tracks/playabletrack/wavetrack/ui/WaveTrackView.h"
26 #include "../tracks/playabletrack/wavetrack/ui/WaveTrackViewConstants.h"
27 
28 // private helper classes and functions
29 namespace {
30 
31 void DoNextPeakFrequency(AudacityProject &project, bool up)
32 {
33  auto &tracks = TrackList::Get( project );
34  auto &viewInfo = ViewInfo::Get( project );
35 
36  // Find the first selected wave track that is in a spectrogram view.
37  const WaveTrack *pTrack {};
38  for ( auto wt : tracks.Selected< const WaveTrack >() ) {
39  const auto displays = WaveTrackView::Get( *wt ).GetDisplays();
40  bool hasSpectrum = (displays.end() != std::find(
41  displays.begin(), displays.end(),
42  WaveTrackSubView::Type{ WaveTrackViewConstants::Spectrum, {} }
43  ) );
44  if ( hasSpectrum ) {
45  pTrack = wt;
46  break;
47  }
48  }
49 
50  if (pTrack) {
51  SpectrumAnalyst analyst;
52  SelectHandle::SnapCenterOnce(analyst, viewInfo, pTrack, up);
53  ProjectHistory::Get( project ).ModifyState(false);
54  }
55 }
56 
58 (AudacityProject &project, double t0)
59 {
60  auto rate = ProjectRate::Get(project).GetRate();
61  auto &tracks = TrackList::Get( project );
62 
63  // Window is 1/100th of a second.
64  auto windowSize = size_t(std::max(1.0, rate / 100));
65  Floats dist{ windowSize, true };
66 
67  int nTracks = 0;
68  for (auto one : tracks.Selected< const WaveTrack >()) {
69  auto oneWindowSize = size_t(std::max(1.0, one->GetRate() / 100));
70  Floats oneDist{ oneWindowSize };
71  auto s = one->TimeToLongSamples(t0);
72  // fillTwo to ensure that missing values are treated as 2, and hence do
73  // not get used as zero crossings.
74  one->GetFloats(oneDist.get(),
75  s - (int)oneWindowSize/2, oneWindowSize, fillTwo);
76 
77 
78  // Looking for actual crossings.
79  double prev = 2.0;
80  for(size_t i=0; i<oneWindowSize; i++){
81  float fDist = fabs( oneDist[i]); // score is absolute value
82  if( prev * oneDist[i] > 0 ) // both same sign? No good.
83  fDist = fDist + 0.4; // No good if same sign.
84  else if( prev > 0.0 )
85  fDist = fDist + 0.1; // medium penalty for downward crossing.
86  prev = oneDist[i];
87  oneDist[i] = fDist;
88  }
89 
90  // TODO: The mixed rate zero crossing code is broken,
91  // if oneWindowSize > windowSize we'll miss out some
92  // samples - so they will still be zero, so we'll use them.
93  for(size_t i = 0; i < windowSize; i++) {
94  size_t j;
95  if (windowSize != oneWindowSize)
96  j = i * (oneWindowSize-1) / (windowSize-1);
97  else
98  j = i;
99 
100  dist[i] += oneDist[j];
101  // Apply a small penalty for distance from the original endpoint
102  // We'll always prefer an upward
103  dist[i] +=
104  0.1 * (abs(int(i) - int(windowSize/2))) / float(windowSize/2);
105  }
106  nTracks++;
107  }
108 
109  // Find minimum
110  int argmin = 0;
111  float min = 3.0;
112  for(size_t i=0; i<windowSize; i++) {
113  if (dist[i] < min) {
114  argmin = i;
115  min = dist[i];
116  }
117  }
118 
119  // If we're worse than 0.2 on average, on one track, then no good.
120  if(( nTracks == 1 ) && ( min > (0.2*nTracks) ))
121  return t0;
122  // If we're worse than 0.6 on average, on multi-track, then no good.
123  if(( nTracks > 1 ) && ( min > (0.6*nTracks) ))
124  return t0;
125 
126  return t0 + (argmin - (int)windowSize/2) / rate;
127 }
128 
129 // If this returns true, then there was a key up, and nothing more to do,
130 // after this function has completed.
131 // (at most this function just does a ModifyState for the keyup)
132 bool OnlyHandleKeyUp( const CommandContext &context )
133 {
134  auto &project = context.project;
135  auto evt = context.pEvt;
136  bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP;
137 
138  if( ProjectAudioIO::Get( project ).IsAudioActive() )
139  return bKeyUp;
140  if( !bKeyUp )
141  return false;
142 
143  ProjectHistory::Get( project ).ModifyState(false);
144  return true;
145 }
146 
149  DIRECTION_RIGHT = +1
150 };
151 
156 };
157 
158 enum TimeUnit {
161 };
162 
163 struct SeekInfo
164 {
165  wxLongLong mLastSelectionAdjustment { ::wxGetUTCTimeMillis() };
166  double mSeekShort{ 0.0 };
167  double mSeekLong{ 0.0 };
168 };
169 
170 void SeekWhenAudioActive(double seekStep, wxLongLong &lastSelectionAdjustment)
171 {
172  auto gAudioIO = AudioIO::Get();
173 #ifdef EXPERIMENTAL_IMPROVED_SEEKING
174  if (gAudioIO->GetLastPlaybackTime() < lastSelectionAdjustment) {
175  // Allow time for the last seek to output a buffer before
176  // discarding samples again
177  // Do not advance mLastSelectionAdjustment
178  return;
179  }
180 #endif
181  lastSelectionAdjustment = ::wxGetUTCTimeMillis();
182 
183  gAudioIO->SeekStream(seekStep);
184 }
185 
186 // Handles moving a selection edge with the keyboard in snap-to-time mode;
187 // returns the moved value.
188 // Will move at least minPix pixels -- set minPix positive to move forward,
189 // negative to move backward.
190 // Helper for moving by keyboard with snap-to-grid enabled
191 double GridMove
192 (AudacityProject &project, double t, int minPix)
193 {
194  auto &settings = ProjectSettings::Get(project);
195  auto rate = ProjectRate::Get(project).GetRate();
196  auto &viewInfo = ViewInfo::Get( project );
197  auto format = settings.GetSelectionFormat();
198 
200 
201  // Try incrementing/decrementing the value; if we've moved far enough we're
202  // done
203  double result;
204  minPix >= 0 ? nc.Increment() : nc.Decrement();
205  result = nc.GetValue();
206  if (std::abs(viewInfo.TimeToPosition(result) - viewInfo.TimeToPosition(t))
207  >= abs(minPix))
208  return result;
209 
210  // Otherwise, move minPix pixels, then snap to the time.
211  result = viewInfo.OffsetTimeByPixels(t, minPix);
212  nc.SetValue(result);
213  result = nc.GetValue();
214  return result;
215 }
216 
218 (AudacityProject &project,
219  double t, double offset, TimeUnit timeUnit, int snapToTime)
220 {
221  auto &viewInfo = ViewInfo::Get( project );
222 
223  if (timeUnit == TIME_UNIT_SECONDS)
224  return t + offset; // snapping is currently ignored for non-pixel moves
225 
226  if (snapToTime == SNAP_OFF)
227  return viewInfo.OffsetTimeByPixels(t, (int)offset);
228 
229  return GridMove(project, t, (int)offset);
230 }
231 
232 // Moving a cursor, and collapsed selection.
234 (AudacityProject &project, double seekStep, TimeUnit timeUnit)
235 {
236  auto &viewInfo = ViewInfo::Get( project );
237  auto &trackPanel = TrackPanel::Get( project );
238  auto &tracks = TrackList::Get( project );
239  auto &ruler = AdornedRulerPanel::Get( project );
240  const auto &settings = ProjectSettings::Get( project );
241  auto &window = ProjectWindow::Get( project );
242 
243  // If TIME_UNIT_SECONDS, snap-to will be off.
244  int snapToTime = settings.GetSnapTo();
245  const double t0 = viewInfo.selectedRegion.t0();
246  const double end = std::max(
247  tracks.GetEndTime(),
248  viewInfo.GetScreenEndTime());
249 
250  // Move the cursor
251  // Already in cursor mode?
252  if( viewInfo.selectedRegion.isPoint() )
253  {
254  double newT = OffsetTime(project,
255  t0, seekStep, timeUnit, snapToTime);
256  // constrain.
257  newT = std::max(0.0, newT);
258  newT = std::min(newT, end);
259  // Move
260  viewInfo.selectedRegion.setT0(
261  newT,
262  false); // do not swap selection boundaries
263  viewInfo.selectedRegion.collapseToT0();
264 
265  // Move the visual cursor, avoiding an unnecessary complete redraw
266  trackPanel.DrawOverlays(false);
267  ruler.DrawOverlays(false);
268  }
269  else
270  {
271  // Transition to cursor mode.
272  if( seekStep < 0 )
273  viewInfo.selectedRegion.collapseToT0();
274  else
275  viewInfo.selectedRegion.collapseToT1();
276  trackPanel.Refresh(false);
277  }
278 
279  // Make sure NEW position is in view
280  window.ScrollIntoView(viewInfo.selectedRegion.t1());
281  return;
282 }
283 
285 (AudacityProject &project, double seekStep, TimeUnit timeUnit,
286 SelectionOperation operation)
287 {
288  auto &viewInfo = ViewInfo::Get( project );
289  auto &tracks = TrackList::Get( project );
290  const auto &settings = ProjectSettings::Get( project );
291  auto &window = ProjectWindow::Get( project );
292 
293  if( operation == CURSOR_MOVE )
294  {
295  MoveWhenAudioInactive( project, seekStep, timeUnit);
296  return;
297  }
298 
299  int snapToTime = settings.GetSnapTo();
300  const double t0 = viewInfo.selectedRegion.t0();
301  const double t1 = viewInfo.selectedRegion.t1();
302  const double end = std::max(
303  tracks.GetEndTime(),
304  viewInfo.GetScreenEndTime());
305 
306  // Is it t0 or t1 moving?
307  bool bMoveT0 = (operation == SELECTION_CONTRACT && seekStep > 0) ||
308  (operation == SELECTION_EXTEND && seekStep < 0);
309  // newT is where we want to move to
310  double newT = OffsetTime( project,
311  bMoveT0 ? t0 : t1, seekStep, timeUnit, snapToTime);
312  // constrain to be in the track/screen limits.
313  newT = std::max( 0.0, newT );
314  newT = std::min( newT, end);
315  // optionally constrain to be a contraction, i.e. so t0/t1 do not cross over
316  if( operation == SELECTION_CONTRACT )
317  newT = bMoveT0 ? std::min( t1, newT ) : std::max( t0, newT );
318 
319  // Actually move
320  if( bMoveT0 )
321  viewInfo.selectedRegion.setT0( newT );
322  else
323  viewInfo.selectedRegion.setT1( newT );
324 
325  // Ensure it is visible
326  window.ScrollIntoView(newT);
327 }
328 
329 // Handle small cursor and play head movements
331 (AudacityProject &project, double direction, SelectionOperation operation,
332  SeekInfo &info)
333 {
334  // PRL: What I found and preserved, strange though it be:
335  // During playback: jump depends on preferences and is independent of the
336  // zoom and does not vary if the key is held
337  // Else: jump depends on the zoom and gets bigger if the key is held
338 
339  if( ProjectAudioIO::Get( project ).IsAudioActive() )
340  {
341  if( operation == CURSOR_MOVE )
342  SeekWhenAudioActive( info.mSeekShort * direction,
344  else if( operation == SELECTION_EXTEND )
345  SeekWhenAudioActive( info.mSeekLong * direction,
347  // Note: no action for CURSOR_CONTRACT
348  return;
349  }
350 
351  // If the last adjustment was very recent, we are
352  // holding the key down and should move faster.
353  const wxLongLong curtime = ::wxGetUTCTimeMillis();
354  enum { MIN_INTERVAL = 50 };
355  const bool fast =
356  (curtime - info.mLastSelectionAdjustment < MIN_INTERVAL);
357 
358  info.mLastSelectionAdjustment = curtime;
359 
360  // How much faster should the cursor move if shift is down?
361  enum { LARGER_MULTIPLIER = 4 };
362  const double seekStep = (fast ? LARGER_MULTIPLIER : 1.0) * direction;
363 
364  SeekWhenAudioInactive( project, seekStep, TIME_UNIT_PIXELS, operation);
365 }
366 
367 // Move the cursor forward or backward, while paused or while playing.
369  AudacityProject &project, double seekStep,
370  wxLongLong &lastSelectionAdjustment)
371 {
372  if (ProjectAudioIO::Get( project ).IsAudioActive()) {
373  SeekWhenAudioActive(seekStep, lastSelectionAdjustment);
374  }
375  else
376  {
377  lastSelectionAdjustment = ::wxGetUTCTimeMillis();
378  MoveWhenAudioInactive(project, seekStep, TIME_UNIT_SECONDS);
379  }
380 
381  ProjectHistory::Get( project ).ModifyState(false);
382 }
383 
384 void DoBoundaryMove(AudacityProject &project, int step, SeekInfo &info)
385 {
386  auto &viewInfo = ViewInfo::Get( project );
387  auto &tracks = TrackList::Get( project );
388  auto &window = ProjectWindow::Get( project );
389 
390  // step is negative, then is moving left. step positive, moving right.
391  // Move the left/right selection boundary, to expand the selection
392 
393  // If the last adjustment was very recent, we are
394  // holding the key down and should move faster.
395  wxLongLong curtime = ::wxGetUTCTimeMillis();
396  int pixels = step;
397  if( curtime - info.mLastSelectionAdjustment < 50 )
398  {
399  pixels *= 4;
400  }
401  info.mLastSelectionAdjustment = curtime;
402 
403  // we used to have a parameter boundaryContract to say if expanding or
404  // contracting. it is no longer needed.
405  bool bMoveT0 = (step < 0 );// ^ boundaryContract ;
406 
407  if( ProjectAudioIO::Get( project ).IsAudioActive() )
408  {
409  auto gAudioIO = AudioIO::Get();
410  double indicator = gAudioIO->GetStreamTime();
411  if( bMoveT0 )
412  viewInfo.selectedRegion.setT0(indicator, false);
413  else
414  viewInfo.selectedRegion.setT1(indicator);
415 
416  ProjectHistory::Get( project ).ModifyState(false);
417  return;
418  }
419 
420  const double t0 = viewInfo.selectedRegion.t0();
421  const double t1 = viewInfo.selectedRegion.t1();
422  const double end = std::max(
423  tracks.GetEndTime(),
424  viewInfo.GetScreenEndTime());
425 
426  double newT = viewInfo.OffsetTimeByPixels( bMoveT0 ? t0 : t1, pixels);
427  // constrain to be in the track/screen limits.
428  newT = std::max( 0.0, newT );
429  newT = std::min( newT, end);
430  // optionally constrain to be a contraction, i.e. so t0/t1 do not cross over
431  //if( boundaryContract )
432  // newT = bMoveT0 ? std::min( t1, newT ) : std::max( t0, newT );
433 
434  // Actually move
435  if( bMoveT0 )
436  viewInfo.selectedRegion.setT0( newT );
437  else
438  viewInfo.selectedRegion.setT1( newT );
439 
440  // Ensure it is visible
441  window.ScrollIntoView(newT);
442 
443  ProjectHistory::Get( project ).ModifyState(false);
444 }
445 
446 }
447 
448 namespace SelectActions {
449 
450 
451 // Menu handler functions
452 
453 struct Handler
454  : CommandHandlerObject // MUST be the first base class!
456  , PrefsListener
457 {
458 
459 void OnSelectAll(const CommandContext &context)
460 {
462 }
463 
464 void OnSelectNone(const CommandContext &context)
465 {
466  auto &project = context.project;
467  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
468 
469  selectedRegion.collapseToT0();
470  SelectUtilities::SelectNone( project );
471  ProjectHistory::Get( project ).ModifyState(false);
472 }
473 
474 void OnSelectAllTracks(const CommandContext &context)
475 {
476  auto &project = context.project;
477  SelectUtilities::DoSelectTimeAndTracks( project, false, true );
478 }
479 
481 {
482  auto &project = context.project;
483  auto &tracks = TrackList::Get( project );
484 
485  bool selected = false;
486  for (auto t : tracks.Any() + &Track::SupportsBasicEditing
488  t->SetSelected(true);
489  selected = true;
490  }
491 
492  if (selected)
493  ProjectHistory::Get( project ).ModifyState(false);
494 }
495 
496 //this pops up a dialog which allows the left selection to be set.
497 //If playing/recording is happening, it sets the left selection at
498 //the current play position.
499 void OnSetLeftSelection(const CommandContext &context)
500 {
501  auto &project = context.project;
502  auto token = ProjectAudioIO::Get( project ).GetAudioIOToken();
503  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
504  const auto &settings = ProjectSettings::Get( project );
505  auto &window = GetProjectFrame( project );
506 
507  bool bSelChanged = false;
508  auto gAudioIO = AudioIO::Get();
509  if ((token > 0) && gAudioIO->IsStreamActive(token))
510  {
511  double indicator = gAudioIO->GetStreamTime();
512  selectedRegion.setT0(indicator, false);
513  bSelChanged = true;
514  }
515  else
516  {
517  auto fmt = settings.GetSelectionFormat();
518  auto rate = ProjectRate::Get(project).GetRate();
519 
520  TimeDialog dlg(&window, XO("Set Left Selection Boundary"),
521  fmt, rate, selectedRegion.t0(), XO("Position"));
522 
523  if (wxID_OK == dlg.ShowModal())
524  {
525  //Get the value from the dialog
526  selectedRegion.setT0(
527  std::max(0.0, dlg.GetTimeValue()), false);
528  bSelChanged = true;
529  }
530  }
531 
532  if (bSelChanged)
533  {
534  ProjectHistory::Get( project ).ModifyState(false);
535  }
536 }
537 
539 {
540  auto &project = context.project;
541  auto token = ProjectAudioIO::Get( project ).GetAudioIOToken();
542  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
543  const auto &settings = ProjectSettings::Get( project );
544  auto &window = GetProjectFrame( project );
545 
546  bool bSelChanged = false;
547  auto gAudioIO = AudioIO::Get();
548  if ((token > 0) && gAudioIO->IsStreamActive(token))
549  {
550  double indicator = gAudioIO->GetStreamTime();
551  selectedRegion.setT1(indicator, false);
552  bSelChanged = true;
553  }
554  else
555  {
556  auto fmt = settings.GetSelectionFormat();
557  auto rate = ProjectRate::Get(project).GetRate();
558 
559  TimeDialog dlg(&window, XO("Set Right Selection Boundary"),
560  fmt, rate, selectedRegion.t1(), XO("Position"));
561 
562  if (wxID_OK == dlg.ShowModal())
563  {
564  //Get the value from the dialog
565  selectedRegion.setT1(
566  std::max(0.0, dlg.GetTimeValue()), false);
567  bSelChanged = true;
568  }
569  }
570 
571  if (bSelChanged)
572  {
573  ProjectHistory::Get( project ).ModifyState(false);
574  }
575 }
576 
578 {
579  auto &project = context.project;
580  auto &tracks = TrackList::Get( project );
581  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
582 
583  double kWayOverToRight = std::numeric_limits<double>::max();
584 
585  auto range = tracks.Selected();
586  if ( ! range )
587  return;
588 
589  double minOffset = range.min( &Track::GetStartTime );
590 
591  if( minOffset >=
592  (kWayOverToRight * (1 - std::numeric_limits<double>::epsilon()) ))
593  return;
594 
595  selectedRegion.setT0(minOffset);
596 
597  ProjectHistory::Get( project ).ModifyState(false);
598 }
599 
600 void OnSelectCursorEnd(const CommandContext &context)
601 {
602  auto &project = context.project;
603  auto &tracks = TrackList::Get( project );
604  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
605 
606  double kWayOverToLeft = std::numeric_limits<double>::lowest();
607 
608  auto range = tracks.Selected();
609  if ( ! range )
610  return;
611 
612  double maxEndOffset = range.max( &Track::GetEndTime );
613 
614  if( maxEndOffset <=
615  (kWayOverToLeft * (1 - std::numeric_limits<double>::epsilon()) ))
616  return;
617 
618  selectedRegion.setT1(maxEndOffset);
619 
620  ProjectHistory::Get( project ).ModifyState(false);
621 }
622 
624 {
625  auto &project = context.project;
626  auto &viewInfo = ViewInfo::Get( project );
627  auto &tracks = TrackList::Get( project );
628 
629  auto range = tracks.Selected();
630  double maxEndOffset = range.max( &Track::GetEndTime );
631  double minOffset = range.min( &Track::GetStartTime );
632 
633  if( maxEndOffset < minOffset)
634  return;
635 
636  viewInfo.selectedRegion.setTimes( minOffset, maxEndOffset );
637  ProjectHistory::Get( project ).ModifyState(false);
638 }
639 
640 // Handler state:
642 
643 void OnSelectionSave(const CommandContext &context)
644 {
645  auto &project = context.project;
646  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
647 
648  mRegionSave = selectedRegion;
649 }
650 
651 void OnSelectionRestore(const CommandContext &context)
652 {
653  auto &project = context.project;
654  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
655  auto &window = ProjectWindow::Get(project);
656 
657  if ((mRegionSave.t0() == 0.0) &&
658  (mRegionSave.t1() == 0.0))
659  return;
660 
661  selectedRegion = mRegionSave;
662  window.ScrollIntoView(selectedRegion.t0());
663 
664  ProjectHistory::Get( project ).ModifyState(false);
665 }
666 
667 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
668 
669 // Handler state:
670 double mLastF0{ SelectedRegion::UndefinedFrequency };
671 double mLastF1{ SelectedRegion::UndefinedFrequency };
672 
673 void OnToggleSpectralSelection(const CommandContext &context)
674 {
675  auto &project = context.project;
676  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
677 
678  const double f0 = selectedRegion.f0();
679  const double f1 = selectedRegion.f1();
680  const bool haveSpectralSelection =
683  if (haveSpectralSelection)
684  {
685  mLastF0 = f0;
686  mLastF1 = f1;
687  selectedRegion.setFrequencies
689  }
690  else
691  selectedRegion.setFrequencies(mLastF0, mLastF1);
692 
693  ProjectHistory::Get( project ).ModifyState(false);
694 }
695 
696 void OnNextHigherPeakFrequency(const CommandContext &context)
697 {
698  auto &project = context.project;
699  DoNextPeakFrequency(project, true);
700 }
701 
702 void OnNextLowerPeakFrequency(const CommandContext &context)
703 {
704  auto &project = context.project;
705  DoNextPeakFrequency(project, false);
706 }
707 #endif
708 
709 // Handler state:
711 double mCursorPositionStored{ 0.0 };
712 
714 {
715  auto &project = context.project;
716  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
717  auto isAudioActive = ProjectAudioIO::Get( project ).IsAudioActive();
718 
720  auto gAudioIO = AudioIO::Get();
721  double cursorPositionCurrent = isAudioActive
722  ? gAudioIO->GetStreamTime()
723  : selectedRegion.t0();
724  selectedRegion.setTimes(
725  std::min(cursorPositionCurrent, mCursorPositionStored),
726  std::max(cursorPositionCurrent, mCursorPositionStored));
727 
728  ProjectHistory::Get( project ).ModifyState(false);
729  }
730 }
731 
733 {
734  auto &project = context.project;
735  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
736  auto isAudioActive = ProjectAudioIO::Get( project ).IsAudioActive();
737 
738  auto gAudioIO = AudioIO::Get();
740  isAudioActive ? gAudioIO->GetStreamTime() : selectedRegion.t0();
742 }
743 
744 void OnZeroCrossing(const CommandContext &context)
745 {
746  auto &project = context.project;
747  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
748 
749  const double t0 = NearestZeroCrossing(project, selectedRegion.t0());
750  if (selectedRegion.isPoint())
751  selectedRegion.setTimes(t0, t0);
752  else {
753  const double t1 = NearestZeroCrossing(project, selectedRegion.t1());
754  // Empty selection is generally not much use, so do not make it if empty.
755  if( fabs( t1 - t0 ) * ProjectRate::Get(project).GetRate() > 1.5 )
756  selectedRegion.setTimes(t0, t1);
757  }
758 
759  ProjectHistory::Get( project ).ModifyState(false);
760 }
761 
762 void OnSnapToOff(const CommandContext &context)
763 {
764  auto &project = context.project;
766 }
767 
768 void OnSnapToNearest(const CommandContext &context)
769 {
770  auto &project = context.project;
772 }
773 
774 void OnSnapToPrior(const CommandContext &context)
775 {
776  auto &project = context.project;
778 }
779 
780 void OnSelToStart(const CommandContext &context)
781 {
782  auto &project = context.project;
783  auto &window = ProjectWindow::Get( project );
784  window.Rewind(true);
785  ProjectHistory::Get( project ).ModifyState(false);
786 }
787 
788 void OnSelToEnd(const CommandContext &context)
789 {
790  auto &project = context.project;
791  auto &window = ProjectWindow::Get( project );
792  window.SkipEnd(true);
793  ProjectHistory::Get( project ).ModifyState(false);
794 }
795 
796 // Handler state:
797 SeekInfo mSeekInfo;
798 
799 void OnSelExtendLeft(const CommandContext &context)
800 {
801  if( !OnlyHandleKeyUp( context ) )
803  mSeekInfo );
804 }
805 
806 void OnSelExtendRight(const CommandContext &context)
807 {
808  if( !OnlyHandleKeyUp( context ) )
810  mSeekInfo );
811 }
812 
813 void OnSelSetExtendLeft(const CommandContext &context)
814 {
816 }
817 
819 {
821 }
822 
823 void OnSelContractLeft(const CommandContext &context)
824 {
825  if( !OnlyHandleKeyUp( context ) )
827  mSeekInfo );
828 }
829 
830 void OnSelContractRight(const CommandContext &context)
831 {
832  if( !OnlyHandleKeyUp( context ) )
834  mSeekInfo );
835 }
836 
837 void OnCursorSelStart(const CommandContext &context)
838 {
839  auto &project = context.project;
840  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
841  auto &window = ProjectWindow::Get( project );
842 
843  selectedRegion.collapseToT0();
844  ProjectHistory::Get( project ).ModifyState(false);
845  window.ScrollIntoView(selectedRegion.t0());
846 }
847 
848 void OnCursorSelEnd(const CommandContext &context)
849 {
850  auto &project = context.project;
851  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
852  auto &window = ProjectWindow::Get( project );
853 
854  selectedRegion.collapseToT1();
855  ProjectHistory::Get( project ).ModifyState(false);
856  window.ScrollIntoView(selectedRegion.t1());
857 }
858 
859 void OnCursorTrackStart(const CommandContext &context)
860 {
861  auto &project = context.project;
862  auto &tracks = TrackList::Get( project );
863  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
864  auto &window = ProjectWindow::Get( project );
865 
866  double kWayOverToRight = std::numeric_limits<double>::max();
867 
868  auto trackRange = tracks.Selected() + &Track::SupportsBasicEditing;
869  if (trackRange.empty())
870  // This should have been prevented by command manager
871  return;
872 
873  // Range is surely nonempty now
874  auto minOffset = std::max( 0.0, trackRange.min( &Track::GetOffset ) );
875 
876  if( minOffset >=
877  (kWayOverToRight * (1 - std::numeric_limits<double>::epsilon()) ))
878  return;
879 
880  selectedRegion.setTimes(minOffset, minOffset);
881  ProjectHistory::Get( project ).ModifyState(false);
882  window.ScrollIntoView(selectedRegion.t0());
883 }
884 
885 void OnCursorTrackEnd(const CommandContext &context)
886 {
887  auto &project = context.project;
888  auto &tracks = TrackList::Get( project );
889  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
890  auto &window = ProjectWindow::Get( project );
891 
892  double kWayOverToLeft = std::numeric_limits<double>::lowest();
893 
894  auto trackRange = tracks.Selected() + &Track::SupportsBasicEditing;
895  if (trackRange.empty())
896  // This should have been prevented by command manager
897  return;
898 
899  // Range is surely nonempty now
900  auto maxEndOffset = trackRange.max( &Track::GetEndTime );
901 
902  if( maxEndOffset <
903  (kWayOverToLeft * (1 - std::numeric_limits<double>::epsilon()) ))
904  return;
905 
906  selectedRegion.setTimes(maxEndOffset, maxEndOffset);
907  ProjectHistory::Get( project ).ModifyState(false);
908  window.ScrollIntoView(selectedRegion.t1());
909 }
910 
911 void OnSkipStart(const CommandContext &context)
912 {
913  auto &project = context.project;
914  wxCommandEvent evt;
915 
916  auto &controlToolBar = ControlToolBar::Get( project );
917  controlToolBar.OnRewind(evt);
918  ProjectHistory::Get( project ).ModifyState(false);
919 }
920 
921 void OnSkipEnd(const CommandContext &context)
922 {
923  auto &project = context.project;
924  wxCommandEvent evt;
925 
926  auto &controlToolBar = ControlToolBar::Get( project );
927  controlToolBar.OnFF(evt);
928  ProjectHistory::Get( project ).ModifyState(false);
929 }
930 
931 void OnCursorLeft(const CommandContext &context)
932 {
933  if( !OnlyHandleKeyUp( context ) )
935  mSeekInfo );
936 }
937 
938 void OnCursorRight(const CommandContext &context)
939 {
940  if( !OnlyHandleKeyUp( context ) )
942  mSeekInfo );
943 }
944 
946 {
947  DoCursorMove( context.project,
948  -mSeekInfo.mSeekShort, mSeekInfo.mLastSelectionAdjustment );
949 }
950 
952 {
953  DoCursorMove( context.project,
954  mSeekInfo.mSeekShort, mSeekInfo.mLastSelectionAdjustment );
955 }
956 
958 {
959  DoCursorMove( context.project,
960  -mSeekInfo.mSeekLong, mSeekInfo.mLastSelectionAdjustment );
961 }
962 
964 {
965  DoCursorMove( context.project,
966  mSeekInfo.mSeekLong, mSeekInfo.mLastSelectionAdjustment );
967 }
968 
969 void OnSeekLeftShort(const CommandContext &context)
970 {
971  auto &project = context.project;
973 }
974 
975 void OnSeekRightShort(const CommandContext &context)
976 {
977  auto &project = context.project;
979 }
980 
981 void OnSeekLeftLong(const CommandContext &context)
982 {
983  auto &project = context.project;
985 }
986 
987 void OnSeekRightLong(const CommandContext &context)
988 {
989  auto &project = context.project;
991 }
992 
993 #if 1
994 // Legacy functions, not used as of version 2.3.0
995 void OnSelectAllTime(const CommandContext &context)
996 {
997  auto &project = context.project;
998  SelectUtilities::DoSelectTimeAndTracks( project, true, false );
999 }
1000 #endif
1001 
1002 void UpdatePrefs() override
1003 {
1004  gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &mSeekInfo.mSeekShort, 1.0);
1005  gPrefs->Read(wxT("/AudioIO/SeekLongPeriod"), &mSeekInfo.mSeekLong, 15.0);
1006 }
1008 {
1009  UpdatePrefs();
1010 }
1011 Handler( const Handler & ) PROHIBITED;
1012 Handler &operator=( const Handler & ) PROHIBITED;
1013 
1014 }; // struct Handler
1015 
1016 } // namespace
1017 
1018 // Handler is stateful. Needs a factory registered with
1019 // AudacityProject.
1021  [](AudacityProject&) {
1022  return std::make_unique< SelectActions::Handler >(); } };
1023 
1025  return project.AttachedObjects::Get< SelectActions::Handler >( key );
1026 };
1027 
1028 // Menu definitions
1029 
1030 #define FN(X) (& SelectActions::Handler :: X)
1031 
1032 namespace {
1033 using namespace MenuTable;
1035 {
1037  static BaseItemSharedPtr menu{
1039  /* i18n-hint: (verb) It's an item on a menu. */
1040  Menu( wxT("Select"), XXO("&Select"),
1041  Section( "Basic",
1042  Command( wxT("SelectAll"), XXO("&All"), FN(OnSelectAll),
1043  TracksExistFlag(),
1044  Options{ wxT("Ctrl+A"), XO("Select All") } ),
1045  Command( wxT("SelectNone"), XXO("&None"), FN(OnSelectNone),
1046  TracksExistFlag(),
1047  Options{ wxT("Ctrl+Shift+A"), XO("Select None") } ),
1048 
1050 
1051  Menu( wxT("Tracks"), XXO("&Tracks"),
1052  Command( wxT("SelAllTracks"), XXO("In All &Tracks"),
1053  FN(OnSelectAllTracks),
1054  TracksExistFlag(),
1055  wxT("Ctrl+Shift+K") )
1056 
1057  #ifdef EXPERIMENTAL_SYNC_LOCK
1058  ,
1059  Command( wxT("SelSyncLockTracks"), XXO("In All &Sync-Locked Tracks"),
1060  FN(OnSelectSyncLockSel),
1062  Options{ wxT("Ctrl+Shift+Y"), XO("Select Sync-Locked") } )
1063  #endif
1064  ),
1065 
1067 
1068  Menu( wxT("Region"), XXO("R&egion"),
1069  Section( "",
1070  Command( wxT("SetLeftSelection"), XXO("&Left at Playback Position"),
1071  FN(OnSetLeftSelection), TracksExistFlag(),
1072  Options{ wxT("["), XO("Set Selection Left at Play Position") } ),
1073  Command( wxT("SetRightSelection"), XXO("&Right at Playback Position"),
1074  FN(OnSetRightSelection), TracksExistFlag(),
1075  Options{ wxT("]"), XO("Set Selection Right at Play Position") } ),
1076  Command( wxT("SelTrackStartToCursor"), XXO("Track &Start to Cursor"),
1077  FN(OnSelectStartCursor), AlwaysEnabledFlag,
1078  Options{ wxT("Shift+J"), XO("Select Track Start to Cursor") } ),
1079  Command( wxT("SelCursorToTrackEnd"), XXO("Cursor to Track &End"),
1080  FN(OnSelectCursorEnd), AlwaysEnabledFlag,
1081  Options{ wxT("Shift+K"), XO("Select Cursor to Track End") } ),
1082  Command( wxT("SelTrackStartToEnd"), XXO("Track Start to En&d"),
1083  FN(OnSelectTrackStartToEnd), AlwaysEnabledFlag,
1084  Options{}.LongName( XO("Select Track Start to End") ) )
1085  ),
1086 
1087  Section( "",
1088  // GA: Audacity had 'Store Re&gion' here previously. There is no
1089  // one-step way to restore the 'Saved Cursor Position' in Select Menu,
1090  // so arguably using the word 'Selection' to do duty for both saving
1091  // the region or the cursor is better. But it does not belong in a
1092  // 'Region' submenu.
1093  Command( wxT("SelSave"), XXO("S&tore Selection"), FN(OnSelectionSave),
1095  // Audacity had 'Retrieve Regio&n' here previously.
1096  Command( wxT("SelRestore"), XXO("Retrieve Selectio&n"),
1097  FN(OnSelectionRestore), TracksExistFlag() )
1098  )
1099  ),
1100 
1102 
1103  #ifdef EXPERIMENTAL_SPECTRAL_EDITING
1104  Menu( wxT("Spectral"), XXO("S&pectral"),
1105  Command( wxT("ToggleSpectralSelection"),
1106  XXO("To&ggle Spectral Selection"), FN(OnToggleSpectralSelection),
1107  TracksExistFlag(), wxT("Q") ),
1108  Command( wxT("NextHigherPeakFrequency"),
1109  XXO("Next &Higher Peak Frequency"), FN(OnNextHigherPeakFrequency),
1110  TracksExistFlag() ),
1111  Command( wxT("NextLowerPeakFrequency"),
1112  XXO("Next &Lower Peak Frequency"), FN(OnNextLowerPeakFrequency),
1113  TracksExistFlag() )
1114  )
1115  #endif
1116  ),
1117 
1118  Section( "",
1119  Command( wxT("SelCursorStoredCursor"),
1120  XXO("Cursor to Stored &Cursor Position"),
1121  FN(OnSelectCursorStoredCursor), TracksExistFlag(),
1122  Options{}.LongName( XO("Select Cursor to Stored") ) ),
1123 
1124  Command( wxT("StoreCursorPosition"), XXO("Store Cursor Pos&ition"),
1125  FN(OnCursorPositionStore),
1127  // Save cursor position is used in some selections.
1128  // Maybe there should be a restore for it?
1129  ),
1130 
1131  Section( "",
1132  Command( wxT("ZeroCross"), XXO("At &Zero Crossings"),
1133  FN(OnZeroCrossing), EditableTracksSelectedFlag(),
1134  Options{ wxT("Z"), XO("Select Zero Crossing") } )
1135  )
1136  ) ) };
1137  return menu;
1138 }
1139 
1141  wxT(""),
1142  Shared( SelectMenu() )
1143 };
1144 
1146 {
1148  static BaseItemSharedPtr menu{
1150  Menu( wxT("Select"), XXO("&Selection"),
1151  Command( wxT("SnapToOff"), XXO("Snap-To &Off"), FN(OnSnapToOff),
1153  Command( wxT("SnapToNearest"), XXO("Snap-To &Nearest"),
1154  FN(OnSnapToNearest), AlwaysEnabledFlag ),
1155  Command( wxT("SnapToPrior"), XXO("Snap-To &Prior"), FN(OnSnapToPrior),
1157  Command( wxT("SelStart"), XXO("Selection to &Start"), FN(OnSelToStart),
1158  AlwaysEnabledFlag, wxT("Shift+Home") ),
1159  Command( wxT("SelEnd"), XXO("Selection to En&d"), FN(OnSelToEnd),
1160  AlwaysEnabledFlag, wxT("Shift+End") ),
1161  Command( wxT("SelExtLeft"), XXO("Selection Extend &Left"),
1162  FN(OnSelExtendLeft),
1164  Options{ wxT("Shift+Left") }.WantKeyUp().AllowDup() ),
1165  Command( wxT("SelExtRight"), XXO("Selection Extend &Right"),
1166  FN(OnSelExtendRight),
1168  Options{ wxT("Shift+Right") }.WantKeyUp().AllowDup() ),
1169  Command( wxT("SelSetExtLeft"), XXO("Set (or Extend) Le&ft Selection"),
1170  FN(OnSelSetExtendLeft),
1172  Command( wxT("SelSetExtRight"), XXO("Set (or Extend) Rig&ht Selection"),
1173  FN(OnSelSetExtendRight),
1175  Command( wxT("SelCntrLeft"), XXO("Selection Contract L&eft"),
1176  FN(OnSelContractLeft),
1178  Options{ wxT("Ctrl+Shift+Right") }.WantKeyUp() ),
1179  Command( wxT("SelCntrRight"), XXO("Selection Contract R&ight"),
1180  FN(OnSelContractRight),
1182  Options{ wxT("Ctrl+Shift+Left") }.WantKeyUp() )
1183  ) ) };
1184  return menu;
1185 }
1186 
1188  wxT("Optional/Extra/Part1"),
1190 };
1191 }
1192 
1193 namespace {
1195 {
1197  static const auto CanStopFlags = AudioIONotBusyFlag() | CanStopAudioStreamFlag();
1198 
1199  // JKC: ANSWER-ME: How is 'cursor to' different to 'Skip To' and how is it
1200  // useful?
1201  // GA: 'Skip to' moves the viewpoint to center of the track and preserves the
1202  // selection. 'Cursor to' does neither. 'Center at' might describe it better
1203  // than 'Skip'.
1204  static BaseItemSharedPtr menu{
1206  Menu( wxT("Cursor"), XXO("&Cursor to"),
1207  Command( wxT("CursSelStart"), XXO("Selection Star&t"),
1208  FN(OnCursorSelStart),
1209  TimeSelectedFlag(),
1210  Options{}.LongName( XO("Cursor to Selection Start") ) ),
1211  Command( wxT("CursSelEnd"), XXO("Selection En&d"),
1212  FN(OnCursorSelEnd),
1213  TimeSelectedFlag(),
1214  Options{}.LongName( XO("Cursor to Selection End") ) ),
1215 
1216  Command( wxT("CursTrackStart"), XXO("Track &Start"),
1217  FN(OnCursorTrackStart),
1219  Options{ wxT("J"), XO("Cursor to Track Start") } ),
1220  Command( wxT("CursTrackEnd"), XXO("Track &End"),
1221  FN(OnCursorTrackEnd),
1223  Options{ wxT("K"), XO("Cursor to Track End") } ),
1224 
1225  Command( wxT("CursProjectStart"), XXO("&Project Start"),
1226  FN(OnSkipStart),
1227  CanStopFlags,
1228  Options{ wxT("Home"), XO("Cursor to Project Start") } ),
1229  Command( wxT("CursProjectEnd"), XXO("Project E&nd"), FN(OnSkipEnd),
1230  CanStopFlags,
1231  Options{ wxT("End"), XO("Cursor to Project End") } )
1232  ) ) };
1233  return menu;
1234 }
1235 
1237  wxT("Transport/Basic"),
1238  Shared( CursorMenu() )
1239 };
1240 
1242 {
1244  static BaseItemSharedPtr menu{
1246  Menu( wxT("Cursor"), XXO("&Cursor"),
1247  Command( wxT("CursorLeft"), XXO("Cursor &Left"), FN(OnCursorLeft),
1249  Options{ wxT("Left") }.WantKeyUp().AllowDup() ),
1250  Command( wxT("CursorRight"), XXO("Cursor &Right"), FN(OnCursorRight),
1252  Options{ wxT("Right") }.WantKeyUp().AllowDup() ),
1253  Command( wxT("CursorShortJumpLeft"), XXO("Cursor Sh&ort Jump Left"),
1254  FN(OnCursorShortJumpLeft),
1255  TracksExistFlag() | TrackPanelHasFocus(), wxT(",") ),
1256  Command( wxT("CursorShortJumpRight"), XXO("Cursor Shor&t Jump Right"),
1257  FN(OnCursorShortJumpRight),
1258  TracksExistFlag() | TrackPanelHasFocus(), wxT(".") ),
1259  Command( wxT("CursorLongJumpLeft"), XXO("Cursor Long J&ump Left"),
1260  FN(OnCursorLongJumpLeft),
1261  TracksExistFlag() | TrackPanelHasFocus(), wxT("Shift+,") ),
1262  Command( wxT("CursorLongJumpRight"), XXO("Cursor Long Ju&mp Right"),
1263  FN(OnCursorLongJumpRight),
1264  TracksExistFlag() | TrackPanelHasFocus(), wxT("Shift+.") )
1265  ) ) };
1266  return menu;
1267 }
1268 
1270  wxT("Optional/Extra/Part2"),
1271  Shared( ExtraCursorMenu() )
1272 };
1273 
1275 {
1277  static BaseItemSharedPtr menu{
1279  Menu( wxT("Seek"), XXO("See&k"),
1280  Command( wxT("SeekLeftShort"), XXO("Short Seek &Left During Playback"),
1281  FN(OnSeekLeftShort), AudioIOBusyFlag(),
1282  Options{ wxT("Left") }.AllowDup() ),
1283  Command( wxT("SeekRightShort"),
1284  XXO("Short Seek &Right During Playback"), FN(OnSeekRightShort),
1285  AudioIOBusyFlag(),
1286  Options{ wxT("Right") }.AllowDup() ),
1287  Command( wxT("SeekLeftLong"), XXO("Long Seek Le&ft During Playback"),
1288  FN(OnSeekLeftLong), AudioIOBusyFlag(),
1289  Options{ wxT("Shift+Left") }.AllowDup() ),
1290  Command( wxT("SeekRightLong"), XXO("Long Seek Rig&ht During Playback"),
1291  FN(OnSeekRightLong), AudioIOBusyFlag(),
1292  Options{ wxT("Shift+Right") }.AllowDup() )
1293  ) ) };
1294  return menu;
1295 }
1296 
1298  wxT("Optional/Extra/Part1"),
1299  Shared( ExtraSeekMenu() )
1300 };
1301 
1302 }
1303 
1304 #undef FN
anonymous_namespace{SelectMenus.cpp}::OnlyHandleKeyUp
bool OnlyHandleKeyUp(const CommandContext &context)
Definition: SelectMenus.cpp:132
ProjectHistory::ModifyState
void ModifyState(bool bWantsAutoSave)
Definition: ProjectHistory.cpp:124
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:161
SelectActions::Handler::OnCursorShortJumpLeft
void OnCursorShortJumpLeft(const CommandContext &context)
Definition: SelectMenus.cpp:945
ProjectAudioIO::GetAudioIOToken
int GetAudioIOToken() const
Definition: ProjectAudioIO.cpp:41
SelectActions::Handler::mCursorPositionHasBeenStored
bool mCursorPositionHasBeenStored
Definition: SelectMenus.cpp:710
CanStopAudioStreamFlag
const ReservedCommandFlag & CanStopAudioStreamFlag()
Definition: ProjectAudioManager.cpp:1003
SNAP_OFF
@ SNAP_OFF
Definition: ProjectSettings.h:29
SelectActions::Handler::OnCursorSelEnd
void OnCursorSelEnd(const CommandContext &context)
Definition: SelectMenus.cpp:848
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
anonymous_namespace{SelectMenus.cpp}::ExtraSelectionMenu
BaseItemSharedPtr ExtraSelectionMenu()
Definition: SelectMenus.cpp:1145
SelectActions::Handler::OnSelectCursorStoredCursor
void OnSelectCursorStoredCursor(const CommandContext &context)
Definition: SelectMenus.cpp:713
anonymous_namespace{SelectMenus.cpp}::sAttachment2
AttachedItem sAttachment2
Definition: SelectMenus.cpp:1187
SelectActions::Handler::OnSelContractLeft
void OnSelContractLeft(const CommandContext &context)
Definition: SelectMenus.cpp:823
MenuTable::FinderScope
Definition: CommandManager.h:485
SelectActions::Handler::OnZeroCrossing
void OnZeroCrossing(const CommandContext &context)
Definition: SelectMenus.cpp:744
SelectActions::Handler::OnSkipStart
void OnSkipStart(const CommandContext &context)
Definition: SelectMenus.cpp:911
findCommandHandler
static CommandHandlerObject & findCommandHandler(AudacityProject &project)
Definition: SelectMenus.cpp:1024
IsSyncLockedFlag
const ReservedCommandFlag & IsSyncLockedFlag()
Definition: CommonCommandFlags.cpp:313
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
Track::GetEndTime
virtual double GetEndTime() const =0
SelectedRegion::t1
double t1() const
Definition: SelectedRegion.h:92
anonymous_namespace{SelectMenus.cpp}::SELECTION_CONTRACT
@ SELECTION_CONTRACT
Definition: SelectMenus.cpp:154
anonymous_namespace{SelectMenus.cpp}::SeekWhenAudioInactive
void SeekWhenAudioInactive(AudacityProject &project, double seekStep, TimeUnit timeUnit, SelectionOperation operation)
Definition: SelectMenus.cpp:285
anonymous_namespace{SelectMenus.cpp}::ExtraSeekMenu
BaseItemSharedPtr ExtraSeekMenu()
Definition: SelectMenus.cpp:1274
Project.h
anonymous_namespace{SelectMenus.cpp}::SELECTION_EXTEND
@ SELECTION_EXTEND
Definition: SelectMenus.cpp:153
TimeDialog::GetTimeValue
const double GetTimeValue()
Definition: TimeDialog.cpp:97
Track::SupportsBasicEditing
virtual bool SupportsBasicEditing() const
Whether this track type implements cut-copy-paste; by default, true.
Definition: Track.cpp:1239
ProjectRate::Get
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:42
FN
#define FN(X)
Definition: SelectMenus.cpp:1030
CommandContext::pEvt
const wxEvent * pEvt
Definition: CommandContext.h:66
SelectActions::Handler::OnSnapToNearest
void OnSnapToNearest(const CommandContext &context)
Definition: SelectMenus.cpp:768
AudioIONotBusyFlag
const ReservedCommandFlag & AudioIONotBusyFlag()
Definition: CommonCommandFlags.cpp:128
anonymous_namespace{SelectMenus.cpp}::sAttachment1
AttachedItem sAttachment1
Definition: SelectMenus.cpp:1140
AudioIOBusyFlag
const ReservedCommandFlag & AudioIOBusyFlag()
Definition: CommonCommandFlags.cpp:209
SelectActions::Handler::OnCursorRight
void OnCursorRight(const CommandContext &context)
Definition: SelectMenus.cpp:938
WaveTracksExistFlag
const ReservedCommandFlag & WaveTracksExistFlag()
Definition: CommonCommandFlags.cpp:287
fillTwo
@ fillTwo
Definition: SampleFormat.h:55
Registry::Shared
std::unique_ptr< SharedItem > Shared(const BaseItemSharedPtr &ptr)
Definition: Registry.h:93
NotifyingSelectedRegion::collapseToT0
void collapseToT0()
Definition: ViewInfo.cpp:92
SelectActions::Handler::OnSelExtendLeft
void OnSelExtendLeft(const CommandContext &context)
Definition: SelectMenus.cpp:799
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:227
XO
#define XO(s)
Definition: Internat.h:31
SelectActions::Handler
Definition: SelectMenus.cpp:457
SelectActions::Handler::OnCursorLongJumpLeft
void OnCursorLongJumpLeft(const CommandContext &context)
Definition: SelectMenus.cpp:957
ProjectSettings::Get
static ProjectSettings & Get(AudacityProject &project)
Definition: ProjectSettings.cpp:41
ClientData::Base
A convenient default parameter for class template Site.
Definition: ClientData.h:28
SelectActions::Handler::Handler
Handler(const Handler &) PROHIBITED
anonymous_namespace{SelectMenus.cpp}::TimeUnit
TimeUnit
Definition: SelectMenus.cpp:158
NumericConverter::Increment
void Increment()
Definition: NumericTextCtrl.cpp:1235
ProjectWindow::Get
static ProjectWindow & Get(AudacityProject &project)
Definition: ProjectWindow.cpp:535
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
SelectedRegion::UndefinedFrequency
static const int UndefinedFrequency
Definition: SelectedRegion.h:41
MenuTable::AttachedItem
Definition: CommandManager.h:708
ControlToolBar::Get
static ControlToolBar & Get(AudacityProject &project)
Definition: ControlToolBar.cpp:133
SelectActions::Handler::OnSelectStartCursor
void OnSelectStartCursor(const CommandContext &context)
Definition: SelectMenus.cpp:577
SelectActions
Definition: SelectMenus.cpp:448
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:22
EditableTracksSelectedFlag
const ReservedCommandFlag & EditableTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:181
SelectActions::Handler::OnSelectAllTracks
void OnSelectAllTracks(const CommandContext &context)
Definition: SelectMenus.cpp:474
anonymous_namespace{TimeTrackVRulerControls.cpp}::ruler
Ruler & ruler()
Definition: TimeTrackVRulerControls.cpp:34
SelectActions::Handler::OnSelectAll
void OnSelectAll(const CommandContext &context)
Definition: SelectMenus.cpp:459
Track::IsSyncLockSelected
bool IsSyncLockSelected() const
Definition: Track.cpp:254
anonymous_namespace{SelectMenus.cpp}::SelectMenu
BaseItemSharedPtr SelectMenu()
Definition: SelectMenus.cpp:1034
ClientData::Site::RegisteredFactory
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:266
WaveTracksSelectedFlag
const ReservedCommandFlag & WaveTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:165
ProjectAudioIO::IsAudioActive
bool IsAudioActive() const
Definition: ProjectAudioIO.cpp:51
SelectHandle::SnapCenterOnce
static void SnapCenterOnce(SpectrumAnalyst &analyst, ViewInfo &viewInfo, const WaveTrack *pTrack, bool up)
Definition: SelectHandle.cpp:1441
PrefsListener
A listener notified of changes in preferences.
Definition: Prefs.h:389
SpectrumAnalyst
Used for finding the peaks, for snapping to peaks.
Definition: SpectrumAnalyst.h:21
SelectActions::Handler::OnCursorLeft
void OnCursorLeft(const CommandContext &context)
Definition: SelectMenus.cpp:931
SelectActions::Handler::OnSelSetExtendLeft
void OnSelSetExtendLeft(const CommandContext &context)
Definition: SelectMenus.cpp:813
SelectActions::Handler::OnSelSetExtendRight
void OnSelSetExtendRight(const CommandContext &context)
Definition: SelectMenus.cpp:818
anonymous_namespace{SelectMenus.cpp}::SeekLeftOrRight
void SeekLeftOrRight(AudacityProject &project, double direction, SelectionOperation operation, SeekInfo &info)
Definition: SelectMenus.cpp:331
SelectActions::Handler::mSeekInfo
SeekInfo mSeekInfo
Definition: SelectMenus.cpp:797
SelectActions::Handler::OnSeekRightLong
void OnSeekRightLong(const CommandContext &context)
Definition: SelectMenus.cpp:987
anonymous_namespace{SelectMenus.cpp}::OffsetTime
double OffsetTime(AudacityProject &project, double t, double offset, TimeUnit timeUnit, int snapToTime)
Definition: SelectMenus.cpp:218
Track::GetStartTime
virtual double GetStartTime() const =0
anonymous_namespace{SelectMenus.cpp}::SeekInfo::mSeekShort
double mSeekShort
Definition: SelectMenus.cpp:166
AdornedRulerPanel::Get
static AdornedRulerPanel & Get(AudacityProject &project)
Definition: AdornedRulerPanel.cpp:874
SelectActions::Handler::OnSetRightSelection
void OnSetRightSelection(const CommandContext &context)
Definition: SelectMenus.cpp:538
SNAP_NEAREST
@ SNAP_NEAREST
Definition: ProjectSettings.h:30
SelectActions::Handler::mCursorPositionStored
double mCursorPositionStored
Definition: SelectMenus.cpp:711
TimeDialog
Dialog used to request a time value.
Definition: TimeDialog.h:24
SelectActions::Handler::OnCursorTrackEnd
void OnCursorTrackEnd(const CommandContext &context)
Definition: SelectMenus.cpp:885
SelectActions::Handler::OnSeekRightShort
void OnSeekRightShort(const CommandContext &context)
Definition: SelectMenus.cpp:975
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:196
XXO
#define XXO(s)
Definition: Internat.h:44
SelectActions::Handler::OnSnapToPrior
void OnSnapToPrior(const CommandContext &context)
Definition: SelectMenus.cpp:774
SNAP_PRIOR
@ SNAP_PRIOR
Definition: ProjectSettings.h:31
SelectActions::Handler::OnSelContractRight
void OnSelContractRight(const CommandContext &context)
Definition: SelectMenus.cpp:830
WaveTrackSubViewType
Definition: WaveTrackViewConstants.h:91
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:34
SelectActions::Handler::UpdatePrefs
void UpdatePrefs() override
Definition: SelectMenus.cpp:1002
SelectActions::Handler::OnSelectionRestore
void OnSelectionRestore(const CommandContext &context)
Definition: SelectMenus.cpp:651
ProjectSelectionManager::AS_SetSnapTo
void AS_SetSnapTo(int snap) override
Definition: ProjectSelectionManager.cpp:108
SelectActions::Handler::OnSelectAllTime
void OnSelectAllTime(const CommandContext &context)
Definition: SelectMenus.cpp:995
ProjectSelectionManager::Get
static ProjectSelectionManager & Get(AudacityProject &project)
Definition: ProjectSelectionManager.cpp:36
SelectActions::Handler::OnSkipEnd
void OnSkipEnd(const CommandContext &context)
Definition: SelectMenus.cpp:921
Registry::BaseItemSharedPtr
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
SelectActions::Handler::OnCursorShortJumpRight
void OnCursorShortJumpRight(const CommandContext &context)
Definition: SelectMenus.cpp:951
anonymous_namespace{SelectMenus.cpp}::ExtraCursorMenu
BaseItemSharedPtr ExtraCursorMenu()
Definition: SelectMenus.cpp:1241
anonymous_namespace{SelectMenus.cpp}::DIRECTION_LEFT
@ DIRECTION_LEFT
Definition: SelectMenus.cpp:148
Track::GetOffset
virtual double GetOffset() const =0
anonymous_namespace{TimeTrack.cpp}::GetRate
double GetRate()
Definition: TimeTrack.cpp:175
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: SelectMenus.cpp:1020
NumericConverter::TIME
@ TIME
Definition: NumericTextCtrl.h:52
SelectActions::Handler::OnSelectSyncLockSel
void OnSelectSyncLockSel(const CommandContext &context)
Definition: SelectMenus.cpp:480
anonymous_namespace{SelectMenus.cpp}::CURSOR_MOVE
@ CURSOR_MOVE
Definition: SelectMenus.cpp:155
Track::IsSelected
bool IsSelected() const
Definition: Track.cpp:373
anonymous_namespace{SelectMenus.cpp}::DoNextPeakFrequency
void DoNextPeakFrequency(AudacityProject &project, bool up)
Definition: SelectMenus.cpp:31
format
int format
Definition: ExportPCM.cpp:56
SelectActions::Handler::OnCursorSelStart
void OnCursorSelStart(const CommandContext &context)
Definition: SelectMenus.cpp:837
SelectActions::Handler::operator=
Handler & operator=(const Handler &) PROHIBITED
anonymous_namespace{SelectMenus.cpp}::NearestZeroCrossing
double NearestZeroCrossing(AudacityProject &project, double t0)
Definition: SelectMenus.cpp:58
ProjectRate::GetRate
double GetRate() const
Definition: ProjectRate.cpp:68
SelectActions::Handler::mRegionSave
SelectedRegion mRegionSave
Definition: SelectMenus.cpp:641
TracksExistFlag
const ReservedCommandFlag & TracksExistFlag()
Definition: CommonCommandFlags.cpp:174
SelectActions::Handler::OnSelExtendRight
void OnSelExtendRight(const CommandContext &context)
Definition: SelectMenus.cpp:806
anonymous_namespace{SelectMenus.cpp}::TIME_UNIT_PIXELS
@ TIME_UNIT_PIXELS
Definition: SelectMenus.cpp:160
SelectActions::Handler::OnSeekLeftShort
void OnSeekLeftShort(const CommandContext &context)
Definition: SelectMenus.cpp:969
anonymous_namespace{SelectMenus.cpp}::CursorDirection
CursorDirection
Definition: SelectMenus.cpp:147
anonymous_namespace{SelectMenus.cpp}::DIRECTION_RIGHT
@ DIRECTION_RIGHT
Definition: SelectMenus.cpp:149
SelectActions::Handler::OnCursorTrackStart
void OnCursorTrackStart(const CommandContext &context)
Definition: SelectMenus.cpp:859
SelectActions::Handler::OnSelToStart
void OnSelToStart(const CommandContext &context)
Definition: SelectMenus.cpp:780
anonymous_namespace{SelectMenus.cpp}::CursorMenu
BaseItemSharedPtr CursorMenu()
Definition: SelectMenus.cpp:1194
NotifyingSelectedRegion::f0
double f0() const
Definition: ViewInfo.h:49
SelectActions::Handler::OnSelToEnd
void OnSelToEnd(const CommandContext &context)
Definition: SelectMenus.cpp:788
WaveTrackView::GetDisplays
std::vector< WaveTrackSubView::Type > GetDisplays() const
Definition: WaveTrackView.cpp:970
anonymous_namespace{SelectMenus.cpp}::SeekWhenAudioActive
void SeekWhenAudioActive(double seekStep, wxLongLong &lastSelectionAdjustment)
Definition: SelectMenus.cpp:170
anonymous_namespace{SelectMenus.cpp}::TIME_UNIT_SECONDS
@ TIME_UNIT_SECONDS
Definition: SelectMenus.cpp:159
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
SelectedRegion::t0
double t0() const
Definition: SelectedRegion.h:91
TrackPanelHasFocus
const ReservedCommandFlag & TrackPanelHasFocus()
Definition: CommonCommandFlags.cpp:197
NumericConverter
NumericConverter provides the advanced formatting control used in the selection bar of Audacity.
Definition: NumericTextCtrl.h:48
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
SelectActions::Handler::OnSelectNone
void OnSelectNone(const CommandContext &context)
Definition: SelectMenus.cpp:464
SelectActions::Handler::OnSnapToOff
void OnSnapToOff(const CommandContext &context)
Definition: SelectMenus.cpp:762
NumericConverter::SetValue
void SetValue(double newValue)
Definition: NumericTextCtrl.cpp:1136
anonymous_namespace{SelectMenus.cpp}::sAttachment4
AttachedItem sAttachment4
Definition: SelectMenus.cpp:1269
MenuTable::Command
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
Definition: CommandManager.h:675
SelectActions::Handler::OnSelectCursorEnd
void OnSelectCursorEnd(const CommandContext &context)
Definition: SelectMenus.cpp:600
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
TimeSelectedFlag
const ReservedCommandFlag & TimeSelectedFlag()
Definition: CommonCommandFlags.cpp:160
WaveTrackView::Get
static WaveTrackView & Get(WaveTrack &track)
Definition: WaveTrackView.cpp:880
SelectUtilities::SelectNone
void SelectNone(AudacityProject &project)
Definition: SelectUtilities.cpp:73
GetProjectFrame
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
Definition: ProjectWindows.cpp:72
CommandHandlerObject
wxEvtHandler CommandHandlerObject
Definition: CommandFunctors.h:28
anonymous_namespace{SelectMenus.cpp}::GridMove
double GridMove(AudacityProject &project, double t, int minPix)
Definition: SelectMenus.cpp:192
MenuTable::Menu
std::unique_ptr< MenuItem > Menu(const Identifier &internalName, const TranslatableString &title, Args &&... args)
Definition: CommandManager.h:623
ProjectRate.h
an object holding per-project preferred sample rate
anonymous_namespace{SelectMenus.cpp}::sAttachment0
AttachedItem sAttachment0
Definition: SelectMenus.cpp:1236
SelectActions::Handler::OnSeekLeftLong
void OnSeekLeftLong(const CommandContext &context)
Definition: SelectMenus.cpp:981
SelectUtilities::DoSelectAll
void DoSelectAll(AudacityProject &project)
Definition: SelectUtilities.cpp:134
MenuTable::Section
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
Definition: CommandManager.h:611
SelectActions::Handler::OnSelectionSave
void OnSelectionSave(const CommandContext &context)
Definition: SelectMenus.cpp:643
SelectActions::Handler::OnSetLeftSelection
void OnSetLeftSelection(const CommandContext &context)
Definition: SelectMenus.cpp:499
anonymous_namespace{SelectMenus.cpp}::SeekInfo::mLastSelectionAdjustment
wxLongLong mLastSelectionAdjustment
Definition: SelectMenus.cpp:165
Prefs.h
SelectUtilities::DoSelectTimeAndTracks
void DoSelectTimeAndTracks(AudacityProject &project, bool bAllTime, bool bAllTracks)
Definition: SelectUtilities.cpp:56
NumericConverter::Decrement
void Decrement()
Definition: NumericTextCtrl.cpp:1241
MenuTable
Definition: CommandManager.h:416
anonymous_namespace{SelectMenus.cpp}::MoveWhenAudioInactive
void MoveWhenAudioInactive(AudacityProject &project, double seekStep, TimeUnit timeUnit)
Definition: SelectMenus.cpp:234
anonymous_namespace{SelectMenus.cpp}::SeekInfo::mSeekLong
double mSeekLong
Definition: SelectMenus.cpp:167
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:606
settings
static Settings & settings()
Definition: TrackInfo.cpp:86
anonymous_namespace{SelectMenus.cpp}::SelectionOperation
SelectionOperation
Definition: SelectMenus.cpp:152
NumericConverter::GetValue
double GetValue()
Definition: NumericTextCtrl.cpp:1172
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:64
anonymous_namespace{Menus.cpp}::Options
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:527
anonymous_namespace{SelectMenus.cpp}::DoBoundaryMove
void DoBoundaryMove(AudacityProject &project, int step, SeekInfo &info)
Definition: SelectMenus.cpp:384
SelectActions::Handler::OnCursorLongJumpRight
void OnCursorLongJumpRight(const CommandContext &context)
Definition: SelectMenus.cpp:963
ArrayOf< float >
anonymous_namespace{SelectMenus.cpp}::DoCursorMove
void DoCursorMove(AudacityProject &project, double seekStep, wxLongLong &lastSelectionAdjustment)
Definition: SelectMenus.cpp:368
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
SelectActions::Handler::OnSelectTrackStartToEnd
void OnSelectTrackStartToEnd(const CommandContext &context)
Definition: SelectMenus.cpp:623
anonymous_namespace{SelectMenus.cpp}::SeekInfo
Definition: SelectMenus.cpp:164
SelectActions::Handler::Handler
Handler()
Definition: SelectMenus.cpp:1007
SelectActions::Handler::OnCursorPositionStore
void OnCursorPositionStore(const CommandContext &context)
Definition: SelectMenus.cpp:732
anonymous_namespace{SelectMenus.cpp}::sAttachment5
AttachedItem sAttachment5
Definition: SelectMenus.cpp:1297
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:35