1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-21 06:40:08 +02:00

Update to Select Previous/Next clip commands

Previously, these two commands used the clips in the focused track. They now have similar to the Tracks->Pan->Left/Right/Center commands. That is if any audio tracks are selected, the clips in these tracks are used, otherwise the clips in all audio tracks are used.
This commit is contained in:
David Bailes 2017-04-27 11:28:33 +01:00
parent ce1d067f84
commit baf46c1f85
2 changed files with 156 additions and 39 deletions

View File

@ -5509,6 +5509,120 @@ void AudacityProject::OnSelectClipBoundary(bool next)
}
}
AudacityProject::FoundClip AudacityProject::FindNextClip(const WaveTrack* wt, double t0, double t1)
{
AudacityProject::FoundClip result{};
result.waveTrack = wt;
const auto clips = wt->SortedClipArray();
auto p = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
return clip->GetStartTime() == t0; });
if (p != clips.end() && (*p)->GetEndTime() > t1) {
result.found = true;
result.startTime = (*p)->GetStartTime();
result.endTime = (*p)->GetEndTime();
result.index = std::distance(clips.begin(), p);
}
else {
auto p = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
return clip->GetStartTime() > t0; });
if (p != clips.end()) {
result.found = true;
result.startTime = (*p)->GetStartTime();
result.endTime = (*p)->GetEndTime();
result.index = std::distance(clips.begin(), p);
}
}
return result;
}
AudacityProject::FoundClip AudacityProject::FindPrevClip(const WaveTrack* wt, double t0, double t1)
{
AudacityProject::FoundClip result{};
result.waveTrack = wt;
const auto clips = wt->SortedClipArray();
auto p = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
return clip->GetStartTime() == t0; });
if (p != clips.end() && (*p)->GetEndTime() < t1) {
result.found = true;
result.startTime = (*p)->GetStartTime();
result.endTime = (*p)->GetEndTime();
result.index = std::distance(clips.begin(), p);
}
else {
auto p = std::find_if(clips.rbegin(), clips.rend(), [&] (const WaveClip* const& clip) {
return clip->GetStartTime() < t0; });
if (p != clips.rend()) {
result.found = true;
result.startTime = (*p)->GetStartTime();
result.endTime = (*p)->GetEndTime();
result.index = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), p);
}
}
return result;
}
int AudacityProject::FindClips(double t0, double t1, bool next, std::vector<FoundClip>& finalResults)
{
const TrackList* tracks = GetTracks();
finalResults.clear();
bool anyWaveTracksSelected = std::any_of(tracks->begin(), tracks->end(), [] (const movable_ptr<Track>& t) {
return t->GetSelected() && t->GetKind() == Track::Wave; });
// first search the tracks individually
std::vector<FoundClip> results;
int nTracksSearched = 0;
for (auto& track : *tracks) {
if (track->GetKind() == Track::Wave && (!anyWaveTracksSelected || track->GetSelected())) {
auto waveTrack = static_cast<const WaveTrack*>(track.get());
auto result = next ? FindNextClip(waveTrack, t0, t1) :
FindPrevClip(waveTrack, t0, t1);
nTracksSearched++;
if (result.found)
results.push_back(result);
}
}
if (results.size() > 0) {
// if any clips were found,
// find the clip or clips with the min/max start time
auto compareStart = [] (const FoundClip& a, const FoundClip& b)
{ return a.startTime < b.startTime; };
auto p = next ? std::min_element(results.begin(), results.end(), compareStart) :
std::max_element(results.begin(), results.end(), compareStart);
std::vector<FoundClip> resultsStartTime;
std::copy_if(results.begin(), results.end(), std::back_inserter(resultsStartTime),
[&] (const FoundClip& r) { return r.startTime == (*p).startTime; } );
if (resultsStartTime.size() > 1) {
// more than one clip with same start time so
// find the clip or clips with the min/max end time
auto compareEnd = [] (const FoundClip& a, const FoundClip& b)
{ return a.endTime < b.endTime; };
auto p = next ? std::min_element(resultsStartTime.begin(),
resultsStartTime.end(), compareEnd) :
std::max_element(resultsStartTime.begin(),
resultsStartTime.end(), compareEnd);
std::copy_if(resultsStartTime.begin(), resultsStartTime.end(),
std::back_inserter(finalResults),
[&] (const FoundClip& r) { return r.endTime == (*p).endTime; } );
}
else {
finalResults = resultsStartTime;
}
}
return nTracksSearched;
}
void AudacityProject::OnSelectPrevClip()
{
OnSelectClip(false);
@ -5521,50 +5635,43 @@ void AudacityProject::OnSelectNextClip()
void AudacityProject::OnSelectClip(bool next)
{
auto track = mTrackPanel->GetFocusedTrack();
std::vector<FoundClip> results;
int nTracksSearched = FindClips(mViewInfo.selectedRegion.t0(),
mViewInfo.selectedRegion.t1(), next, results);
if (track && track->GetKind() == Track::Wave) {
auto wt = static_cast<WaveTrack*>(track);
const auto clips = wt->SortedClipArray();
double t0 = mViewInfo.selectedRegion.t0();
double t1 = mViewInfo.selectedRegion.t1();
WaveClip* clip = nullptr;
int i = 0;
if (results.size() > 0) {
// note that if there is more than one result, each has the same start
// and end time
double t0 = results[0].startTime;
double t1 = results[0].endTime;
mViewInfo.selectedRegion.setTimes(t0, t1);
ModifyState(false);
mTrackPanel->ScrollIntoView(mViewInfo.selectedRegion.t0());
mTrackPanel->Refresh(false);
if (next) {
auto result = std::find_if(clips.begin(), clips.end(), [&] (WaveClip* const& clip) {
return clip->GetStartTime() == t0; });
if (result != clips.end() && (*result)->GetEndTime() != t1 ) {
clip = *result;
i = result - clips.begin();
}
else {
auto result = std::find_if(clips.begin(), clips.end(), [&] (WaveClip* const& clip) {
return clip->GetStartTime() > t0; });
if (result != clips.end()) {
clip = *result;
i = result - clips.begin();
// create and send message to screen reader
wxString message;
for (auto& result : results) {
wxString temp;
if (nTracksSearched > 1) {
if (result.waveTrack->GetName() == result.waveTrack->GetDefaultName()) {
auto track = std::find_if(GetTracks()->begin(), GetTracks()->end(),
[&] (const movable_ptr<Track>& t) { return t.get() == result.waveTrack; });
temp.Printf(wxT("%s %d "), _("Track"), std::distance(GetTracks()->begin(), track) + 1);
}
}
}
else {
auto result = std::find_if(clips.rbegin(), clips.rend(), [&] (WaveClip* const& clip) {
return clip->GetStartTime() < t0; });
if (result != clips.rend()) {
clip = *result;
i = static_cast<int>(clips.size()) - 1 - (result - clips.rbegin());
}
}
else
temp.Printf(wxT("%s "), result.waveTrack->GetName());
if (clip) {
mViewInfo.selectedRegion.setTimes(clip->GetStartTime(), clip->GetEndTime());
mTrackPanel->ScrollIntoView(mViewInfo.selectedRegion.t0());
ModifyState(false);
mTrackPanel->Refresh(false);
wxString message;
message.Printf(wxT("%d %s %d %s"), i + 1, _("of"), clips.size(), _("selected"));
mTrackPanel->MessageForScreenReader(message);
message += temp;
}
if (result.waveTrack->GetNumClips() > 1 || nTracksSearched == 1) {
temp.Printf(wxT("%d %s %d "), result.index + 1, _("of"), result.waveTrack->GetNumClips());
message += temp;
}
message += wxT(", ");
}
mTrackPanel->MessageForScreenReader(message);
}
}

View File

@ -288,6 +288,16 @@ void OnSelectStartCursor();
void OnSelectPrevClipBoundaryToCursor();
void OnSelectCursorToNextClipBoundary();
void OnSelectClipBoundary(bool next);
typedef struct FoundClip {
const WaveTrack* waveTrack;
bool found;
double startTime;
double endTime;
int index;
} FoundClip;
FoundClip FindNextClip(const WaveTrack* wt, double t0, double t1);
FoundClip FindPrevClip(const WaveTrack* wt, double t0, double t1);
int FindClips(double t0, double t1, bool next, std::vector<FoundClip>& results);
void OnSelectPrevClip();
void OnSelectNextClip();
void OnSelectClip(bool next);