]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
fix crash when the user code refuses to validate the new text when editing the item...
[wxWidgets.git] / src / generic / grid.cpp
index 097a75dcafef49deabfab1da02b52ab8a9a6fb6e..20389dfc4802a7435b0d1f0ae8fe1635a1fb64cf 100644 (file)
@@ -3502,6 +3502,23 @@ void wxGridWindow::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
 
 //////////////////////////////////////////////////////////////////////
 
+// Internal Helper function for computing row or column from some
+// (unscrolled) coordinate value, using either
+// m_defaultRowHeight/m_defaultColWidth or binary search on array
+// of m_rowBottoms/m_ColRights to speed up the search!
+
+// Internal helper macros for simpler use of that function
+
+static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
+                           const wxArrayInt& BorderArray, bool maxOnOverflow);
+
+#define internalXToCol(x) CoordToRowOrCol(x, m_defaultColWidth, \
+                                          WXGRID_MIN_COL_WIDTH, \
+                                          m_colRights, TRUE)
+#define internalYToRow(y) CoordToRowOrCol(y, m_defaultRowHeight, \
+                                          WXGRID_MIN_ROW_HEIGHT, \
+                                          m_rowBottoms, TRUE)
+/////////////////////////////////////////////////////////////////////
 
 IMPLEMENT_DYNAMIC_CLASS( wxGrid, wxScrolledWindow )
 
@@ -3587,7 +3604,8 @@ void wxGrid::Create()
 
     // create the type registry
     m_typeRegistry = new wxGridTypeRegistry;
-    m_selection = 0;
+    m_selection = NULL;
+
     // subwindow components that make up the wxGrid
     m_cornerLabelWin = new wxGridCornerLabelWindow( this,
                                                     -1,
@@ -3653,9 +3671,9 @@ bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership,
     if ( m_created )
     {
         // RD: Actually, this should probably be allowed.  I think it would be
-        // nice to be able to switch multiple Tables in and out of a single
-        // View at runtime.  Is there anything in the implmentation that would
-        // prevent this?
+        //     nice to be able to switch multiple Tables in and out of a single
+        //     View at runtime.  Is there anything in the implementation that
+        //     would prevent this?
 
         // At least, you now have to cope with m_selection
         wxFAIL_MSG( wxT("wxGrid::CreateGrid or wxGrid::SetTable called more than once") );
@@ -3960,7 +3978,9 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
                 //
                 SetCurrentCell( 0, 0 );
             }
-            m_selection->UpdateRows( pos, numRows );
+
+            if ( m_selection )
+                m_selection->UpdateRows( pos, numRows );
             wxGridCellAttrProvider * attrProvider = m_table->GetAttrProvider();
             if (attrProvider)
                 attrProvider->UpdateAttrRows( pos, numRows );
@@ -4043,7 +4063,9 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
                 if ( m_currentCellCoords.GetRow() >= m_numRows )
                     m_currentCellCoords.Set( 0, 0 );
             }
-            m_selection->UpdateRows( pos, -((int)numRows) );
+
+            if ( m_selection )
+                m_selection->UpdateRows( pos, -((int)numRows) );
             wxGridCellAttrProvider * attrProvider = m_table->GetAttrProvider();
             if (attrProvider) {
                 attrProvider->UpdateAttrRows( pos, -((int)numRows) );
@@ -4097,7 +4119,9 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
                 //
                 SetCurrentCell( 0, 0 );
             }
-            m_selection->UpdateCols( pos, numCols );
+
+            if ( m_selection )
+                m_selection->UpdateCols( pos, numCols );
             wxGridCellAttrProvider * attrProvider = m_table->GetAttrProvider();
             if (attrProvider)
                 attrProvider->UpdateAttrCols( pos, numCols );
@@ -4179,7 +4203,9 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
                 if ( m_currentCellCoords.GetCol() >= m_numCols )
                   m_currentCellCoords.Set( 0, 0 );
             }
-            m_selection->UpdateCols( pos, -((int)numCols) );
+
+            if ( m_selection )
+                m_selection->UpdateCols( pos, -((int)numCols) );
             wxGridCellAttrProvider * attrProvider = m_table->GetAttrProvider();
             if (attrProvider) {
                 attrProvider->UpdateAttrCols( pos, -((int)numCols) );
@@ -4243,7 +4269,7 @@ wxArrayInt wxGrid::CalcRowLabelsExposed( const wxRegion& reg )
         // find the row labels within these bounds
         //
         int row;
-        for ( row = YToRow(top);  row < m_numRows;  row++ )
+        for ( row = internalYToRow(top);  row < m_numRows;  row++ )
         {
             if ( GetRowBottom(row) < top )
                 continue;
@@ -4294,7 +4320,7 @@ wxArrayInt wxGrid::CalcColLabelsExposed( const wxRegion& reg )
         // find the cells within these bounds
         //
         int col;
-        for ( col = XToCol(left);  col < m_numCols;  col++ )
+        for ( col = internalXToCol(left);  col < m_numCols;  col++ )
         {
             if ( GetColRight(col) < left )
                 continue;
@@ -4345,7 +4371,7 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg )
         // find the cells within these bounds
         //
         int row, col;
-        for ( row = YToRow(top);  row < m_numRows;  row++ )
+        for ( row = internalYToRow(top);  row < m_numRows;  row++ )
         {
             if ( GetRowBottom(row) <= top )
                 continue;
@@ -4353,7 +4379,7 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg )
             if ( GetRowTop(row) > bottom )
                 break;
 
-            for ( col = XToCol(left);  col < m_numCols;  col++ )
+            for ( col = internalXToCol(left);  col < m_numCols;  col++ )
             {
                 if ( GetColRight(col) <= left )
                     continue;
@@ -4380,7 +4406,11 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
 
     if ( event.Dragging() )
     {
-        m_isDragging = TRUE;
+        if (!m_isDragging)
+        {
+            m_isDragging = TRUE;
+            m_rowLabelWin->CaptureMouse();
+        }
 
         if ( event.LeftIsDown() )
         {
@@ -4410,11 +4440,14 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
                 case WXGRID_CURSOR_SELECT_ROW:
                     if ( (row = YToRow( y )) >= 0 )
                     {
-                        m_selection->SelectRow( row,
-                                                event.ControlDown(),
-                                                event.ShiftDown(),
-                                                event.AltDown(),
-                                                event.MetaDown() );
+                        if ( m_selection )
+                        {
+                            m_selection->SelectRow( row,
+                                                    event.ControlDown(),
+                                                    event.ShiftDown(),
+                                                    event.AltDown(),
+                                                    event.MetaDown() );
+                        }
                     }
 
                 // default label to suppress warnings about "enumeration value
@@ -4426,8 +4459,14 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
         return;
     }
 
-    m_isDragging = FALSE;
+    if ( m_isDragging && (event.Entering() || event.Leaving()) )
+        return;
 
+    if (m_isDragging)
+    {
+        if (m_rowLabelWin->HasCapture()) m_rowLabelWin->ReleaseMouse();
+        m_isDragging = FALSE;
+    }
 
     // ------------ Entering or leaving the window
     //
@@ -4453,21 +4492,29 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
             {
                 if ( !event.ShiftDown() && !event.ControlDown() )
                     ClearSelection();
-                if ( event.ShiftDown() )
-                    m_selection->SelectBlock( m_currentCellCoords.GetRow(),
-                                              0,
-                                              row,
-                                              GetNumberCols() - 1,
-                                              event.ControlDown(),
-                                              event.ShiftDown(),
-                                              event.AltDown(),
-                                              event.MetaDown() );
-                else
-                    m_selection->SelectRow( row,
-                                            event.ControlDown(),
-                                            event.ShiftDown(),
-                                            event.AltDown(),
-                                            event.MetaDown() );
+                else if ( m_selection )
+                {
+                    if ( event.ShiftDown() )
+                    {
+                        m_selection->SelectBlock( m_currentCellCoords.GetRow(),
+                                                  0,
+                                                  row,
+                                                  GetNumberCols() - 1,
+                                                  event.ControlDown(),
+                                                  event.ShiftDown(),
+                                                  event.AltDown(),
+                                                  event.MetaDown() );
+                    }
+                    else
+                    {
+                        m_selection->SelectRow( row,
+                                                event.ControlDown(),
+                                                event.ShiftDown(),
+                                                event.AltDown(),
+                                                event.MetaDown() );
+                    }
+                }
+
                 ChangeCursorMode(WXGRID_CURSOR_SELECT_ROW, m_rowLabelWin);
             }
         }
@@ -4566,7 +4613,11 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
 
     if ( event.Dragging() )
     {
-        m_isDragging = TRUE;
+        if (!m_isDragging)
+        {
+            m_isDragging = TRUE;
+            m_colLabelWin->CaptureMouse();
+        }
 
         if ( event.LeftIsDown() )
         {
@@ -4596,11 +4647,14 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
                 case WXGRID_CURSOR_SELECT_COL:
                     if ( (col = XToCol( x )) >= 0 )
                     {
-                        m_selection->SelectCol( col,
-                                                event.ControlDown(),
-                                                event.ShiftDown(),
-                                                event.AltDown(),
-                                                event.MetaDown() );
+                        if ( m_selection )
+                        {
+                            m_selection->SelectCol( col,
+                                                    event.ControlDown(),
+                                                    event.ShiftDown(),
+                                                    event.AltDown(),
+                                                    event.MetaDown() );
+                        }
                     }
 
                 // default label to suppress warnings about "enumeration value
@@ -4612,8 +4666,14 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
         return;
     }
 
-    m_isDragging = FALSE;
+    if ( m_isDragging && (event.Entering() || event.Leaving()) )
+        return;
 
+    if (m_isDragging)
+    {
+        if (m_colLabelWin->HasCapture()) m_colLabelWin->ReleaseMouse();
+        m_isDragging = FALSE;
+    }
 
     // ------------ Entering or leaving the window
     //
@@ -4639,20 +4699,28 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
             {
                 if ( !event.ShiftDown() && !event.ControlDown() )
                     ClearSelection();
-                if ( event.ShiftDown() )
-                    m_selection->SelectBlock( 0,
-                                              m_currentCellCoords.GetCol(),
-                                              GetNumberRows() - 1, col,
-                                              event.ControlDown(),
-                                              event.ShiftDown(),
-                                              event.AltDown(),
-                                              event.MetaDown() );
-                else
-                    m_selection->SelectCol( col,
-                                            event.ControlDown(),
-                                            event.ShiftDown(),
-                                            event.AltDown(),
-                                            event.MetaDown() );
+                if ( m_selection )
+                {
+                    if ( event.ShiftDown() )
+                    {
+                        m_selection->SelectBlock( 0,
+                                                  m_currentCellCoords.GetCol(),
+                                                  GetNumberRows() - 1, col,
+                                                  event.ControlDown(),
+                                                  event.ShiftDown(),
+                                                  event.AltDown(),
+                                                  event.MetaDown() );
+                    }
+                    else
+                    {
+                        m_selection->SelectCol( col,
+                                                event.ControlDown(),
+                                                event.ShiftDown(),
+                                                event.AltDown(),
+                                                event.MetaDown() );
+                    }
+                }
+
                 ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin);
             }
         }
@@ -4813,7 +4881,7 @@ void wxGrid::ChangeCursorMode(CursorMode mode,
 
     if ( m_winCapture )
     {
-        m_winCapture->ReleaseMouse();
+        if (m_winCapture->HasCapture()) m_winCapture->ReleaseMouse();
         m_winCapture = (wxWindow *)NULL;
     }
 
@@ -4984,14 +5052,17 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
                 ClearSelection();
             if ( event.ShiftDown() )
             {
-                m_selection->SelectBlock( m_currentCellCoords.GetRow(),
-                                          m_currentCellCoords.GetCol(),
-                                          coords.GetRow(),
-                                          coords.GetCol(),
-                                          event.ControlDown(),
-                                          event.ShiftDown(),
-                                          event.AltDown(),
-                                          event.MetaDown() );
+                if ( m_selection )
+                {
+                    m_selection->SelectBlock( m_currentCellCoords.GetRow(),
+                                              m_currentCellCoords.GetCol(),
+                                              coords.GetRow(),
+                                              coords.GetCol(),
+                                              event.ControlDown(),
+                                              event.ShiftDown(),
+                                              event.AltDown(),
+                                              event.MetaDown() );
+                }
             }
             else if ( XToEdgeOfCol(x) < 0  &&
                       YToEdgeOfRow(y) < 0 )
@@ -5021,12 +5092,15 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
                 {
                     if ( event.ControlDown() )
                     {
-                        m_selection->ToggleCellSelection( coords.GetRow(),
-                                                          coords.GetCol(),
-                                                          event.ControlDown(),
-                                                          event.ShiftDown(),
-                                                          event.AltDown(),
-                                                          event.MetaDown() );
+                        if ( m_selection )
+                        {
+                            m_selection->ToggleCellSelection( coords.GetRow(),
+                                                              coords.GetCol(),
+                                                              event.ControlDown(),
+                                                              event.ShiftDown(),
+                                                              event.AltDown(),
+                                                              event.MetaDown() );
+                        }
                         m_selectingTopLeft = wxGridNoCellCoords;
                         m_selectingBottomRight = wxGridNoCellCoords;
                         m_selectingKeyboard = coords;
@@ -5034,9 +5108,14 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
                     else
                     {
                         SetCurrentCell( coords );
-                        if ( m_selection->GetSelectionMode()
-                             != wxGrid::wxGridSelectCells)
-                            HighlightBlock( coords, coords );
+                        if ( m_selection )
+                        {
+                            if ( m_selection->GetSelectionMode() != 
+                                    wxGrid::wxGridSelectCells )
+                            {
+                                HighlightBlock( coords, coords );
+                            }
+                        }
                     }
                     m_waitForSlowClick = TRUE;
                 }
@@ -5072,17 +5151,22 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
             {
                 if (m_winCapture)
                 {
-                    m_winCapture->ReleaseMouse();
+                    if (m_winCapture->HasCapture()) m_winCapture->ReleaseMouse();
                     m_winCapture = NULL;
                 }
-                m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
-                                          m_selectingTopLeft.GetCol(),
-                                          m_selectingBottomRight.GetRow(),
-                                          m_selectingBottomRight.GetCol(),
-                                          event.ControlDown(),
-                                          event.ShiftDown(),
-                                          event.AltDown(),
-                                          event.MetaDown() );
+
+                if ( m_selection )
+                {
+                    m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
+                                              m_selectingTopLeft.GetCol(),
+                                              m_selectingBottomRight.GetRow(),
+                                              m_selectingBottomRight.GetCol(),
+                                              event.ControlDown(),
+                                              event.ShiftDown(),
+                                              event.AltDown(),
+                                              event.MetaDown() );
+                }
+
                 m_selectingTopLeft = wxGridNoCellCoords;
                 m_selectingBottomRight = wxGridNoCellCoords;
             }
@@ -5738,12 +5822,15 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
             case WXK_SPACE:
                 if ( event.ControlDown() )
                 {
-                    m_selection->ToggleCellSelection( m_currentCellCoords.GetRow(),
-                                                      m_currentCellCoords.GetCol(),
-                                                      event.ControlDown(),
-                                                      event.ShiftDown(),
-                                                      event.AltDown(),
-                                                      event.MetaDown() );
+                    if ( m_selection )
+                    {
+                        m_selection->ToggleCellSelection( m_currentCellCoords.GetRow(),
+                                                          m_currentCellCoords.GetCol(),
+                                                          event.ControlDown(),
+                                                          event.ShiftDown(),
+                                                          event.AltDown(),
+                                                          event.MetaDown() );
+                    }
                     break;
                 }
                 if ( !IsEditable() )
@@ -5807,14 +5894,20 @@ void wxGrid::OnKeyUp( wxKeyEvent& event )
     {
         if ( m_selectingTopLeft != wxGridNoCellCoords &&
              m_selectingBottomRight != wxGridNoCellCoords )
-            m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
-                                      m_selectingTopLeft.GetCol(),
-                                      m_selectingBottomRight.GetRow(),
-                                      m_selectingBottomRight.GetCol(),
-                                      event.ControlDown(),
-                                      TRUE,
-                                      event.AltDown(),
-                                      event.MetaDown() );
+        {
+            if ( m_selection )
+            {
+                m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
+                                          m_selectingTopLeft.GetCol(),
+                                          m_selectingBottomRight.GetRow(),
+                                          m_selectingBottomRight.GetCol(),
+                                          event.ControlDown(),
+                                          TRUE,
+                                          event.AltDown(),
+                                          event.MetaDown() );
+            }
+        }
+
         m_selectingTopLeft = wxGridNoCellCoords;
         m_selectingBottomRight = wxGridNoCellCoords;
         m_selectingKeyboard = wxGridNoCellCoords;
@@ -5876,16 +5969,20 @@ void wxGrid::HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCo
     int temp;
     wxGridCellCoords updateTopLeft, updateBottomRight;
 
-    if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectRows )
-    {
-        leftCol = 0;
-        rightCol = GetNumberCols() - 1;
-    }
-    else if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectColumns )
+    if ( m_selection )
     {
-        topRow = 0;
-        bottomRow = GetNumberRows() - 1;
+        if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectRows )
+        {
+            leftCol = 0;
+            rightCol = GetNumberCols() - 1;
+        }
+        else if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectColumns )
+        {
+            topRow = 0;
+            bottomRow = GetNumberRows() - 1;
+        }
     }
+
     if ( topRow > bottomRow )
     {
         temp = topRow;
@@ -6293,7 +6390,7 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
     // horizontal grid lines
     //
     int i;
-    for ( i = YToRow(top); i < m_numRows; i++ )
+    for ( i = internalYToRow(top); i < m_numRows; i++ )
     {
         int bot = GetRowBottom(i) - 1;
 
@@ -6311,7 +6408,7 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
 
     // vertical grid lines
     //
-    for ( i = XToCol(left); i < m_numCols; i++ )
+    for ( i = internalXToCol(left); i < m_numCols; i++ )
     {
         int colRight = GetColRight(i) - 1;
         if ( colRight > right )
@@ -6724,8 +6821,13 @@ void wxGrid::ShowCellEditControl()
 #endif // 0
 
             // cell is shifted by one pixel
-            rect.x--;
-            rect.y--;
+            // However, don't allow x or y to become negative
+            // since the SetSize() method interprets that as
+            // "don't change."
+            if (rect.x > 0)
+                rect.x--;
+            if (rect.y > 0)
+                rect.y--;
 
             wxGridCellAttr* attr = GetCellAttr(row, col);
             wxGridCellEditor* editor = attr->GetEditor(this, row, col);
@@ -6830,16 +6932,16 @@ void wxGrid::XYToCell( int x, int y, wxGridCellCoords& coords )
 
 // Internal Helper function for computing row or column from some
 // (unscrolled) coordinate value, using either
-// m_defaultRowHeight/m_defaultColWidth or binary search on array 
+// m_defaultRowHeight/m_defaultColWidth or binary search on array
 // of m_rowBottoms/m_ColRights to speed up the search!
 
 static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
-                           wxArrayInt BorderArray)
+                           const wxArrayInt& BorderArray, bool maxOnOverflow)
 {
     if (!defaultDist)
         defaultDist = 1;
-    unsigned int i_max = coord / defaultDist,
-                 i_min = 0;
+    size_t i_max = coord / defaultDist,
+           i_min = 0;
     if (BorderArray.IsEmpty())
     {
         return i_max;
@@ -6847,7 +6949,7 @@ static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
 
     if ( i_max >= BorderArray.GetCount())
         i_max = BorderArray.GetCount() - 1;
-    else 
+    else
     {
         if ( coord >= BorderArray[i_max])
         {
@@ -6857,17 +6959,17 @@ static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
         if ( i_max >= BorderArray.GetCount())
             i_max = BorderArray.GetCount() - 1;
     }
-    if ( coord > BorderArray[i_max])    
-        return -1;
+    if ( coord >= BorderArray[i_max])
+        return maxOnOverflow ? (int)i_max : -1;
+    if ( coord < BorderArray[0] )
+        return 0;
 
-    while ( i_max - i_min > 1 )
+    while ( i_max - i_min > 0 )
     {
         wxCHECK_MSG(BorderArray[i_min] <= coord && coord < BorderArray[i_max],
-                    -1, _T("wxGrid: internal error in CoordToRowOrCol"));
+                    0, _T("wxGrid: internal error in CoordToRowOrCol"));
         if (coord >=  BorderArray[ i_max - 1])
-        {
             return i_max;
-        }
         else
             i_max--;
         int median = i_min + (i_max - i_min + 1) / 2;
@@ -6882,14 +6984,14 @@ static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
 int wxGrid::YToRow( int y )
 {
     return CoordToRowOrCol(y, m_defaultRowHeight,
-                           WXGRID_MIN_ROW_HEIGHT, m_rowBottoms);
+                           WXGRID_MIN_ROW_HEIGHT, m_rowBottoms, FALSE);
 }
 
 
 int wxGrid::XToCol( int x )
 {
     return CoordToRowOrCol(x, m_defaultColWidth,
-                           WXGRID_MIN_COL_WIDTH, m_colRights);
+                           WXGRID_MIN_COL_WIDTH, m_colRights, FALSE);
 }
 
 
@@ -6898,16 +7000,17 @@ int wxGrid::XToCol( int x )
 //
 int wxGrid::YToEdgeOfRow( int y )
 {
-    int i, d;
+    int i;
+    i = internalYToRow(y);
 
-    for ( i = YToRow( y ) - 1;  i < m_numRows;  i++ )
+    if ( GetRowHeight(i) > WXGRID_LABEL_EDGE_ZONE )
     {
-        if ( GetRowHeight(i) > WXGRID_LABEL_EDGE_ZONE )
-        {
-            d = abs( y - GetRowBottom(i) );
-            if ( d < WXGRID_LABEL_EDGE_ZONE )
-                return i;
-        }
+        // We know that we are in row i, test whether we are
+        // close enough to lower or upper border, respectively.
+        if ( abs(GetRowBottom(i) - y) < WXGRID_LABEL_EDGE_ZONE )
+            return i;
+        else if( i > 0 && y - GetRowTop(i) < WXGRID_LABEL_EDGE_ZONE )
+            return i - 1;
     }
 
     return -1;
@@ -6919,16 +7022,17 @@ int wxGrid::YToEdgeOfRow( int y )
 //
 int wxGrid::XToEdgeOfCol( int x )
 {
-    int i, d;
+    int i;
+    i = internalXToCol(x);
 
-    for (i = XToCol( x ) - 1;  i < m_numCols;  i++ )
+    if ( GetColWidth(i) > WXGRID_LABEL_EDGE_ZONE )
     {
-        if ( GetColWidth(i) > WXGRID_LABEL_EDGE_ZONE )
-        {
-            d = abs( x - GetColRight(i) );
-            if ( d < WXGRID_LABEL_EDGE_ZONE )
-                return i;
-        }
+        // We know that we are in column i,  test whether we are
+        // close enough to right or left border, respectively.
+        if ( abs(GetColRight(i) - x) < WXGRID_LABEL_EDGE_ZONE )
+            return i;
+        else if( i > 0 && x - GetColLeft(i) < WXGRID_LABEL_EDGE_ZONE )
+            return i - 1;
     }
 
     return -1;
@@ -8717,7 +8821,8 @@ void wxGrid::SelectRow( int row, bool addToSelected )
     if ( IsSelection() && !addToSelected )
         ClearSelection();
 
-    m_selection->SelectRow( row, FALSE, addToSelected );
+    if ( m_selection )
+        m_selection->SelectRow( row, FALSE, addToSelected );
 }
 
 
@@ -8726,7 +8831,8 @@ void wxGrid::SelectCol( int col, bool addToSelected )
     if ( IsSelection() && !addToSelected )
         ClearSelection();
 
-    m_selection->SelectCol( col, FALSE, addToSelected );
+    if ( m_selection )
+        m_selection->SelectCol( col, FALSE, addToSelected );
 }
 
 
@@ -8736,15 +8842,19 @@ void wxGrid::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol,
     if ( IsSelection() && !addToSelected )
         ClearSelection();
 
-    m_selection->SelectBlock( topRow, leftCol, bottomRow, rightCol,
-                              FALSE, addToSelected );
+    if ( m_selection )
+        m_selection->SelectBlock( topRow, leftCol, bottomRow, rightCol,
+                                  FALSE, addToSelected );
 }
 
 
 void wxGrid::SelectAll()
 {
     if ( m_numRows > 0 && m_numCols > 0 )
-        m_selection->SelectBlock( 0, 0, m_numRows-1, m_numCols-1 );
+    {
+        if ( m_selection )
+            m_selection->SelectBlock( 0, 0, m_numRows-1, m_numCols-1 );
+    }
 }
 
 //
@@ -8753,6 +8863,9 @@ void wxGrid::SelectAll()
 
 void wxGrid::DeselectRow( int row )
 {
+    if ( !m_selection )
+        return;
+
     if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectRows )
     {
         if ( m_selection->IsInSelection(row, 0 ) )
@@ -8771,6 +8884,9 @@ void wxGrid::DeselectRow( int row )
 
 void wxGrid::DeselectCol( int col )
 {
+    if ( !m_selection )
+        return;
+
     if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectColumns )
     {
         if ( m_selection->IsInSelection(0, col ) )
@@ -8789,31 +8905,32 @@ void wxGrid::DeselectCol( int col )
 
 void wxGrid::DeselectCell( int row, int col )
 {
-    if ( m_selection->IsInSelection(row, col) )
+    if ( m_selection && m_selection->IsInSelection(row, col) )
         m_selection->ToggleCellSelection(row, col);
 }
 
 bool wxGrid::IsSelection()
 {
-    return ( m_selection->IsSelection() ||
+    return ( m_selection && (m_selection->IsSelection() ||
              ( m_selectingTopLeft != wxGridNoCellCoords &&
-               m_selectingBottomRight != wxGridNoCellCoords ) );
+               m_selectingBottomRight != wxGridNoCellCoords) ) );
 }
 
 bool wxGrid::IsInSelection( int row, int col )
 {
-    return ( m_selection->IsInSelection( row, col ) ||
+    return ( m_selection && (m_selection->IsInSelection( row, col ) ||
              ( row >= m_selectingTopLeft.GetRow() &&
                col >= m_selectingTopLeft.GetCol() &&
                row <= m_selectingBottomRight.GetRow() &&
-               col <= m_selectingBottomRight.GetCol() ) );
+               col <= m_selectingBottomRight.GetCol() )) );
 }
 
 void wxGrid::ClearSelection()
 {
     m_selectingTopLeft = wxGridNoCellCoords;
     m_selectingBottomRight = wxGridNoCellCoords;
-    m_selection->ClearSelection();
+    if ( m_selection )
+        m_selection->ClearSelection();
 }