mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-23 17:30:17 +01:00
Bug 2616 - Labelled Audio Cut and Delete disabled by Sync-Lock
This commit is contained in:
@@ -7,7 +7,6 @@
|
|||||||
#include "../Project.h"
|
#include "../Project.h"
|
||||||
#include "../ProjectAudioIO.h"
|
#include "../ProjectAudioIO.h"
|
||||||
#include "../ProjectHistory.h"
|
#include "../ProjectHistory.h"
|
||||||
#include "../ProjectWindow.h"
|
|
||||||
#include "../TrackPanelAx.h"
|
#include "../TrackPanelAx.h"
|
||||||
#include "../TrackPanel.h"
|
#include "../TrackPanel.h"
|
||||||
#include "../ViewInfo.h"
|
#include "../ViewInfo.h"
|
||||||
@@ -51,7 +50,6 @@ int DoAddLabel(
|
|||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &trackFocus = TrackFocus::Get( project );
|
auto &trackFocus = TrackFocus::Get( project );
|
||||||
auto &trackPanel = TrackPanel::Get( project );
|
auto &trackPanel = TrackPanel::Get( project );
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
wxString title; // of label
|
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
|
//Executes the edit function on all selected wave tracks with
|
||||||
//regions specified by selected labels
|
//regions specified by selected labels
|
||||||
@@ -161,7 +159,7 @@ using EditFunction = void (WaveTrack::*)(double, double);
|
|||||||
// selected tracks.
|
// selected tracks.
|
||||||
void EditByLabel(
|
void EditByLabel(
|
||||||
TrackList &tracks, const SelectedRegion &selectedRegion,
|
TrackList &tracks, const SelectedRegion &selectedRegion,
|
||||||
EditFunction action, bool bSyncLockedTracks )
|
EditFunction action)
|
||||||
{
|
{
|
||||||
Regions regions;
|
Regions regions;
|
||||||
|
|
||||||
@@ -169,27 +167,23 @@ void EditByLabel(
|
|||||||
if( regions.size() == 0 )
|
if( regions.size() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if at least one wave track is selected
|
//Apply action on tracks starting from
|
||||||
// apply only on the selected track
|
|
||||||
const bool allTracks = (tracks.Selected< WaveTrack >()).empty();
|
|
||||||
|
|
||||||
//Apply action on wavetracks starting from
|
|
||||||
//labeled regions in the end. This is to correctly perform
|
//labeled regions in the end. This is to correctly perform
|
||||||
//actions like 'Delete' which collapse the track area.
|
//actions like 'Delete' which collapse the track area.
|
||||||
for (auto wt : tracks.Any<WaveTrack>())
|
for (auto t : tracks.Any())
|
||||||
{
|
{
|
||||||
if (allTracks || wt->GetSelected() ||
|
if (t->GetSelected() || t->IsSyncLockSelected())
|
||||||
(bSyncLockedTracks && wt->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);
|
const Region ®ion = 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
|
//Executes the edit function on all selected wave tracks with
|
||||||
//regions specified by selected labels
|
//regions specified by selected labels
|
||||||
@@ -207,10 +201,6 @@ void EditClipboardByLabel( AudacityProject &project,
|
|||||||
if( regions.size() == 0 )
|
if( regions.size() == 0 )
|
||||||
return;
|
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();
|
auto &clipboard = Clipboard::Get();
|
||||||
clipboard.Clear();
|
clipboard.Clear();
|
||||||
|
|
||||||
@@ -221,19 +211,19 @@ void EditClipboardByLabel( AudacityProject &project,
|
|||||||
//labeled regions in the end. This is to correctly perform
|
//labeled regions in the end. This is to correctly perform
|
||||||
//actions like 'Cut' which collapse the track area.
|
//actions like 'Cut' which collapse the track area.
|
||||||
|
|
||||||
for(auto wt :
|
for( auto t : tracks.Any())
|
||||||
tracks.Any<WaveTrack>()
|
{
|
||||||
+ (allTracks ? &Track::Any : &Track::IsSelected)
|
if (t->GetSelected() || t->IsSyncLockSelected())
|
||||||
) {
|
{
|
||||||
// This track accumulates the needed clips, right to left:
|
// This track accumulates the needed clips, right to left:
|
||||||
Track::Holder merged;
|
Track::Holder merged;
|
||||||
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);
|
const Region ®ion = regions.at(i);
|
||||||
auto dest = ( wt->*action )( region.start, region.end );
|
auto dest = action(t, region.start, region.end );
|
||||||
if( dest )
|
if( dest )
|
||||||
{
|
{
|
||||||
Track::FinishCopy( wt, dest.get() );
|
Track::FinishCopy( t, dest.get() );
|
||||||
if( !merged )
|
if( !merged )
|
||||||
merged = dest;
|
merged = dest;
|
||||||
else
|
else
|
||||||
@@ -263,6 +253,7 @@ void EditClipboardByLabel( AudacityProject &project,
|
|||||||
if( merged )
|
if( merged )
|
||||||
newClipboard.Add( merged );
|
newClipboard.Add( merged );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Survived possibility of exceptions. Commit changes to the clipboard now.
|
// Survived possibility of exceptions. Commit changes to the clipboard now.
|
||||||
clipboard.Assign( std::move( newClipboard ),
|
clipboard.Assign( std::move( newClipboard ),
|
||||||
@@ -316,7 +307,6 @@ void OnPasteNewLabel(const CommandContext &context)
|
|||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &trackPanel = TrackPanel::Get( project );
|
auto &trackPanel = TrackPanel::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
bool bPastedSomething = false;
|
bool bPastedSomething = false;
|
||||||
|
|
||||||
@@ -387,21 +377,47 @@ void OnCutLabels(const CommandContext &context)
|
|||||||
auto &project = context.project;
|
auto &project = context.project;
|
||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
if( selectedRegion.isPoint() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Because of grouping the copy may need to operate on different tracks than
|
// Because of grouping the copy may need to operate on different tracks than
|
||||||
// the clear, so we do these actions separately.
|
// the clear, so we do these actions separately.
|
||||||
EditClipboardByLabel( project,
|
auto copyfunc = [&](Track *track, double t0, double t1)
|
||||||
tracks, selectedRegion, &WaveTrack::CopyNonconst );
|
{
|
||||||
|
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 ) )
|
bool enableCutlines = gPrefs->ReadBool(wxT( "/GUI/EnableCutLines"), false);
|
||||||
EditByLabel(
|
auto editfunc = [&](Track *track, double t0, double t1)
|
||||||
tracks, selectedRegion, &WaveTrack::ClearAndAddCutLine, true );
|
{
|
||||||
|
track->TypeSwitch(
|
||||||
|
[&](WaveTrack *t)
|
||||||
|
{
|
||||||
|
if (enableCutlines)
|
||||||
|
{
|
||||||
|
t->ClearAndAddCutLine(t0, t1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
EditByLabel( tracks, selectedRegion, &WaveTrack::Clear, true );
|
{
|
||||||
|
t->Clear(t0, t1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](Track *t)
|
||||||
|
{
|
||||||
|
t->Clear(t0, t1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
EditByLabel(tracks, selectedRegion, editfunc);
|
||||||
|
|
||||||
selectedRegion.collapseToT0();
|
selectedRegion.collapseToT0();
|
||||||
|
|
||||||
@@ -418,12 +434,15 @@ void OnDeleteLabels(const CommandContext &context)
|
|||||||
auto &project = context.project;
|
auto &project = context.project;
|
||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
if( selectedRegion.isPoint() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
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();
|
selectedRegion.collapseToT0();
|
||||||
|
|
||||||
@@ -439,13 +458,27 @@ void OnSplitCutLabels(const CommandContext &context)
|
|||||||
auto &project = context.project;
|
auto &project = context.project;
|
||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
if( selectedRegion.isPoint() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EditClipboardByLabel( project,
|
auto copyfunc = [&](Track *track, double t0, double t1)
|
||||||
tracks, selectedRegion, &WaveTrack::SplitCut );
|
{
|
||||||
|
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(
|
ProjectHistory::Get( project ).PushState(
|
||||||
/* i18n-hint: (verb) Audacity has just split cut the labeled audio
|
/* 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 &project = context.project;
|
||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
if( selectedRegion.isPoint() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
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(
|
ProjectHistory::Get( project ).PushState(
|
||||||
/* i18n-hint: (verb) Audacity has just done a special kind of DELETE on
|
/* 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() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
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(
|
ProjectHistory::Get( project ).PushState(
|
||||||
/* i18n-hint: (verb)*/
|
/* i18n-hint: (verb)*/
|
||||||
@@ -503,8 +557,17 @@ void OnCopyLabels(const CommandContext &context)
|
|||||||
if( selectedRegion.isPoint() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EditClipboardByLabel( project,
|
auto copyfunc = [&](Track *track, double t0, double t1)
|
||||||
tracks, selectedRegion, &WaveTrack::CopyNonconst );
|
{
|
||||||
|
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" ),
|
ProjectHistory::Get( project ).PushState( XO( "Copied labeled audio regions to clipboard" ),
|
||||||
/* i18n-hint: (verb)*/
|
/* i18n-hint: (verb)*/
|
||||||
@@ -516,9 +579,20 @@ void OnSplitLabels(const CommandContext &context)
|
|||||||
auto &project = context.project;
|
auto &project = context.project;
|
||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
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(
|
ProjectHistory::Get( project ).PushState(
|
||||||
/* i18n-hint: (verb) past tense. Audacity has just split the labeled
|
/* 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 &project = context.project;
|
||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
if( selectedRegion.isPoint() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
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(
|
ProjectHistory::Get( project ).PushState(
|
||||||
/* i18n-hint: (verb) Audacity has just joined the labeled audio (points or
|
/* 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 &project = context.project;
|
||||||
auto &tracks = TrackList::Get( project );
|
auto &tracks = TrackList::Get( project );
|
||||||
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
|
||||||
auto &window = ProjectWindow::Get( project );
|
|
||||||
|
|
||||||
if( selectedRegion.isPoint() )
|
if( selectedRegion.isPoint() )
|
||||||
return;
|
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(
|
ProjectHistory::Get( project ).PushState(
|
||||||
/* i18n-hint: (verb) Audacity has just detached the labeled audio regions.
|
/* i18n-hint: (verb) Audacity has just detached the labeled audio regions.
|
||||||
|
|||||||
Reference in New Issue
Block a user