Possible bug in wx.lib.gridmovers

Hi,

I believe there might be a bug in wx.lib.gridmovers that causes various
exceptions when the grid contains no rows.

Here is a sample app:

···

----------------------------------------------------------

import wx.grid
import wx.lib.gridmovers as gridmovers

class TestFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(TestFrame, self).__init__(*args, **kwargs)

        grid = wx.grid.Grid(self)
        grid.CreateGrid(0, 3)
        grid.SetRowLabelSize(0)
        gridmovers.GridColMover(grid)

if __name__ == '__main__':
    print wx.version()
    app = wx.PySimpleApp(False)
    frame = TestFrame(None)
    frame.Show()
    app.MainLoop()

----------------------------------------------------------

Using version 2.8.9.1 (msw-unicode) on Windows XP, I get the following
traceback if I click in the area to the right of the column labels:

Traceback (most recent call last):
  File
"C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\gridmovers.py",
line 311, in OnPress
    rect = self.grid.ColToRect(col)
  File
"C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\gridmovers.py",
line 79, in _ColToRect
    rect.width = self.GetColSize(col)
  File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\grid.py",
line 1643,
in GetColSize
    return _grid.Grid_GetColSize(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "col >= 0 && col < m_numCols"
failed at
..\..\src\generic\grid.cpp(9842) in wxGrid::GetColSize(): invalid
column index

(A number of other exceptions occur immediately afterwards because the
gridmover class is in an unexpected state)

Also, if I drag one of the columns off the right-hand side of the
window, I get the following traceback:

Traceback (most recent call last):
  File
"C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\gridmovers.py",
line 166, in OnPaint
    iPos = self.GetInsertionPos()
  File
"C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\gridmovers.py",
line 157, in GetInsertionPos
    return self._GetInsertionInfo()[0]
  File
"C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\gridmovers.py",
line 141, in _GetInsertionInfo
    cx = parent.ColToRect(col)[0]
  File
"C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\gridmovers.py",
line 79, in _ColToRect
    rect.width = self.GetColSize(col)
  File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\grid.py",
line 1643,
in GetColSize
    return _grid.Grid_GetColSize(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "col >= 0 && col < m_numCols"
failed at
..\..\src\generic\grid.cpp(9842) in wxGrid::GetColSize(): invalid
column index

I think both of these are triggered by the gridmovers code not checking
the return value of grid.XToCol to see whether the column is valid. The
value gets passed to the _ColToRect function, which (if there are no
rows in the table) calls grid.GetColSize, which raises the exception.

The patch below fixes it for me, but I'm not sure if it's complete. A
similar change should be applied to the GridRowMover, but grid.YToRow
doesn't accept the clipToMinMax parameter like grid.XToCol does.

I hope that helps,

Simon

--- D:\Profiles\nfhd78\My
Documents\virtualenvs\link_planner\Lib\site-packages\wxPython-2.8.7.1-py
2.5-win32.egg\wx\lib\gridmovers.py 2008-09-17 14:45:55.000000000
+-0100
+++
C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\gridmovers.py
2008-10-09 15:41:14.000000000 +-0100
@@ -129,13 +129,13 @@
     def _GetInsertionInfo(self):
         parent = self.GetParent()
         sx = parent.GetViewStart()[0] * self.ux
         sx -= parent.GetRowLabelSize()
         x = self.GetPosition()[0]
         w = self.GetSize()[0]
- sCol = parent.XToCol(x + sx)
+ sCol = parent.XToCol(x + sx, True)
         eCol = parent.XToCol(x + w + sx)
         iPos = xPos = xCol = 99999
         centerPos = x + sx + (w / 2)

         for col in range(sCol,eCol + 1):
             cx = parent.ColToRect(col)[0]
@@ -302,15 +302,19 @@
         px,py = self.grid.ScreenToClientXY(px,py)

         if self.grid.XToEdgeOfCol(px + sx) != wx.NOT_FOUND:
             evt.Skip()
             return

+ col = self.grid.XToCol(px + sx)
+ if col == wx.NOT_FOUND:
+ evt.Skip()
+ return
+
         self.isDragging = True
         self.didMove = False
- col = self.grid.XToCol(px + sx)
         rect = self.grid.ColToRect(col)
         self.cellX = px + sx - rect.x
         size = self.lwin.GetSize()
         rect.y = 0
         rect.x -= sx + _rlSize
         rect.height = size[1]