]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
fixed typo : _ instead of wxT
[wxWidgets.git] / src / generic / grid.cpp
index 889afc9226d65f708446588e6115df7515a71d22..4a3a28cce051a4c579aad4616e23776020fd99e2 100644 (file)
@@ -52,6 +52,9 @@
 #include "wx/grid.h"
 #include "wx/generic/gridsel.h"
 
 #include "wx/grid.h"
 #include "wx/generic/gridsel.h"
 
+// Required for wxIs... functions
+#include <ctype.h>
+
 // ----------------------------------------------------------------------------
 // array classes
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // array classes
 // ----------------------------------------------------------------------------
@@ -2453,12 +2456,12 @@ wxGridStringTable::~wxGridStringTable()
 {
 }
 
 {
 }
 
-long wxGridStringTable::GetNumberRows()
+int wxGridStringTable::GetNumberRows()
 {
     return m_data.GetCount();
 }
 
 {
     return m_data.GetCount();
 }
 
-long wxGridStringTable::GetNumberCols()
+int wxGridStringTable::GetNumberCols()
 {
     if ( m_data.GetCount() > 0 )
         return m_data[0].GetCount();
 {
     if ( m_data.GetCount() > 0 )
         return m_data[0].GetCount();
@@ -3090,7 +3093,6 @@ wxGrid::~wxGrid()
 void wxGrid::Create()
 {
     m_created = FALSE;    // set to TRUE by CreateGrid
 void wxGrid::Create()
 {
     m_created = FALSE;    // set to TRUE by CreateGrid
-    m_displayed = TRUE; // FALSE;  // set to TRUE by OnPaint
 
     m_table        = (wxGridTableBase *) NULL;
     m_ownTable     = FALSE;
 
     m_table        = (wxGridTableBase *) NULL;
     m_ownTable     = FALSE;
@@ -3165,13 +3167,24 @@ bool wxGrid::CreateGrid( int numRows, int numCols,
         m_table->SetView( this );
         m_ownTable = TRUE;
         Init();
         m_table->SetView( this );
         m_ownTable = TRUE;
         Init();
+        m_selection = new wxGridSelection( this, selmode );
         m_created = TRUE;
     }
         m_created = TRUE;
     }
-    m_selection = new wxGridSelection( this, selmode );
     return m_created;
 }
 
     return m_created;
 }
 
-bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership )
+void wxGrid::SetSelectionMode(wxGrid::wxGridSelectionModes selmode)
+{
+    if ( !m_created )
+    {
+        wxFAIL_MSG( wxT("Called wxGrid::SetSelectionMode() before calling CreateGrid()") );
+    }
+    else
+        m_selection->SetSelectionMode( selmode );
+}
+
+bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership,
+                       wxGrid::wxGridSelectionModes selmode )
 {
     if ( m_created )
     {
 {
     if ( m_created )
     {
@@ -3180,6 +3193,7 @@ bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership )
         // View at runtime.  Is there anything in the implmentation that would
         // prevent this?
 
         // View at runtime.  Is there anything in the implmentation 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") );
         return FALSE;
     }
         wxFAIL_MSG( wxT("wxGrid::CreateGrid or wxGrid::SetTable called more than once") );
         return FALSE;
     }
@@ -3193,6 +3207,7 @@ bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership )
         if (takeOwnership)
             m_ownTable = TRUE;
         Init();
         if (takeOwnership)
             m_ownTable = TRUE;
         Init();
+        m_selection = new wxGridSelection( this, selmode );
         m_created = TRUE;
     }
 
         m_created = TRUE;
     }
 
@@ -3788,10 +3803,13 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
                 break;
 
                 case WXGRID_CURSOR_SELECT_ROW:
                 break;
 
                 case WXGRID_CURSOR_SELECT_ROW:
-                    if ( (row = YToRow( y )) >= 0  &&
-                         !IsInSelection( row, 0 ) )
-                    {
-                        SelectRow( row, TRUE );
+                    if ( (row = YToRow( y )) >= 0 )
+                   {
+                       m_selection->SelectRow( row,
+                                               event.ControlDown(),
+                                               event.ShiftDown(),
+                                               event.AltDown(),
+                                               event.MetaDown() );
                     }
 
                 // default label to suppress warnings about "enumeration value
                     }
 
                 // default label to suppress warnings about "enumeration value
@@ -3828,7 +3846,23 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
             if ( row >= 0  &&
                  !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, row, -1, event ) )
             {
             if ( row >= 0  &&
                  !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, row, -1, event ) )
             {
-                SelectRow( row, event.ShiftDown() );
+               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() );
                 ChangeCursorMode(WXGRID_CURSOR_SELECT_ROW, m_rowLabelWin);
             }
         }
                 ChangeCursorMode(WXGRID_CURSOR_SELECT_ROW, m_rowLabelWin);
             }
         }
@@ -3955,10 +3989,13 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
                 break;
 
                 case WXGRID_CURSOR_SELECT_COL:
                 break;
 
                 case WXGRID_CURSOR_SELECT_COL:
-                    if ( (col = XToCol( x )) >= 0  &&
-                         !IsInSelection( 0, col ) )
-                    {
-                        SelectCol( col, TRUE );
+                    if ( (col = XToCol( x )) >= 0 )
+                   {
+                       m_selection->SelectCol( col,
+                                               event.ControlDown(),
+                                               event.ShiftDown(),
+                                               event.AltDown(),
+                                               event.MetaDown() );
                     }
 
                 // default label to suppress warnings about "enumeration value
                     }
 
                 // default label to suppress warnings about "enumeration value
@@ -3995,7 +4032,22 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
             if ( col >= 0  &&
                  !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
             {
             if ( col >= 0  &&
                  !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
             {
-                SelectCol( col, event.ShiftDown() );
+               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() );
                 ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin);
             }
         }
                 ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin);
             }
         }
@@ -4231,20 +4283,29 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
 
             if ( coords != wxGridNoCellCoords )
             {
 
             if ( coords != wxGridNoCellCoords )
             {
-                if ( !IsSelection() )
-                {
-                    SelectBlock( coords, coords );
-                }
-                else
-                {
-                    SelectBlock( m_currentCellCoords, coords );
+               if ( event.ControlDown() )
+               {
+                   if ( m_selectingKeyboard == wxGridNoCellCoords)
+                       m_selectingKeyboard = coords;
+                   SelectBlock ( m_selectingKeyboard, coords );
+               }
+               else
+               {
+                   if ( !IsSelection() )
+                   {
+                       SelectBlock( coords, coords );
+                   }
+                   else
+                   {
+                       SelectBlock( m_currentCellCoords, coords );
+                   }
                 }
 
                 if (! IsVisible(coords))
                 {
                     MakeCellVisible(coords);
                     // TODO: need to introduce a delay or something here.  The
                 }
 
                 if (! IsVisible(coords))
                 {
                     MakeCellVisible(coords);
                     // TODO: need to introduce a delay or something here.  The
-                    // scrolling is way to fast, at least on MSW.
+                    // scrolling is way to fast, at least on MSW - also on GTK.
                 }
             }
         }
                 }
             }
         }
@@ -4311,7 +4372,14 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
             ClearSelection();
         if ( event.ShiftDown() )
         {
             ClearSelection();
         if ( event.ShiftDown() )
         {
-            SelectBlock( m_currentCellCoords, coords );
+            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 )
         }
         else if ( XToEdgeOfCol(x) < 0  &&
                   YToEdgeOfRow(y) < 0 )
@@ -4344,11 +4412,20 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
                 }
                 else
                 {
                 }
                 else
                 {
-                    m_selection->ToggleCellSelection( coords.GetRow(),
-                                                      coords.GetCol() );
-                    m_selectingTopLeft = wxGridNoCellCoords;
-                    m_selectingBottomRight = wxGridNoCellCoords;
-                    SetCurrentCell( coords );
+                   if ( event.ControlDown() )
+                   {
+                       m_selection->ToggleCellSelection( coords.GetRow(),
+                                                         coords.GetCol(),
+                                                         event.ControlDown(),
+                                                         event.ShiftDown(),
+                                                         event.AltDown(),
+                                                         event.MetaDown() );
+                       m_selectingTopLeft = wxGridNoCellCoords;
+                       m_selectingBottomRight = wxGridNoCellCoords;
+                       m_selectingKeyboard = coords;
+                   }
+                   else
+                       SetCurrentCell( coords );
                     m_waitForSlowClick = TRUE;
                 }
             }
                     m_waitForSlowClick = TRUE;
                 }
             }
@@ -4381,16 +4458,21 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
             if ( m_selectingTopLeft != wxGridNoCellCoords &&
                  m_selectingBottomRight != wxGridNoCellCoords )
             {
             if ( m_selectingTopLeft != wxGridNoCellCoords &&
                  m_selectingBottomRight != wxGridNoCellCoords )
             {
-                m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
-                                          m_selectingTopLeft.GetCol(),
-                                          m_selectingBottomRight.GetRow(),
-                                          m_selectingBottomRight.GetCol() );
                 if (m_winCapture)
                 {
                     m_winCapture->ReleaseMouse();
                     m_winCapture = NULL;
                 }
                 if (m_winCapture)
                 {
                     m_winCapture->ReleaseMouse();
                     m_winCapture = NULL;
                 }
-                SendEvent( wxEVT_GRID_RANGE_SELECT, -1, -1, event );
+                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;
             }
 
             // Show the edit control, if it has been hidden for
             }
 
             // Show the edit control, if it has been hidden for
@@ -4884,11 +4966,13 @@ bool wxGrid::SendEvent( const wxEventType type,
     }
     else if ( type == wxEVT_GRID_RANGE_SELECT )
     {
     }
     else if ( type == wxEVT_GRID_RANGE_SELECT )
     {
+        // Right now, it should _never_ end up here! 
         wxGridRangeSelectEvent gridEvt( GetId(),
                                         type,
                                         this,
                                         m_selectingTopLeft,
                                         m_selectingBottomRight,
         wxGridRangeSelectEvent gridEvt( GetId(),
                                         type,
                                         this,
                                         m_selectingTopLeft,
                                         m_selectingBottomRight,
+                                        TRUE,
                                         mouseEv.ControlDown(),
                                         mouseEv.ShiftDown(),
                                         mouseEv.AltDown(),
                                         mouseEv.ControlDown(),
                                         mouseEv.ShiftDown(),
                                         mouseEv.AltDown(),
@@ -4903,6 +4987,7 @@ bool wxGrid::SendEvent( const wxEventType type,
                              this,
                              row, col,
                              mouseEv.GetX(), mouseEv.GetY(),
                              this,
                              row, col,
                              mouseEv.GetX(), mouseEv.GetY(),
+                             FALSE,
                              mouseEv.ControlDown(),
                              mouseEv.ShiftDown(),
                              mouseEv.AltDown(),
                              mouseEv.ControlDown(),
                              mouseEv.ShiftDown(),
                              mouseEv.AltDown(),
@@ -4945,15 +5030,6 @@ bool wxGrid::SendEvent( const wxEventType type,
 void wxGrid::OnPaint( wxPaintEvent& WXUNUSED(event) )
 {
     wxPaintDC dc( this );
 void wxGrid::OnPaint( wxPaintEvent& WXUNUSED(event) )
 {
     wxPaintDC dc( this );
-
-    if ( m_currentCellCoords == wxGridNoCellCoords  &&
-         m_numRows && m_numCols )
-    {
-        m_currentCellCoords.Set(0, 0);
-        ShowCellEditControl();
-    }
-
-    m_displayed = TRUE;
 }
 
 
 }
 
 
@@ -4988,56 +5064,69 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
     if ( !parent->GetEventHandler()->ProcessEvent( keyEvt ) )
     {
 
     if ( !parent->GetEventHandler()->ProcessEvent( keyEvt ) )
     {
 
-        // TODO:  Should also support Shift-cursor keys for
-        //        extending the selection.  Maybe add a flag to
-        //        MoveCursorXXX() and MoveCursorXXXBlock() and
-        //        just send event.ShiftDown().
-
         // try local handlers
         //
         // try local handlers
         //
+        if ( !event.ShiftDown() && 
+             m_selectingKeyboard != wxGridNoCellCoords )
+        {
+           if ( m_selectingTopLeft != wxGridNoCellCoords &&
+                m_selectingBottomRight != wxGridNoCellCoords )
+               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;
+            m_selectingKeyboard = wxGridNoCellCoords;
+        }
+
         switch ( event.KeyCode() )
         {
             case WXK_UP:
                 if ( event.ControlDown() )
                 {
         switch ( event.KeyCode() )
         {
             case WXK_UP:
                 if ( event.ControlDown() )
                 {
-                    MoveCursorUpBlock();
+                    MoveCursorUpBlock( event.ShiftDown() );
                 }
                 else
                 {
                 }
                 else
                 {
-                    MoveCursorUp();
+                    MoveCursorUp( event.ShiftDown() );
                 }
                 break;
 
             case WXK_DOWN:
                 if ( event.ControlDown() )
                 {
                 }
                 break;
 
             case WXK_DOWN:
                 if ( event.ControlDown() )
                 {
-                    MoveCursorDownBlock();
+                    MoveCursorDownBlock( event.ShiftDown() );
                 }
                 else
                 {
                 }
                 else
                 {
-                    MoveCursorDown();
+                    MoveCursorDown( event.ShiftDown() );
                 }
                 break;
 
             case WXK_LEFT:
                 if ( event.ControlDown() )
                 {
                 }
                 break;
 
             case WXK_LEFT:
                 if ( event.ControlDown() )
                 {
-                    MoveCursorLeftBlock();
+                    MoveCursorLeftBlock( event.ShiftDown() );
                 }
                 else
                 {
                 }
                 else
                 {
-                    MoveCursorLeft();
+                    MoveCursorLeft( event.ShiftDown() );
                 }
                 break;
 
             case WXK_RIGHT:
                 if ( event.ControlDown() )
                 {
                 }
                 break;
 
             case WXK_RIGHT:
                 if ( event.ControlDown() )
                 {
-                    MoveCursorRightBlock();
+                    MoveCursorRightBlock( event.ShiftDown() );
                 }
                 else
                 {
                 }
                 else
                 {
-                    MoveCursorRight();
+                    MoveCursorRight( event.ShiftDown() );
                 }
                 break;
 
                 }
                 break;
 
@@ -5048,15 +5137,19 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
                 }
                 else
                 {
                 }
                 else
                 {
-                    MoveCursorDown();
+                    MoveCursorDown( event.ShiftDown() );
                 }
                 break;
 
                 }
                 break;
 
+            case WXK_ESCAPE:
+                ClearSelection();
+                break;
+
             case WXK_TAB:
                 if (event.ShiftDown())
             case WXK_TAB:
                 if (event.ShiftDown())
-                    MoveCursorLeft();
+                    MoveCursorLeft( FALSE );
                 else
                 else
-                    MoveCursorRight();
+                    MoveCursorRight( FALSE );
                 break;
 
             case WXK_HOME:
                 break;
 
             case WXK_HOME:
@@ -5092,9 +5185,19 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
                 break;
 
             case WXK_SPACE:
                 break;
 
             case WXK_SPACE:
+               if ( event.ControlDown() )
+               {
+                   m_selection->ToggleCellSelection( m_currentCellCoords.GetRow(),
+                                                     m_currentCellCoords.GetCol(),
+                                                     event.ControlDown(),
+                                                     event.ShiftDown(),
+                                                     event.AltDown(),
+                                                     event.MetaDown() );
+                   break;
+               }
                 if ( !IsEditable() )
                 {
                 if ( !IsEditable() )
                 {
-                    MoveCursorRight();
+                    MoveCursorRight( FALSE );
                     break;
                 }
                 // Otherwise fall through to default
                     break;
                 }
                 // Otherwise fall through to default
@@ -5102,10 +5205,15 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
             default:
                 // alphanumeric keys or F2 (special key just for this) enable
                 // the cell edit control
             default:
                 // alphanumeric keys or F2 (special key just for this) enable
                 // the cell edit control
+                // On just Shift/Control I get values for event.KeyCode()
+                // that are outside the range where isalnum's behaviour is
+                // well defined, so do an additional sanity check.
                 if ( !(event.AltDown() ||
                        event.MetaDown() ||
                        event.ControlDown()) &&
                 if ( !(event.AltDown() ||
                        event.MetaDown() ||
                        event.ControlDown()) &&
-                     (isalnum(event.KeyCode()) || event.KeyCode() == WXK_F2) &&
+                     ((isalnum(event.KeyCode()) &&
+                       (event.KeyCode() < 256 && event.KeyCode() >= 0)) ||
+                      event.KeyCode() == WXK_F2) &&
                      !IsCellEditControlEnabled() &&
                      CanEnableCellControl() )
                 {
                      !IsCellEditControlEnabled() &&
                      CanEnableCellControl() )
                 {
@@ -5131,21 +5239,13 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
     m_inOnKeyDown = FALSE;
 }
 
     m_inOnKeyDown = FALSE;
 }
 
-
 void wxGrid::OnEraseBackground(wxEraseEvent&)
 {
 }
 
 void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
 {
 void wxGrid::OnEraseBackground(wxEraseEvent&)
 {
 }
 
 void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
 {
-    if ( SendEvent( wxEVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) )
-    {
-        // the event has been intercepted - do nothing
-        return;
-    }
-
-    if ( m_displayed  &&
-         m_currentCellCoords != wxGridNoCellCoords )
+    if ( m_currentCellCoords != wxGridNoCellCoords )
     {
         HideCellEditControl();
         DisableCellEditControl();
     {
         HideCellEditControl();
         DisableCellEditControl();
@@ -5161,14 +5261,13 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
 
     m_currentCellCoords = coords;
 
 
     m_currentCellCoords = coords;
 
-    if ( m_displayed )
-    {
-        wxClientDC dc(m_gridWin);
-        PrepareDC(dc);
+    wxClientDC dc(m_gridWin);
+    PrepareDC(dc);
+
+    wxGridCellAttr* attr = GetCellAttr(coords);
+    DrawCellHighlight(dc, attr);
+    attr->DecRef();
 
 
-        wxGridCellAttr* attr = GetCellAttr(coords);
-        DrawCellHighlight(dc, attr);
-        attr->DecRef();
 #if 0
         // SN: For my extended selection code, automatic
         //     deselection is definitely not a good idea.
 #if 0
         // SN: For my extended selection code, automatic
         //     deselection is definitely not a good idea.
@@ -5179,7 +5278,6 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
             if ( !GetBatchCount() ) m_gridWin->Refresh( FALSE, &r );
         }
 #endif
             if ( !GetBatchCount() ) m_gridWin->Refresh( FALSE, &r );
         }
 #endif
-    }
 }
 
 
 }
 
 
@@ -5382,6 +5480,15 @@ void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords )
 
 void wxGrid::DrawHighlight(wxDC& dc)
 {
 
 void wxGrid::DrawHighlight(wxDC& dc)
 {
+    // This if block was previously in wxGrid::OnPaint but that doesn't
+    // seem to get called under wxGTK - MB
+    //
+    if ( m_currentCellCoords == wxGridNoCellCoords  &&
+         m_numRows && m_numCols )
+    {
+        m_currentCellCoords.Set(0, 0);
+    }
+
     if ( IsCellEditControlEnabled() )
     {
         // don't show highlight when the edit control is shown
     if ( IsCellEditControlEnabled() )
     {
         // don't show highlight when the edit control is shown
@@ -6104,17 +6211,28 @@ void wxGrid::MakeCellVisible( int row, int col )
 // ------ Grid cursor movement functions
 //
 
 // ------ Grid cursor movement functions
 //
 
-bool wxGrid::MoveCursorUp()
+bool wxGrid::MoveCursorUp( bool expandSelection )
 {
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetRow() > 0 )
     {
 {
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetRow() > 0 )
     {
-        MakeCellVisible( m_currentCellCoords.GetRow() - 1,
-                        m_currentCellCoords.GetCol() );
-
-        SetCurrentCell( m_currentCellCoords.GetRow() - 1,
-                        m_currentCellCoords.GetCol() );
-
+        if ( expandSelection )
+        {
+            if ( m_selectingKeyboard == wxGridNoCellCoords )
+                m_selectingKeyboard = m_currentCellCoords;
+            m_selectingKeyboard.SetRow( m_selectingKeyboard.GetRow() - 1 );
+           MakeCellVisible( m_selectingKeyboard.GetRow(),
+                            m_selectingKeyboard.GetCol() );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           MakeCellVisible( m_currentCellCoords.GetRow() - 1,
+                            m_currentCellCoords.GetCol() );
+            SetCurrentCell( m_currentCellCoords.GetRow() - 1,
+                            m_currentCellCoords.GetCol() );
+       }
         return TRUE;
     }
 
         return TRUE;
     }
 
@@ -6122,19 +6240,28 @@ bool wxGrid::MoveCursorUp()
 }
 
 
 }
 
 
-bool wxGrid::MoveCursorDown()
+bool wxGrid::MoveCursorDown( bool expandSelection )
 {
 {
-    // TODO: allow for scrolling
-    //
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetRow() < m_numRows-1 )
     {
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetRow() < m_numRows-1 )
     {
-        MakeCellVisible( m_currentCellCoords.GetRow() + 1,
-                        m_currentCellCoords.GetCol() );
-
-        SetCurrentCell( m_currentCellCoords.GetRow() + 1,
-                        m_currentCellCoords.GetCol() );
-
+        if ( expandSelection )
+        {
+            if ( m_selectingKeyboard == wxGridNoCellCoords )
+                m_selectingKeyboard = m_currentCellCoords;
+            m_selectingKeyboard.SetRow( m_selectingKeyboard.GetRow() + 1 );
+           MakeCellVisible( m_selectingKeyboard.GetRow(),
+                            m_selectingKeyboard.GetCol() );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           MakeCellVisible( m_currentCellCoords.GetRow() + 1,
+                            m_currentCellCoords.GetCol() );
+            SetCurrentCell( m_currentCellCoords.GetRow() + 1,
+                            m_currentCellCoords.GetCol() );
+       }
         return TRUE;
     }
 
         return TRUE;
     }
 
@@ -6142,17 +6269,28 @@ bool wxGrid::MoveCursorDown()
 }
 
 
 }
 
 
-bool wxGrid::MoveCursorLeft()
+bool wxGrid::MoveCursorLeft( bool expandSelection )
 {
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetCol() > 0 )
     {
 {
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetCol() > 0 )
     {
-        MakeCellVisible( m_currentCellCoords.GetRow(),
-                        m_currentCellCoords.GetCol() - 1 );
-
-        SetCurrentCell( m_currentCellCoords.GetRow(),
-                        m_currentCellCoords.GetCol() - 1 );
-
+        if ( expandSelection )
+        {
+            if ( m_selectingKeyboard == wxGridNoCellCoords )
+                m_selectingKeyboard = m_currentCellCoords;
+            m_selectingKeyboard.SetCol( m_selectingKeyboard.GetCol() - 1 );
+           MakeCellVisible( m_selectingKeyboard.GetRow(),
+                            m_selectingKeyboard.GetCol() );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           MakeCellVisible( m_currentCellCoords.GetRow(),
+                            m_currentCellCoords.GetCol() - 1 );
+            SetCurrentCell( m_currentCellCoords.GetRow(),
+                            m_currentCellCoords.GetCol() - 1 );
+       }
         return TRUE;
     }
 
         return TRUE;
     }
 
@@ -6160,17 +6298,28 @@ bool wxGrid::MoveCursorLeft()
 }
 
 
 }
 
 
-bool wxGrid::MoveCursorRight()
+bool wxGrid::MoveCursorRight( bool expandSelection )
 {
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetCol() < m_numCols - 1 )
     {
 {
     if ( m_currentCellCoords != wxGridNoCellCoords  &&
          m_currentCellCoords.GetCol() < m_numCols - 1 )
     {
-        MakeCellVisible( m_currentCellCoords.GetRow(),
-                        m_currentCellCoords.GetCol() + 1 );
-
-        SetCurrentCell( m_currentCellCoords.GetRow(),
-                        m_currentCellCoords.GetCol() + 1 );
-
+        if ( expandSelection )
+        {
+            if ( m_selectingKeyboard == wxGridNoCellCoords )
+                m_selectingKeyboard = m_currentCellCoords;
+            m_selectingKeyboard.SetCol( m_selectingKeyboard.GetCol() + 1 );
+           MakeCellVisible( m_selectingKeyboard.GetRow(),
+                            m_selectingKeyboard.GetCol() );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           MakeCellVisible( m_currentCellCoords.GetRow(),
+                            m_currentCellCoords.GetCol() + 1 );
+           SetCurrentCell( m_currentCellCoords.GetRow(),
+                            m_currentCellCoords.GetCol() + 1 );
+       }
         return TRUE;
     }
 
         return TRUE;
     }
 
@@ -6238,7 +6387,7 @@ bool wxGrid::MovePageDown()
     return FALSE;
 }
 
     return FALSE;
 }
 
-bool wxGrid::MoveCursorUpBlock()
+bool wxGrid::MoveCursorUpBlock( bool expandSelection )
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
@@ -6285,15 +6434,23 @@ bool wxGrid::MoveCursorUpBlock()
         }
 
         MakeCellVisible( row, col );
         }
 
         MakeCellVisible( row, col );
-        SetCurrentCell( row, col );
-
+        if ( expandSelection )
+        {
+            m_selectingKeyboard = wxGridCellCoords( row, col );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           SetCurrentCell( row, col );
+       }
         return TRUE;
     }
 
     return FALSE;
 }
 
         return TRUE;
     }
 
     return FALSE;
 }
 
-bool wxGrid::MoveCursorDownBlock()
+bool wxGrid::MoveCursorDownBlock( bool expandSelection )
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
@@ -6340,7 +6497,16 @@ bool wxGrid::MoveCursorDownBlock()
         }
 
         MakeCellVisible( row, col );
         }
 
         MakeCellVisible( row, col );
-        SetCurrentCell( row, col );
+        if ( expandSelection )
+        {
+            m_selectingKeyboard = wxGridCellCoords( row, col );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           SetCurrentCell( row, col );
+       }
 
         return TRUE;
     }
 
         return TRUE;
     }
@@ -6348,7 +6514,7 @@ bool wxGrid::MoveCursorDownBlock()
     return FALSE;
 }
 
     return FALSE;
 }
 
-bool wxGrid::MoveCursorLeftBlock()
+bool wxGrid::MoveCursorLeftBlock( bool expandSelection )
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
@@ -6395,7 +6561,16 @@ bool wxGrid::MoveCursorLeftBlock()
         }
 
         MakeCellVisible( row, col );
         }
 
         MakeCellVisible( row, col );
-        SetCurrentCell( row, col );
+        if ( expandSelection )
+        {
+            m_selectingKeyboard = wxGridCellCoords( row, col );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           SetCurrentCell( row, col );
+       }
 
         return TRUE;
     }
 
         return TRUE;
     }
@@ -6403,7 +6578,7 @@ bool wxGrid::MoveCursorLeftBlock()
     return FALSE;
 }
 
     return FALSE;
 }
 
-bool wxGrid::MoveCursorRightBlock()
+bool wxGrid::MoveCursorRightBlock( bool expandSelection )
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
 {
     if ( m_table &&
          m_currentCellCoords != wxGridNoCellCoords  &&
@@ -6450,7 +6625,16 @@ bool wxGrid::MoveCursorRightBlock()
         }
 
         MakeCellVisible( row, col );
         }
 
         MakeCellVisible( row, col );
-        SetCurrentCell( row, col );
+        if ( expandSelection )
+        {
+            m_selectingKeyboard = wxGridCellCoords( row, col );
+            SelectBlock( m_currentCellCoords, m_selectingKeyboard );
+        }
+        else
+       {
+           ClearSelection();
+           SetCurrentCell( row, col );
+       }
 
         return TRUE;
     }
 
         return TRUE;
     }
@@ -7438,34 +7622,18 @@ void wxGrid::SetCellValue( int row, int col, const wxString& s )
 void wxGrid::SelectRow( int row, bool addToSelected )
 {
     if ( IsSelection() && !addToSelected )
 void wxGrid::SelectRow( int row, bool addToSelected )
 {
     if ( IsSelection() && !addToSelected )
-        m_selection->ClearSelection();
+        ClearSelection();
 
     m_selection->SelectRow( row );
 
     m_selection->SelectRow( row );
-
-    wxGridRangeSelectEvent gridEvt( GetId(),
-                                    wxEVT_GRID_RANGE_SELECT,
-                                    this,
-                                    wxGridCellCoords( row, 0 ),
-                                    wxGridCellCoords( row, m_numCols - 1 ) );
-
-    GetEventHandler()->ProcessEvent(gridEvt);
 }
 
 
 void wxGrid::SelectCol( int col, bool addToSelected )
 {
     if ( IsSelection() && !addToSelected )
 }
 
 
 void wxGrid::SelectCol( int col, bool addToSelected )
 {
     if ( IsSelection() && !addToSelected )
-        m_selection->ClearSelection();
+        ClearSelection();
 
     m_selection->SelectCol( col );
 
     m_selection->SelectCol( col );
-
-    wxGridRangeSelectEvent gridEvt( GetId(),
-                                    wxEVT_GRID_RANGE_SELECT,
-                                    this,
-                                    wxGridCellCoords( 0, col ),
-                                    wxGridCellCoords( m_numRows - 1, col ) );
-
-    GetEventHandler()->ProcessEvent(gridEvt);
 }
 
 
 }
 
 
@@ -7588,19 +7756,8 @@ void wxGrid::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol )
                 m_gridWin->Refresh( FALSE, &(rect[i]) );
     }
 
                 m_gridWin->Refresh( FALSE, &(rect[i]) );
     }
 
-    // only generate an event if the block is not being selected by
-    // dragging the mouse (in which case the event will be generated in
-    // the mouse event handler)
-    if ( !m_isDragging )
-    {
-        wxGridRangeSelectEvent gridEvt( GetId(),
-                                        wxEVT_GRID_RANGE_SELECT,
-                                        this,
-                                        m_selectingTopLeft,
-                                        m_selectingBottomRight );
-
-        GetEventHandler()->ProcessEvent(gridEvt);
-    }
+    // never generate an event as it will be generated from
+    // wxGridSelection::SelectBlock!
 }
 
 void wxGrid::SelectAll()
 }
 
 void wxGrid::SelectAll()
@@ -7687,7 +7844,7 @@ wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords &topLeft,
 IMPLEMENT_DYNAMIC_CLASS( wxGridEvent, wxEvent )
 
 wxGridEvent::wxGridEvent( int id, wxEventType type, wxObject* obj,
 IMPLEMENT_DYNAMIC_CLASS( wxGridEvent, wxEvent )
 
 wxGridEvent::wxGridEvent( int id, wxEventType type, wxObject* obj,
-                          int row, int col, int x, int y,
+                          int row, int col, int x, int y, bool sel,
                           bool control, bool shift, bool alt, bool meta )
         : wxNotifyEvent( type, id )
 {
                           bool control, bool shift, bool alt, bool meta )
         : wxNotifyEvent( type, id )
 {
@@ -7695,6 +7852,7 @@ wxGridEvent::wxGridEvent( int id, wxEventType type, wxObject* obj,
     m_col = col;
     m_x = x;
     m_y = y;
     m_col = col;
     m_x = x;
     m_y = y;
+    m_selecting = sel;
     m_control = control;
     m_shift = shift;
     m_alt = alt;
     m_control = control;
     m_shift = shift;
     m_alt = alt;
@@ -7728,11 +7886,13 @@ IMPLEMENT_DYNAMIC_CLASS( wxGridRangeSelectEvent, wxEvent )
 wxGridRangeSelectEvent::wxGridRangeSelectEvent(int id, wxEventType type, wxObject* obj,
                                                const wxGridCellCoords& topLeft,
                                                const wxGridCellCoords& bottomRight,
 wxGridRangeSelectEvent::wxGridRangeSelectEvent(int id, wxEventType type, wxObject* obj,
                                                const wxGridCellCoords& topLeft,
                                                const wxGridCellCoords& bottomRight,
-                                               bool control, bool shift, bool alt, bool meta )
+                                               bool sel, bool control,
+                                               bool shift, bool alt, bool meta )
         : wxNotifyEvent( type, id )
 {
     m_topLeft     = topLeft;
     m_bottomRight = bottomRight;
         : wxNotifyEvent( type, id )
 {
     m_topLeft     = topLeft;
     m_bottomRight = bottomRight;
+    m_selecting   = sel;
     m_control     = control;
     m_shift       = shift;
     m_alt         = alt;
     m_control     = control;
     m_shift       = shift;
     m_alt         = alt;