Audacity 3.2.0
Public Member Functions | List of all members
EditActions::Handler Struct Reference
Inheritance diagram for EditActions::Handler:
[legend]
Collaboration diagram for EditActions::Handler:
[legend]

Public Member Functions

void OnUndo (const CommandContext &context)
 
void OnRedo (const CommandContext &context)
 
void OnCut (const CommandContext &context)
 
void OnDelete (const CommandContext &context)
 
void OnCopy (const CommandContext &context)
 
std::pair< double, double > FindSelection (const CommandContext &context)
 
void OnPaste (const CommandContext &context)
 
void OnDuplicate (const CommandContext &context)
 
void OnSplitCut (const CommandContext &context)
 
void OnSplitDelete (const CommandContext &context)
 
void OnSilence (const CommandContext &context)
 
void OnTrim (const CommandContext &context)
 
void OnSplit (const CommandContext &context)
 
void OnSplitNew (const CommandContext &context)
 
void OnJoin (const CommandContext &context)
 
void OnDisjoin (const CommandContext &context)
 
void OnEditMetadata (const CommandContext &context)
 
void OnPreferences (const CommandContext &context)
 

Detailed Description

Definition at line 141 of file EditMenus.cpp.

Member Function Documentation

◆ FindSelection()

std::pair< double, double > EditActions::Handler::FindSelection ( const CommandContext context)
inline

Definition at line 373 of file EditMenus.cpp.

374{
375 double sel0 = 0.0, sel1 = 0.0;
376
377#if 0
378 // Use the overriding selection if any was given in the context
379 if (auto *pRegion = context.temporarySelection.pSelectedRegion) {
380 auto &selectedRegion = *pRegion;
381 sel0 = selectedRegion.t0();
382 sel1 = selectedRegion.t1();
383 }
384 else
385#endif
386 {
387 auto &selectedRegion = ViewInfo::Get(context.project).selectedRegion;
388 sel0 = selectedRegion.t0();
389 sel1 = selectedRegion.t1();
390 }
391
392 return { sel0, sel1 };
393}
TemporarySelection temporarySelection
AudacityProject & project
double t0() const
Definition: ViewInfo.h:34
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:216
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
SelectedRegion * pSelectedRegion

References ViewInfo::Get(), CommandContext::project, TemporarySelection::pSelectedRegion, ViewInfo::selectedRegion, NotifyingSelectedRegion::t0(), and CommandContext::temporarySelection.

Referenced by OnPaste().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnCopy()

void EditActions::Handler::OnCopy ( const CommandContext context)
inline

Definition at line 328 of file EditMenus.cpp.

329{
330 auto &project = context.project;
331 auto &tracks = TrackList::Get( project );
332 auto &trackPanel = TrackPanel::Get( project );
333 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
334
335 for (auto lt : tracks.Selected< LabelTrack >()) {
336 auto &view = LabelTrackView::Get( *lt );
337 if (view.CopySelectedText( context.project )) {
338 //trackPanel.Refresh(false);
339 return;
340 }
341 }
342 //Presumably, there might be not more than one track
343 //that expects text input
344 for (auto wt : tracks.Any<WaveTrack>()) {
345 auto& view = WaveTrackView::Get(*wt);
346 if (view.CopySelectedText(context.project)) {
347 return;
348 }
349 }
350
351 auto &clipboard = Clipboard::Get();
352 clipboard.Clear();
353
354 auto pNewClipboard = TrackList::Create( nullptr );
355 auto &newClipboard = *pNewClipboard;
356
357 for (auto n : tracks.Selected()) {
358 if (n->SupportsBasicEditing()) {
359 auto dest = n->Copy(selectedRegion.t0(),
360 selectedRegion.t1());
361 FinishCopy(n, dest, newClipboard);
362 }
363 }
364
365 // Survived possibility of exceptions. Commit changes to the clipboard now.
366 clipboard.Assign( std::move( newClipboard ),
367 selectedRegion.t0(), selectedRegion.t1(), project.shared_from_this() );
368
369 //Make sure the menus/toolbar states get updated
370 trackPanel.Refresh(false);
371}
static Clipboard & Get()
Definition: Clipboard.cpp:29
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:89
static LabelTrackView & Get(LabelTrack &)
static std::shared_ptr< TrackList > Create(AudacityProject *pOwner)
Definition: Track.cpp:502
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:230
A Track that contains audio waveform data.
Definition: WaveTrack.h:57
static WaveTrackView & Get(WaveTrack &track)
void FinishCopy(const Track *n, const Track::Holder &dest, TrackList &list)
Definition: EditMenus.cpp:35

References TrackList::Create(), anonymous_namespace{EditMenus.cpp}::FinishCopy(), Clipboard::Get(), ViewInfo::Get(), TrackList::Get(), TrackPanel::Get(), LabelTrackView::Get(), WaveTrackView::Get(), CommandContext::project, and ViewInfo::selectedRegion.

Here is the call graph for this function:

◆ OnCut()

void EditActions::Handler::OnCut ( const CommandContext context)
inline

Definition at line 203 of file EditMenus.cpp.

204{
205 auto &project = context.project;
206 auto &tracks = TrackList::Get( project );
207 auto &trackPanel = TrackPanel::Get( project );
208 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
209 auto &ruler = AdornedRulerPanel::Get( project );
210 auto &window = ProjectWindow::Get( project );
211
212 // This doesn't handle cutting labels, it handles
213 // cutting the _text_ inside of labels, i.e. if you're
214 // in the middle of editing the label text and select "Cut".
215
216 for (auto lt : tracks.Selected< LabelTrack >()) {
217 auto &view = LabelTrackView::Get( *lt );
218 if (view.CutSelectedText( context.project )) {
219 trackPanel.Refresh(false);
220 return;
221 }
222 }
223
224 //Presumably, there might be not more than one track
225 //that expects text input
226 for (auto wt : tracks.Any<WaveTrack>()) {
227 auto& view = WaveTrackView::Get(*wt);
228 if (view.CutSelectedText(context.project)) {
229 trackPanel.Refresh(false);
230 return;
231 }
232 }
233
234 auto &clipboard = Clipboard::Get();
235 clipboard.Clear();
236
237 auto pNewClipboard = TrackList::Create( nullptr );
238 auto &newClipboard = *pNewClipboard;
239
240 tracks.Selected().Visit(
241#if defined(USE_MIDI)
242 [&](NoteTrack *n) {
243 // Since portsmf has a built-in cut operator, we use that instead
244 auto dest = n->Cut(selectedRegion.t0(),
245 selectedRegion.t1());
246 FinishCopy(n, dest, newClipboard);
247 },
248#endif
249 [&](Track *n) {
250 if (n->SupportsBasicEditing()) {
251 auto dest = n->Copy(selectedRegion.t0(),
252 selectedRegion.t1());
253 FinishCopy(n, dest, newClipboard);
254 }
255 }
256 );
257
258 // Survived possibility of exceptions. Commit changes to the clipboard now.
259 clipboard.Assign(
260 std::move( newClipboard ),
261 selectedRegion.t0(),
262 selectedRegion.t1(),
263 project.shared_from_this()
264 );
265
266 // Proceed to change the project. If this throws, the project will be
267 // rolled back by the top level handler.
268
270#if defined(USE_MIDI)
271 [](NoteTrack*) {
272 //if NoteTrack, it was cut, so do not clear anything
273
274 // PRL: But what if it was sync lock selected only, not selected?
275 },
276#endif
277 [&](WaveTrack *wt, const Track::Fallthrough &fallthrough) {
278 if (gPrefs->Read(wxT("/GUI/EnableCutLines"), (long)0)) {
280 selectedRegion.t0(),
281 selectedRegion.t1());
282 }
283 else
284 fallthrough();
285 },
286 [&](Track *n) {
287 if (n->SupportsBasicEditing())
288 n->Clear(selectedRegion.t0(), selectedRegion.t1());
289 }
290 );
291
292 selectedRegion.collapseToT0();
293
294 ProjectHistory::Get( project )
295 .PushState(XO("Cut to the clipboard"), XO("Cut"));
296
297 // Bug 1663
298 //mRuler->ClearPlayRegion();
299 ruler.DrawOverlays( true );
300}
wxT("CloseDown"))
#define XO(s)
Definition: Internat.h:31
auto Visit(Visitor &&vis, Variant &&var)
Mimic some of std::visit, for the case of one visitor only.
Definition: MemoryX.h:611
FileConfig * gPrefs
Definition: Prefs.cpp:71
static AdornedRulerPanel & Get(AudacityProject &project)
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:63
Track::Holder Cut(double t0, double t1) override
Definition: NoteTrack.cpp:444
void Clear(double t0, double t1) override
Definition: NoteTrack.cpp:521
Track::Holder Copy(double t0, double t1, bool forClipboard=true) const override
Definition: NoteTrack.cpp:474
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
static bool IsSelectedOrSyncLockSelected(const Track *pTrack)
Definition: SyncLock.cpp:73
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
virtual bool SupportsBasicEditing() const
Whether this track type implements cut-copy-paste; by default, true.
Definition: Track.cpp:1258
Continuation<> Fallthrough
Type of arguments passed as optional second parameter to TypeSwitch<void>() cases.
Definition: Track.h:541
void ClearAndAddCutLine(double t0, double t1)
Definition: WaveTrack.cpp:794

References NoteTrack::Clear(), WaveTrack::ClearAndAddCutLine(), NoteTrack::Copy(), TrackList::Create(), NoteTrack::Cut(), anonymous_namespace{EditMenus.cpp}::FinishCopy(), Clipboard::Get(), ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), AdornedRulerPanel::Get(), ProjectWindow::Get(), TrackPanel::Get(), LabelTrackView::Get(), WaveTrackView::Get(), gPrefs, SyncLock::IsSelectedOrSyncLockSelected(), CommandContext::project, ProjectHistory::PushState(), anonymous_namespace{TimeTrackVRulerControls.cpp}::ruler(), ViewInfo::selectedRegion, Track::SupportsBasicEditing(), Visit(), wxT(), and XO.

Here is the call graph for this function:

◆ OnDelete()

void EditActions::Handler::OnDelete ( const CommandContext context)
inline

Definition at line 302 of file EditMenus.cpp.

303{
304 auto &project = context.project;
305 auto &tracks = TrackList::Get( project );
306 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
307 auto &window = ProjectWindow::Get( project );
308
309 for (auto n : tracks.Any()) {
310 if (!n->SupportsBasicEditing())
311 continue;
313 n->Clear(selectedRegion.t0(), selectedRegion.t1());
314 }
315 }
316
317 double seconds = selectedRegion.duration();
318
319 selectedRegion.collapseToT0();
320
322 XO("Deleted %.2f seconds at t=%.2f")
323 .Format( seconds, selectedRegion.t0()),
324 XO("Delete"));
325}
Abstract base class used in importing a file.

References ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), SyncLock::IsSelectedOrSyncLockSelected(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, and XO.

Here is the call graph for this function:

◆ OnDisjoin()

void EditActions::Handler::OnDisjoin ( const CommandContext context)
inline

Definition at line 944 of file EditMenus.cpp.

945{
946 auto &project = context.project;
947 auto &tracks = TrackList::Get( project );
948 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
949 auto &window = ProjectWindow::Get( project );
950
951 for (auto wt : tracks.Selected< WaveTrack >())
952 wt->Disjoin(selectedRegion.t0(),
953 selectedRegion.t1());
954
956 XO("Detached %.2f seconds at t=%.2f")
957 .Format( selectedRegion.duration(), selectedRegion.t0() ),
958 XO("Detach"));
959}

References ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, and XO.

Here is the call graph for this function:

◆ OnDuplicate()

void EditActions::Handler::OnDuplicate ( const CommandContext context)
inline

Definition at line 669 of file EditMenus.cpp.

670{
671 auto &project = context.project;
672 auto &tracks = TrackList::Get( project );
673 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
674 auto &window = ProjectWindow::Get( project );
675
676 // This iteration is unusual because we add to the list inside the loop
677 auto range = tracks.Selected();
678 auto last = *range.rbegin();
679 for (auto n : range) {
680 if (!n->SupportsBasicEditing())
681 continue;
682
683 // Make copies not for clipboard but for direct addition to the project
684 auto dest = n->Copy(selectedRegion.t0(),
685 selectedRegion.t1(), false);
686 dest->Init(*n);
687 dest->SetOffset(wxMax(selectedRegion.t0(), n->GetOffset()));
688 tracks.Add( dest );
689
690 // This break is really needed, else we loop infinitely
691 if (n == last)
692 break;
693 }
694
695 ProjectHistory::Get( project )
696 .PushState(XO("Duplicated"), XO("Duplicate"));
697}

References ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, and XO.

Here is the call graph for this function:

◆ OnEditMetadata()

void EditActions::Handler::OnEditMetadata ( const CommandContext context)
inline

Definition at line 961 of file EditMenus.cpp.

962{
963 auto &project = context.project;
964 (void)Exporter::DoEditMetadata( project,
965 XO("Edit Metadata Tags"), XO("Metadata Tags"), true);
966}
static bool DoEditMetadata(AudacityProject &project, const TranslatableString &title, const TranslatableString &shortUndoDescription, bool force)
Definition: Export.cpp:405

References Exporter::DoEditMetadata(), CommandContext::project, and XO.

Here is the call graph for this function:

◆ OnJoin()

void EditActions::Handler::OnJoin ( const CommandContext context)
inline

Definition at line 927 of file EditMenus.cpp.

928{
929 auto &project = context.project;
930 auto &tracks = TrackList::Get( project );
931 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
932 auto &window = ProjectWindow::Get( project );
933
934 for (auto wt : tracks.Selected< WaveTrack >())
935 wt->Join(selectedRegion.t0(),
936 selectedRegion.t1());
937
939 XO("Joined %.2f seconds at t=%.2f")
940 .Format( selectedRegion.duration(), selectedRegion.t0() ),
941 XO("Join"));
942}

References ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, and XO.

Here is the call graph for this function:

◆ OnPaste()

void EditActions::Handler::OnPaste ( const CommandContext context)
inline

Definition at line 395 of file EditMenus.cpp.

396{
397 auto &project = context.project;
398 auto &tracks = TrackList::Get( project );
399 auto& trackPanel = TrackPanel::Get(project);
400 auto &trackFactory = WaveTrackFactory::Get( project );
401 auto &pSampleBlockFactory = trackFactory.GetSampleBlockFactory();
402 const auto &settings = ProjectSettings::Get( project );
403 auto &window = ProjectWindow::Get( project );
404
405 auto isSyncLocked = settings.IsSyncLocked();
406
407 // Handle text paste (into active label) first.
408 if (DoPasteText(project))
409 return;
410
411 //Presumably, there might be not more than one track
412 //that expects text input
413 for (auto wt : tracks.Any<WaveTrack>()) {
414 auto& view = WaveTrackView::Get(*wt);
415 if (view.PasteText(context.project)) {
416 trackPanel.Refresh(false);
417 return;
418 }
419 }
420
421 // If nothing's selected, we just insert NEW tracks.
422 if (DoPasteNothingSelected(project))
423 return;
424
425 const auto &clipboard = Clipboard::Get();
426 auto clipTrackRange = clipboard.GetTracks().Any< const Track >();
427 if (clipTrackRange.empty())
428 return;
429
430 // Otherwise, paste into the selected tracks.
431 double t0, t1;
432 std::tie(t0, t1) = FindSelection(context);
433
434 auto pN = tracks.Any().begin();
435
436 Track *ff = NULL;
437 const Track *lastClipBeforeMismatch = NULL;
438 const Track *mismatchedClip = NULL;
439 const Track *prevClip = NULL;
440
441 bool bAdvanceClipboard = true;
442 bool bPastedSomething = false;
443
444 auto pasteWaveTrack = [&](WaveTrack *dst, const Track *src){
445 bPastedSomething = true;
446 // For correct remapping of preserved split lines:
447 PasteTimeWarper warper{ t1, t0 + src->GetEndTime() };
448 dst->ClearAndPaste(t0, t1, src, true, true, &warper);
449 };
450
451 auto pC = clipTrackRange.begin();
452 size_t nnChannels=0, ncChannels=0;
453 while (*pN && *pC) {
454 auto n = *pN;
455 auto c = *pC;
456 if (n->GetSelected()) {
457 bAdvanceClipboard = true;
458 if (mismatchedClip)
459 c = mismatchedClip;
460 if (!c->SameKindAs(*n)) {
461 if (!mismatchedClip) {
462 lastClipBeforeMismatch = prevClip;
463 mismatchedClip = c;
464 }
465 bAdvanceClipboard = false;
466 c = lastClipBeforeMismatch;
467
468
469 // If the types still don't match...
470 while (c && !c->SameKindAs(*n)) {
471 prevClip = c;
472 c = * ++ pC;
473 }
474 }
475
476 // Handle case where the first track in clipboard
477 // is of different type than the first selected track
478 if (!c) {
479 c = mismatchedClip;
480 while (n && (!c->SameKindAs(*n) || !n->GetSelected()))
481 {
482 // Must perform sync-lock adjustment before incrementing n
484 auto newT1 = t0 + clipboard.Duration();
485 if (t1 != newT1 && t1 <= n->GetEndTime()) {
486 n->SyncLockAdjust(t1, newT1);
487 bPastedSomething = true;
488 }
489 }
490 n = * ++ pN;
491 }
492 if (!n)
493 c = NULL;
494 }
495
496 // The last possible case for cross-type pastes: triggered when we try
497 // to paste 1+ tracks from one type into 1+ tracks of another type. If
498 // there's a mix of types, this shouldn't run.
499 if (!c)
500 // Throw, so that any previous changes to the project in this loop
501 // are discarded.
504 XO("Pasting one type of track into another is not allowed."),
505 XO("Warning"),
506 "Error:_Copying_or_Pasting"
507 };
508
509 // We should need this check only each time we visit the leading
510 // channel
511 if ( n->IsLeader() ) {
512 wxASSERT( c->IsLeader() ); // the iteration logic should ensure this
513
514 auto cChannels = TrackList::Channels(c);
515 ncChannels = cChannels.size();
516 auto nChannels = TrackList::Channels(n);
517 nnChannels = nChannels.size();
518
519 // When trying to copy from stereo to mono track, show error and
520 // exit
521 // TODO: Automatically offer user to mix down to mono (unfortunately
522 // this is not easy to implement
523 if (ncChannels > nnChannels)
524 {
525 if (ncChannels > 2) {
526 // TODO: more-than-two-channels-message
527 // Re-word the error message
528 }
529 // else
530
531 // Throw, so that any previous changes to the project in this
532 // loop are discarded.
535 XO("Copying stereo audio into a mono track is not allowed."),
536 XO("Warning"),
537 "Error:_Copying_or_Pasting"
538 };
539 }
540 }
541
542 if (!ff)
543 ff = n;
544
545 wxASSERT( n && c && n->SameKindAs(*c) );
546 n->TypeSwitch(
547 [&](WaveTrack *wn){
548 pasteWaveTrack(wn, static_cast<const WaveTrack *>(c));
549 },
550 [&](LabelTrack *ln){
551 // Per Bug 293, users expect labels to move on a paste into
552 // a label track.
553 ln->Clear(t0, t1);
554
555 ln->ShiftLabelsOnInsert( clipboard.Duration(), t0 );
556
557 bPastedSomething |= ln->PasteOver(t0, c);
558 },
559 [&](Track *){
560 bPastedSomething = true;
561 n->Clear(t0, t1);
562 n->Paste(t0, c);
563 }
564 );
565
566 --nnChannels;
567 --ncChannels;
568
569 // When copying from mono to stereo track, paste the wave form
570 // to both channels
571 // TODO: more-than-two-channels
572 // This will replicate the last pasted channel as many times as needed
573 while (nnChannels > 0 && ncChannels == 0)
574 {
575 n = * ++ pN;
576 --nnChannels;
577
578 n->TypeSwitch(
579 [&](WaveTrack *wn){
580 pasteWaveTrack(wn, c);
581 },
582 [&](Track *){
583 n->Clear(t0, t1);
584 bPastedSomething = true;
585 n->Paste(t0, c);
586 }
587 );
588 }
589
590 if (bAdvanceClipboard) {
591 prevClip = c;
592 c = * ++ pC;
593 }
594 } // if (n->GetSelected())
596 {
597 auto newT1 = t0 + clipboard.Duration();
598 if (t1 != newT1 && t1 <= n->GetEndTime()) {
599 n->SyncLockAdjust(t1, newT1);
600 bPastedSomething = true;
601 }
602 }
603 ++pN;
604 }
605
606 // This block handles the cases where our clipboard is smaller
607 // than the amount of selected destination tracks. We take the
608 // last wave track, and paste that one into the remaining
609 // selected tracks.
610 if ( *pN && ! *pC )
611 {
612 const auto wc =
613 *clipboard.GetTracks().Any< const WaveTrack >().rbegin();
614
615 tracks.Any().StartingWith(*pN).Visit(
616 [&](WaveTrack *wt, const Track::Fallthrough &fallthrough) {
617 if (!wt->GetSelected())
618 return fallthrough();
619
620 if (wc) {
621 pasteWaveTrack(wt, wc);
622 }
623 else {
624 auto tmp = wt->EmptyCopy( pSampleBlockFactory );
625 tmp->InsertSilence( 0.0,
626 // MJS: Is this correct?
627 clipboard.Duration() );
628 tmp->Flush();
629
630 pasteWaveTrack(wt, tmp.get());
631 }
632 },
633 [&](LabelTrack *lt, const Track::Fallthrough &fallthrough) {
635 return fallthrough();
636
637 lt->Clear(t0, t1);
638
639 // As above, only shift labels if sync-lock is on.
640 if (isSyncLocked)
642 clipboard.Duration(), t0);
643 },
644 [&](Track *n) {
646 n->SyncLockAdjust(t1, t0 + clipboard.Duration() );
647 }
648 );
649 }
650
651 // TODO: What if we clicked past the end of the track?
652
653 if (bPastedSomething)
654 {
656 .setTimes( t0, t0 + clipboard.Duration() );
657
658 ProjectHistory::Get( project )
659 .PushState(XO("Pasted from the clipboard"), XO("Paste"));
660
661 if (ff) {
662 TrackFocus::Get(project).Set(ff);
663 ff->EnsureVisible();
664 ff->LinkConsistencyFix();
665 }
666 }
667}
@ BadUserAction
Indicates that the user performed an action that is not allowed.
static Settings & settings()
Definition: TrackInfo.cpp:87
void ShiftLabelsOnInsert(double length, double pt)
Definition: LabelTrack.cpp:231
void Clear(double t0, double t1) override
Definition: LabelTrack.cpp:182
bool setTimes(double t0, double t1)
Definition: ViewInfo.cpp:51
Unit slope but with either a jump (pasting more) or a flat interval (pasting less)
Definition: TimeWarper.h:181
static ProjectSettings & Get(AudacityProject &project)
A MessageBoxException that shows a given, unvarying string.
static bool IsSyncLockSelected(const Track *pTrack)
Definition: SyncLock.cpp:43
Track * Get()
void EnsureVisible(bool modifyState=false)
Definition: Track.cpp:97
virtual void SyncLockAdjust(double oldT1, double newT1)
Definition: Track.cpp:285
virtual bool LinkConsistencyFix(bool doFix=true, bool completeList=true)
Check consistency of channel groups, and maybe fix it.
Definition: Track.cpp:424
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1541
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2810
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Definition: WaveTrack.cpp:915
bool DoPasteText(AudacityProject &project)
Definition: EditMenus.cpp:44
bool DoPasteNothingSelected(AudacityProject &project)
Definition: EditMenus.cpp:79
std::pair< double, double > FindSelection(const CommandContext &context)
Definition: EditMenus.cpp:373

References BadUserAction, TrackList::Channels(), LabelTrack::Clear(), WaveTrack::ClearAndPaste(), anonymous_namespace{EditMenus.cpp}::DoPasteNothingSelected(), anonymous_namespace{EditMenus.cpp}::DoPasteText(), FindSelection(), Clipboard::Get(), TrackList::Get(), ProjectSettings::Get(), ProjectWindow::Get(), TrackPanel::Get(), WaveTrackFactory::Get(), WaveTrackView::Get(), SyncLock::IsSelectedOrSyncLockSelected(), SyncLock::IsSyncLockSelected(), CommandContext::project, settings(), LabelTrack::ShiftLabelsOnInsert(), Track::SyncLockAdjust(), and XO.

Here is the call graph for this function:

◆ OnPreferences()

void EditActions::Handler::OnPreferences ( const CommandContext context)
inline

Definition at line 968 of file EditMenus.cpp.

969{
970 auto &project = context.project;
971
972 GlobalPrefsDialog dialog(&GetProjectFrame( project ) /* parent */, &project );
973
974 if( VetoDialogHook::Call( &dialog ) )
975 return;
976
977 if (!dialog.ShowModal()) {
978 // Canceled
979 return;
980 }
981
982 // LL: Moved from PrefsDialog since wxWidgets on OSX can't deal with
983 // rebuilding the menus while the PrefsDialog is still in the modal
984 // state.
985 for (auto p : AllProjects{}) {
987// TODO: The comment below suggests this workaround is obsolete.
988#if defined(__WXGTK__)
989 // Workaround for:
990 //
991 // http://bugzilla.audacityteam.org/show_bug.cgi?id=458
992 //
993 // This workaround should be removed when Audacity updates to wxWidgets
994 // 3.x which has a fix.
995 auto &window = GetProjectFrame( *p );
996 wxRect r = window.GetRect();
997 window.SetSize(wxSize(1,1));
998 window.SetSize(r.GetSize());
999#endif
1000 }
1001}
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 ...
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
void RebuildMenuBar(AudacityProject &project)
Definition: Menus.cpp:486
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:71

References GlobalHook< VetoDialogHook, bool(wxDialog *) >::Call(), MenuManager::Get(), GetProjectFrame(), CommandContext::project, MenuCreator::RebuildMenuBar(), and PrefsDialog::ShowModal().

Here is the call graph for this function:

◆ OnRedo()

void EditActions::Handler::OnRedo ( const CommandContext context)
inline

Definition at line 173 of file EditMenus.cpp.

174{
175 auto &project = context.project;
176 auto &tracks = TrackList::Get( project );
177 auto &trackPanel = TrackPanel::Get( project );
178 auto &undoManager = UndoManager::Get( project );
179 auto &window = ProjectWindow::Get( project );
180
181 if (!ProjectHistory::Get( project ).RedoAvailable()) {
182 AudacityMessageBox( XO("Nothing to redo") );
183 return;
184 }
185 // Can't redo whilst dragging
186 if (trackPanel.IsMouseCaptured()) {
187 return;
188 }
189
190 undoManager.Redo(
191 [&]( const UndoStackElem &elem ){
192 ProjectHistory::Get( project ).PopState( elem.state ); } );
193
194 auto t = *tracks.Selected().begin();
195 if (!t)
196 t = *tracks.Any().begin();
197 TrackFocus::Get(project).Set(t);
198 if (t) {
199 t->EnsureVisible();
200 }
201}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
void PopState(const UndoState &state, bool doAutosave=true)
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:67
Holds one item with description and time range for the UndoManager.
Definition: UndoManager.h:127
UndoState state
Definition: UndoManager.h:140

References AudacityMessageBox(), Track::EnsureVisible(), TrackFocus::Get(), ProjectHistory::Get(), UndoManager::Get(), TrackList::Get(), ProjectWindow::Get(), TrackPanel::Get(), ProjectHistory::PopState(), CommandContext::project, UndoStackElem::state, and XO.

Here is the call graph for this function:

◆ OnSilence()

void EditActions::Handler::OnSilence ( const CommandContext context)
inline

Definition at line 767 of file EditMenus.cpp.

768{
769 auto &project = context.project;
770 auto &tracks = TrackList::Get( project );
771 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
772
773 for ( auto n : tracks.Selected< WaveTrack >() )
774 n->Silence(selectedRegion.t0(), selectedRegion.t1());
775
777 XO("Silenced selected tracks for %.2f seconds at %.2f")
778 .Format( selectedRegion.duration(), selectedRegion.t0() ),
779 /* i18n-hint: verb */
780 XC("Silence", "command"));
781}
#define XC(s, c)
Definition: Internat.h:37

References ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, XC, and XO.

Here is the call graph for this function:

◆ OnSplit()

void EditActions::Handler::OnSplit ( const CommandContext context)
inline

Definition at line 807 of file EditMenus.cpp.

808{
809 auto &project = context.project;
810 auto &tracks = TrackList::Get( project );
811
812 auto [sel0, sel1] = FindSelection(context);
813
814 if (auto *pTrack = context.temporarySelection.pTrack) {
815 if (auto pWaveTrack = dynamic_cast<WaveTrack*>(pTrack))
816 for (auto pChannel : TrackList::Channels(pWaveTrack))
817 pChannel->Split( sel0, sel1 );
818 else
819 // Did nothing, don't push history
820 return;
821 }
822 else {
823 for (auto wt : tracks.Selected< WaveTrack >())
824 wt->Split( sel0, sel1 );
825 }
826
827 ProjectHistory::Get( project ).PushState(XO("Split"), XO("Split"));
828#if 0
829//ANSWER-ME: Do we need to keep this commented out OnSplit() code?
830// This whole section no longer used...
831 /*
832 * Previous (pre-multiclip) implementation of "Split" command
833 * This does work only when a range is selected!
834 *
835 TrackListIterator iter(tracks);
836
837 Track *n = iter.First();
838 Track *dest;
839
840 TrackList newTracks;
841
842 while (n) {
843 if (n->GetSelected()) {
844 double sel0 = selectedRegion.t0();
845 double sel1 = selectedRegion.t1();
846
847 dest = n->Copy(sel0, sel1);
848 dest->Init(*n);
849 dest->SetOffset(wxMax(sel0, n->GetOffset()));
850
851 if (sel1 >= n->GetEndTime())
852 n->Clear(sel0, sel1);
853 else if (sel0 <= n->GetOffset()) {
854 n->Clear(sel0, sel1);
855 n->SetOffset(sel1);
856 } else
857 n->Silence(sel0, sel1);
858
859 newTracks.Add(dest);
860 }
861 n = iter.Next();
862 }
863
864 TrackListIterator nIter(&newTracks);
865 n = nIter.First();
866 while (n) {
867 tracks->Add(n);
868 n = nIter.Next();
869 }
870
871 PushState(XO("Split"), XO("Split"));
872 */
873#endif
874}

References TrackList::Channels(), ProjectHistory::Get(), TrackList::Get(), CommandContext::project, TemporarySelection::pTrack, ProjectHistory::PushState(), CommandContext::temporarySelection, and XO.

Here is the call graph for this function:

◆ OnSplitCut()

void EditActions::Handler::OnSplitCut ( const CommandContext context)
inline

Definition at line 699 of file EditMenus.cpp.

700{
701 auto &project = context.project;
702 auto &tracks = TrackList::Get( project );
703 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
704 auto &window = ProjectWindow::Get( project );
705
706 auto &clipboard = Clipboard::Get();
707 clipboard.Clear();
708
709 auto pNewClipboard = TrackList::Create( nullptr );
710 auto &newClipboard = *pNewClipboard;
711
712 Track::Holder dest;
713
714 tracks.Selected().Visit(
715 [&](WaveTrack *n) {
716 dest = n->SplitCut(
717 selectedRegion.t0(),
718 selectedRegion.t1());
719 if (dest)
720 FinishCopy(n, dest, newClipboard);
721 },
722 [&](Track *n) {
723 if (n->SupportsBasicEditing()) {
724 dest = n->Copy(selectedRegion.t0(),
725 selectedRegion.t1());
726 n->Silence(selectedRegion.t0(),
727 selectedRegion.t1());
728 if (dest)
729 FinishCopy(n, dest, newClipboard);
730 }
731 }
732 );
733
734 // Survived possibility of exceptions. Commit changes to the clipboard now.
735 clipboard.Assign( std::move( newClipboard ),
736 selectedRegion.t0(), selectedRegion.t1(), project.shared_from_this() );
737
738 ProjectHistory::Get( project )
739 .PushState(XO("Split-cut to the clipboard"), XO("Split Cut"));
740}
std::shared_ptr< Track > Holder
Definition: Track.h:368
void Silence(double t0, double t1) override
Definition: WaveTrack.cpp:1582
Track::Holder SplitCut(double t0, double t1)
Definition: WaveTrack.cpp:640
Track::Holder Copy(double t0, double t1, bool forClipboard=true) const override
Definition: WaveTrack.cpp:716

References WaveTrack::Copy(), TrackList::Create(), anonymous_namespace{EditMenus.cpp}::FinishCopy(), Clipboard::Get(), ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, WaveTrack::Silence(), WaveTrack::SplitCut(), Track::SupportsBasicEditing(), and XO.

Here is the call graph for this function:

◆ OnSplitDelete()

void EditActions::Handler::OnSplitDelete ( const CommandContext context)
inline

Definition at line 742 of file EditMenus.cpp.

743{
744 auto &project = context.project;
745 auto &tracks = TrackList::Get( project );
746 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
747 auto &window = ProjectWindow::Get( project );
748
749 tracks.Selected().Visit(
750 [&](WaveTrack *wt) {
751 wt->SplitDelete(selectedRegion.t0(),
752 selectedRegion.t1());
753 },
754 [&](Track *n) {
755 if (n->SupportsBasicEditing())
756 n->Silence(selectedRegion.t0(),
757 selectedRegion.t1());
758 }
759 );
760
762 XO("Split-deleted %.2f seconds at t=%.2f")
763 .Format( selectedRegion.duration(), selectedRegion.t0() ),
764 XO("Split Delete"));
765}
void SplitDelete(double t0, double t1)
Definition: WaveTrack.cpp:1175

References ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, WaveTrack::SplitDelete(), and XO.

Here is the call graph for this function:

◆ OnSplitNew()

void EditActions::Handler::OnSplitNew ( const CommandContext context)
inline

Definition at line 876 of file EditMenus.cpp.

877{
878 auto &project = context.project;
879 auto &tracks = TrackList::Get( project );
880 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
881 auto &window = ProjectWindow::Get( project );
882
883 Track::Holder dest;
884
885 // This iteration is unusual because we add to the list inside the loop
886 auto range = tracks.Selected();
887 auto last = *range.rbegin();
888 for (auto track : range) {
889 track->TypeSwitch(
890 [&](WaveTrack *wt) {
891 // Clips must be aligned to sample positions or the NEW clip will
892 // not fit in the gap where it came from
893 double offset = wt->GetOffset();
894 offset = wt->LongSamplesToTime(wt->TimeToLongSamples(offset));
895 double newt0 = wt->LongSamplesToTime(wt->TimeToLongSamples(
896 selectedRegion.t0()));
897 double newt1 = wt->LongSamplesToTime(wt->TimeToLongSamples(
898 selectedRegion.t1()));
899 dest = wt->SplitCut(newt0, newt1);
900 if (dest) {
901 dest->SetOffset(wxMax(newt0, offset));
902 FinishCopy(wt, dest, tracks);
903 }
904 }
905#if 0
906 ,
907 // LL: For now, just skip all non-wave tracks since the other do not
908 // yet support proper splitting.
909 [&](Track *n) {
910 dest = n->Cut(viewInfo.selectedRegion.t0(),
911 viewInfo.selectedRegion.t1());
912 if (dest) {
913 dest->SetOffset(wxMax(0, n->GetOffset()));
914 FinishCopy(n, dest, *tracks);
915 }
916 }
917#endif
918 );
919 if (track == last)
920 break;
921 }
922
923 ProjectHistory::Get( project )
924 .PushState(XO("Split to new track"), XO("Split New"));
925}
double LongSamplesToTime(sampleCount pos) const
Convert correctly between a number of samples and an (absolute) time in seconds.
Definition: SampleTrack.cpp:47
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: SampleTrack.cpp:42
double GetOffset() const override
Definition: WaveTrack.cpp:237

References anonymous_namespace{EditMenus.cpp}::FinishCopy(), ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), WaveTrack::GetOffset(), SampleTrack::LongSamplesToTime(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, WaveTrack::SplitCut(), SampleTrack::TimeToLongSamples(), and XO.

Here is the call graph for this function:

◆ OnTrim()

void EditActions::Handler::OnTrim ( const CommandContext context)
inline

Definition at line 783 of file EditMenus.cpp.

784{
785 auto &project = context.project;
786 auto &tracks = TrackList::Get( project );
787 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
788 auto &window = ProjectWindow::Get( project );
789
790 if (selectedRegion.isPoint())
791 return;
792
793 tracks.Selected().Visit(
794 [&](WaveTrack *wt) {
795 //Hide the section before the left selector
796 wt->Trim(selectedRegion.t0(),
797 selectedRegion.t1());
798 }
799 );
800
802 XO("Trim selected audio tracks from %.2f seconds to %.2f seconds")
803 .Format( selectedRegion.t0(), selectedRegion.t1() ),
804 XO("Trim Audio"));
805}
void Trim(double t0, double t1)
Definition: WaveTrack.cpp:673

References ProjectHistory::Get(), ViewInfo::Get(), TrackList::Get(), ProjectWindow::Get(), CommandContext::project, ProjectHistory::PushState(), ViewInfo::selectedRegion, WaveTrack::Trim(), and XO.

Here is the call graph for this function:

◆ OnUndo()

void EditActions::Handler::OnUndo ( const CommandContext context)
inline

Definition at line 142 of file EditMenus.cpp.

143{
144 auto &project = context.project;
145 auto &tracks = TrackList::Get( project );
146 auto &trackPanel = TrackPanel::Get( project );
147 auto &undoManager = UndoManager::Get( project );
148 auto &window = ProjectWindow::Get( project );
149
150 if (!ProjectHistory::Get( project ).UndoAvailable()) {
151 AudacityMessageBox( XO("Nothing to undo") );
152 return;
153 }
154
155 // can't undo while dragging
156 if (trackPanel.IsMouseCaptured()) {
157 return;
158 }
159
160 undoManager.Undo(
161 [&]( const UndoStackElem &elem ){
162 ProjectHistory::Get( project ).PopState( elem.state ); } );
163
164 auto t = *tracks.Selected().begin();
165 if (!t)
166 t = *tracks.Any().begin();
167 TrackFocus::Get(project).Set(t);
168 if (t) {
169 t->EnsureVisible();
170 }
171}

References AudacityMessageBox(), Track::EnsureVisible(), TrackFocus::Get(), ProjectHistory::Get(), UndoManager::Get(), TrackList::Get(), ProjectWindow::Get(), TrackPanel::Get(), ProjectHistory::PopState(), CommandContext::project, UndoStackElem::state, and XO.

Here is the call graph for this function:

The documentation for this struct was generated from the following file: