Bug 2616 - Labelled Audio Cut and Delete disabled by Sync-Lock

This commit is contained in:
Leland Lucius 2021-01-19 15:31:06 -06:00
parent dbd517751a
commit 26d8fcad66
1 changed files with 168 additions and 78 deletions

View File

@ -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<void(Track *, double, double)>;
//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<WaveTrack>())
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 &region = regions.at(i);
(wt->*action)(region.start, region.end);
action(t, region.start, region.end);
}
}
}
}
using EditDestFunction = std::shared_ptr<Track> (WaveTrack::*)(double, double);
using EditDestFunction = std::function<Track::Holder (Track *, double, double)>;
//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<WaveTrack>()
+ (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 &region = 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 &region = 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.