From 71ac4bb2f5d66be1e51d55936647cfc88c6c7f99 Mon Sep 17 00:00:00 2001 From: David Bailes Date: Tue, 11 Jul 2017 15:25:21 +0100 Subject: [PATCH] Fixes for commands to move cursor to or select to clip boundaries The messages sent to screen readers for these commands were incorrect when stereo tracks were present. This has been fixed, including the case where the two channels of a stereo track have different clip boundaries. --- src/Menus.cpp | 72 +++++++++++++++++++++++++++++++++++---------------- src/Menus.h | 4 ++- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index 179f1871e..f04e4a34e 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -5936,7 +5936,7 @@ void AudacityProject::OnSelectCursorToNextClipBoundary() void AudacityProject::OnSelectClipBoundary(bool next) { std::vector results; - int nTracksSearched = FindClipBoundaries(next ? mViewInfo.selectedRegion.t1() : + FindClipBoundaries(next ? mViewInfo.selectedRegion.t1() : mViewInfo.selectedRegion.t0(), next, results); if (results.size() > 0) { @@ -5949,7 +5949,7 @@ void AudacityProject::OnSelectClipBoundary(bool next) ModifyState(false); mTrackPanel->Refresh(false); - wxString message = ClipBoundaryMessage(nTracksSearched, results); + wxString message = ClipBoundaryMessage(results); mTrackPanel->MessageForScreenReader(message); } } @@ -7138,20 +7138,46 @@ int AudacityProject::FindClipBoundaries(double time, bool next, std::vector& t) { return t->GetSelected() && t->GetKind() == Track::Wave; }); + // first search the tracks individually + + TrackListIterator iter(GetTracks()); + Track* track = iter.First(); std::vector results; + int nTracksSearched = 0; - for (auto& track : *tracks) { - if ( track->GetKind() == Track::Wave && (!anyWaveTracksSelected || track->GetSelected())) { - auto waveTrack = static_cast(track.get()); + int trackNumber = 1; + while (track) { + if (track->GetKind() == Track::Wave && (!anyWaveTracksSelected || track->GetSelected())) { + auto waveTrack = static_cast(track); + bool stereoAndDiff = waveTrack->GetLinked() && !ChannelsHaveSameClipBoundaries(waveTrack); + auto result = next ? FindNextClipBoundary(waveTrack, time) : FindPrevClipBoundary(waveTrack, time); - nTracksSearched++; - if (result.nFound > 0) + if (result.nFound > 0) { + result.trackNumber = trackNumber; + result.channel = stereoAndDiff; results.push_back(result); + } + if (stereoAndDiff) { + auto waveTrack2 = static_cast(track->GetLink()); + auto result = next ? FindNextClipBoundary(waveTrack2, time) : + FindPrevClipBoundary(waveTrack2, time); + if (result.nFound > 0) { + result.trackNumber = trackNumber; + result.channel = stereoAndDiff; + results.push_back(result); + } + } + + nTracksSearched++; } + + trackNumber++; + track = iter.Next(true); } + if (results.size() > 0) { // If any clip boundaries were found // find the clip boundary or boundaries with the min/max time @@ -7166,7 +7192,7 @@ int AudacityProject::FindClipBoundaries(double time, bool next, std::vector results; - int nTracksSearched = FindClipBoundaries(next ? mViewInfo.selectedRegion.t1() : + FindClipBoundaries(next ? mViewInfo.selectedRegion.t1() : mViewInfo.selectedRegion.t0(), next, results); if (results.size() > 0) { @@ -7194,28 +7220,18 @@ void AudacityProject::OnCursorClipBoundary(bool next) mTrackPanel->ScrollIntoView(mViewInfo.selectedRegion.t0()); mTrackPanel->Refresh(false); - wxString message = ClipBoundaryMessage(nTracksSearched, results); + wxString message = ClipBoundaryMessage(results); mTrackPanel->MessageForScreenReader(message); } } // for clip boundary commands, create a message for screen readers -wxString AudacityProject::ClipBoundaryMessage(int nTracksSearched, const std::vector& results) +wxString AudacityProject::ClipBoundaryMessage(const std::vector& results) { 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 std::shared_ptr& t) { return t.get() == result.waveTrack; }); - temp.Printf(wxT("%s %d "), _("Track"), std::distance(GetTracks()->begin(), track) + 1); - } - else - temp.Printf( wxT("%s "), result.waveTrack->GetName()); - - message += temp; - } + message += (result.clipStart1 ? _("start") : _("end")) + wxT(" "); temp.Printf(wxT("%d %s %d %s "), result.index1 + 1, _("of"), result.waveTrack->GetNumClips(), @@ -7227,6 +7243,18 @@ wxString AudacityProject::ClipBoundaryMessage(int nTracksSearched, const std::ve result.index2 + 1); message += temp; } + + if (result.waveTrack->GetName() == result.waveTrack->GetDefaultName()) + temp.Printf(wxT("%s %d "), _("Track"), result.trackNumber); + else + temp.Printf( wxT("%s "), result.waveTrack->GetName()); + message += temp; + + if (result.channel) { + message += result.waveTrack->GetLinked() ? _("left") : _("right"); + message += wxT(" "); + } + message += wxT(", "); } diff --git a/src/Menus.h b/src/Menus.h index 6afeaddfd..303318b57 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -424,6 +424,8 @@ void OnCursorSelStart(); void OnCursorSelEnd(); typedef struct FoundClipBoundary { const WaveTrack* waveTrack; + int trackNumber; + bool channel; int nFound; // 0, 1, or 2 double time; int index1; @@ -439,7 +441,7 @@ int FindClipBoundaries(double time, bool next, std::vector& r void OnCursorNextClipBoundary(); void OnCursorPrevClipBoundary(); void OnCursorClipBoundary(bool next); -wxString ClipBoundaryMessage(int nTracksSearched, const std::vector& results); +wxString ClipBoundaryMessage(const std::vector& results); void OnAlignNoSync(int index); void OnAlign(int index);