diff --git a/src/menus/LabelMenus.cpp b/src/menus/LabelMenus.cpp index f932b07c2..233113909 100644 --- a/src/menus/LabelMenus.cpp +++ b/src/menus/LabelMenus.cpp @@ -7,7 +7,6 @@ #include "../Project.h" #include "../ProjectAudioIO.h" #include "../ProjectHistory.h" -#include "../ProjectWindow.h" #include "../TrackPanelAx.h" #include "../TrackPanel.h" #include "../ViewInfo.h" @@ -51,7 +50,6 @@ int DoAddLabel( auto &tracks = TrackList::Get( project ); auto &trackFocus = TrackFocus::Get( project ); auto &trackPanel = TrackPanel::Get( project ); - auto &window = ProjectWindow::Get( project ); wxString title; // of label @@ -151,7 +149,7 @@ void GetRegionsByLabel( } } -using EditFunction = void (WaveTrack::*)(double, double); +using EditFunction = std::function; //Executes the edit function on all selected wave tracks with //regions specified by selected labels @@ -161,7 +159,7 @@ using EditFunction = void (WaveTrack::*)(double, double); // selected tracks. void EditByLabel( TrackList &tracks, const SelectedRegion &selectedRegion, - EditFunction action, bool bSyncLockedTracks ) + EditFunction action) { Regions regions; @@ -169,27 +167,23 @@ void EditByLabel( if( regions.size() == 0 ) return; - // if at least one wave track is selected - // apply only on the selected track - const bool allTracks = (tracks.Selected< WaveTrack >()).empty(); - - //Apply action on wavetracks starting from + //Apply action on tracks starting from //labeled regions in the end. This is to correctly perform //actions like 'Delete' which collapse the track area. - for (auto wt : tracks.Any()) + for (auto t : tracks.Any()) { - if (allTracks || wt->GetSelected() || - (bSyncLockedTracks && wt->IsSyncLockSelected())) + if (t->GetSelected() || t->IsSyncLockSelected()) { - for (int i = (int)regions.size() - 1; i >= 0; i--) { + for (int i = (int)regions.size() - 1; i >= 0; i--) + { const Region ®ion = regions.at(i); - (wt->*action)(region.start, region.end); + action(t, region.start, region.end); } } } } -using EditDestFunction = std::shared_ptr (WaveTrack::*)(double, double); +using EditDestFunction = std::function; //Executes the edit function on all selected wave tracks with //regions specified by selected labels @@ -207,10 +201,6 @@ void EditClipboardByLabel( AudacityProject &project, if( regions.size() == 0 ) return; - // if at least one wave track is selected - // apply only on the selected track - const bool allTracks = (tracks.Selected< WaveTrack >()).empty(); - auto &clipboard = Clipboard::Get(); clipboard.Clear(); @@ -221,47 +211,48 @@ void EditClipboardByLabel( AudacityProject &project, //labeled regions in the end. This is to correctly perform //actions like 'Cut' which collapse the track area. - for(auto wt : - tracks.Any() - + (allTracks ? &Track::Any : &Track::IsSelected) - ) { - // This track accumulates the needed clips, right to left: - Track::Holder merged; - for( int i = (int)regions.size() - 1; i >= 0; i-- ) + for( auto t : tracks.Any()) + { + if (t->GetSelected() || t->IsSyncLockSelected()) { - const Region ®ion = regions.at(i); - auto dest = ( wt->*action )( region.start, region.end ); - if( dest ) + // This track accumulates the needed clips, right to left: + Track::Holder merged; + for( int i = (int)regions.size() - 1; i >= 0; i-- ) { - Track::FinishCopy( wt, dest.get() ); - if( !merged ) - merged = dest; - else + const Region ®ion = regions.at(i); + auto dest = action(t, region.start, region.end ); + if( dest ) { - // Paste to the beginning; unless this is the first region, - // offset the track to account for time between the regions - if (i < (int)regions.size() - 1) - merged->Offset( - regions.at(i + 1).start - region.end); + Track::FinishCopy( t, dest.get() ); + if( !merged ) + merged = dest; + else + { + // Paste to the beginning; unless this is the first region, + // offset the track to account for time between the regions + if (i < (int)regions.size() - 1) + merged->Offset( + regions.at(i + 1).start - region.end); - // dest may have a placeholder clip at the end that is - // removed when pasting, which is okay because we proceed - // right to left. Any placeholder already in merged is kept. - // Only the rightmost placeholder is important in the final - // result. - merged->Paste( 0.0 , dest.get() ); + // dest may have a placeholder clip at the end that is + // removed when pasting, which is okay because we proceed + // right to left. Any placeholder already in merged is kept. + // Only the rightmost placeholder is important in the final + // result. + merged->Paste( 0.0 , dest.get() ); + } } + else + // nothing copied but there is a 'region', so the 'region' must + // be a 'point label' so offset + if (i < (int)regions.size() - 1) + if (merged) + merged->Offset( + regions.at(i + 1).start - region.end); } - else - // nothing copied but there is a 'region', so the 'region' must - // be a 'point label' so offset - if (i < (int)regions.size() - 1) - if (merged) - merged->Offset( - regions.at(i + 1).start - region.end); + if( merged ) + newClipboard.Add( merged ); } - if( merged ) - newClipboard.Add( merged ); } // Survived possibility of exceptions. Commit changes to the clipboard now. @@ -316,7 +307,6 @@ void OnPasteNewLabel(const CommandContext &context) auto &tracks = TrackList::Get( project ); auto &trackPanel = TrackPanel::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); bool bPastedSomething = false; @@ -387,21 +377,47 @@ void OnCutLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; // Because of grouping the copy may need to operate on different tracks than // the clear, so we do these actions separately. - EditClipboardByLabel( project, - tracks, selectedRegion, &WaveTrack::CopyNonconst ); + auto copyfunc = [&](Track *track, double t0, double t1) + { + Track::Holder dest = nullptr; + track->TypeSwitch( + [&](WaveTrack *t) + { + dest = t->CopyNonconst(t0, t1); + } + ); + return dest; + }; + EditClipboardByLabel( project, tracks, selectedRegion, copyfunc ); - if( gPrefs->Read( wxT( "/GUI/EnableCutLines" ), ( long )0 ) ) - EditByLabel( - tracks, selectedRegion, &WaveTrack::ClearAndAddCutLine, true ); - else - EditByLabel( tracks, selectedRegion, &WaveTrack::Clear, true ); + bool enableCutlines = gPrefs->ReadBool(wxT( "/GUI/EnableCutLines"), false); + auto editfunc = [&](Track *track, double t0, double t1) + { + track->TypeSwitch( + [&](WaveTrack *t) + { + if (enableCutlines) + { + t->ClearAndAddCutLine(t0, t1); + } + else + { + t->Clear(t0, t1); + } + }, + [&](Track *t) + { + t->Clear(t0, t1); + } + ); + }; + EditByLabel(tracks, selectedRegion, editfunc); selectedRegion.collapseToT0(); @@ -418,12 +434,15 @@ void OnDeleteLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; - EditByLabel( tracks, selectedRegion, &WaveTrack::Clear, true ); + auto editfunc = [&](Track *track, double t0, double t1) + { + track->Clear(t0, t1); + }; + EditByLabel(tracks, selectedRegion, editfunc); selectedRegion.collapseToT0(); @@ -439,13 +458,27 @@ void OnSplitCutLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; - EditClipboardByLabel( project, - tracks, selectedRegion, &WaveTrack::SplitCut ); + auto copyfunc = [&](Track *track, double t0, double t1) + { + Track::Holder dest = nullptr; + track->TypeSwitch( + [&](WaveTrack *t) + { + dest = t->SplitCut(t0, t1); + }, + [&](Track *t) + { + dest = t->Copy(t0, t1); + t->Silence(t0, t1); + } + ); + return dest; + }; + EditClipboardByLabel( project, tracks, selectedRegion, copyfunc ); ProjectHistory::Get( project ).PushState( /* i18n-hint: (verb) Audacity has just split cut the labeled audio @@ -460,12 +493,24 @@ void OnSplitDeleteLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; - EditByLabel( tracks, selectedRegion, &WaveTrack::SplitDelete, false ); + auto editfunc = [&](Track *track, double t0, double t1) + { + track->TypeSwitch( + [&](WaveTrack *t) + { + t->SplitDelete(t0, t1); + }, + [&](Track *t) + { + t->Silence(t0, t1); + } + ); + }; + EditByLabel(tracks, selectedRegion, editfunc); ProjectHistory::Get( project ).PushState( /* i18n-hint: (verb) Audacity has just done a special kind of DELETE on @@ -485,7 +530,16 @@ void OnSilenceLabels(const CommandContext &context) if( selectedRegion.isPoint() ) return; - EditByLabel( tracks, selectedRegion, &WaveTrack::Silence, false ); + auto editfunc = [&](Track *track, double t0, double t1) + { + track->TypeSwitch( + [&](WaveTrack *t) + { + t->Silence(t0, t1); + } + ); + }; + EditByLabel(tracks, selectedRegion, editfunc); ProjectHistory::Get( project ).PushState( /* i18n-hint: (verb)*/ @@ -503,8 +557,17 @@ void OnCopyLabels(const CommandContext &context) if( selectedRegion.isPoint() ) return; - EditClipboardByLabel( project, - tracks, selectedRegion, &WaveTrack::CopyNonconst ); + auto copyfunc = [&](Track *track, double t0, double t1) + { + Track::Holder dest = nullptr; + track->TypeSwitch( + [&](WaveTrack *t) + { + dest = t->CopyNonconst(t0, t1); + }); + return dest; + }; + EditClipboardByLabel( project, tracks, selectedRegion, copyfunc ); ProjectHistory::Get( project ).PushState( XO( "Copied labeled audio regions to clipboard" ), /* i18n-hint: (verb)*/ @@ -516,9 +579,20 @@ void OnSplitLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); - EditByLabel( tracks, selectedRegion, &WaveTrack::Split, false ); + if( selectedRegion.isPoint() ) + return; + + auto editfunc = [&](Track *track, double t0, double t1) + { + track->TypeSwitch( + [&](WaveTrack *t) + { + t->Split(t0, t1); + } + ); + }; + EditByLabel(tracks, selectedRegion, editfunc); ProjectHistory::Get( project ).PushState( /* i18n-hint: (verb) past tense. Audacity has just split the labeled @@ -533,12 +607,20 @@ void OnJoinLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; - EditByLabel( tracks, selectedRegion, &WaveTrack::Join, false ); + auto editfunc = [&](Track *track, double t0, double t1) + { + track->TypeSwitch( + [&](WaveTrack *t) + { + t->Join(t0, t1); + } + ); + }; + EditByLabel(tracks, selectedRegion, editfunc); ProjectHistory::Get( project ).PushState( /* i18n-hint: (verb) Audacity has just joined the labeled audio (points or @@ -553,12 +635,20 @@ void OnDisjoinLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; - EditByLabel( tracks, selectedRegion, &WaveTrack::Disjoin, false ); + auto editfunc = [&](Track *track, double t0, double t1) + { + track->TypeSwitch( + [&](WaveTrack *t) + { + t->Disjoin(t0, t1); + } + ); + }; + EditByLabel(tracks, selectedRegion, editfunc); ProjectHistory::Get( project ).PushState( /* i18n-hint: (verb) Audacity has just detached the labeled audio regions.