Audacity  3.0.3
LabelMenus.cpp
Go to the documentation of this file.
1 #include "../AudioIO.h"
2 #include "../Clipboard.h"
3 #include "../CommonCommandFlags.h"
4 #include "../LabelTrack.h"
5 #include "../Menus.h"
6 #include "Prefs.h"
7 #include "Project.h"
8 #include "../ProjectAudioIO.h"
9 #include "../ProjectHistory.h"
10 #include "../ProjectSettings.h"
11 #include "../SelectFile.h"
12 #include "../TrackPanelAx.h"
13 #include "../TrackPanel.h"
14 #include "ViewInfo.h"
15 #include "../WaveTrack.h"
16 #include "../commands/CommandContext.h"
17 #include "../commands/CommandManager.h"
18 #include "../tracks/labeltrack/ui/LabelTrackView.h"
19 
20 // private helper classes and functions
21 namespace {
22 
25  [](const AudacityProject &project){
26  // At least one label track selected, having at least one label
27  // completely within the time selection.
28  const auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
29  const auto &test = [&]( const LabelTrack *pTrack ){
30  const auto &labels = pTrack->GetLabels();
31  return std::any_of( labels.begin(), labels.end(),
32  [&](const LabelStruct &label){
33  return
34  label.getT0() >= selectedRegion.t0()
35  &&
36  label.getT1() <= selectedRegion.t1()
37  ;
38  }
39  );
40  };
41  auto range = TrackList::Get( project ).Selected<const LabelTrack>()
42  + test;
43  return !range.empty();
44  }
45 }; return flag; }
46 
47 //Adds label and returns index of label in labeltrack.
49  AudacityProject &project, const SelectedRegion &region,
50  bool preserveFocus = false)
51 {
52  auto &tracks = TrackList::Get( project );
53  auto &trackFocus = TrackFocus::Get( project );
54  auto &trackPanel = TrackPanel::Get( project );
55 
56  wxString title; // of label
57 
58  bool useDialog;
59  gPrefs->Read(wxT("/GUI/DialogForNameNewLabel"), &useDialog, false);
60  if (useDialog) {
62  project, region, wxEmptyString, title) == wxID_CANCEL)
63  return -1; // index
64  }
65 
66  // If the focused track is a label track, use that
67  const auto pFocusedTrack = trackFocus.Get();
68 
69  // Look for a label track at or after the focused track
70  auto iter = pFocusedTrack
71  ? tracks.Find(pFocusedTrack)
72  : tracks.Any().begin();
73  auto lt = * iter.Filter< LabelTrack >();
74 
75  // If none found, start a NEW label track and use it
76  if (!lt)
77  lt = tracks.Add( std::make_shared<LabelTrack>() );
78 
79 // LLL: Commented as it seemed a little forceful to remove users
80 // selection when adding the label. This does not happen if
81 // you select several tracks and the last one of those is a
82 // label track...typing a label will not clear the selections.
83 //
84 // SelectNone();
85  lt->SetSelected(true);
86 
87  int index;
88  if (useDialog) {
89  index = lt->AddLabel(region, title);
90  }
91  else {
92  int focusTrackNumber = -1;
93  if (pFocusedTrack && preserveFocus) {
94  // Must remember the track to re-focus after finishing a label edit.
95  // do NOT identify it by a pointer, which might dangle! Identify
96  // by position.
97  focusTrackNumber = pFocusedTrack->GetIndex();
98  }
99  index =
100  LabelTrackView::Get( *lt ).AddLabel(region, title, focusTrackNumber);
101  }
102 
103  ProjectHistory::Get( project )
104  .PushState(XO("Added label"), XO("Label"));
105 
106  if (!useDialog) {
107  TrackFocus::Get(project).Set(lt);
108  lt->EnsureVisible();
109  }
110  trackPanel.SetFocus();
111 
112  return index;
113 }
114 
115 //get regions selected by selected labels
116 //removes unnecessary regions, overlapping regions are merged
118  const TrackList &tracks, const SelectedRegion &selectedRegion,
119  Regions &regions )
120 {
121  //determine labeled regions
122  for (auto lt : tracks.Selected< const LabelTrack >()) {
123  for (int i = 0; i < lt->GetNumLabels(); i++)
124  {
125  const LabelStruct *ls = lt->GetLabel(i);
126  if (ls->selectedRegion.t0() >= selectedRegion.t0() &&
127  ls->selectedRegion.t1() <= selectedRegion.t1())
128  regions.push_back(Region(ls->getT0(), ls->getT1()));
129  }
130  }
131 
132  //anything to do ?
133  if( regions.size() == 0 )
134  return;
135 
136  //sort and remove unnecessary regions
137  std::sort(regions.begin(), regions.end());
138  unsigned int selected = 1;
139  while( selected < regions.size() )
140  {
141  const Region &cur = regions.at( selected );
142  Region &last = regions.at( selected - 1 );
143  if( cur.start < last.end )
144  {
145  if( cur.end > last.end )
146  last.end = cur.end;
147  regions.erase( regions.begin() + selected );
148  }
149  else
150  ++selected;
151  }
152 }
153 
154 using EditFunction = std::function<void(Track *, double, double)>;
155 
156 //Executes the edit function on all selected wave tracks with
157 //regions specified by selected labels
158 //If No tracks selected, function is applied on all tracks
159 //If the function replaces the selection with audio of a different length,
160 // bSyncLockedTracks should be set true to perform the same action on sync-lock
161 // selected tracks.
163  TrackList &tracks, const SelectedRegion &selectedRegion,
164  EditFunction action)
165 {
166  Regions regions;
167 
168  GetRegionsByLabel( tracks, selectedRegion, regions );
169  if( regions.size() == 0 )
170  return;
171 
172  const bool notLocked = (!ProjectSettings::Get(project).IsSyncLocked() &&
173  (tracks.Selected<PlayableTrack>()).empty());
174 
175  //Apply action on tracks starting from
176  //labeled regions in the end. This is to correctly perform
177  //actions like 'Delete' which collapse the track area.
178  for (auto t : tracks.Any())
179  {
180  const bool playable = dynamic_cast<const PlayableTrack *>(t) != nullptr;
181 
182  if (t->IsSyncLockSelected() || notLocked && playable)
183  {
184  for (int i = (int)regions.size() - 1; i >= 0; i--)
185  {
186  const Region &region = regions.at(i);
187  action(t, region.start, region.end);
188  }
189  }
190  }
191 }
192 
193 using EditDestFunction = std::function<Track::Holder (Track *, double, double)>;
194 
195 //Executes the edit function on all selected wave tracks with
196 //regions specified by selected labels
197 //If No tracks selected, function is applied on all tracks
198 //Functions copy the edited regions to clipboard, possibly in multiple tracks
199 //This probably should not be called if *action() changes the timeline, because
200 // the copy needs to happen by track, and the timeline change by group.
202  TrackList &tracks, const SelectedRegion &selectedRegion,
203  EditDestFunction action )
204 {
205  Regions regions;
206 
207  GetRegionsByLabel( tracks, selectedRegion, regions );
208  if( regions.size() == 0 )
209  return;
210 
211  const bool notLocked = (!ProjectSettings::Get(project).IsSyncLocked() &&
212  (tracks.Selected<PlayableTrack>()).empty());
213 
214  auto &clipboard = Clipboard::Get();
215  clipboard.Clear();
216 
217  auto pNewClipboard = TrackList::Create( nullptr );
218  auto &newClipboard = *pNewClipboard;
219 
220  //Apply action on wavetracks starting from
221  //labeled regions in the end. This is to correctly perform
222  //actions like 'Cut' which collapse the track area.
223 
224  for( auto t : tracks.Any())
225  {
226  const bool playable = dynamic_cast<const PlayableTrack *>(t) != nullptr;
227 
228  if (t->IsSyncLockSelected() || notLocked && playable)
229  {
230  // This track accumulates the needed clips, right to left:
231  Track::Holder merged;
232  for( int i = (int)regions.size() - 1; i >= 0; i-- )
233  {
234  const Region &region = regions.at(i);
235  auto dest = action(t, region.start, region.end );
236  if( dest )
237  {
238  Track::FinishCopy( t, dest.get() );
239  if( !merged )
240  merged = dest;
241  else
242  {
243  // Paste to the beginning; unless this is the first region,
244  // offset the track to account for time between the regions
245  if (i < (int)regions.size() - 1)
246  merged->Offset(
247  regions.at(i + 1).start - region.end);
248 
249  // dest may have a placeholder clip at the end that is
250  // removed when pasting, which is okay because we proceed
251  // right to left. Any placeholder already in merged is kept.
252  // Only the rightmost placeholder is important in the final
253  // result.
254  merged->Paste( 0.0 , dest.get() );
255  }
256  }
257  else
258  // nothing copied but there is a 'region', so the 'region' must
259  // be a 'point label' so offset
260  if (i < (int)regions.size() - 1)
261  if (merged)
262  merged->Offset(
263  regions.at(i + 1).start - region.end);
264  }
265  if( merged )
266  newClipboard.Add( merged );
267  }
268  }
269 
270  // Survived possibility of exceptions. Commit changes to the clipboard now.
271  clipboard.Assign( std::move( newClipboard ),
272  regions.front().start, regions.back().end, project.shared_from_this() );
273 }
274 
275 }
276 
278 namespace LabelEditActions {
279 
280 // exported helper functions
281 // none
282 
283 // Menu handler functions
284 
286 
287 void OnEditLabels(const CommandContext &context)
288 {
289  auto &project = context.project;
291 }
292 
293 void OnAddLabel(const CommandContext &context)
294 {
295  auto &project = context.project;
296  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
297 
298  DoAddLabel(project, selectedRegion);
299 }
300 
301 void OnAddLabelPlaying(const CommandContext &context)
302 {
303  auto &project = context.project;
304  auto token = ProjectAudioIO::Get( project ).GetAudioIOToken();
305 
306  auto gAudioIO = AudioIO::Get();
307  if (token > 0 &&
308  gAudioIO->IsStreamActive(token)) {
309  double indicator = gAudioIO->GetStreamTime();
310  DoAddLabel(project, SelectedRegion(indicator, indicator), true);
311  }
312 }
313 
314 // Creates a NEW label in each selected label track with text from the system
315 // clipboard
316 void OnPasteNewLabel(const CommandContext &context)
317 {
318  auto &project = context.project;
319  auto &tracks = TrackList::Get( project );
320  auto &trackPanel = TrackPanel::Get( project );
321  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
322 
323  bool bPastedSomething = false;
324 
325  {
326  auto trackRange = tracks.Selected< const LabelTrack >();
327  if (trackRange.empty())
328  {
329  // If there are no selected label tracks, try to choose the first label
330  // track after some other selected track
331  Track *t = *tracks.Selected().begin()
332  .Filter( &Track::Any )
333  .Filter<LabelTrack>();
334 
335  // If no match found, add one
336  if (!t)
337  t = tracks.Add( std::make_shared<LabelTrack>() );
338 
339  // Select this track so the loop picks it up
340  t->SetSelected(true);
341  }
342  }
343 
344  LabelTrack *plt = NULL; // the previous track
345  for ( auto lt : tracks.Selected< LabelTrack >() )
346  {
347  // Unselect the last label, so we'll have just one active label when
348  // we're done
349  if (plt)
351 
352  // Add a NEW label, paste into it
353  // Paul L: copy whatever defines the selected region, not just times
354  auto &view = LabelTrackView::Get( *lt );
355  view.AddLabel(selectedRegion);
356  if (view.PasteSelectedText( context.project, selectedRegion.t0(),
357  selectedRegion.t1() ))
358  bPastedSomething = true;
359 
360  // Set previous track
361  plt = lt;
362  }
363 
364  // plt should point to the last label track pasted to -- ensure it's visible
365  // and set focus
366  if (plt) {
367  TrackFocus::Get(project).Set(plt);
368  plt->EnsureVisible();
369  trackPanel.SetFocus();
370  }
371 
372  if (bPastedSomething) {
373  ProjectHistory::Get( project ).PushState(
374  XO("Pasted from the clipboard"), XO("Paste Text to New Label"));
375  }
376 }
377 
378 void OnToggleTypeToCreateLabel(const CommandContext &WXUNUSED(context) )
379 {
380  bool typeToCreateLabel;
381  gPrefs->Read(wxT("/GUI/TypeToCreateLabel"), &typeToCreateLabel, false);
382  gPrefs->Write(wxT("/GUI/TypeToCreateLabel"), !typeToCreateLabel);
383  gPrefs->Flush();
385 }
386 
387 void OnCutLabels(const CommandContext &context)
388 {
389  auto &project = context.project;
390  auto &tracks = TrackList::Get( project );
391  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
392 
393  if( selectedRegion.isPoint() )
394  return;
395 
396  // Because of grouping the copy may need to operate on different tracks than
397  // the clear, so we do these actions separately.
398  auto copyfunc = [&](Track *track, double t0, double t1)
399  {
400  Track::Holder dest = nullptr;
401  track->TypeSwitch(
402  [&](WaveTrack *t)
403  {
404  dest = t->CopyNonconst(t0, t1);
405  }
406  );
407  return dest;
408  };
409  EditClipboardByLabel( project, tracks, selectedRegion, copyfunc );
410 
411  bool enableCutlines = gPrefs->ReadBool(wxT( "/GUI/EnableCutLines"), false);
412  auto editfunc = [&](Track *track, double t0, double t1)
413  {
414  track->TypeSwitch(
415  [&](WaveTrack *t)
416  {
417  if (enableCutlines)
418  {
419  t->ClearAndAddCutLine(t0, t1);
420  }
421  else
422  {
423  t->Clear(t0, t1);
424  }
425  },
426  [&](Track *t)
427  {
428  t->Clear(t0, t1);
429  }
430  );
431  };
432  EditByLabel(project, tracks, selectedRegion, editfunc);
433 
434  selectedRegion.collapseToT0();
435 
436  ProjectHistory::Get( project ).PushState(
437  /* i18n-hint: (verb) past tense. Audacity has just cut the labeled audio
438  regions.*/
439  XO( "Cut labeled audio regions to clipboard" ),
440  /* i18n-hint: (verb)*/
441  XO( "Cut Labeled Audio" ) );
442 }
443 
444 void OnDeleteLabels(const CommandContext &context)
445 {
446  auto &project = context.project;
447  auto &tracks = TrackList::Get( project );
448  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
449 
450  if( selectedRegion.isPoint() )
451  return;
452 
453  auto editfunc = [&](Track *track, double t0, double t1)
454  {
455  track->Clear(t0, t1);
456  };
457  EditByLabel(project, tracks, selectedRegion, editfunc);
458 
459  selectedRegion.collapseToT0();
460 
461  ProjectHistory::Get( project ).PushState(
462  /* i18n-hint: (verb) Audacity has just deleted the labeled audio regions*/
463  XO( "Deleted labeled audio regions" ),
464  /* i18n-hint: (verb)*/
465  XO( "Delete Labeled Audio" ) );
466 }
467 
468 void OnSplitCutLabels(const CommandContext &context)
469 {
470  auto &project = context.project;
471  auto &tracks = TrackList::Get( project );
472  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
473 
474  if( selectedRegion.isPoint() )
475  return;
476 
477  auto copyfunc = [&](Track *track, double t0, double t1)
478  {
479  Track::Holder dest = nullptr;
480  track->TypeSwitch(
481  [&](WaveTrack *t)
482  {
483  dest = t->SplitCut(t0, t1);
484  },
485  [&](Track *t)
486  {
487  dest = t->Copy(t0, t1);
488  t->Silence(t0, t1);
489  }
490  );
491  return dest;
492  };
493  EditClipboardByLabel( project, tracks, selectedRegion, copyfunc );
494 
495  ProjectHistory::Get( project ).PushState(
496  /* i18n-hint: (verb) Audacity has just split cut the labeled audio
497  regions*/
498  XO( "Split Cut labeled audio regions to clipboard" ),
499  /* i18n-hint: (verb) Do a special kind of cut on the labels*/
500  XO( "Split Cut Labeled Audio" ) );
501 }
502 
504 {
505  auto &project = context.project;
506  auto &tracks = TrackList::Get( project );
507  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
508 
509  if( selectedRegion.isPoint() )
510  return;
511 
512  auto editfunc = [&](Track *track, double t0, double t1)
513  {
514  track->TypeSwitch(
515  [&](WaveTrack *t)
516  {
517  t->SplitDelete(t0, t1);
518  },
519  [&](Track *t)
520  {
521  t->Silence(t0, t1);
522  }
523  );
524  };
525  EditByLabel(project, tracks, selectedRegion, editfunc);
526 
527  ProjectHistory::Get( project ).PushState(
528  /* i18n-hint: (verb) Audacity has just done a special kind of DELETE on
529  the labeled audio regions */
530  XO( "Split Deleted labeled audio regions" ),
531  /* i18n-hint: (verb) Do a special kind of DELETE on labeled audio
532  regions */
533  XO( "Split Delete Labeled Audio" ) );
534 }
535 
536 void OnSilenceLabels(const CommandContext &context)
537 {
538  auto &project = context.project;
539  auto &tracks = TrackList::Get( project );
540  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
541 
542  if( selectedRegion.isPoint() )
543  return;
544 
545  auto editfunc = [&](Track *track, double t0, double t1)
546  {
547  track->TypeSwitch(
548  [&](WaveTrack *t)
549  {
550  t->Silence(t0, t1);
551  }
552  );
553  };
554  EditByLabel(project, tracks, selectedRegion, editfunc);
555 
556  ProjectHistory::Get( project ).PushState(
557  /* i18n-hint: (verb)*/
558  XO( "Silenced labeled audio regions" ),
559  /* i18n-hint: (verb)*/
560  XO( "Silence Labeled Audio" ) );
561 }
562 
563 void OnCopyLabels(const CommandContext &context)
564 {
565  auto &project = context.project;
566  auto &tracks = TrackList::Get( project );
567  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
568 
569  if( selectedRegion.isPoint() )
570  return;
571 
572  auto copyfunc = [&](Track *track, double t0, double t1)
573  {
574  Track::Holder dest = nullptr;
575  track->TypeSwitch(
576  [&](WaveTrack *t)
577  {
578  dest = t->CopyNonconst(t0, t1);
579  });
580  return dest;
581  };
582  EditClipboardByLabel( project, tracks, selectedRegion, copyfunc );
583 
584  ProjectHistory::Get( project ).PushState( XO( "Copied labeled audio regions to clipboard" ),
585  /* i18n-hint: (verb)*/
586  XO( "Copy Labeled Audio" ) );
587 }
588 
589 void OnSplitLabels(const CommandContext &context)
590 {
591  auto &project = context.project;
592  auto &tracks = TrackList::Get( project );
593  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
594 
595  if( selectedRegion.isPoint() )
596  return;
597 
598  auto editfunc = [&](Track *track, double t0, double t1)
599  {
600  track->TypeSwitch(
601  [&](WaveTrack *t)
602  {
603  t->Split(t0, t1);
604  }
605  );
606  };
607  EditByLabel(project, tracks, selectedRegion, editfunc);
608 
609  ProjectHistory::Get( project ).PushState(
610  /* i18n-hint: (verb) past tense. Audacity has just split the labeled
611  audio (a point or a region)*/
612  XO( "Split labeled audio (points or regions)" ),
613  /* i18n-hint: (verb)*/
614  XO( "Split Labeled Audio" ) );
615 }
616 
617 void OnJoinLabels(const CommandContext &context)
618 {
619  auto &project = context.project;
620  auto &tracks = TrackList::Get( project );
621  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
622 
623  if( selectedRegion.isPoint() )
624  return;
625 
626  auto editfunc = [&](Track *track, double t0, double t1)
627  {
628  track->TypeSwitch(
629  [&](WaveTrack *t)
630  {
631  t->Join(t0, t1);
632  }
633  );
634  };
635  EditByLabel(project, tracks, selectedRegion, editfunc);
636 
637  ProjectHistory::Get( project ).PushState(
638  /* i18n-hint: (verb) Audacity has just joined the labeled audio (points or
639  regions) */
640  XO( "Joined labeled audio (points or regions)" ),
641  /* i18n-hint: (verb) */
642  XO( "Join Labeled Audio" ) );
643 }
644 
645 void OnDisjoinLabels(const CommandContext &context)
646 {
647  auto &project = context.project;
648  auto &tracks = TrackList::Get( project );
649  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
650 
651  if( selectedRegion.isPoint() )
652  return;
653 
654  auto editfunc = [&](Track *track, double t0, double t1)
655  {
656  track->TypeSwitch(
657  [&](WaveTrack *t)
658  {
659  t->Disjoin(t0, t1);
660  }
661  );
662  };
663  EditByLabel(project, tracks, selectedRegion, editfunc);
664 
665  ProjectHistory::Get( project ).PushState(
666  /* i18n-hint: (verb) Audacity has just detached the labeled audio regions.
667  This message appears in history and tells you about something
668  Audacity has done.*/
669  XO( "Detached labeled audio regions" ),
670  /* i18n-hint: (verb)*/
671  XO( "Detach Labeled Audio" ) );
672 }
673 
674 }; // struct Handler
675 
676 } // namespace
677 
679  // Handler is not stateful. Doesn't need a factory registered with
680  // AudacityProject.
681  static LabelEditActions::Handler instance;
682  return instance;
683 };
684 
685 // Menu definitions
686 
687 #define FN(X) (& LabelEditActions::Handler :: X)
688 
689 namespace {
690 using namespace MenuTable;
692 {
693  using namespace MenuTable;
695 
696  static const auto NotBusyLabelsAndWaveFlags =
699 
700  // Returns TWO menus.
701 
702  static BaseItemSharedPtr menus{
704  Items( wxT("LabelEditMenus"),
705 
706  Menu( wxT("Labels"), XXO("&Labels"),
707  Section( "",
708  Command( wxT("EditLabels"), XXO("&Edit Labels..."), FN(OnEditLabels),
710  ),
711 
712  Section( "",
713  Command( wxT("AddLabel"), XXO("Add Label at &Selection"),
714  FN(OnAddLabel), AlwaysEnabledFlag, wxT("Ctrl+B") ),
715  Command( wxT("AddLabelPlaying"),
716  XXO("Add Label at &Playback Position"),
717  FN(OnAddLabelPlaying), AudioIOBusyFlag(),
718  #ifdef __WXMAC__
719  wxT("Ctrl+.")
720  #else
721  wxT("Ctrl+M")
722  #endif
723  ),
724  Command( wxT("PasteNewLabel"), XXO("Paste Te&xt to New Label"),
725  FN(OnPasteNewLabel),
726  AudioIONotBusyFlag(), wxT("Ctrl+Alt+V") )
727  ),
728 
729  Section( "",
730  Command( wxT("TypeToCreateLabel"),
731  XXO("&Type to Create a Label (on/off)"),
732  FN(OnToggleTypeToCreateLabel), AlwaysEnabledFlag,
733  Options{}.CheckTest(wxT("/GUI/TypeToCreateLabel"), false) )
734  )
735  ), // first menu
736 
738 
739  Menu( wxT("Labeled"), XXO("La&beled Audio"),
740  Section( "",
741  /* i18n-hint: (verb)*/
742  Command( wxT("CutLabels"), XXO("&Cut"), FN(OnCutLabels),
745  Options{ wxT("Alt+X"), XO("Label Cut") } ),
746  Command( wxT("DeleteLabels"), XXO("&Delete"), FN(OnDeleteLabels),
749  Options{ wxT("Alt+K"), XO("Label Delete") } )
750  ),
751 
752  Section( "",
753  /* i18n-hint: (verb) A special way to cut out a piece of audio*/
754  Command( wxT("SplitCutLabels"), XXO("&Split Cut"),
755  FN(OnSplitCutLabels), NotBusyLabelsAndWaveFlags,
756  Options{ wxT("Alt+Shift+X"), XO("Label Split Cut") } ),
757  Command( wxT("SplitDeleteLabels"), XXO("Sp&lit Delete"),
758  FN(OnSplitDeleteLabels), NotBusyLabelsAndWaveFlags,
759  Options{ wxT("Alt+Shift+K"), XO("Label Split Delete") } )
760  ),
761 
762  Section( "",
763  Command( wxT("SilenceLabels"), XXO("Silence &Audio"),
764  FN(OnSilenceLabels), NotBusyLabelsAndWaveFlags,
765  Options{ wxT("Alt+L"), XO("Label Silence") } ),
766  /* i18n-hint: (verb)*/
767  Command( wxT("CopyLabels"), XXO("Co&py"), FN(OnCopyLabels),
768  NotBusyLabelsAndWaveFlags,
769  Options{ wxT("Alt+Shift+C"), XO("Label Copy") } )
770  ),
771 
772  Section( "",
773  /* i18n-hint: (verb)*/
774  Command( wxT("SplitLabels"), XXO("Spli&t"), FN(OnSplitLabels),
776  Options{ wxT("Alt+I"), XO("Label Split") } ),
777  /* i18n-hint: (verb)*/
778  Command( wxT("JoinLabels"), XXO("&Join"), FN(OnJoinLabels),
779  NotBusyLabelsAndWaveFlags,
780  Options{ wxT("Alt+J"), XO("Label Join") } ),
781  Command( wxT("DisjoinLabels"), XXO("Detac&h at Silences"),
782  FN(OnDisjoinLabels), NotBusyLabelsAndWaveFlags,
783  wxT("Alt+Shift+J") )
784  )
785  ) // second menu
786 
787  ) ) }; // two menus
788  return menus;
789 }
790 
792  { wxT("Edit/Other"),
793  { OrderingHint::Before, wxT("EditMetaData") } },
795 };
796 
797 }
798 
799 #undef FN
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:241
LabelTrack::SetSelected
void SetSelected(bool s) override
Definition: LabelTrack.cpp:299
ProjectAudioIO::GetAudioIOToken
int GetAudioIOToken() const
Definition: ProjectAudioIO.cpp:41
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
anonymous_namespace{LabelMenus.cpp}::DoAddLabel
int DoAddLabel(AudacityProject &project, const SelectedRegion &region, bool preserveFocus=false)
Definition: LabelMenus.cpp:48
MenuTable::FinderScope
Definition: CommandManager.h:485
flag
static std::once_flag flag
Definition: WaveformView.cpp:1119
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
SelectedRegion::t1
double t1() const
Definition: SelectedRegion.h:92
Project.h
Track::EnsureVisible
void EnsureVisible(bool modifyState=false)
Definition: Track.cpp:100
anonymous_namespace{LabelMenus.cpp}::LabelsSelectedFlag
const ReservedCommandFlag & LabelsSelectedFlag()
Definition: LabelMenus.cpp:24
AudioIONotBusyFlag
const ReservedCommandFlag & AudioIONotBusyFlag()
Definition: CommonCommandFlags.cpp:127
anonymous_namespace{LabelMenus.cpp}::EditByLabel
void EditByLabel(AudacityProject &project, TrackList &tracks, const SelectedRegion &selectedRegion, EditFunction action)
Definition: LabelMenus.cpp:162
TrackList
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1280
AudioIOBusyFlag
const ReservedCommandFlag & AudioIOBusyFlag()
Definition: CommonCommandFlags.cpp:208
WaveTracksExistFlag
const ReservedCommandFlag & WaveTracksExistFlag()
Definition: CommonCommandFlags.cpp:273
WaveTrack::ClearAndAddCutLine
void ClearAndAddCutLine(double t0, double t1)
Definition: WaveTrack.cpp:758
FN
#define FN(X)
Definition: LabelMenus.cpp:687
ReservedCommandFlag
Definition: CommandFlag.h:89
Registry::Shared
std::unique_ptr< SharedItem > Shared(const BaseItemSharedPtr &ptr)
Definition: Registry.h:93
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:227
XO
#define XO(s)
Definition: Internat.h:31
ProjectSettings::Get
static ProjectSettings & Get(AudacityProject &project)
Definition: ProjectSettings.cpp:44
Region::start
double start
Definition: WaveTrack.h:56
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
Track::Any
bool Any() const
Definition: Track.cpp:370
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
MenuTable::AttachedItem
Definition: CommandManager.h:708
MenuManager::ModifyAllProjectToolbarMenus
static void ModifyAllProjectToolbarMenus()
Definition: Menus.cpp:584
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:22
LabelEditActions::Handler::OnCutLabels
void OnCutLabels(const CommandContext &context)
Definition: LabelMenus.cpp:387
WaveTrack::Copy
Track::Holder Copy(double t0, double t1, bool forClipboard=true) const override
Definition: WaveTrack.cpp:680
Regions
std::vector< Region > Regions
Definition: WaveTrack.h:65
LabelStruct
A LabelStruct holds information for ONE label in a LabelTrack.
Definition: LabelTrack.h:30
LabelEditActions::Handler::OnPasteNewLabel
void OnPasteNewLabel(const CommandContext &context)
Definition: LabelMenus.cpp:316
WaveTrack::SplitDelete
void SplitDelete(double t0, double t1)
Definition: WaveTrack.cpp:1012
LabelEditActions::Handler::OnDeleteLabels
void OnDeleteLabels(const CommandContext &context)
Definition: LabelMenus.cpp:444
LabelEditActions::Handler::OnDisjoinLabels
void OnDisjoinLabels(const CommandContext &context)
Definition: LabelMenus.cpp:645
Track::SetSelected
virtual void SetSelected(bool s)
Definition: Track.cpp:90
ProjectSettings::IsSyncLocked
bool IsSyncLocked() const
Definition: ProjectSettings.cpp:179
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:229
XXO
#define XXO(s)
Definition: Internat.h:44
findCommandHandler
static CommandHandlerObject & findCommandHandler(AudacityProject &)
Definition: LabelMenus.cpp:678
LabelEditActions::Handler::OnSplitCutLabels
void OnSplitCutLabels(const CommandContext &context)
Definition: LabelMenus.cpp:468
WaveTrack::Clear
void Clear(double t0, double t1) override
Definition: WaveTrack.cpp:752
WaveTrack::Split
void Split(double t0, double t1)
Definition: WaveTrack.cpp:2389
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:34
label
TranslatableString label
Definition: Tags.cpp:756
Track::Holder
std::shared_ptr< Track > Holder
Definition: Track.h:336
LabelStruct::selectedRegion
SelectedRegion selectedRegion
Definition: LabelTrack.h:70
LabelStruct::getT0
double getT0() const
Definition: LabelTrack.h:40
WaveTrack::SplitCut
Track::Holder SplitCut(double t0, double t1)
Definition: WaveTrack.cpp:606
Registry::BaseItemSharedPtr
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
anonymous_namespace{LabelMenus.cpp}::GetRegionsByLabel
void GetRegionsByLabel(const TrackList &tracks, const SelectedRegion &selectedRegion, Regions &regions)
Definition: LabelMenus.cpp:117
Registry::OrderingHint::Before
@ Before
Definition: Registry.h:29
MenuTable::Items
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
Definition: CommandManager.h:600
LabelTrackView::Get
static LabelTrackView & Get(LabelTrack &)
Definition: LabelTrackView.cpp:162
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:755
Region::end
double end
Definition: WaveTrack.h:56
PlayableTrack
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:854
ViewInfo.h
LabelEditActions::Handler::OnToggleTypeToCreateLabel
void OnToggleTypeToCreateLabel(const CommandContext &WXUNUSED(context))
Definition: LabelMenus.cpp:378
LabelEditActions::Handler
Definition: LabelMenus.cpp:285
ProjectHistory::PushState
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
Definition: ProjectHistory.cpp:90
Clipboard::Get
static Clipboard & Get()
Definition: Clipboard.cpp:29
SelectedRegion::t0
double t0() const
Definition: SelectedRegion.h:91
LabelEditActions
Namespace for functions for Edit Label submenu.
Definition: LabelMenus.cpp:278
Track::TypeSwitch
R TypeSwitch(const Functions &...functions)
Use this function rather than testing track type explicitly and making down-casts.
Definition: Track.h:709
WaveTrack::Join
void Join(double t0, double t1)
Definition: WaveTrack.cpp:1564
title
static const auto title
Definition: NoUpdatesAvailableDialog.cpp:22
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
LabelTrackView::DoEditLabels
static void DoEditLabels(AudacityProject &project, LabelTrack *lt=nullptr, int index=-1)
Definition: LabelTrackView.cpp:2245
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
LabelEditActions::Handler::OnSilenceLabels
void OnSilenceLabels(const CommandContext &context)
Definition: LabelMenus.cpp:536
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:159
LabelEditActions::Handler::OnSplitLabels
void OnSplitLabels(const CommandContext &context)
Definition: LabelMenus.cpp:589
CommandHandlerObject
wxEvtHandler CommandHandlerObject
Definition: CommandFunctors.h:28
WaveTrack::CopyNonconst
Track::Holder CopyNonconst(double t0, double t1)
Definition: WaveTrack.cpp:746
MenuTable::Menu
std::unique_ptr< MenuItem > Menu(const Identifier &internalName, const TranslatableString &title, Args &&... args)
Definition: CommandManager.h:623
anonymous_namespace{LabelMenus.cpp}::EditClipboardByLabel
void EditClipboardByLabel(AudacityProject &project, TrackList &tracks, const SelectedRegion &selectedRegion, EditDestFunction action)
Definition: LabelMenus.cpp:201
LabelEditActions::Handler::OnEditLabels
void OnEditLabels(const CommandContext &context)
Definition: LabelMenus.cpp:287
LabelEditActions::Handler::OnCopyLabels
void OnCopyLabels(const CommandContext &context)
Definition: LabelMenus.cpp:563
TrackList::Create
static std::shared_ptr< TrackList > Create(AudacityProject *pOwner)
Definition: Track.cpp:523
LabelEditActions::Handler::OnJoinLabels
void OnJoinLabels(const CommandContext &context)
Definition: LabelMenus.cpp:617
Track::FinishCopy
static void FinishCopy(const Track *n, Track *dest)
Definition: Track.cpp:388
Track::Clear
virtual void Clear(double WXUNUSED(t0), double WXUNUSED(t1))=0
WaveTrack::Silence
void Silence(double t0, double t1) override
Definition: WaveTrack.cpp:1422
MenuTable::Section
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
Definition: CommandManager.h:611
Region
#define Region
Definition: VSTControlGTK.h:16
LabelTrackView::DialogForLabelName
static int DialogForLabelName(AudacityProject &project, const SelectedRegion &region, const wxString &initialValue, wxString &value)
Definition: LabelTrackView.cpp:2269
Prefs.h
anonymous_namespace{LabelMenus.cpp}::EditFunction
std::function< void(Track *, double, double)> EditFunction
Definition: LabelMenus.cpp:154
MenuTable
Definition: CommandManager.h:416
TrackList::Any
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1371
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:141
Region
Structure to hold region of a wavetrack and a comparison function for sortability.
Definition: WaveTrack.h:52
anonymous_namespace{LabelMenus.cpp}::EditDestFunction
std::function< Track::Holder(Track *, double, double)> EditDestFunction
Definition: LabelMenus.cpp:193
LabelEditActions::Handler::OnAddLabelPlaying
void OnAddLabelPlaying(const CommandContext &context)
Definition: LabelMenus.cpp:301
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:64
TrackList::Selected
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1388
anonymous_namespace{Menus.cpp}::Options
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:527
WaveTrack::Disjoin
void Disjoin(double t0, double t1)
Definition: WaveTrack.cpp:1487
LabelTrackView::AddLabel
int AddLabel(const SelectedRegion &region, const wxString &title={}, int restoreFocus=-1)
Definition: LabelTrackView.cpp:2050
LabelStruct::getT1
double getT1() const
Definition: LabelTrack.h:41
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
LabelTrackView::ResetTextSelection
void ResetTextSelection()
Definition: LabelTrackView.cpp:1009
anonymous_namespace{LabelMenus.cpp}::LabelEditMenus
BaseItemSharedPtr LabelEditMenus()
Definition: LabelMenus.cpp:691
LabelEditActions::Handler::OnSplitDeleteLabels
void OnSplitDeleteLabels(const CommandContext &context)
Definition: LabelMenus.cpp:503
anonymous_namespace{LabelMenus.cpp}::sAttachment1
AttachedItem sAttachment1
Definition: LabelMenus.cpp:791
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:35
LabelEditActions::Handler::OnAddLabel
void OnAddLabel(const CommandContext &context)
Definition: LabelMenus.cpp:293