Fix incidentals to Bug 1331, though not the bug itself...

... See comments #1 and #2 at
http://bugzilla.audacityteam.org/show_bug.cgi?id=1331

Don't make strange undo history if, e.g., R to record (or other keystroke
with undoable effects) interrupts a drag with undoable effects (like time
shift).  Ensure that by first simulating a mouse button up event to stop the
drag, before dispatching the keystroke.

Don't crash if certain other drags, that do not have undoable effects, such
as selection or vertical ruler drag -- are interrupted by a keystroke
command (Ctrl+C in particular could cause crash).  However, in these cases,
the drag is still allowed to continue.
This commit is contained in:
Paul Licameli 2016-05-21 23:19:09 -04:00
parent 079eb3e98e
commit 7e0de9a9bc
4 changed files with 70 additions and 3 deletions

View File

@ -1167,7 +1167,7 @@ bool TrackList::MoveDown(Track * t)
return false;
}
bool TrackList::Contains(Track * t) const
bool TrackList::Contains(const Track * t) const
{
return std::find_if(begin(), end(),
[=](const value_type &track) { return t == track.get(); }

View File

@ -492,7 +492,7 @@ class TrackList final : public wxEvtHandler, public ListOfTracks
#endif
/// Mainly a test function. Uses a linear search, so could be slow.
bool Contains(Track * t) const;
bool Contains(const Track * t) const;
bool IsEmpty() const;
int GetCount() const;

View File

@ -1114,6 +1114,52 @@ void TrackPanel::MakeParentRedrawScrollbars()
mListener->TP_RedrawScrollbars();
}
void TrackPanel::HandleInterruptedDrag()
{
// Certain drags need to complete their effects before handling keystroke shortcut
// commands: those that have undoable editing effects. For others, keystrokes are
// harmless and we do nothing.
switch (mMouseCapture)
{
case IsUncaptured:
case IsVZooming:
case IsSelecting:
case IsSelectingLabelText:
case IsResizing:
case IsResizingBetweenLinkedTracks:
case IsResizingBelowLinkedTracks:
case IsMuting:
case IsSoloing:
case IsMinimizing:
case IsPopping:
case IsZooming:
return;
default:
;
}
/*
So this includes the cases:
IsClosing,
IsAdjustingLabel,
IsAdjustingSample,
IsRearranging,
IsSliding,
IsEnveloping,
IsGainSliding,
IsPanSliding,
WasOverCutLine,
IsStretching
*/
wxMouseEvent evt { wxEVT_LEFT_UP };
evt.SetPosition(this->ScreenToClient(::wxGetMousePosition()));
this->ProcessEvent(evt);
}
bool TrackPanel::HandleEscapeKey(bool down)
{
if (!down)
@ -4756,6 +4802,24 @@ void TrackPanel::OnTrackListUpdated(wxCommandEvent & e)
SetFocusedTrack(NULL);
}
if (!mTracks->Contains(mCapturedTrack)) {
SetCapturedTrack(nullptr);
if (HasCapture())
ReleaseMouse();
}
if (!mTracks->Contains(mFreqSelTrack)) {
mFreqSelTrack = nullptr;
if (HasCapture())
ReleaseMouse();
}
if (!mTracks->Contains(mPopupMenuTarget)) {
mPopupMenuTarget = nullptr;
if (HasCapture())
ReleaseMouse();
}
if (e.GetClientData()) {
OnTrackListResized(e);
return;
@ -5674,6 +5738,8 @@ void TrackPanel::HandleWheelRotationInVRuler
/// Filter captured keys typed into LabelTracks.
void TrackPanel::OnCaptureKey(wxCommandEvent & event)
{
HandleInterruptedDrag();
// Only deal with LabelTracks
Track *t = GetFocusedTrack();
if (!t || t->GetKind() != Track::Label) {
@ -8617,7 +8683,7 @@ void TrackPanel::SetFocusedTrack( Track *t )
AudacityProject::ReleaseKeyboard(this);
}
if (t && t->GetKind() == Track::Label) {
if (t) {
AudacityProject::CaptureKeyboard(this);
}

View File

@ -193,6 +193,7 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
//virtual void SetSelectionFormat(int iformat)
//virtual void SetSnapTo(int snapto)
virtual void HandleInterruptedDrag();
virtual bool HandleEscapeKey(bool down);
virtual void HandleAltKey(bool down);
virtual void HandleShiftKey(bool down);