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