Audacity 3.2.0
Classes | Functions | Variables
anonymous_namespace{ClipMenus.cpp} Namespace Reference

Namespace for functions for Clip menu. More...

Classes

struct  FoundClip
 
struct  FoundClipBoundary
 
struct  FoundTrack
 

Functions

bool TwoChannelsHaveSameBoundaries (const WaveTrack *first, const WaveTrack *second)
 
bool ChannelsHaveDifferentClipBoundaries (const WaveTrack *wt)
 
double AdjustForFindingStartTimes (const std::vector< const WaveClip * > &clips, double time)
 
double AdjustForFindingEndTimes (const std::vector< const WaveClip * > &clips, double time)
 
FoundClipBoundary FindNextClipBoundary (const WaveTrack *wt, double time)
 
FoundClipBoundary FindPrevClipBoundary (const WaveTrack *wt, double time)
 
int FindClipBoundaries (AudacityProject &project, double time, bool next, std::vector< FoundClipBoundary > &finalResults)
 
TranslatableString ClipBoundaryMessage (const std::vector< FoundClipBoundary > &results)
 
void DoSelectClipBoundary (AudacityProject &project, bool next)
 
FoundClip FindNextClip (AudacityProject &project, const WaveTrack *wt, double t0, double t1)
 
FoundClip FindPrevClip (AudacityProject &project, const WaveTrack *wt, double t0, double t1)
 
int FindClips (AudacityProject &project, double t0, double t1, bool next, std::vector< FoundClip > &finalResults)
 
void DoSelectClip (AudacityProject &project, bool next)
 
void DoCursorClipBoundary (AudacityProject &project, bool next)
 
double DoClipMove (AudacityProject &project, Track *track, TrackList &trackList, bool syncLocked, bool right)
 
void DoClipLeftOrRight (AudacityProject &project, bool right, bool keyUp)
 
void OnSelectPrevClipBoundaryToCursor (const CommandContext &context)
 
void OnSelectCursorToNextClipBoundary (const CommandContext &context)
 
void OnSelectPrevClip (const CommandContext &context)
 
void OnSelectNextClip (const CommandContext &context)
 
void OnCursorPrevClipBoundary (const CommandContext &context)
 
void OnCursorNextClipBoundary (const CommandContext &context)
 
void OnClipLeft (const CommandContext &context)
 
void OnClipRight (const CommandContext &context)
 
BaseItemSharedPtr ClipSelectMenu ()
 
BaseItemSharedPtr ClipCursorItems ()
 
BaseItemSharedPtr ExtraTimeShiftItems ()
 

Variables

AttachedItem sAttachment1
 
AttachedItem sAttachment2
 
AttachedItem sAttachment3
 

Detailed Description

Namespace for functions for Clip menu.

Function Documentation

◆ AdjustForFindingEndTimes()

double anonymous_namespace{ClipMenus.cpp}::AdjustForFindingEndTimes ( const std::vector< const WaveClip * > &  clips,
double  time 
)

Definition at line 129 of file ClipMenus.cpp.

131{
132 auto q = std::find_if(clips.begin(), clips.end(),
133 [&] (const WaveClip* const& clip) {
134 return clip->GetPlayStartTime() == time; });
135 if (q != clips.end() && q != clips.begin() &&
136 (*(q - 1))->SharesBoundaryWithNextClip(*q)) {
137 time = (*(q-1))->GetPlayEndTime();
138 }
139
140 return time;
141}
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:101

Referenced by FindNextClipBoundary(), and FindPrevClipBoundary().

Here is the caller graph for this function:

◆ AdjustForFindingStartTimes()

double anonymous_namespace{ClipMenus.cpp}::AdjustForFindingStartTimes ( const std::vector< const WaveClip * > &  clips,
double  time 
)

Definition at line 107 of file ClipMenus.cpp.

109{
110 auto q = std::find_if(clips.begin(), clips.end(),
111 [&] (const WaveClip* const& clip) {
112 return clip->GetPlayEndTime() == time; });
113 if (q != clips.end() && q + 1 != clips.end() &&
114 (*q)->SharesBoundaryWithNextClip(*(q+1))) {
115 time = (*(q+1))->GetPlayStartTime();
116 }
117
118 return time;
119}

Referenced by FindNextClip(), FindNextClipBoundary(), FindPrevClip(), and FindPrevClipBoundary().

Here is the caller graph for this function:

◆ ChannelsHaveDifferentClipBoundaries()

bool anonymous_namespace{ClipMenus.cpp}::ChannelsHaveDifferentClipBoundaries ( const WaveTrack wt)

Definition at line 83 of file ClipMenus.cpp.

85{
86 // This is quadratic in the number of channels
87 auto channels = TrackList::Channels(wt);
88 while (!channels.empty()) {
89 auto channel = *channels.first++;
90 for (auto other : channels) {
91 if (!TwoChannelsHaveSameBoundaries(channel, other))
92 return true;
93 }
94 }
95
96 return false;
97}
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1541
bool TwoChannelsHaveSameBoundaries(const WaveTrack *first, const WaveTrack *second)
Definition: ClipMenus.cpp:59

References TrackList::Channels(), and TwoChannelsHaveSameBoundaries().

Referenced by FindClipBoundaries(), and FindClips().

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

◆ ClipBoundaryMessage()

TranslatableString anonymous_namespace{ClipMenus.cpp}::ClipBoundaryMessage ( const std::vector< FoundClipBoundary > &  results)

Definition at line 319 of file ClipMenus.cpp.

321{
322 TranslatableString message;
323 for (auto& result : results) {
324
325 auto longName = result.ComposeTrackName();
326
328 auto nClips = result.waveTrack->GetNumClips();
329 if (result.nFound < 2) {
330 str = XP(
331 /* i18n-hint:
332 First %s is replaced with the noun "start" or "end"
333 identifying one end of a clip,
334 second string is the name of that clip,
335 first number gives the position of that clip in a sequence
336 of clips,
337 last number counts all clips,
338 and the last string is the name of the track containing the
339 clips.
340 */
341 "%s %s, %d of %d clip %s",
342 "%s %s, %d of %d clips %s",
343 3
344 )(
345 result.clipStart1 ? XO("start") : XO("end"),
346 result.name1,
347 result.index1 + 1,
348 nClips,
349 longName
350 );
351 }
352 else {
353 str = XP(
354 /* i18n-hint:
355 First and third %s are each replaced with the noun "start"
356 or with "end", identifying and end of a clip,
357 second and fourth strings are the names of those clips,
358 first and second numbers give the position of those clips in
359 a sequence of clips,
360 last number counts all clips,
361 and the last string is the name of the track containing the
362 clips.
363 */
364 "%s %s and %s %s, %d and %d of %d clip %s",
365 "%s %s and %s %s, %d and %d of %d clips %s",
366 6
367 )(
368 result.clipStart1 ? XO("start") : XO("end"),
369 result.name1,
370 result.clipStart2 ? XO("start") : XO("end"),
371 result.name2,
372 result.index1 + 1,
373 result.index2 + 1,
374 nClips,
375 longName
376 );
377 }
378
379 if (message.empty())
380 message = str;
381 else
382 message = XO("%s, %s").Format( message, str );
383 }
384
385 return message;
386}
#define str(a)
XO("Cut/Copy/Paste")
#define XP(sing, plur, n)
Definition: Internat.h:96
Holds a msgid for the translation catalog; may also bind format arguments.

References TranslatableString::empty(), str, XO(), and XP.

Referenced by DoCursorClipBoundary(), and DoSelectClipBoundary().

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

◆ ClipCursorItems()

BaseItemSharedPtr anonymous_namespace{ClipMenus.cpp}::ClipCursorItems ( )

Definition at line 853 of file ClipMenus.cpp.

854{
856
857 static BaseItemSharedPtr items{
858 Items( wxT("Clip"),
859 Command( wxT("CursPrevClipBoundary"), XXO("Pre&vious Clip Boundary"),
862 Options{}.LongName( XO("Cursor to Prev Clip Boundary") ) ),
863 Command( wxT("CursNextClipBoundary"), XXO("Ne&xt Clip Boundary"),
866 Options{}.LongName( XO("Cursor to Next Clip Boundary") ) )
867 ) };
868 return items;
869}
wxT("CloseDown"))
const ReservedCommandFlag & WaveTracksExistFlag()
XXO("&Cut/Copy/Paste Toolbar")
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
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())
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
void OnCursorPrevClipBoundary(const CommandContext &context)
Definition: ClipMenus.cpp:778
void OnCursorNextClipBoundary(const CommandContext &context)
Definition: ClipMenus.cpp:785
Options && LongName(const TranslatableString &value) &&

References MenuTable::Command(), MenuTable::Items(), CommandManager::Options::LongName(), OnCursorNextClipBoundary(), OnCursorPrevClipBoundary(), WaveTracksExistFlag(), wxT(), XO(), and XXO().

Here is the call graph for this function:

◆ ClipSelectMenu()

BaseItemSharedPtr anonymous_namespace{ClipMenus.cpp}::ClipSelectMenu ( )

Definition at line 824 of file ClipMenus.cpp.

825{
827
828 static BaseItemSharedPtr menu {
829 Menu( wxT("Clip"), XXO("Audi&o Clips"),
830 Command( wxT("SelPrevClipBoundaryToCursor"),
831 XXO("Pre&vious Clip Boundary to Cursor"),
834 Command( wxT("SelCursorToNextClipBoundary"),
835 XXO("Cursor to Ne&xt Clip Boundary"),
838 Command( wxT("SelPrevClip"), XXO("Previo&us Clip"),
840 Options{ wxT("Alt+,"), XO("Select Previous Clip") } ),
841 Command( wxT("SelNextClip"), XXO("N&ext Clip"), OnSelectNextClip,
843 Options{ wxT("Alt+."), XO("Select Next Clip") } )
844 ) };
845 return menu;
846}
std::unique_ptr< MenuItem > Menu(const Identifier &internalName, const TranslatableString &title, Args &&... args)
void OnSelectPrevClip(const CommandContext &context)
Definition: ClipMenus.cpp:766
void OnSelectCursorToNextClipBoundary(const CommandContext &context)
Definition: ClipMenus.cpp:760
void OnSelectNextClip(const CommandContext &context)
Definition: ClipMenus.cpp:772
void OnSelectPrevClipBoundaryToCursor(const CommandContext &context)
Definition: ClipMenus.cpp:753

References MenuTable::Command(), MenuTable::Menu(), OnSelectCursorToNextClipBoundary(), OnSelectNextClip(), OnSelectPrevClip(), OnSelectPrevClipBoundaryToCursor(), WaveTracksExistFlag(), wxT(), XO(), and XXO().

Here is the call graph for this function:

◆ DoClipLeftOrRight()

void anonymous_namespace{ClipMenus.cpp}::DoClipLeftOrRight ( AudacityProject project,
bool  right,
bool  keyUp 
)

Definition at line 703 of file ClipMenus.cpp.

705{
706 auto &undoManager = UndoManager::Get( project );
707 auto &window = ProjectWindow::Get( project );
708
709 if (keyUp) {
710 undoManager.StopConsolidating();
711 return;
712 }
713
714 auto &trackFocus = TrackFocus::Get( project );
715 auto &viewInfo = ViewInfo::Get( project );
716 auto &selectedRegion = viewInfo.selectedRegion;
717 const auto &settings = ProjectSettings::Get( project );
718 auto &tracks = TrackList::Get( project );
719 auto isSyncLocked = settings.IsSyncLocked();
720
721 auto amount = DoClipMove( project, trackFocus.Get(),
722 tracks, isSyncLocked, right );
723
724 window.ScrollIntoView(selectedRegion.t0());
725
726 if (amount != 0.0) {
727 auto message = right? XO("Time shifted clips to the right") :
728 XO("Time shifted clips to the left");
729
730 // The following use of the UndoPush flags is so that both a single
731 // keypress (keydown, then keyup), and holding down a key
732 // (multiple keydowns followed by a keyup) result in a single
733 // entry in Audacity's history dialog.
734 ProjectHistory::Get( project )
735 .PushState(message, XO("Time-Shift"), UndoPush::CONSOLIDATE);
736 }
737
738 if ( amount == 0.0 )
739 trackFocus.MessageForScreenReader( XO("clip not moved"));
740}
static Settings & settings()
Definition: TrackInfo.cpp:87
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
Track * Get()
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:67
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:234
double DoClipMove(AudacityProject &project, Track *track, TrackList &trackList, bool syncLocked, bool right)
Definition: ClipMenus.cpp:651

References CONSOLIDATE, DoClipMove(), TrackFocus::Get(), ProjectHistory::Get(), UndoManager::Get(), ViewInfo::Get(), TrackList::Get(), ProjectSettings::Get(), ProjectWindow::Get(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Get(), ProjectHistory::PushState(), settings(), and XO().

Referenced by OnClipLeft(), and OnClipRight().

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

◆ DoClipMove()

double anonymous_namespace{ClipMenus.cpp}::DoClipMove ( AudacityProject project,
Track track,
TrackList trackList,
bool  syncLocked,
bool  right 
)

Definition at line 651 of file ClipMenus.cpp.

653{
654 auto &viewInfo = ViewInfo::Get(project);
655 auto &selectedRegion = viewInfo.selectedRegion;
656
657 if (track) {
658 ClipMoveState state;
659
660 auto t0 = selectedRegion.t0();
661
662 std::unique_ptr<TrackShifter> uShifter;
663
664 // Find the first channel that has a clip at time t0
665 auto hitTestResult = TrackShifter::HitTestResult::Track;
666 for (auto channel : TrackList::Channels(track) ) {
667 uShifter = MakeTrackShifter::Call( *channel, project );
668 if ( (hitTestResult = uShifter->HitTest( t0, viewInfo )) ==
670 uShifter.reset();
671 else
672 break;
673 }
674
675 if (!uShifter)
676 return 0.0;
677 auto pShifter = uShifter.get();
678 auto desiredT0 = viewInfo.OffsetTimeByPixels( t0, ( right ? 1 : -1 ) );
679 auto desiredSlideAmount = pShifter->HintOffsetLarger( desiredT0 - t0 );
680
681 state.Init( project, pShifter->GetTrack(), hitTestResult, std::move( uShifter ),
682 t0, viewInfo, trackList, syncLocked );
683
684 auto hSlideAmount = state.DoSlideHorizontal( desiredSlideAmount );
685
686 double newT0 = t0 + hSlideAmount;
687 if (hitTestResult != TrackShifter::HitTestResult::Track) {
688 // If necessary, correct for rounding errors. For example,
689 // for a wavetrack, ensure that t0 is still in the clip
690 // which it was within before the move.
691 // (pShifter is still undestroyed in the ClipMoveState.)
692 newT0 = pShifter->AdjustT0(newT0);
693 }
694
695 double diff = selectedRegion.duration();
696 selectedRegion.setTimes(newT0, newT0 + diff);
697
698 return hSlideAmount;
699 };
700 return 0.0;
701}
static Return Call(This &obj, Arguments &&...arguments)
Invoke the method – but only after static initialization time.
@ Track
Shift selected track and sister channels only, as a whole.
@ Miss
Don't shift anything.
double DoSlideHorizontal(double desiredSlideAmount)
Do sliding of tracks and intervals, maybe adjusting the offset.
void Init(AudacityProject &project, Track &capturedTrack, TrackShifter::HitTestResult hitTestResult, std::unique_ptr< TrackShifter > pHit, double clickTime, const ViewInfo &viewInfo, TrackList &trackList, bool syncLocked)
Will associate a TrackShifter with each track in the list.

References AttachedVirtualFunction< Tag, Return, This, Arguments >::Call(), TrackList::Channels(), ClipMoveState::DoSlideHorizontal(), ViewInfo::Get(), ClipMoveState::Init(), TrackShifter::Miss, and TrackShifter::Track.

Referenced by DoClipLeftOrRight().

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

◆ DoCursorClipBoundary()

void anonymous_namespace{ClipMenus.cpp}::DoCursorClipBoundary ( AudacityProject project,
bool  next 
)

Definition at line 626 of file ClipMenus.cpp.

628{
629 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
630 auto &trackFocus = TrackFocus::Get( project );
631 auto &window = ProjectWindow::Get( project );
632
633 std::vector<FoundClipBoundary> results;
634 FindClipBoundaries(project, next ? selectedRegion.t1() :
635 selectedRegion.t0(), next, results);
636
637 if (results.size() > 0) {
638 // note that if there is more than one result, each has the same time
639 // value.
640 double time = results[0].time;
641 selectedRegion.setTimes(time, time);
642 ProjectHistory::Get( project ).ModifyState(false);
643 window.ScrollIntoView(selectedRegion.t0());
644
645 auto message = ClipBoundaryMessage(results);
646 trackFocus.MessageForScreenReader(message);
647 }
648}
void ModifyState(bool bWantsAutoSave)
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:217
int FindClipBoundaries(AudacityProject &project, double time, bool next, std::vector< FoundClipBoundary > &finalResults)
Definition: ClipMenus.cpp:261
TranslatableString ClipBoundaryMessage(const std::vector< FoundClipBoundary > &results)
Definition: ClipMenus.cpp:319

References ClipBoundaryMessage(), FindClipBoundaries(), TrackFocus::Get(), ProjectHistory::Get(), ViewInfo::Get(), ProjectWindow::Get(), ProjectHistory::ModifyState(), and ViewInfo::selectedRegion.

Referenced by OnCursorNextClipBoundary(), and OnCursorPrevClipBoundary().

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

◆ DoSelectClip()

void anonymous_namespace{ClipMenus.cpp}::DoSelectClip ( AudacityProject project,
bool  next 
)

Definition at line 576 of file ClipMenus.cpp.

577{
578 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
579 auto &trackFocus = TrackFocus::Get( project );
580 auto &window = ProjectWindow::Get( project );
581
582 std::vector<FoundClip> results;
583 FindClips(project, selectedRegion.t0(),
584 selectedRegion.t1(), next, results);
585
586 if (results.size() > 0) {
587 // note that if there is more than one result, each has the same start
588 // and end time
589 double t0 = results[0].startTime;
590 double t1 = results[0].endTime;
591 selectedRegion.setTimes(t0, t1);
592 ProjectHistory::Get( project ).ModifyState(false);
593 window.ScrollIntoView(selectedRegion.t0());
594
595 // create and send message to screen reader
596 TranslatableString message;
597 for (auto& result : results) {
598 auto longName = result.ComposeTrackName();
599 auto nClips = result.waveTrack->GetNumClips();
600 auto str = XP(
601 /* i18n-hint:
602 first string is the name of a clip,
603 first number gives the position of that clip
604 in a sequence of clips,
605 last number counts all clips,
606 last string names a track */
607 "%s, %d of %d clip %s",
608 "%s, %d of %d clips %s",
609 2
610 )(
611 result.name,
612 result.index + 1,
613 nClips,
614 longName
615 );
616
617 if (message.empty())
618 message = str;
619 else
620 message = XO("%s, %s").Format( message, str );
621 }
622 trackFocus.MessageForScreenReader(message);
623 }
624}
int FindClips(AudacityProject &project, double t0, double t1, bool next, std::vector< FoundClip > &finalResults)
Definition: ClipMenus.cpp:499

References TranslatableString::empty(), FindClips(), TrackFocus::Get(), ProjectHistory::Get(), ViewInfo::Get(), ProjectWindow::Get(), ProjectHistory::ModifyState(), ViewInfo::selectedRegion, str, XO(), and XP.

Referenced by OnSelectNextClip(), and OnSelectPrevClip().

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

◆ DoSelectClipBoundary()

void anonymous_namespace{ClipMenus.cpp}::DoSelectClipBoundary ( AudacityProject project,
bool  next 
)

Definition at line 388 of file ClipMenus.cpp.

389{
390 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
391 auto &trackFocus = TrackFocus::Get( project );
392
393 std::vector<FoundClipBoundary> results;
394 FindClipBoundaries(project, next ? selectedRegion.t1() :
395 selectedRegion.t0(), next, results);
396
397 if (results.size() > 0) {
398 // note that if there is more than one result, each has the same time
399 // value.
400 if (next)
401 selectedRegion.setT1(results[0].time);
402 else
403 selectedRegion.setT0(results[0].time);
404
405 ProjectHistory::Get( project ).ModifyState(false);
406
407 auto message = ClipBoundaryMessage(results);
408 trackFocus.MessageForScreenReader(message);
409 }
410}

References ClipBoundaryMessage(), FindClipBoundaries(), TrackFocus::Get(), ProjectHistory::Get(), ViewInfo::Get(), ProjectHistory::ModifyState(), and ViewInfo::selectedRegion.

Referenced by OnSelectCursorToNextClipBoundary(), and OnSelectPrevClipBoundaryToCursor().

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

◆ ExtraTimeShiftItems()

BaseItemSharedPtr anonymous_namespace{ClipMenus.cpp}::ExtraTimeShiftItems ( )

Definition at line 877 of file ClipMenus.cpp.

878{
880 static BaseItemSharedPtr items{
881 Items( wxT("TimeShift"),
882 Command( wxT("ClipLeft"), XXO("Time Shift &Left"), OnClipLeft,
884 Command( wxT("ClipRight"), XXO("Time Shift &Right"), OnClipRight,
886 ) };
887 return items;
888}
const ReservedCommandFlag & TracksExistFlag()
const ReservedCommandFlag & TrackPanelHasFocus()
void OnClipLeft(const CommandContext &context)
Definition: ClipMenus.cpp:794
void OnClipRight(const CommandContext &context)
Definition: ClipMenus.cpp:806
Options && WantKeyUp() &&

References MenuTable::Command(), MenuTable::Items(), OnClipLeft(), OnClipRight(), TrackPanelHasFocus(), TracksExistFlag(), CommandManager::Options::WantKeyUp(), wxT(), and XXO().

Here is the call graph for this function:

◆ FindClipBoundaries()

int anonymous_namespace{ClipMenus.cpp}::FindClipBoundaries ( AudacityProject project,
double  time,
bool  next,
std::vector< FoundClipBoundary > &  finalResults 
)

Definition at line 260 of file ClipMenus.cpp.

263{
264 auto &tracks = TrackList::Get( project );
265 finalResults.clear();
266
267 bool anyWaveTracksSelected{ tracks.Selected< const WaveTrack >() };
268
269
270 // first search the tracks individually
271
272 std::vector<FoundClipBoundary> results;
273
274 int nTracksSearched = 0;
275 auto leaders = tracks.Leaders();
276 auto rangeLeaders = leaders.Filter<const WaveTrack>();
277 if (anyWaveTracksSelected)
278 rangeLeaders = rangeLeaders + &Track::GetSelected;
279 for (auto waveTrack : rangeLeaders) {
280 bool stereoAndDiff = ChannelsHaveDifferentClipBoundaries(waveTrack);
281
282 auto rangeChan = stereoAndDiff
283 ? TrackList::Channels( waveTrack )
284 : TrackList::SingletonRange(waveTrack);
285
286 for (auto wt : rangeChan) {
287 auto result = next ? FindNextClipBoundary(wt, time) :
288 FindPrevClipBoundary(wt, time);
289 if (result.nFound > 0) {
290 result.trackNum =
291 1 + std::distance( leaders.begin(), leaders.find( waveTrack ) );
292 result.channel = stereoAndDiff;
293 results.push_back(result);
294 }
295 }
296
297 nTracksSearched++;
298 }
299
300
301 if (results.size() > 0) {
302 // If any clip boundaries were found
303 // find the clip boundary or boundaries with the min/max time
304 auto compare = [] (const FoundClipBoundary& a, const FoundClipBoundary&b)
305 { return a.time < b.time; };
306
307 auto p = next ? min_element(results.begin(), results.end(), compare ) :
308 max_element(results.begin(), results.end(), compare);
309
310 for ( auto &r : results )
311 if ( r.time == (*p).time )
312 finalResults.push_back( r );
313 }
314
315 return nTracksSearched; // can be used for screen reader messages if required
316}
bool GetSelected() const
Definition: Track.h:469
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1338
A Track that contains audio waveform data.
Definition: WaveTrack.h:57
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
FoundClipBoundary FindNextClipBoundary(const WaveTrack *wt, double time)
Definition: ClipMenus.cpp:144
FoundClipBoundary FindPrevClipBoundary(const WaveTrack *wt, double time)
Definition: ClipMenus.cpp:197
bool ChannelsHaveDifferentClipBoundaries(const WaveTrack *wt)
Definition: ClipMenus.cpp:83

References TrackList::Channels(), ChannelsHaveDifferentClipBoundaries(), FindNextClipBoundary(), FindPrevClipBoundary(), TrackList::Get(), Track::GetSelected(), TrackList::SingletonRange(), and anonymous_namespace{ClipMenus.cpp}::FoundClipBoundary::time.

Referenced by DoCursorClipBoundary(), and DoSelectClipBoundary().

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

◆ FindClips()

int anonymous_namespace{ClipMenus.cpp}::FindClips ( AudacityProject project,
double  t0,
double  t1,
bool  next,
std::vector< FoundClip > &  finalResults 
)

Definition at line 498 of file ClipMenus.cpp.

501{
502 auto &tracks = TrackList::Get( project );
503 finalResults.clear();
504
505 bool anyWaveTracksSelected{ tracks.Selected< const WaveTrack >() };
506
507 // first search the tracks individually
508
509 std::vector<FoundClip> results;
510
511 int nTracksSearched = 0;
512 auto leaders = tracks.Leaders();
513 auto rangeLeaders = leaders.Filter<const WaveTrack>();
514 if (anyWaveTracksSelected)
515 rangeLeaders = rangeLeaders + &Track::GetSelected;
516 for (auto waveTrack : rangeLeaders) {
517 bool stereoAndDiff = ChannelsHaveDifferentClipBoundaries(waveTrack);
518
519 auto rangeChans = stereoAndDiff
520 ? TrackList::Channels( waveTrack )
521 : TrackList::SingletonRange( waveTrack );
522
523 for ( auto wt : rangeChans ) {
524 auto result = next ? FindNextClip(project, wt, t0, t1) :
525 FindPrevClip(project, wt, t0, t1);
526 if (result.found) {
527 result.trackNum =
528 1 + std::distance( leaders.begin(), leaders.find( waveTrack ) );
529 result.channel = stereoAndDiff;
530 results.push_back(result);
531 }
532 }
533
534 nTracksSearched++;
535 }
536
537
538 if (results.size() > 0) {
539 // if any clips were found,
540 // find the clip or clips with the min/max start time
541 auto compareStart = [] (const FoundClip& a, const FoundClip& b)
542 { return a.startTime < b.startTime; };
543
544 auto pStart = next
545 ? std::min_element(results.begin(), results.end(), compareStart)
546 : std::max_element(results.begin(), results.end(), compareStart);
547
548 std::vector<FoundClip> resultsStartTime;
549 for ( auto &r : results )
550 if ( r.startTime == (*pStart).startTime )
551 resultsStartTime.push_back( r );
552
553 if (resultsStartTime.size() > 1) {
554 // more than one clip with same start time so
555 // find the clip or clips with the min/max end time
556 auto compareEnd = [] (const FoundClip& a, const FoundClip& b)
557 { return a.endTime < b.endTime; };
558
559 auto pEnd = next ? std::min_element(resultsStartTime.begin(),
560 resultsStartTime.end(), compareEnd) :
561 std::max_element(resultsStartTime.begin(),
562 resultsStartTime.end(), compareEnd);
563
564 for ( auto &r : resultsStartTime )
565 if ( r.endTime == (*pEnd).endTime )
566 finalResults.push_back( r );
567 }
568 else {
569 finalResults = resultsStartTime;
570 }
571 }
572
573 return nTracksSearched; // can be used for screen reader messages if required
574}
FoundClip FindNextClip(AudacityProject &project, const WaveTrack *wt, double t0, double t1)
Definition: ClipMenus.cpp:413
FoundClip FindPrevClip(AudacityProject &project, const WaveTrack *wt, double t0, double t1)
Definition: ClipMenus.cpp:455
STL namespace.

References TrackList::Channels(), ChannelsHaveDifferentClipBoundaries(), anonymous_namespace{ClipMenus.cpp}::FoundClip::endTime, FindNextClip(), FindPrevClip(), TrackList::Get(), Track::GetSelected(), TrackList::SingletonRange(), and anonymous_namespace{ClipMenus.cpp}::FoundClip::startTime.

Referenced by DoSelectClip().

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

◆ FindNextClip()

FoundClip anonymous_namespace{ClipMenus.cpp}::FindNextClip ( AudacityProject project,
const WaveTrack wt,
double  t0,
double  t1 
)

Definition at line 412 of file ClipMenus.cpp.

414{
415 (void)project;//Compiler food.
416
417 FoundClip result{};
418 result.waveTrack = wt;
419 const auto clips = wt->SortedClipArray();
420
421 t0 = AdjustForFindingStartTimes(clips, t0);
422
423 {
424 auto p = std::find_if(clips.begin(), clips.end(),
425 [&] (const WaveClip* const& clip) {
426 return clip->GetPlayStartTime() == t0; });
427 if (p != clips.end() && (*p)->GetPlayEndTime() > t1) {
428 result.found = true;
429 result.startTime = (*p)->GetPlayStartTime();
430 result.endTime = (*p)->GetPlayEndTime();
431 result.name = (*p)->GetName();
432 result.index = std::distance(clips.begin(), p);
433 return result;
434 }
435 }
436
437 {
438 auto p = std::find_if(clips.begin(), clips.end(),
439 [&] (const WaveClip* const& clip) {
440 return clip->GetPlayStartTime() > t0; });
441 if (p != clips.end()) {
442 result.found = true;
443 result.startTime = (*p)->GetPlayStartTime();
444 result.endTime = (*p)->GetPlayEndTime();
445 result.name = (*p)->GetName();
446 result.index = std::distance(clips.begin(), p);
447 return result;
448 }
449 }
450
451 return result;
452}
WaveClipPointers SortedClipArray()
Definition: WaveTrack.cpp:2720
double AdjustForFindingStartTimes(const std::vector< const WaveClip * > &clips, double time)
Definition: ClipMenus.cpp:107

References AdjustForFindingStartTimes(), WaveTrack::SortedClipArray(), and anonymous_namespace{ClipMenus.cpp}::FoundTrack::waveTrack.

Referenced by FindClips().

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

◆ FindNextClipBoundary()

FoundClipBoundary anonymous_namespace{ClipMenus.cpp}::FindNextClipBoundary ( const WaveTrack wt,
double  time 
)

Definition at line 143 of file ClipMenus.cpp.

145{
146 FoundClipBoundary result{};
147 result.waveTrack = wt;
148 const auto clips = wt->SortedClipArray();
149 double timeStart = AdjustForFindingStartTimes(clips, time);
150 double timeEnd = AdjustForFindingEndTimes(clips, time);
151
152 auto pStart = std::find_if(clips.begin(), clips.end(),
153 [&] (const WaveClip* const& clip) {
154 return clip->GetPlayStartTime() > timeStart; });
155 auto pEnd = std::find_if(clips.begin(), clips.end(),
156 [&] (const WaveClip* const& clip) {
157 return clip->GetPlayEndTime() > timeEnd; });
158
159 if (pStart != clips.end() && pEnd != clips.end()) {
160 if ((*pEnd)->SharesBoundaryWithNextClip(*pStart)) {
161 // boundary between two clips which are immediately next to each other.
162 result.nFound = 2;
163 result.time = (*pEnd)->GetPlayEndTime();
164 result.index1 = std::distance(clips.begin(), pEnd);
165 result.name1 = (*pEnd)->GetName();
166 result.clipStart1 = false;
167 result.index2 = std::distance(clips.begin(), pStart);
168 result.name2 = (*pStart)->GetName();
169 result.clipStart2 = true;
170 }
171 else if ((*pStart)->GetPlayStartTime() < (*pEnd)->GetPlayEndTime()) {
172 result.nFound = 1;
173 result.time = (*pStart)->GetPlayStartTime();
174 result.index1 = std::distance(clips.begin(), pStart);
175 result.name1 = (*pStart)->GetName();
176 result.clipStart1 = true;
177 }
178 else {
179 result.nFound = 1;
180 result.time = (*pEnd)->GetPlayEndTime();
181 result.index1 = std::distance(clips.begin(), pEnd);
182 result.name1 = (*pEnd)->GetName();
183 result.clipStart1 = false;
184 }
185 }
186 else if (pEnd != clips.end()) {
187 result.nFound = 1;
188 result.time = (*pEnd)->GetPlayEndTime();
189 result.index1 = std::distance(clips.begin(), pEnd);
190 result.name1 = (*pEnd)->GetName();
191 result.clipStart1 = false;
192 }
193
194 return result;
195}
double AdjustForFindingEndTimes(const std::vector< const WaveClip * > &clips, double time)
Definition: ClipMenus.cpp:129

References AdjustForFindingEndTimes(), AdjustForFindingStartTimes(), WaveTrack::SortedClipArray(), and anonymous_namespace{ClipMenus.cpp}::FoundTrack::waveTrack.

Referenced by FindClipBoundaries().

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

◆ FindPrevClip()

FoundClip anonymous_namespace{ClipMenus.cpp}::FindPrevClip ( AudacityProject project,
const WaveTrack wt,
double  t0,
double  t1 
)

Definition at line 454 of file ClipMenus.cpp.

456{
457 (void)project;//Compiler food.
458
459 FoundClip result{};
460 result.waveTrack = wt;
461 const auto clips = wt->SortedClipArray();
462
463 t0 = AdjustForFindingStartTimes(clips, t0);
464
465 {
466 auto p = std::find_if(clips.begin(), clips.end(),
467 [&] (const WaveClip* const& clip) {
468 return clip->GetPlayStartTime() == t0; });
469 if (p != clips.end() && (*p)->GetPlayEndTime() < t1) {
470 result.found = true;
471 result.startTime = (*p)->GetPlayStartTime();
472 result.endTime = (*p)->GetPlayEndTime();
473 result.name = (*p)->GetName();
474 result.index = std::distance(clips.begin(), p);
475 return result;
476 }
477 }
478
479 {
480 auto p = std::find_if(clips.rbegin(), clips.rend(),
481 [&] (const WaveClip* const& clip) {
482 return clip->GetPlayStartTime() < t0; });
483 if (p != clips.rend()) {
484 result.found = true;
485 result.startTime = (*p)->GetPlayStartTime();
486 result.endTime = (*p)->GetPlayEndTime();
487 result.name = (*p)->GetName();
488 result.index =
489 static_cast<int>(clips.size()) - 1 -
490 std::distance(clips.rbegin(), p);
491 return result;
492 }
493 }
494
495 return result;
496}

References AdjustForFindingStartTimes(), WaveTrack::SortedClipArray(), and anonymous_namespace{ClipMenus.cpp}::FoundTrack::waveTrack.

Referenced by FindClips().

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

◆ FindPrevClipBoundary()

FoundClipBoundary anonymous_namespace{ClipMenus.cpp}::FindPrevClipBoundary ( const WaveTrack wt,
double  time 
)

Definition at line 197 of file ClipMenus.cpp.

198{
199 FoundClipBoundary result{};
200 result.waveTrack = wt;
201 const auto clips = wt->SortedClipArray();
202 double timeStart = AdjustForFindingStartTimes(clips, time);
203 double timeEnd = AdjustForFindingEndTimes(clips, time);
204
205 auto pStart = std::find_if(clips.rbegin(), clips.rend(),
206 [&] (const WaveClip* const& clip) {
207 return clip->GetPlayStartTime() < timeStart; });
208 auto pEnd = std::find_if(clips.rbegin(), clips.rend(),
209 [&] (const WaveClip* const& clip) {
210 return clip->GetPlayEndTime() < timeEnd; });
211
212 if (pStart != clips.rend() && pEnd != clips.rend()) {
213 if ((*pEnd)->SharesBoundaryWithNextClip(*pStart)) {
214 // boundary between two clips which are immediately next to each other.
215 result.nFound = 2;
216 result.time = (*pStart)->GetPlayStartTime();
217 result.index1 =
218 static_cast<int>(clips.size()) - 1 -
219 std::distance(clips.rbegin(), pStart);
220 result.name1 = (*pStart)->GetName();
221 result.clipStart1 = true;
222 result.index2 =
223 static_cast<int>(clips.size()) - 1 -
224 std::distance(clips.rbegin(), pEnd);
225 result.name2 = (*pEnd)->GetName();
226 result.clipStart2 = false;
227 }
228 else if ((*pStart)->GetPlayStartTime() > (*pEnd)->GetPlayEndTime()) {
229 result.nFound = 1;
230 result.time = (*pStart)->GetPlayStartTime();
231 result.index1 =
232 static_cast<int>(clips.size()) - 1 -
233 std::distance(clips.rbegin(), pStart);
234 result.name1 = (*pStart)->GetName();
235 result.clipStart1 = true;
236 }
237 else {
238 result.nFound = 1;
239 result.time = (*pEnd)->GetPlayEndTime();
240 result.index1 =
241 static_cast<int>(clips.size()) - 1 -
242 std::distance(clips.rbegin(), pEnd);
243 result.name1 = (*pEnd)->GetName();
244 result.clipStart1 = false;
245 }
246 }
247 else if (pStart != clips.rend()) {
248 result.nFound = 1;
249 result.time = (*pStart)->GetPlayStartTime();
250 result.index1 =
251 static_cast<int>(clips.size()) - 1 -
252 std::distance(clips.rbegin(), pStart);
253 result.name1 = (*pStart)->GetName();
254 result.clipStart1 = true;
255 }
256
257 return result;
258}

References AdjustForFindingEndTimes(), AdjustForFindingStartTimes(), WaveTrack::SortedClipArray(), and anonymous_namespace{ClipMenus.cpp}::FoundTrack::waveTrack.

Referenced by FindClipBoundaries().

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

◆ OnClipLeft()

void anonymous_namespace{ClipMenus.cpp}::OnClipLeft ( const CommandContext context)

Definition at line 794 of file ClipMenus.cpp.

795{
796 auto &project = context.project;
797 auto evt = context.pEvt;
798 if (evt)
799 DoClipLeftOrRight( project, false, evt->GetEventType() == wxEVT_KEY_UP );
800 else { // called from menu, so simulate keydown and keyup
801 DoClipLeftOrRight( project, false, false );
802 DoClipLeftOrRight( project, false, true );
803 }
804}
const wxEvent * pEvt
AudacityProject & project
void DoClipLeftOrRight(AudacityProject &project, bool right, bool keyUp)
Definition: ClipMenus.cpp:704

References DoClipLeftOrRight(), CommandContext::pEvt, and CommandContext::project.

Referenced by ExtraTimeShiftItems().

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

◆ OnClipRight()

void anonymous_namespace{ClipMenus.cpp}::OnClipRight ( const CommandContext context)

Definition at line 806 of file ClipMenus.cpp.

807{
808 auto &project = context.project;
809 auto evt = context.pEvt;
810 if (evt)
811 DoClipLeftOrRight( project, true, evt->GetEventType() == wxEVT_KEY_UP );
812 else { // called from menu, so simulate keydown and keyup
813 DoClipLeftOrRight( project, true, false );
814 DoClipLeftOrRight( project, true, true );
815 }
816}

References DoClipLeftOrRight(), CommandContext::pEvt, and CommandContext::project.

Referenced by ExtraTimeShiftItems().

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

◆ OnCursorNextClipBoundary()

void anonymous_namespace{ClipMenus.cpp}::OnCursorNextClipBoundary ( const CommandContext context)

Definition at line 785 of file ClipMenus.cpp.

786{
787 AudacityProject &project = context.project;
788
789 DoCursorClipBoundary(project, true);
790}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
void DoCursorClipBoundary(AudacityProject &project, bool next)
Definition: ClipMenus.cpp:627

References DoCursorClipBoundary(), and CommandContext::project.

Referenced by ClipCursorItems().

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

◆ OnCursorPrevClipBoundary()

void anonymous_namespace{ClipMenus.cpp}::OnCursorPrevClipBoundary ( const CommandContext context)

Definition at line 778 of file ClipMenus.cpp.

779{
780 AudacityProject &project = context.project;
781
782 DoCursorClipBoundary(project, false);
783}

References DoCursorClipBoundary(), and CommandContext::project.

Referenced by ClipCursorItems().

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

◆ OnSelectCursorToNextClipBoundary()

void anonymous_namespace{ClipMenus.cpp}::OnSelectCursorToNextClipBoundary ( const CommandContext context)

Definition at line 759 of file ClipMenus.cpp.

761{
762 auto &project = context.project;
763 DoSelectClipBoundary(project, true);
764}
void DoSelectClipBoundary(AudacityProject &project, bool next)
Definition: ClipMenus.cpp:388

References DoSelectClipBoundary(), and CommandContext::project.

Referenced by ClipSelectMenu().

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

◆ OnSelectNextClip()

void anonymous_namespace{ClipMenus.cpp}::OnSelectNextClip ( const CommandContext context)

Definition at line 772 of file ClipMenus.cpp.

773{
774 auto &project = context.project;
775 DoSelectClip(project, true);
776}
void DoSelectClip(AudacityProject &project, bool next)
Definition: ClipMenus.cpp:576

References DoSelectClip(), and CommandContext::project.

Referenced by ClipSelectMenu().

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

◆ OnSelectPrevClip()

void anonymous_namespace{ClipMenus.cpp}::OnSelectPrevClip ( const CommandContext context)

Definition at line 766 of file ClipMenus.cpp.

767{
768 auto &project = context.project;
769 DoSelectClip(project, false);
770}

References DoSelectClip(), and CommandContext::project.

Referenced by ClipSelectMenu().

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

◆ OnSelectPrevClipBoundaryToCursor()

void anonymous_namespace{ClipMenus.cpp}::OnSelectPrevClipBoundaryToCursor ( const CommandContext context)

Definition at line 752 of file ClipMenus.cpp.

754{
755 auto &project = context.project;
756 DoSelectClipBoundary(project, false);
757}

References DoSelectClipBoundary(), and CommandContext::project.

Referenced by ClipSelectMenu().

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

◆ TwoChannelsHaveSameBoundaries()

bool anonymous_namespace{ClipMenus.cpp}::TwoChannelsHaveSameBoundaries ( const WaveTrack first,
const WaveTrack second 
)

Definition at line 58 of file ClipMenus.cpp.

60{
61 bool sameClips = false;
62
63 auto& left = first->GetClips();
64 auto& right = second->GetClips();
65
66 // PRL: should that have been? :
67 // auto left = first->SortedClipArray();
68 // auto right = second->SortedClipArray();
69
70 if (left.size() == right.size()) {
71 sameClips = true;
72 for (unsigned int i = 0; i < left.size(); i++) {
73 if (left[i]->GetPlayStartTime() != right[i]->GetPlayStartTime() ||
74 left[i]->GetPlayEndTime() != right[i]->GetPlayEndTime()) {
75 sameClips = false;
76 break;
77 }
78 }
79 }
80 return sameClips;
81}
WaveClipHolders & GetClips()
Definition: WaveTrack.h:338

References WaveTrack::GetClips().

Referenced by ChannelsHaveDifferentClipBoundaries().

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

Variable Documentation

◆ sAttachment1

AttachedItem anonymous_namespace{ClipMenus.cpp}::sAttachment1
Initial value:
{
wxT("Select/Basic"),
}
BaseItemSharedPtr ClipSelectMenu()
Definition: ClipMenus.cpp:824

Definition at line 848 of file ClipMenus.cpp.

◆ sAttachment2

AttachedItem anonymous_namespace{ClipMenus.cpp}::sAttachment2
Initial value:
{
{ wxT("Transport/Basic/Cursor"),
{ OrderingHint::Before, wxT("CursProjectStart") } },
}
BaseItemSharedPtr ClipCursorItems()
Definition: ClipMenus.cpp:853

Definition at line 871 of file ClipMenus.cpp.

◆ sAttachment3

AttachedItem anonymous_namespace{ClipMenus.cpp}::sAttachment3
Initial value:
{
{ wxT("Optional/Extra/Part1/Edit"), { OrderingHint::End, {} } },
}
BaseItemSharedPtr ExtraTimeShiftItems()
Definition: ClipMenus.cpp:877

Definition at line 890 of file ClipMenus.cpp.