Fix dragging beyond the rightmost column in generic wxHeaderCtrl

Dragging a column header in a wxHeaderCtrl and dropping it past the
rightmost column resulted in a crash due to accessing a column with
invalid index.

Fix this and correctly move the column to the last position when this
happens instead.

This bug notably affected dragging columns in wxGrid.

Closes https://github.com/wxWidgets/wxWidgets/pull/972
This commit is contained in:
John Gehrig
2018-10-11 15:47:16 -04:00
committed by Vadim Zeitlin
parent 6e3f818da1
commit b07305234c
2 changed files with 34 additions and 4 deletions

View File

@@ -98,6 +98,10 @@ private:
// column 1 but close enough to the divider separating it from column 0)
unsigned int FindColumnAtPoint(int x, bool *onSeparator = NULL) const;
// return the result of FindColumnAtPoint() if it is a valid column,
// otherwise the index of the last (rightmost) displayed column
unsigned int FindColumnClosestToPoint(int xPhysical) const;
// return true if a drag resizing operation is currently in progress
bool IsResizing() const;

View File

@@ -208,6 +208,23 @@ unsigned int wxHeaderCtrl::FindColumnAtPoint(int xPhysical, bool *onSeparator) c
return COL_NONE;
}
unsigned int wxHeaderCtrl::FindColumnClosestToPoint(int xPhysical) const
{
const unsigned int colIndexAtPoint = FindColumnAtPoint(xPhysical);
// valid column found?
if ( colIndexAtPoint != COL_NONE )
return colIndexAtPoint;
// if not, xPhysical must be beyond the rightmost column, so return its
// index instead -- if we have it
const unsigned int count = GetColumnCount();
if ( !count )
return COL_NONE;
return m_colIndices[count - 1];
}
// ----------------------------------------------------------------------------
// wxHeaderCtrl repainting
// ----------------------------------------------------------------------------
@@ -372,7 +389,7 @@ void wxHeaderCtrl::UpdateReorderingMarker(int xPhysical)
// and also a hint indicating where it is going to be inserted if it's
// dropped now
unsigned int col = FindColumnAtPoint(xPhysical);
unsigned int col = FindColumnClosestToPoint(xPhysical);
if ( col != COL_NONE )
{
static const int DROP_MARKER_WIDTH = 4;
@@ -414,15 +431,24 @@ bool wxHeaderCtrl::EndReordering(int xPhysical)
ReleaseMouse();
const int colOld = m_colBeingReordered,
colNew = FindColumnAtPoint(xPhysical);
const int colOld = m_colBeingReordered;
const unsigned colNew = FindColumnClosestToPoint(xPhysical);
m_colBeingReordered = COL_NONE;
// mouse drag must be longer than min distance m_dragOffset
if ( xPhysical - GetColStart(colOld) == m_dragOffset )
{
return false;
}
if ( colNew != colOld )
// cannot proceed without a valid column index
if ( colNew == COL_NONE )
{
return false;
}
if ( static_cast<int>(colNew) != colOld )
{
wxHeaderCtrlEvent event(wxEVT_HEADER_END_REORDER, GetId());
event.SetEventObject(this);