1 //////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxGrid and related classes 
   4 // Author:      Michael Bedward (based on code by Julian Smart, Robin Dunn) 
   8 // Copyright:   (c) Michael Bedward (mbedward@ozemail.com.au) 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  15 #if !defined(wxUSE_NEW_GRID) || !(wxUSE_NEW_GRID)  
  20     #pragma implementation "grid.h" 
  23 // For compilers that support precompilation, includes "wx/wx.h". 
  24 #include "wx/wxprec.h" 
  32     #include "wx/dcclient.h" 
  33     #include "wx/settings.h" 
  37 #include "wx/generic/grid.h" 
  40 ////////////////////////////////////////////////////////////////////// 
  42 wxGridCellCoords 
wxGridNoCellCoords( -1, -1 ); 
  43 wxRect           
wxGridNoCellRect( -1, -1, -1, -1 ); 
  47 ////////////////////////////////////////////////////////////////////// 
  49 // Abstract base class for grid data (the model) 
  51 IMPLEMENT_ABSTRACT_CLASS( wxGridTableBase
, wxObject 
) 
  54 wxGridTableBase::wxGridTableBase() 
  57     m_view 
= (wxGrid 
*) NULL
; 
  60 wxGridTableBase::~wxGridTableBase() 
  65 bool wxGridTableBase::InsertRows( size_t pos
, size_t numRows 
) 
  67     wxLogWarning( "Called grid table class function InsertRows(pos=%d, N=%d)\n" 
  68                   "but your derived table class does not override this function", 
  74 bool wxGridTableBase::AppendRows( size_t numRows 
) 
  76     wxLogWarning( "Called grid table class function AppendRows(N=%d)\n" 
  77                   "but your derived table class does not override this function", 
  83 bool wxGridTableBase::DeleteRows( size_t pos
, size_t numRows 
) 
  85     wxLogWarning( "Called grid table class function DeleteRows(pos=%d, N=%d)\n" 
  86                   "but your derived table class does not override this function", 
  92 bool wxGridTableBase::InsertCols( size_t pos
, size_t numCols 
) 
  94     wxLogWarning( "Called grid table class function InsertCols(pos=%d, N=%d)\n" 
  95                   "but your derived table class does not override this function", 
 101 bool wxGridTableBase::AppendCols( size_t numCols 
) 
 103     wxLogWarning( "Called grid table class function AppendCols(N=%d)\n" 
 104                   "but your derived table class does not override this function", 
 110 bool wxGridTableBase::DeleteCols( size_t pos
, size_t numCols 
) 
 112     wxLogWarning( "Called grid table class function DeleteCols(pos=%d, N=%d)\n" 
 113                   "but your derived table class does not override this function", 
 120 wxString 
wxGridTableBase::GetRowLabelValue( int row 
) 
 127 wxString 
wxGridTableBase::GetColLabelValue( int col 
) 
 129     // default col labels are: 
 130     //   cols 0 to 25   : A-Z 
 131     //   cols 26 to 675 : AA-ZZ 
 138         s 
+= ('A' + (char)( col%26 
)); 
 140         if ( col 
< 0 ) break; 
 143     // reverse the string... 
 145     for ( i 
= 0;  i 
< n
;  i
++ ) 
 155 ////////////////////////////////////////////////////////////////////// 
 157 // Message class for the grid table to send requests and notifications 
 161 wxGridTableMessage::wxGridTableMessage() 
 163     m_table 
= (wxGridTableBase 
*) NULL
; 
 169 wxGridTableMessage::wxGridTableMessage( wxGridTableBase 
*table
, int id
, 
 170                                         int commandInt1
, int commandInt2 
) 
 174     m_comInt1 
= commandInt1
; 
 175     m_comInt2 
= commandInt2
; 
 180 ////////////////////////////////////////////////////////////////////// 
 182 // A basic grid table for string data. An object of this class will 
 183 // created by wxGrid if you don't specify an alternative table class. 
 187 // this is a magic incantation which must be done! 
 188 #include <wx/arrimpl.cpp> 
 190 WX_DEFINE_OBJARRAY(wxGridStringArray
); 
 192 IMPLEMENT_DYNAMIC_CLASS( wxGridStringTable
, wxGridTableBase 
) 
 194 wxGridStringTable::wxGridStringTable() 
 199 wxGridStringTable::wxGridStringTable( int numRows
, int numCols 
) 
 204     m_data
.Alloc( numRows 
); 
 208     for ( col 
= 0;  col 
< numCols
;  col
++ ) 
 210         sa
.Add( wxEmptyString 
); 
 213     for ( row 
= 0;  row 
< numRows
;  row
++ ) 
 219 wxGridStringTable::~wxGridStringTable() 
 223 long wxGridStringTable::GetNumberRows() 
 225     return m_data
.GetCount(); 
 228 long wxGridStringTable::GetNumberCols() 
 230     if ( m_data
.GetCount() > 0 ) 
 231         return m_data
[0].GetCount(); 
 236 wxString 
wxGridStringTable::GetValue( int row
, int col 
) 
 238     // TODO: bounds checking 
 240     return m_data
[row
][col
]; 
 243 void wxGridStringTable::SetValue( int row
, int col
, const wxString
& s 
) 
 245     // TODO: bounds checking 
 247     m_data
[row
][col
] = s
; 
 250 bool wxGridStringTable::IsEmptyCell( int row
, int col 
) 
 252     // TODO: bounds checking 
 254     return (m_data
[row
][col
] == wxEmptyString
); 
 258 void wxGridStringTable::Clear() 
 261     int numRows
, numCols
; 
 263     numRows 
= m_data
.GetCount(); 
 266         numCols 
= m_data
[0].GetCount(); 
 268         for ( row 
= 0;  row 
< numRows
;  row
++ ) 
 270             for ( col 
= 0;  col 
< numCols
;  col
++ ) 
 272                 m_data
[row
][col
] = wxEmptyString
; 
 279 bool wxGridStringTable::InsertRows( size_t pos
, size_t numRows 
) 
 283     size_t curNumRows 
= m_data
.GetCount(); 
 284     size_t curNumCols 
= ( curNumRows 
> 0 ? m_data
[0].GetCount() : 0 ); 
 286     if ( pos 
>= curNumRows 
) 
 288         return AppendRows( numRows 
); 
 292     sa
.Alloc( curNumCols 
); 
 293     for ( col 
= 0;  col 
< curNumCols
;  col
++ ) 
 295         sa
.Add( wxEmptyString 
); 
 298     for ( row 
= pos
;  row 
< pos 
+ numRows
;  row
++ ) 
 300         m_data
.Insert( sa
, row 
); 
 305         wxGridTableMessage 
msg( this, 
 306                                 wxGRIDTABLE_NOTIFY_ROWS_INSERTED
, 
 310         GetView()->ProcessTableMessage( msg 
); 
 316 bool wxGridStringTable::AppendRows( size_t numRows 
) 
 320     size_t curNumRows 
= m_data
.GetCount(); 
 321     size_t curNumCols 
= ( curNumRows 
> 0 ? m_data
[0].GetCount() : 0 ); 
 324     if ( curNumCols 
> 0 ) 
 326         sa
.Alloc( curNumCols 
); 
 327         for ( col 
= 0;  col 
< curNumCols
;  col
++ ) 
 329             sa
.Add( wxEmptyString 
); 
 333     for ( row 
= 0;  row 
< numRows
;  row
++ ) 
 340         wxGridTableMessage 
msg( this, 
 341                                 wxGRIDTABLE_NOTIFY_ROWS_APPENDED
, 
 344         GetView()->ProcessTableMessage( msg 
); 
 350 bool wxGridStringTable::DeleteRows( size_t pos
, size_t numRows 
) 
 354     size_t curNumRows 
= m_data
.GetCount(); 
 356     if ( pos 
>= curNumRows 
) 
 358         wxLogError( "Called wxGridStringTable::DeleteRows(pos=%d, N=%d)...\n" 
 359                     "Pos value is invalid for present table with %d rows", 
 360                     pos
, numRows
, curNumRows 
); 
 364     if ( numRows 
> curNumRows 
- pos 
) 
 366         numRows 
= curNumRows 
- pos
; 
 369     if ( numRows 
>= curNumRows 
) 
 371         m_data
.Empty();  // don't release memory just yet 
 375         for ( n 
= 0;  n 
< numRows
;  n
++ ) 
 377             m_data
.Remove( pos 
); 
 383         wxGridTableMessage 
msg( this, 
 384                                 wxGRIDTABLE_NOTIFY_ROWS_DELETED
, 
 388         GetView()->ProcessTableMessage( msg 
); 
 394 bool wxGridStringTable::InsertCols( size_t pos
, size_t numCols 
) 
 398     size_t curNumRows 
= m_data
.GetCount(); 
 399     size_t curNumCols 
= ( curNumRows 
> 0 ? m_data
[0].GetCount() : 0 ); 
 401     if ( pos 
>= curNumCols 
) 
 403         return AppendCols( numCols 
); 
 406     for ( row 
= 0;  row 
< curNumRows
;  row
++ ) 
 408         for ( col 
= pos
;  col 
< pos 
+ numCols
;  col
++ ) 
 410             m_data
[row
].Insert( wxEmptyString
, col 
); 
 416         wxGridTableMessage 
msg( this, 
 417                                 wxGRIDTABLE_NOTIFY_COLS_INSERTED
, 
 421         GetView()->ProcessTableMessage( msg 
); 
 427 bool wxGridStringTable::AppendCols( size_t numCols 
) 
 431     size_t curNumRows 
= m_data
.GetCount(); 
 434         // TODO: something better than this ? 
 436         wxLogError( "Unable to append cols to a grid table with no rows.\n" 
 437                     "Call AppendRows() first" ); 
 441     for ( row 
= 0;  row 
< curNumRows
;  row
++ ) 
 443         for ( n 
= 0;  n 
< numCols
;  n
++ ) 
 445             m_data
[row
].Add( wxEmptyString 
); 
 451         wxGridTableMessage 
msg( this, 
 452                                 wxGRIDTABLE_NOTIFY_COLS_APPENDED
, 
 455         GetView()->ProcessTableMessage( msg 
); 
 461 bool wxGridStringTable::DeleteCols( size_t pos
, size_t numCols 
) 
 465     size_t curNumRows 
= m_data
.GetCount(); 
 466     size_t curNumCols 
= ( curNumRows 
> 0 ? m_data
[0].GetCount() : 0 ); 
 468     if ( pos 
>= curNumCols 
) 
 470         wxLogError( "Called wxGridStringTable::DeleteCols(pos=%d, N=%d)...\n" 
 471                     "Pos value is invalid for present table with %d cols", 
 472                     pos
, numCols
, curNumCols 
); 
 476     if ( numCols 
> curNumCols 
- pos 
) 
 478         numCols 
= curNumCols 
- pos
; 
 481     for ( row 
= 0;  row 
< curNumRows
;  row
++ ) 
 483         if ( numCols 
>= curNumCols 
) 
 489             for ( n 
= 0;  n 
< numCols
;  n
++ ) 
 491                 m_data
[row
].Remove( pos 
); 
 498         wxGridTableMessage 
msg( this, 
 499                                 wxGRIDTABLE_NOTIFY_COLS_DELETED
, 
 503         GetView()->ProcessTableMessage( msg 
); 
 509 wxString 
wxGridStringTable::GetRowLabelValue( int row 
) 
 511     if ( row 
> (int)(m_rowLabels
.GetCount()) - 1 ) 
 513         // using default label 
 515         return wxGridTableBase::GetRowLabelValue( row 
); 
 519         return m_rowLabels
[ row 
]; 
 523 wxString 
wxGridStringTable::GetColLabelValue( int col 
) 
 525     if ( col 
> (int)(m_colLabels
.GetCount()) - 1 ) 
 527         // using default label 
 529         return wxGridTableBase::GetColLabelValue( col 
); 
 533         return m_colLabels
[ col 
]; 
 537 void wxGridStringTable::SetRowLabelValue( int row
, const wxString
& value 
) 
 539     if ( row 
> (int)(m_rowLabels
.GetCount()) - 1 ) 
 541         int n 
= m_rowLabels
.GetCount(); 
 543         for ( i 
= n
;  i 
<= row
;  i
++ ) 
 545             m_rowLabels
.Add( wxGridTableBase::GetRowLabelValue(i
) ); 
 549     m_rowLabels
[row
] = value
; 
 552 void wxGridStringTable::SetColLabelValue( int col
, const wxString
& value 
) 
 554     if ( col 
> (int)(m_colLabels
.GetCount()) - 1 ) 
 556         int n 
= m_colLabels
.GetCount(); 
 558         for ( i 
= n
;  i 
<= col
;  i
++ ) 
 560             m_colLabels
.Add( wxGridTableBase::GetColLabelValue(i
) ); 
 564     m_colLabels
[col
] = value
; 
 570 ////////////////////////////////////////////////////////////////////// 
 572 IMPLEMENT_DYNAMIC_CLASS( wxGridTextCtrl
, wxTextCtrl 
) 
 574 BEGIN_EVENT_TABLE( wxGridTextCtrl
, wxTextCtrl 
) 
 575     EVT_KEY_DOWN( wxGridTextCtrl::OnKeyDown 
) 
 579 wxGridTextCtrl::wxGridTextCtrl( wxWindow 
*par
, 
 582                                 const wxString
& value
, 
 586         : wxTextCtrl( par
, id
, value
, pos
, size
, style 
) 
 588     m_isCellControl 
= isCellControl
; 
 592 void wxGridTextCtrl::OnKeyDown( wxKeyEvent
& ev 
) 
 594     switch ( ev
.KeyCode() ) 
 597             ((wxGrid 
*)GetParent())->SetEditControlValue( startValue 
); 
 598             SetInsertionPointEnd(); 
 606             if ( m_isCellControl 
) 
 608                 // send the event to the parent grid, skipping the 
 609                 // event if nothing happens 
 611                 ev
.Skip( !GetParent()->ProcessEvent( ev 
) ); 
 615                 // default text control response within the top edit 
 624             if ( m_isCellControl 
) 
 626                 // send the event to the parent grid, skipping the 
 627                 // event if nothing happens 
 629                 ev
.Skip( !GetParent()->ProcessEvent( ev 
) ); 
 633                 // default text control response within the top edit 
 645 void wxGridTextCtrl::SetStartValue( const wxString
& s 
) 
 648     wxTextCtrl::SetValue( s
.c_str() ); 
 652 ////////////////////////////////////////////////////////////////////// 
 654 IMPLEMENT_DYNAMIC_CLASS( wxGrid
, wxPanel 
) 
 657 BEGIN_EVENT_TABLE( wxGrid
, wxPanel 
) 
 658     EVT_PAINT( wxGrid::OnPaint 
) 
 659     EVT_SIZE( wxGrid::OnSize 
) 
 660     EVT_MOUSE_EVENTS( wxGrid::OnMouse 
) 
 661     EVT_KEY_DOWN( wxGrid::OnKeyDown 
) 
 662     EVT_TEXT( wxGRID_CELLCTRL
, wxGrid::OnText 
) 
 663     EVT_TEXT( wxGRID_TOPCTRL
, wxGrid::OnText 
) 
 664     EVT_COMMAND_SCROLL( wxGRID_HORIZSCROLL
, wxGrid::OnGridScroll
) 
 665     EVT_COMMAND_SCROLL( wxGRID_VERTSCROLL
, wxGrid::OnGridScroll
) 
 676 // ----- internal init and update functions 
 679 void wxGrid::Create() 
 681     m_table          
= (wxGridTableBase 
*) NULL
; 
 682     m_topEditCtrl    
= (wxWindow 
*) NULL
; 
 683     m_cellEditCtrl   
= (wxWindow 
*) NULL
; 
 684     m_horizScrollBar 
= (wxScrollBar 
*) NULL
; 
 685     m_vertScrollBar  
= (wxScrollBar 
*) NULL
; 
 699     // TODO: perhaps have a style flag for control panel 
 701     m_topEditCtrlEnabled 
= FALSE
; 
 702     m_topEditCtrl 
= new wxGridTextCtrl( this, 
 707                                         wxSize(WXGRID_DEFAULT_TOPEDIT_WIDTH
, 
 708                                                WXGRID_DEFAULT_TOPEDIT_HEIGHT
), 
 710     m_topEditCtrl
->Show( FALSE 
);                                        
 712     if ( m_numRows 
<= 0 ) 
 713         m_numRows 
= WXGRID_DEFAULT_NUMBER_ROWS
; 
 715     if ( m_numCols 
<= 0 ) 
 716         m_numCols 
= WXGRID_DEFAULT_NUMBER_COLS
; 
 718     m_rowLabelWidth  
= WXGRID_DEFAULT_ROW_LABEL_WIDTH
; 
 719     m_colLabelHeight 
= WXGRID_DEFAULT_COL_LABEL_HEIGHT
; 
 721     // default labels are pale grey with black text 
 723     m_labelBackgroundColour 
= wxColour( 192, 192, 192 ); 
 724     m_labelTextColour       
= wxColour(   0,   0,   0 ); 
 726     // TODO: something better than this ? 
 728     m_labelFont 
= this->GetFont(); 
 729     m_labelFont
.SetWeight( m_labelFont
.GetWeight() + 2 ); 
 731     m_rowLabelHorizAlign 
= wxLEFT
; 
 732     m_rowLabelVertAlign  
= wxCENTRE
; 
 734     m_colLabelHorizAlign 
= wxCENTRE
; 
 735     m_colLabelVertAlign  
= wxTOP
; 
 737     m_defaultRowHeight 
= WXGRID_DEFAULT_ROW_HEIGHT
; 
 738     m_defaultColWidth  
= WXGRID_DEFAULT_COL_WIDTH
; 
 740     m_rowHeights
.Alloc( m_numRows 
); 
 741     m_rowBottoms
.Alloc( m_numRows 
); 
 742     for ( i 
= 0;  i 
< m_numRows
;  i
++ ) 
 744         m_rowHeights
.Add( m_defaultRowHeight 
); 
 745         m_rowBottoms
.Add( 0 );  // set by CalcDimensions() 
 748     m_colWidths
.Alloc( m_numCols 
); 
 749     m_colRights
.Alloc( m_numRows 
); 
 750     for ( i 
= 0;  i 
< m_numCols
;  i
++ ) 
 752         m_colWidths
.Add( m_defaultColWidth 
); 
 753         m_colRights
.Add( 0 );  // set by CalcDimensions() 
 756     // TODO: improve this ? 
 758     m_defaultCellFont 
= this->GetFont(); 
 760     m_gridLineColour 
= wxColour(   0,   0, 255 ); 
 761     m_gridLinesEnabled 
= TRUE
; 
 763     m_scrollBarWidth 
= WXGRID_DEFAULT_SCROLLBAR_WIDTH
; 
 765     m_horizScrollBar 
= new wxScrollBar( this, 
 771     m_vertScrollBar 
= new wxScrollBar( this, 
 778     m_wholeColsVisible 
= 0; 
 779     m_wholeRowsVisible 
= 0;     
 782     m_inOnKeyDown 
= FALSE
; 
 785     m_cursorMode  
= WXGRID_CURSOR_DEFAULT
; 
 788     m_isDragging 
= FALSE
; 
 790     m_rowResizeCursor 
= wxCursor( wxCURSOR_SIZENS 
); 
 791     m_colResizeCursor 
= wxCursor( wxCURSOR_SIZEWE 
); 
 793     m_currentCellCoords 
= wxGridNoCellCoords
; 
 794     m_currentCellHighlighted 
= FALSE
; 
 796     m_selectedTopLeft 
= wxGridNoCellCoords
; 
 797     m_selectedBottomRight 
= wxGridNoCellCoords
; 
 799     m_editable 
= TRUE
;  // default for whole grid 
 801     // TODO: extend this to other types of controls 
 803     m_cellEditCtrl 
= new wxGridTextCtrl( this, 
 811                                          | wxTE_MULTILINE 
| wxTE_NO_VSCROLL
 
 815     m_cellEditCtrl
->Show( FALSE 
);                                             
 816     m_cellEditCtrlEnabled 
= TRUE
; 
 817     m_editCtrlType 
= wxGRID_TEXTCTRL
;     
 819     // Not really needed here, it gets called by OnSize() 
 825 void wxGrid::CalcDimensions() 
 829     if ( IsTopEditControlEnabled() ) 
 832         m_topEditCtrl
->GetSize( &ctrlW
, &ctrlH 
); 
 841     int bottom 
=  m_top 
+ m_colLabelHeight
; 
 842     for ( i 
= m_scrollPosY
;  i 
< m_numRows
;  i
++ ) 
 844         bottom 
+= m_rowHeights
[i
]; 
 845         m_rowBottoms
[i
] = bottom
; 
 848     int right 
= m_left 
+ m_rowLabelWidth
; 
 849     for ( i 
= m_scrollPosX
;  i 
< m_numCols
;  i
++ ) 
 851         right 
+= m_colWidths
[i
]; 
 852         m_colRights
[i
] = right
; 
 855     // adjust the scroll bars 
 859     GetClientSize(&cw
, &ch
); 
 861     // begin by assuming that we don't need either scroll bar 
 863     int vertScrollBarWidth 
= 0; 
 864     int horizScrollBarHeight 
= 0; 
 866     // Each scroll bar needs to eventually know if the other one is 
 867     // required in deciding whether or not it is also required - hence 
 868     // this loop. A bit inelegant but simple and it works. 
 871     for ( check 
= 0;  check 
< 2;  check
++ ) 
 873         if ( m_numRows 
> 0  && 
 874              m_rowBottoms
[m_numRows
-1] + horizScrollBarHeight 
> ch 
) 
 876             vertScrollBarWidth 
= m_scrollBarWidth
; 
 878             m_wholeRowsVisible 
= 0; 
 879             for ( i 
= m_scrollPosY
; i 
< m_numRows
; i
++ ) 
 881                 // A partial row doesn't count, we still have to scroll to 
 882                 // see the rest of it 
 883                 if ( m_rowBottoms
[i
] + horizScrollBarHeight 
> ch 
) break; 
 885                 m_wholeRowsVisible
++ ; 
 890             m_wholeRowsVisible 
= m_numRows 
- m_scrollPosY
; 
 893                 vertScrollBarWidth 
= m_scrollBarWidth
; 
 899              m_colRights
[m_numCols
-1] + vertScrollBarWidth 
> cw
) 
 901             horizScrollBarHeight 
= m_scrollBarWidth
; 
 903             m_wholeColsVisible 
= 0; 
 904             for ( i 
= m_scrollPosX
; i 
< m_numCols
; i
++ ) 
 906                 // A partial col doesn't count, we still have to scroll to 
 907                 // see the rest of it 
 908                 if ( m_colRights
[i
] + vertScrollBarWidth 
> cw 
) break; 
 910                 m_wholeColsVisible
++ ; 
 915             // we can see the right-most column 
 917             m_wholeColsVisible 
= m_numCols 
- m_scrollPosX
; 
 920                 horizScrollBarHeight 
= m_scrollBarWidth
; 
 926     if ( m_vertScrollBar 
) 
 928         if ( !vertScrollBarWidth 
) 
 930             m_vertScrollBar
->Show(FALSE
); 
 934             m_vertScrollBar
->Show(TRUE
); 
 935             m_vertScrollBar
->SetScrollbar( 
 937                 wxMax(m_wholeRowsVisible
, 1), 
 938                 (m_wholeRowsVisible 
== 0 ? 1 : m_numRows
), 
 939                 wxMax(m_wholeRowsVisible
, 1) ); 
 941             m_vertScrollBar
->SetSize( cw 
- m_scrollBarWidth
, 
 944                                       ch 
- m_top 
- horizScrollBarHeight
); 
 948     if ( m_horizScrollBar 
) 
 950         if ( !horizScrollBarHeight 
) 
 952             m_horizScrollBar
->Show(FALSE
); 
 956             m_horizScrollBar
->Show(TRUE
); 
 958             m_horizScrollBar
->SetScrollbar( 
 960                 wxMax(m_wholeColsVisible
, 1), 
 961                 (m_wholeColsVisible 
== 0) ? 1 : m_numCols
, 
 962                 wxMax(m_wholeColsVisible
, 1) ); 
 964             m_horizScrollBar
->SetSize( m_left
, 
 965                                        ch 
- m_scrollBarWidth
, 
 966                                        cw 
- m_left 
- vertScrollBarWidth
, 
 971     m_bottom 
= m_right 
= 0; 
 974         m_bottom 
= wxMin( m_rowBottoms
[m_numRows
-1], 
 975                           ch 
- horizScrollBarHeight 
); 
 979         m_right 
= wxMin( m_colRights
[m_numCols
-1], 
 980                          cw 
- vertScrollBarWidth 
); 
 985 bool wxGrid::IsOnScreen() 
 988     GetClientSize( &cw
, &ch 
); 
 993 // this is called when the grid table sends a message to say that it 
 994 // has been redimensioned 
 996 bool wxGrid::Redimension( wxGridTableMessage
& msg 
) 
1000     switch ( msg
.GetId() ) 
1002         case wxGRIDTABLE_NOTIFY_ROWS_INSERTED
: 
1004             size_t pos 
= msg
.GetCommandInt(); 
1005             int numRows 
= msg
.GetCommandInt2(); 
1006             for ( i 
= 0;  i 
< numRows
;  i
++ ) 
1008                 m_rowHeights
.Insert( m_defaultRowHeight
, pos 
); 
1009                 m_rowBottoms
.Insert( 0, pos 
); 
1011             m_numRows 
+= numRows
; 
1016         case wxGRIDTABLE_NOTIFY_ROWS_APPENDED
: 
1018             int numRows 
= msg
.GetCommandInt(); 
1019             for ( i 
= 0;  i 
< numRows
;  i
++ ) 
1021                 m_rowHeights
.Add( m_defaultRowHeight 
); 
1022                 m_rowBottoms
.Add( 0 ); 
1024             m_numRows 
+= numRows
; 
1029         case wxGRIDTABLE_NOTIFY_ROWS_DELETED
: 
1031             size_t pos 
= msg
.GetCommandInt(); 
1032             int numRows 
= msg
.GetCommandInt2(); 
1033             for ( i 
= 0;  i 
< numRows
;  i
++ ) 
1035                 m_rowHeights
.Remove( pos 
); 
1036                 m_rowBottoms
.Remove( pos 
); 
1038             m_numRows 
-= numRows
; 
1040             // TODO: improve these adjustments... 
1042             if ( m_scrollPosY 
>= m_numRows 
) 
1048                 m_colWidths
.Clear(); 
1049                 m_colRights
.Clear(); 
1050                 m_currentCellCoords 
= wxGridNoCellCoords
; 
1052             else if ( m_currentCellCoords
.GetRow() >= m_numRows 
) 
1054                 m_currentCellCoords
.Set( 0, 0 ); 
1060         case wxGRIDTABLE_NOTIFY_COLS_INSERTED
: 
1062             size_t pos 
= msg
.GetCommandInt(); 
1063             int numCols 
= msg
.GetCommandInt2(); 
1064             for ( i 
= 0;  i 
< numCols
;  i
++ ) 
1066                 m_colWidths
.Insert( m_defaultColWidth
, pos 
); 
1067                 m_colRights
.Insert( 0, pos 
); 
1069             m_numCols 
+= numCols
; 
1074         case wxGRIDTABLE_NOTIFY_COLS_APPENDED
: 
1076             int numCols 
= msg
.GetCommandInt(); 
1077             for ( i 
= 0;  i 
< numCols
;  i
++ ) 
1079                 m_colWidths
.Add( m_defaultColWidth 
); 
1080                 m_colRights
.Add( 0 ); 
1082             m_numCols 
+= numCols
; 
1087         case wxGRIDTABLE_NOTIFY_COLS_DELETED
: 
1089             size_t pos 
= msg
.GetCommandInt(); 
1090             int numCols 
= msg
.GetCommandInt2(); 
1091             for ( i 
= 0;  i 
< numCols
;  i
++ ) 
1093                 m_colWidths
.Remove( pos 
); 
1094                 m_colRights
.Remove( pos 
); 
1096             m_numCols 
-= numCols
; 
1098             // TODO: improve these adjustments... 
1100             if ( m_scrollPosX 
>= m_numCols 
) 
1105 #if 0  // leave the row alone here so that AppendCols will work subsequently 
1107                 m_rowHeights
.Clear(); 
1108                 m_rowBottoms
.Clear(); 
1110                 m_currentCellCoords 
= wxGridNoCellCoords
; 
1112             else if ( m_currentCellCoords
.GetCol() >= m_numCols 
) 
1114                 m_currentCellCoords
.Set( 0, 0 ); 
1126 // ----- event handlers 
1129 // Generate a grid event based on a mouse event and  
1130 // return the result of ProcessEvent() 
1132 bool wxGrid::SendEvent( const wxEventType type
, 
1134                         wxMouseEvent
& mouseEv 
) 
1136     if ( type 
== EVT_WXGRID_ROW_SIZE 
|| 
1137          type 
== EVT_WXGRID_COL_SIZE 
) 
1139         int rowOrCol 
= (row 
== -1 ? col 
: row
); 
1141         wxGridSizeEvent 
gridEvt( GetId(), 
1145                                  mouseEv
.GetX(), mouseEv
.GetY(), 
1146                                  mouseEv
.ControlDown(), 
1147                                  mouseEv
.ShiftDown(), 
1149                                  mouseEv
.MetaDown() ); 
1151         return GetEventHandler()->ProcessEvent(gridEvt
); 
1153     else if ( type 
== EVT_WXGRID_RANGE_SELECT 
) 
1155         wxGridRangeSelectEvent 
gridEvt( GetId(), 
1159                                         m_selectedBottomRight
, 
1160                                         mouseEv
.ControlDown(), 
1161                                         mouseEv
.ShiftDown(), 
1163                                         mouseEv
.MetaDown() ); 
1165         return GetEventHandler()->ProcessEvent(gridEvt
); 
1169         wxGridEvent 
gridEvt( GetId(), 
1173                              mouseEv
.GetX(), mouseEv
.GetY(), 
1174                              mouseEv
.ControlDown(), 
1175                              mouseEv
.ShiftDown(), 
1177                              mouseEv
.MetaDown() ); 
1179         return GetEventHandler()->ProcessEvent(gridEvt
); 
1184 // Generate a grid event of specified type and return the result 
1185 // of ProcessEvent(). 
1187 bool wxGrid::SendEvent( const wxEventType type
, 
1190     if ( type 
== EVT_WXGRID_ROW_SIZE 
|| 
1191          type 
== EVT_WXGRID_COL_SIZE 
) 
1193         int rowOrCol 
= (row 
== -1 ? col 
: row
); 
1195         wxGridSizeEvent 
gridEvt( GetId(), 
1200         return GetEventHandler()->ProcessEvent(gridEvt
); 
1204         wxGridEvent 
gridEvt( GetId(), 
1209         return GetEventHandler()->ProcessEvent(gridEvt
); 
1214 void wxGrid::OnPaint( wxPaintEvent
& ev 
) 
1216     wxPaintDC 
dc( this ); 
1218     if ( !m_batchCount 
) 
1220         // define a clipping region to avoid painting over the scroll bars 
1223         if ( m_vertScrollBar 
&& m_vertScrollBar
->IsShown() ) 
1224             vs 
= m_scrollBarWidth
; 
1227         if ( m_horizScrollBar 
&& m_horizScrollBar
->IsShown() ) 
1228             hs 
= m_scrollBarWidth
; 
1231         GetClientSize( &cw
, &ch 
); 
1232         dc
.SetClippingRegion( 0, 0, cw 
- vs
, ch 
- hs 
); 
1234         HideCurrentCellHighlight( dc 
); 
1236         DrawLabelAreas( dc 
); 
1237         DrawColLabels( dc 
); 
1238         DrawRowLabels( dc 
); 
1240         DrawGridLines( dc 
); 
1243         // TODO: something more elegant than this... 
1247             if ( m_currentCellCoords 
== wxGridNoCellCoords 
) 
1248                 m_currentCellCoords
.Set(0, 0); 
1250             SetEditControlValue(); 
1251             ShowCellEditControl(); 
1252             m_firstPaint 
= FALSE
; 
1255         ShowCurrentCellHighlight( dc 
); 
1257         dc
.DestroyClippingRegion(); 
1262 void wxGrid::OnSize( wxSizeEvent
& ev 
) 
1268 void wxGrid::OnMouse( wxMouseEvent
& ev 
) 
1274     // ------------------------------------------------------------ 
1278     if ( ev
.Dragging() ) 
1280         m_isDragging 
= TRUE
; 
1282         if ( ev
.LeftIsDown() ) 
1284             switch( m_cursorMode 
) 
1286                 case WXGRID_CURSOR_SELECT_CELL
: 
1288                     wxGridCellCoords cellCoords
; 
1289                     XYToCell( x
, y
, cellCoords 
); 
1290                     if ( cellCoords 
!= wxGridNoCellCoords 
) 
1292                         if ( !IsSelection() ) 
1294                             SelectBlock( cellCoords
, cellCoords 
); 
1296                         else if ( !IsInSelection( cellCoords 
) ) 
1298                             SelectBlock( m_currentCellCoords
, cellCoords 
); 
1304                 case WXGRID_CURSOR_RESIZE_ROW
: 
1306                     wxClientDC 
dc(this); 
1307                     dc
.SetLogicalFunction(wxXOR
); 
1308                     if ( m_dragLastPos 
>= 0 ) 
1310                         dc
.DrawLine( m_left
, m_dragLastPos
, 
1311                                      m_right
, m_dragLastPos 
); 
1313                     dc
.DrawLine( m_left
, ev
.GetY(), 
1314                                  m_right
, ev
.GetY()); 
1316                     m_dragLastPos 
= ev
.GetY(); 
1320                 case WXGRID_CURSOR_RESIZE_COL
: 
1322                     wxClientDC 
dc(this); 
1323                     dc
.SetLogicalFunction(wxINVERT
); 
1324                     if ( m_dragLastPos 
>= 0 ) 
1326                         dc
.DrawLine( m_dragLastPos
, m_top
, 
1327                                      m_dragLastPos
, m_bottom 
); 
1329                     dc
.DrawLine( ev
.GetX(), m_top
, 
1330                                  ev
.GetX(), m_bottom 
); 
1332                     m_dragLastPos 
= ev
.GetX(); 
1336                 case WXGRID_CURSOR_SELECT_ROW
: 
1338                     if ( (row 
= YToRow( y 
)) >= 0  && 
1339                          !IsInSelection( row
, 0 ) ) 
1341                         SelectRow( row
, TRUE 
); 
1346                 case WXGRID_CURSOR_SELECT_COL
: 
1348                     if ( (col 
= XToCol( x 
)) >= 0  && 
1349                          !IsInSelection( 0, col 
) ) 
1351                         SelectCol( col
, TRUE 
); 
1360     m_isDragging 
= FALSE
; 
1362     // ------------------------------------------------------------ 
1364     // Left mouse button down 
1366     if ( ev
.LeftDown() ) 
1370         wxGridCellCoords cellCoords
; 
1372         switch( XYToArea( x
, y 
) ) 
1374             case WXGRID_ROWLABEL
: 
1376                 // don't send a label click event for a hit on the 
1377                 // edge of the row label - this is probably the user 
1378                 // wanting to resize the row 
1380                 if ( YToEdgeOfRow(y
) < 0 ) 
1383                     if ( !SendEvent( EVT_WXGRID_LABEL_LEFT_CLICK
, row
, col
, ev 
) ) 
1385                         SelectRow( row
, ev
.ShiftDown() ); 
1386                         m_cursorMode 
= WXGRID_CURSOR_SELECT_ROW
; 
1392             case WXGRID_COLLABEL
: 
1394                 // don't send a label click event for a hit on the 
1395                 // edge of the col label - this is probably the user 
1396                 // wanting to resize the col 
1398                 if ( XToEdgeOfCol(x
) < 0 ) 
1401                     if ( !SendEvent( EVT_WXGRID_LABEL_LEFT_CLICK
, row
, col
, ev 
) ) 
1403                         SelectCol( col
, ev
.ShiftDown() ); 
1404                         m_cursorMode 
= WXGRID_CURSOR_SELECT_COL
; 
1410             case WXGRID_CORNERLABEL
: 
1412                 // leave both row and col as -1 
1414                 if ( !SendEvent( EVT_WXGRID_LABEL_LEFT_CLICK
, row
, col
, ev 
) ) 
1423                 XYToCell( x
, y
, cellCoords 
); 
1424                 if ( !SendEvent( EVT_WXGRID_CELL_LEFT_CLICK
, 
1425                                  cellCoords
.GetRow(), 
1426                                  cellCoords
.GetCol(), 
1429                     MakeCellVisible( cellCoords 
); 
1430                     SelectCell( cellCoords 
); 
1437                 wxLogMessage( "outside grid area" ); 
1442     // ------------------------------------------------------------ 
1444     // Left mouse button double click 
1446     else if ( ev
.LeftDClick() ) 
1450         wxGridCellCoords cellCoords
; 
1452         switch( XYToArea( x
, y 
) ) 
1454             case WXGRID_ROWLABEL
: 
1456                 // don't send a label click event for a hit on the 
1457                 // edge of the row label - this is probably the user 
1458                 // wanting to resize the row 
1460                 if ( YToEdgeOfRow(y
) < 0 ) 
1463                     SendEvent(  EVT_WXGRID_LABEL_LEFT_DCLICK
, row
, col
, ev 
); 
1468             case WXGRID_COLLABEL
: 
1470                 // don't send a label click event for a hit on the 
1471                 // edge of the col label - this is probably the user 
1472                 // wanting to resize the col 
1474                 if ( XToEdgeOfCol(x
) < 0 ) 
1477                     SendEvent(  EVT_WXGRID_LABEL_LEFT_DCLICK
, row
, col
, ev 
); 
1482             case WXGRID_CORNERLABEL
: 
1484                 // leave both row and col as -1 
1486                 SendEvent(  EVT_WXGRID_LABEL_LEFT_DCLICK
, row
, col
, ev 
);                 
1492                 XYToCell( x
, y
, cellCoords 
); 
1493                 SendEvent( EVT_WXGRID_CELL_LEFT_DCLICK
, 
1494                                  cellCoords
.GetRow(), 
1495                                  cellCoords
.GetCol(), 
1502                 wxLogMessage( "outside grid area" ); 
1507     // ------------------------------------------------------------ 
1509     // Left mouse button released 
1511     else if ( ev
.LeftUp() ) 
1513         switch ( m_cursorMode 
) 
1515             case WXGRID_CURSOR_RESIZE_ROW
: 
1517                 if ( m_dragLastPos 
>= 0 ) 
1519                     // erase the last line and resize the row 
1521                     wxClientDC 
dc( this ); 
1522                     dc
.SetLogicalFunction( wxINVERT 
); 
1523                     dc
.DrawLine( m_left
, m_dragLastPos
, 
1524                                  m_right
, m_dragLastPos 
); 
1525                     HideCellEditControl(); 
1526                     int top 
= m_top 
+ m_colLabelHeight
; 
1527                     if ( m_dragRowOrCol 
> 0 ) 
1528                         top 
= m_rowBottoms
[m_dragRowOrCol
-1]; 
1529                     m_rowHeights
[m_dragRowOrCol
] = wxMax( ev
.GetY() - top
, 
1530                                                           WXGRID_MIN_ROW_HEIGHT 
); 
1532                     ShowCellEditControl(); 
1535                     // Note: we are ending the event *after* doing 
1536                     // default processing in this case 
1538                     SendEvent( EVT_WXGRID_ROW_SIZE
, m_dragRowOrCol
, -1, ev 
); 
1543             case WXGRID_CURSOR_RESIZE_COL
: 
1545                 if ( m_dragLastPos 
>= 0 ) 
1547                     // erase the last line and resize the col 
1549                     wxClientDC 
dc( this ); 
1550                     dc
.SetLogicalFunction( wxINVERT 
); 
1551                     dc
.DrawLine( m_left
, m_dragLastPos
, 
1552                                  m_right
, m_dragLastPos 
); 
1553                     HideCellEditControl(); 
1554                     int left 
= m_left 
+ m_rowLabelWidth
; 
1555                     if ( m_dragRowOrCol 
> 0 ) 
1556                         left 
= m_colRights
[m_dragRowOrCol
-1]; 
1557                     m_colWidths
[m_dragRowOrCol
] = wxMax( ev
.GetX() - left
, 
1558                                                          WXGRID_MIN_COL_WIDTH 
); 
1560                     ShowCellEditControl(); 
1563                     // Note: we are ending the event *after* doing 
1564                     // default processing in this case 
1566                     SendEvent( EVT_WXGRID_COL_SIZE
, -1, m_dragRowOrCol
, ev 
); 
1571             case WXGRID_CURSOR_SELECT_CELL
: 
1573                 if ( IsSelection() ) 
1575                     // Note: we are ending the event *after* doing 
1576                     // default processing in this case 
1578                     SendEvent( EVT_WXGRID_RANGE_SELECT
, -1, -1, ev 
); 
1586     // ------------------------------------------------------------ 
1588     // Right mouse button down 
1590     else if ( ev
.RightDown() ) 
1594         wxGridCellCoords cellCoords
; 
1596         switch( XYToArea( x
, y 
) ) 
1599             case WXGRID_ROWLABEL
: 
1602                 if ( !SendEvent( EVT_WXGRID_LABEL_RIGHT_CLICK
, row
, col
, ev 
) ) 
1604                     // TODO: default processing ? 
1609             case WXGRID_COLLABEL
: 
1612                 if ( !SendEvent( EVT_WXGRID_LABEL_RIGHT_CLICK
, row
, col
, ev 
) ) 
1614                     // TODO: default processing ? 
1619             case WXGRID_CORNERLABEL
: 
1621                 // leave both row and col as -1 
1623                 if ( !SendEvent( EVT_WXGRID_LABEL_RIGHT_CLICK
, row
, col
, ev 
) ) 
1625                     // TODO: default processing ? 
1632                 XYToCell( x
, y
, cellCoords 
); 
1633                 if ( !SendEvent( EVT_WXGRID_CELL_RIGHT_CLICK
, 
1634                                 cellCoords
.GetRow(), 
1635                                 cellCoords
.GetCol(), 
1638                     // TODO: default processing ? 
1645                 wxLogMessage( "outside grid area" ); 
1650     // ------------------------------------------------------------ 
1652     // Right mouse button double click 
1654     else if ( ev
.RightDClick() ) 
1658         wxGridCellCoords cellCoords
; 
1660         switch( XYToArea( x
, y 
) ) 
1663             case WXGRID_ROWLABEL
: 
1666                 SendEvent( EVT_WXGRID_LABEL_RIGHT_DCLICK
, row
, col
, ev 
); 
1670             case WXGRID_COLLABEL
: 
1673                 SendEvent( EVT_WXGRID_LABEL_RIGHT_DCLICK
, row
, col
, ev 
); 
1677             case WXGRID_CORNERLABEL
: 
1679                 // leave both row and col as -1 
1681                 SendEvent( EVT_WXGRID_LABEL_RIGHT_DCLICK
, row
, col
, ev 
); 
1687                 XYToCell( x
, y
, cellCoords 
); 
1688                 SendEvent( EVT_WXGRID_CELL_RIGHT_DCLICK
, 
1689                            cellCoords
.GetRow(), 
1690                            cellCoords
.GetCol(), 
1697                 wxLogMessage( "outside grid area" ); 
1702     // ------------------------------------------------------------ 
1704     // No buttons down and mouse moving 
1706     else if ( ev
.Moving() ) 
1708         switch( XYToArea( x
, y 
) ) 
1710             case WXGRID_ROWLABEL
: 
1712                 m_dragRowOrCol 
= YToEdgeOfRow( y 
); 
1713                 if ( m_dragRowOrCol 
>= 0 ) 
1715                     if ( m_cursorMode 
== WXGRID_CURSOR_SELECT_CELL 
) 
1717                         m_cursorMode 
= WXGRID_CURSOR_RESIZE_ROW
; 
1718                         SetCursor( m_rowResizeCursor 
); 
1723                     if ( m_cursorMode 
!= WXGRID_CURSOR_SELECT_CELL 
) 
1725                         m_cursorMode 
= WXGRID_CURSOR_SELECT_CELL
; 
1726                         SetCursor( *wxSTANDARD_CURSOR 
); 
1732             case WXGRID_COLLABEL
: 
1734                 m_dragRowOrCol 
= XToEdgeOfCol( x 
); 
1735                 if ( m_dragRowOrCol 
>= 0 ) 
1737                     if ( m_cursorMode 
== WXGRID_CURSOR_SELECT_CELL 
) 
1739                         m_cursorMode 
= WXGRID_CURSOR_RESIZE_COL
; 
1740                         SetCursor( m_colResizeCursor 
); 
1745                     if ( m_cursorMode 
!= WXGRID_CURSOR_SELECT_CELL 
) 
1747                         m_cursorMode 
= WXGRID_CURSOR_SELECT_CELL
; 
1748                         SetCursor( *wxSTANDARD_CURSOR 
); 
1756                 if ( m_cursorMode 
!= WXGRID_CURSOR_SELECT_CELL 
) 
1758                     m_cursorMode 
= WXGRID_CURSOR_SELECT_CELL
; 
1759                     SetCursor( *wxSTANDARD_CURSOR 
); 
1768 void wxGrid::OnKeyDown( wxKeyEvent
& ev 
) 
1770     if ( m_inOnKeyDown 
) 
1772         // shouldn't be here - we are going round in circles... 
1774         wxLogFatalError( "wxGrid::OnKeyDown called while alread active" ); 
1777     m_inOnKeyDown 
= TRUE
; 
1779     // propagate the event up and see if it gets processed 
1781     wxWindow 
*parent 
= GetParent(); 
1782     wxKeyEvent 
keyEvt( ev 
); 
1783     keyEvt
.SetEventObject( parent 
); 
1785     if ( !parent
->GetEventHandler()->ProcessEvent( keyEvt 
) ) 
1787         // try local handlers 
1789         switch ( ev
.KeyCode() ) 
1792                 if ( ev
.ControlDown() ) 
1794                     MoveCursorUpBlock(); 
1803                 if ( ev
.ControlDown() ) 
1805                     MoveCursorDownBlock(); 
1814                 if ( ev
.ControlDown() ) 
1816                     MoveCursorLeftBlock(); 
1825                 if ( ev
.ControlDown() ) 
1827                     MoveCursorRightBlock(); 
1840                 if ( ev
.ControlDown() ) 
1842                     MakeCellVisible( 0, 0 ); 
1852                 if ( ev
.ControlDown() ) 
1854                     MakeCellVisible( m_numRows
-1, m_numCols
-1 ); 
1855                     SelectCell( m_numRows
-1, m_numCols
-1 ); 
1864                 // now try the cell edit control 
1866                 if ( IsCellEditControlEnabled() ) 
1868                     ev
.SetEventObject( m_cellEditCtrl 
); 
1869                     m_cellEditCtrl
->GetEventHandler()->ProcessEvent( ev 
); 
1875     m_inOnKeyDown 
= FALSE
; 
1879 // Text updated in an edit control - either a text control or a 
1882 void wxGrid::OnText( wxKeyEvent
& ev 
) 
1887         wxWindow 
*ctrl 
= (wxWindow 
*)ev
.GetEventObject(); 
1889         if ( ctrl 
== m_cellEditCtrl 
&& 
1890              IsTopEditControlEnabled() ) 
1892             // set the value of the top edit control 
1894             switch ( m_editCtrlType 
) 
1896                 case wxGRID_TEXTCTRL
: 
1897                     ((wxTextCtrl 
*)m_topEditCtrl
)-> 
1898                         SetValue(((wxTextCtrl 
*)ctrl
)->GetValue()); 
1901                 case wxGRID_COMBOBOX
: 
1902                     ((wxComboBox 
*)m_topEditCtrl
)-> 
1903                         SetValue(((wxComboBox 
*)ctrl
)->GetValue()); 
1907         else if ( ctrl 
== m_topEditCtrl 
&& 
1908                   IsCellEditControlEnabled() ) 
1910             switch ( m_editCtrlType 
) 
1912                 case wxGRID_TEXTCTRL
: 
1913                     ((wxTextCtrl 
*)m_cellEditCtrl
)-> 
1914                         SetValue(((wxTextCtrl 
*)ctrl
)->GetValue()); 
1917                 case wxGRID_COMBOBOX
: 
1918                     ((wxComboBox 
*)m_cellEditCtrl
)-> 
1919                         SetValue(((wxComboBox 
*)ctrl
)->GetValue()); 
1928 void wxGrid::OnGridScroll( wxScrollEvent
& ev 
) 
1930     // propagate the event up and see if it gets processed 
1932     wxWindow 
*parent 
= GetParent(); 
1933     wxScrollEvent 
scrollEvt( ev 
); 
1934     if (parent
->GetEventHandler()->ProcessEvent( scrollEvt 
)) return; 
1936     HideCellEditControl(); 
1938     if ( ev
.GetEventObject() == m_horizScrollBar 
) 
1940         if ( ev
.GetPosition() != m_scrollPosX 
) 
1942             SetHorizontalScrollPos( ev
.GetPosition() ); 
1947         if ( ev
.GetPosition() != m_scrollPosY 
) 
1949             SetVerticalScrollPos( ev
.GetPosition() ); 
1953     ShowCellEditControl(); 
1957 void wxGrid::SelectCell( const wxGridCellCoords
& coords 
) 
1959     wxClientDC 
dc( this ); 
1961     if ( m_currentCellCoords 
!= wxGridNoCellCoords 
) 
1963         HideCurrentCellHighlight( dc 
); 
1964         HideCellEditControl(); 
1965         SaveEditControlValue(); 
1968     m_currentCellCoords 
= coords
; 
1970     SetEditControlValue(); 
1973         ShowCellEditControl(); 
1974         ShowCurrentCellHighlight( dc 
); 
1977     if ( IsSelection() ) 
1980         if ( !GetBatchCount() ) Refresh(); 
1985 void wxGrid::ShowCellEditControl() 
1989     if ( IsCellEditControlEnabled() )          
1991         if ( !IsVisible( m_currentCellCoords 
) ) 
1997             rect 
= CellToRect( m_currentCellCoords 
); 
1999             m_cellEditCtrl
->SetSize( rect 
); 
2000             m_cellEditCtrl
->Show( TRUE 
); 
2002             switch ( m_editCtrlType 
) 
2004                 case wxGRID_TEXTCTRL
: 
2005                     ((wxTextCtrl 
*) m_cellEditCtrl
)->SetInsertionPointEnd(); 
2008                 case wxGRID_CHECKBOX
: 
2009                     // TODO: anything ??? 
2014                     // TODO: anything ??? 
2018                 case wxGRID_COMBOBOX
: 
2019                     // TODO: anything ??? 
2024             m_cellEditCtrl
->SetFocus(); 
2030 void wxGrid::HideCellEditControl() 
2032     if ( IsCellEditControlEnabled() ) 
2034         m_cellEditCtrl
->Show( FALSE 
); 
2038 void wxGrid::SetEditControlValue( const wxString
& value 
) 
2043         s 
= ( value 
== wxEmptyString 
? GetCellValue(m_currentCellCoords
) : value 
); 
2045         if ( IsTopEditControlEnabled() ) 
2047             switch ( m_editCtrlType 
) 
2049                 case wxGRID_TEXTCTRL
: 
2050                     ((wxGridTextCtrl 
*)m_topEditCtrl
)->SetStartValue(s
); 
2053                 case wxGRID_CHECKBOX
: 
2054                     // TODO: implement this 
2059                     // TODO: implement this 
2063                 case wxGRID_COMBOBOX
: 
2064                     // TODO: implement this 
2070         if ( IsCellEditControlEnabled() ) 
2072             switch ( m_editCtrlType 
) 
2074                 case wxGRID_TEXTCTRL
: 
2075                     ((wxGridTextCtrl 
*)m_cellEditCtrl
)->SetStartValue(s
); 
2078                 case wxGRID_CHECKBOX
: 
2079                     // TODO: implement this 
2084                     // TODO: implement this 
2088                 case wxGRID_COMBOBOX
: 
2089                     // TODO: implement this 
2097 void wxGrid::SaveEditControlValue() 
2101         wxWindow 
*ctrl 
= (wxWindow 
*)NULL
; 
2103         if ( IsCellEditControlEnabled() ) 
2105             ctrl 
= m_cellEditCtrl
; 
2107         else if ( IsTopEditControlEnabled() ) 
2109             ctrl 
= m_topEditCtrl
; 
2116         bool valueChanged 
= FALSE
; 
2118         switch ( m_editCtrlType 
) 
2120             case wxGRID_TEXTCTRL
: 
2121                 valueChanged 
= (((wxGridTextCtrl 
*)ctrl
)->GetValue() != 
2122                                 ((wxGridTextCtrl 
*)ctrl
)->GetStartValue()); 
2123                 SetCellValue( m_currentCellCoords
, 
2124                               ((wxTextCtrl 
*) ctrl
)->GetValue() ); 
2127             case wxGRID_CHECKBOX
: 
2128                 // TODO: implement this 
2133                 // TODO: implement this 
2137             case wxGRID_COMBOBOX
: 
2138                 // TODO: implement this 
2145             SendEvent( EVT_WXGRID_CELL_CHANGE
, 
2146                        m_currentCellCoords
.GetRow(), 
2147                        m_currentCellCoords
.GetCol() ); 
2153 int wxGrid::XYToArea( int x
, int y 
) 
2155     if ( x 
> m_left 
&& x 
< m_right 
&& 
2156          y 
> m_top 
&& y 
< m_bottom 
) 
2158         if ( y 
< m_top 
+ m_colLabelHeight 
) 
2160             if ( x 
> m_left 
+ m_rowLabelWidth 
) 
2162                 return WXGRID_COLLABEL
; 
2166                 return WXGRID_CORNERLABEL
; 
2169         else if ( x 
<= m_left 
+ m_rowLabelWidth 
) 
2171             return WXGRID_ROWLABEL
; 
2179     return WXGRID_NOAREA
; 
2183 void wxGrid::XYToCell( int x
, int y
, wxGridCellCoords
& coords 
) 
2185     coords
.SetRow( YToRow(y
) ); 
2186     coords
.SetCol( XToCol(x
) ); 
2190 int wxGrid::YToRow( int y 
) 
2194     if ( y 
> m_top 
+ m_colLabelHeight 
) 
2196         for ( i 
= m_scrollPosY
;  i 
< m_numRows
;  i
++ ) 
2198             if ( y 
< m_rowBottoms
[i
] ) 
2209 int wxGrid::XToCol( int x 
) 
2213     if ( x 
> m_left 
+ m_rowLabelWidth 
) 
2215         for ( i 
= m_scrollPosX
;  i 
< m_numCols
;  i
++ ) 
2217             if ( x 
< m_colRights
[i
] ) 
2228 // return the row number that that the y coord is near the edge of, or 
2229 // -1 if not near an edge 
2231 int wxGrid::YToEdgeOfRow( int y 
) 
2235     if ( y 
> m_top 
+ m_colLabelHeight 
) 
2237         for ( i 
= m_scrollPosY
;  i 
< m_numRows
;  i
++ ) 
2239             if ( m_rowHeights
[i
] > WXGRID_LABEL_EDGE_ZONE 
) 
2241                 d 
= abs( y 
- m_rowBottoms
[i
] ); 
2243                     if ( d 
< WXGRID_LABEL_EDGE_ZONE 
) return i
; 
2254 // return the col number that that the x coord is near the edge of, or 
2255 // -1 if not near an edge 
2257 int wxGrid::XToEdgeOfCol( int x 
) 
2261     if ( x 
> m_left 
+ m_rowLabelWidth 
) 
2263         for ( i 
= m_scrollPosX
;  i 
< m_numCols
;  i
++ ) 
2265             if ( m_colWidths
[i
] > WXGRID_LABEL_EDGE_ZONE 
) 
2267                 d 
= abs( x 
- m_colRights
[i
] ); 
2269                     if ( d 
< WXGRID_LABEL_EDGE_ZONE 
) return i
; 
2280 wxRect 
wxGrid::CellToRect( int row
, int col 
) 
2282     wxRect 
rect( -1, -1, -1, -1 ); 
2284     if ( row 
>= m_scrollPosY  
&&  col 
>= m_scrollPosX 
) 
2286         rect
.x 
= m_colRights
[col
] - m_colWidths
[col
]; 
2287         rect
.y 
= m_rowBottoms
[row
] - m_rowHeights
[row
]; 
2288         rect
.width 
= m_colWidths
[col
]; 
2289         rect
.height 
= m_rowHeights
[ row 
]; 
2296 bool wxGrid::MoveCursorUp() 
2298     if ( m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2299          m_currentCellCoords
.GetRow() > 0 ) 
2301         SelectCell( m_currentCellCoords
.GetRow() - 1, 
2302                       m_currentCellCoords
.GetCol() ); 
2304         if ( !IsVisible( m_currentCellCoords 
) ) 
2305             MakeCellVisible( m_currentCellCoords 
); 
2313 bool wxGrid::MoveCursorDown() 
2315     // TODO: allow for scrolling 
2317     if ( m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2318          m_currentCellCoords
.GetRow() < m_numRows
-1 ) 
2320         SelectCell( m_currentCellCoords
.GetRow() + 1, 
2321                       m_currentCellCoords
.GetCol() ); 
2323         if ( !IsVisible( m_currentCellCoords 
) ) 
2324             MakeCellVisible( m_currentCellCoords 
); 
2332 bool wxGrid::MoveCursorLeft() 
2334     if ( m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2335          m_currentCellCoords
.GetCol() > 0 ) 
2337         SelectCell( m_currentCellCoords
.GetRow(), 
2338                       m_currentCellCoords
.GetCol() - 1 ); 
2340         if ( !IsVisible( m_currentCellCoords 
) ) 
2341             MakeCellVisible( m_currentCellCoords 
); 
2349 bool wxGrid::MoveCursorRight() 
2351     if ( m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2352          m_currentCellCoords
.GetCol() < m_numCols 
- 1 ) 
2354         SelectCell( m_currentCellCoords
.GetRow(), 
2355                       m_currentCellCoords
.GetCol() + 1 ); 
2357         if ( !IsVisible( m_currentCellCoords 
) ) 
2358             MakeCellVisible( m_currentCellCoords 
); 
2366 bool wxGrid::MoveCursorUpBlock() 
2369          m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2370          m_currentCellCoords
.GetRow() > 0 ) 
2372         int row 
= m_currentCellCoords
.GetRow(); 
2373         int col 
= m_currentCellCoords
.GetCol(); 
2375         if ( m_table
->IsEmptyCell(row
, col
) ) 
2377             // starting in an empty cell: find the next block of 
2383                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2386         else if ( m_table
->IsEmptyCell(row
-1, col
) ) 
2388             // starting at the top of a block: find the next block 
2394                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2399             // starting within a block: find the top of the block 
2404                 if ( m_table
->IsEmptyCell(row
, col
) ) 
2412         SelectCell( row
, col 
); 
2414         if ( !IsVisible( m_currentCellCoords 
) ) 
2415             MakeCellVisible( m_currentCellCoords 
); 
2423 bool wxGrid::MoveCursorDownBlock() 
2426          m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2427          m_currentCellCoords
.GetRow() < m_numRows
-1 ) 
2429         int row 
= m_currentCellCoords
.GetRow(); 
2430         int col 
= m_currentCellCoords
.GetCol(); 
2432         if ( m_table
->IsEmptyCell(row
, col
) ) 
2434             // starting in an empty cell: find the next block of 
2437             while ( row 
< m_numRows
-1 ) 
2440                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2443         else if ( m_table
->IsEmptyCell(row
+1, col
) ) 
2445             // starting at the bottom of a block: find the next block 
2448             while ( row 
< m_numRows
-1 ) 
2451                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2456             // starting within a block: find the bottom of the block 
2458             while ( row 
< m_numRows
-1 ) 
2461                 if ( m_table
->IsEmptyCell(row
, col
) ) 
2469         SelectCell( row
, col 
); 
2471         if ( !IsVisible( m_currentCellCoords 
) ) 
2472             MakeCellVisible( m_currentCellCoords 
); 
2480 bool wxGrid::MoveCursorLeftBlock() 
2483          m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2484          m_currentCellCoords
.GetCol() > 0 ) 
2486         int row 
= m_currentCellCoords
.GetRow(); 
2487         int col 
= m_currentCellCoords
.GetCol(); 
2489         if ( m_table
->IsEmptyCell(row
, col
) ) 
2491             // starting in an empty cell: find the next block of 
2497                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2500         else if ( m_table
->IsEmptyCell(row
, col
-1) ) 
2502             // starting at the left of a block: find the next block 
2508                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2513             // starting within a block: find the left of the block 
2518                 if ( m_table
->IsEmptyCell(row
, col
) ) 
2526         SelectCell( row
, col 
); 
2528         if ( !IsVisible( m_currentCellCoords 
) ) 
2529             MakeCellVisible( m_currentCellCoords 
); 
2537 bool wxGrid::MoveCursorRightBlock() 
2540          m_currentCellCoords 
!= wxGridNoCellCoords  
&& 
2541          m_currentCellCoords
.GetCol() < m_numCols
-1 ) 
2543         int row 
= m_currentCellCoords
.GetRow(); 
2544         int col 
= m_currentCellCoords
.GetCol(); 
2546         if ( m_table
->IsEmptyCell(row
, col
) ) 
2548             // starting in an empty cell: find the next block of 
2551             while ( col 
< m_numCols
-1 ) 
2554                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2557         else if ( m_table
->IsEmptyCell(row
, col
+1) ) 
2559             // starting at the right of a block: find the next block 
2562             while ( col 
< m_numCols
-1 ) 
2565                 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break; 
2570             // starting within a block: find the right of the block 
2572             while ( col 
< m_numCols
-1 ) 
2575                 if ( m_table
->IsEmptyCell(row
, col
) ) 
2583         SelectCell( row
, col 
); 
2585         if ( !IsVisible( m_currentCellCoords 
) ) 
2586             MakeCellVisible( m_currentCellCoords 
); 
2597 // ----- grid drawing functions 
2600 void wxGrid::DrawLabelAreas( wxDC
& dc 
) 
2603     GetClientSize(&cw
, &ch
); 
2605     dc
.SetPen(*wxTRANSPARENT_PEN
); 
2606     dc
.SetBrush( wxBrush(GetLabelBackgroundColour(), wxSOLID
) ); 
2608     dc
.DrawRectangle( m_left
, m_top
, 
2609                       cw 
- m_left
, m_colLabelHeight 
); 
2611     dc
.DrawRectangle( m_left
, m_top
, 
2612                       m_rowLabelWidth
, ch 
- m_top 
); 
2616 void wxGrid::DrawColLabels( wxDC
& dc 
) 
2619     GetClientSize(&cw
, &ch
); 
2621     if (m_colLabelHeight 
== 0) return; 
2623     DrawColLabelBorders( dc 
); 
2627     rect
.height 
= m_colLabelHeight 
- 1; 
2629     int labelLeft 
= m_left 
+ m_rowLabelWidth
; 
2632     for ( i 
= m_scrollPosX
;  i 
< m_numCols
;  i
++ ) 
2634         if ( labelLeft 
> cw
) break; 
2636         rect
.x 
= 1 + labelLeft
; 
2637         rect
.width 
= m_colWidths
[i
]; 
2638         DrawColLabel( dc
, rect
, i 
); 
2640         labelLeft 
+= m_colWidths
[i
]; 
2645 void wxGrid::DrawColLabelBorders( wxDC
& dc 
) 
2647     if ( m_colLabelHeight 
<= 0 ) return; 
2651     GetClientSize( &cw
, &ch 
); 
2653     dc
.SetPen( *wxBLACK_PEN 
); 
2657     dc
.DrawLine( m_left
, m_top
, cw
, m_top 
); 
2659     dc
.DrawLine( m_left
, m_top 
+ m_colLabelHeight
, 
2660                  cw
,     m_top 
+ m_colLabelHeight 
); 
2664     int colLeft 
= m_left 
+ m_rowLabelWidth
; 
2665     for ( i 
= m_scrollPosX
;  i 
<= m_numCols
;  i
++ ) 
2667         if (colLeft 
> cw
) break; 
2669         dc
.DrawLine( colLeft
, m_top
, 
2670                      colLeft
, m_top 
+ m_colLabelHeight
); 
2672         if ( i 
< m_numCols 
) colLeft 
+= m_colWidths
[i
]; 
2675     // Draw white highlights for a 3d effect 
2677     dc
.SetPen( *wxWHITE_PEN 
); 
2679     colLeft 
= m_left 
+ m_rowLabelWidth
; 
2680     for ( i 
= m_scrollPosX
; i 
< m_numCols
; i
++ ) 
2682         if (colLeft 
> cw
) break; 
2684         dc
.DrawLine(colLeft 
+ 1, m_top 
+ 1, 
2685                     colLeft 
+ m_colWidths
[i
], m_top 
+ 1); 
2687         dc
.DrawLine(colLeft 
+ 1, m_top 
+ 1, 
2688                     colLeft 
+ 1, m_top 
+ m_colLabelHeight
); 
2690         colLeft 
+= m_colWidths
[i
]; 
2695 void wxGrid::DrawColLabel( wxDC
& dc
, const wxRect
& rect
, int col 
) 
2704     dc
.SetBackgroundMode( wxTRANSPARENT 
); 
2705     dc
.SetTextBackground( GetLabelBackgroundColour() ); 
2706     dc
.SetTextForeground( GetLabelTextColour() ); 
2707     dc
.SetFont( GetLabelFont() ); 
2710     GetColLabelAlignment( &hAlign
, &vAlign 
); 
2711     DrawTextRectangle( dc
, GetColLabelValue( col 
), rect2
, hAlign
, vAlign 
); 
2715 void wxGrid::DrawRowLabels( wxDC
& dc 
) 
2718     GetClientSize(&cw
, &ch
); 
2720     if (m_rowLabelWidth 
== 0) return; 
2722     DrawRowLabelBorders( dc 
); 
2725     rect
.x 
= m_left 
+ 1; 
2726     rect
.width 
= m_rowLabelWidth 
- 1; 
2728     int labelTop 
= m_top 
+ m_colLabelHeight
; 
2731     for ( i 
= m_scrollPosY
;  i 
< m_numRows
;  i
++ ) 
2733         if ( labelTop 
> ch 
) break; 
2735         rect
.y 
= 1 + labelTop
; 
2736         rect
.height 
= m_rowHeights
[i
]; 
2737         DrawRowLabel( dc
, rect
, i 
); 
2739         labelTop 
+= m_rowHeights
[i
]; 
2744 void wxGrid::DrawRowLabelBorders( wxDC
& dc 
) 
2746     if ( m_rowLabelWidth 
<= 0 ) return; 
2750     GetClientSize( &cw
, &ch 
); 
2752     dc
.SetPen( *wxBLACK_PEN 
); 
2756     dc
.DrawLine( m_left
, m_top
, m_left
, ch 
); 
2758     dc
.DrawLine( m_left 
+ m_rowLabelWidth
, m_top
, 
2759                  m_left 
+ m_rowLabelWidth
, ch 
); 
2763     int rowTop 
= m_top 
+ m_colLabelHeight
; 
2764     for ( i 
= m_scrollPosY
;  i 
<= m_numRows
;  i
++ ) 
2766         if ( rowTop 
> ch 
) break; 
2768         dc
.DrawLine( m_left
, rowTop
, 
2769                      m_left 
+ m_rowLabelWidth
, rowTop 
); 
2771         if ( i 
< m_numRows 
) rowTop 
+= m_rowHeights
[i
]; 
2774     // Draw white highlights for a 3d effect 
2776     dc
.SetPen( *wxWHITE_PEN 
); 
2778     rowTop 
= m_top 
+ m_colLabelHeight
; 
2779     for ( i 
= m_scrollPosY
; i 
< m_numRows
; i
++ ) 
2781         if ( rowTop 
> ch 
) break; 
2783         dc
.DrawLine( m_left 
+ 1, rowTop 
+ 1, 
2784                      m_left 
+ m_rowLabelWidth
, rowTop 
+ 1 ); 
2786         dc
.DrawLine( m_left 
+ 1, rowTop 
+ 1, 
2787                      m_left 
+ 1, rowTop 
+ m_rowHeights
[i
] ); 
2789         rowTop 
+= m_rowHeights
[i
]; 
2794 void wxGrid::DrawRowLabel( wxDC
& dc
, const wxRect
& rect
, int row 
) 
2803     dc
.SetBackgroundMode( wxTRANSPARENT 
); 
2804     dc
.SetTextBackground( GetLabelBackgroundColour() ); 
2805     dc
.SetTextForeground( GetLabelTextColour() ); 
2806     dc
.SetFont( GetLabelFont() ); 
2809     GetRowLabelAlignment( &hAlign
, &vAlign 
); 
2810     DrawTextRectangle( dc
, GetRowLabelValue( row 
), rect2
, hAlign
, vAlign 
); 
2814 void wxGrid::DrawCellArea( wxDC
& dc 
) 
2817   GetClientSize(&cw
, &ch
); 
2819   dc
.SetPen( *wxTRANSPARENT_PEN 
); 
2820   dc
.SetBrush( wxBrush(GetDefaultCellBackgroundColour(), wxSOLID
) ); 
2822   int left 
= m_left 
+ m_rowLabelWidth 
+ 1; 
2823   int top  
= m_top 
+ m_colLabelHeight 
+ 1; 
2825   dc
.DrawRectangle( left
, top
, cw 
- left
, ch 
- top 
); 
2829 void wxGrid::DrawGridLines( wxDC
& dc 
) 
2831     if ( !m_gridLinesEnabled 
|| !m_numRows 
|| !m_numCols 
) return; 
2835     GetClientSize(&cw
, &ch
); 
2837     dc
.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID
) ); 
2839     // horizontal grid lines 
2841     int rowTop 
= m_top 
+ m_colLabelHeight 
+ m_rowHeights
[m_scrollPosY
]; 
2842     for ( i 
= m_scrollPosY 
+ 1; i 
<= m_numRows
; i
++ ) 
2844         if ( rowTop 
> ch 
) break; 
2846         dc
.DrawLine( m_left 
+ m_rowLabelWidth 
+ 1, rowTop
, 
2849         if ( i 
< m_numRows 
) rowTop 
+= m_rowHeights
[i
]; 
2853     // vertical grid lines 
2855     int colLeft 
= m_left 
+ m_rowLabelWidth 
+ m_colWidths
[m_scrollPosX
]; 
2856     for ( i 
= m_scrollPosX 
+ 1; i 
<= m_numCols
; i
++ ) 
2858         if ( colLeft 
> cw 
) break; 
2860         dc
.DrawLine( colLeft
, m_top 
+ m_colLabelHeight 
+ 1, 
2861                      colLeft
, m_bottom 
); 
2863         if ( i 
< m_numCols 
) colLeft 
+= m_colWidths
[i
]; 
2868 void wxGrid::DrawCells( wxDC
& dc 
) 
2870     if ( !m_numRows 
|| !m_numCols 
) return; 
2875     GetClientSize( &cw
, &ch 
); 
2881         rect
.y 
= m_top 
+ m_colLabelHeight
; 
2882         for ( row 
= m_scrollPosY
;  row 
< m_numRows
;  row
++ ) 
2884             if ( rect
.y 
> ch 
) break; 
2886             rect
.height 
= m_rowHeights
[ row 
]; 
2887             rect
.x 
= m_left 
+ m_rowLabelWidth
; 
2889             for ( col 
= m_scrollPosX
;  col 
< m_numCols
;  col
++ ) 
2891                 if ( rect
.x 
> cw 
) break; 
2893                 rect
.width 
= m_colWidths
[col
]; 
2894                 DrawCellBackground( dc
, rect
, row
, col 
); 
2895                 DrawCellValue( dc
, rect
, row
, col 
); 
2896                 rect
.x 
+= rect
.width
; 
2898             rect
.y 
+= rect
.height
; 
2904 void wxGrid::DrawCellBackground( wxDC
& dc
, const wxRect
& rect
, int row
, int col 
) 
2913     dc
.SetBackgroundMode( wxSOLID 
); 
2915     if ( IsInSelection( row
, col 
) ) 
2917         // TODO: improve this 
2919         dc
.SetBrush( *wxBLACK_BRUSH 
); 
2923         dc
.SetBrush( wxBrush(GetCellBackgroundColour(row
, col
), wxSOLID
) ); 
2925     dc
.SetPen( *wxTRANSPARENT_PEN 
); 
2926     dc
.DrawRectangle( rect2 
); 
2930 void wxGrid::DrawCellValue( wxDC
& dc
, const wxRect
& rect
, int row
, int col 
) 
2939     dc
.SetBackgroundMode( wxTRANSPARENT 
); 
2941     if ( IsInSelection( row
, col 
) ) 
2943         // TODO: improve this 
2945         dc
.SetTextBackground( wxColour(0, 0, 0) ); 
2946         dc
.SetTextForeground( wxColour(255, 255, 255) ); 
2950         dc
.SetTextBackground( GetCellBackgroundColour(row
, col
) ); 
2951         dc
.SetTextForeground( GetCellTextColour(row
, col
) ); 
2953     dc
.SetFont( GetCellFont(row
, col
) ); 
2956     GetCellAlignment( row
, col
, &hAlign
, &vAlign 
); 
2957     DrawTextRectangle( dc
, GetCellValue( row
, col 
), rect2
, hAlign
, vAlign 
); 
2961 void wxGrid::DrawCellHighlight( wxDC
& dc
, int row
, int col 
) 
2963     // TODO: bounds checking on row, col ? 
2966     if ( row 
>= m_scrollPosY  
&&  col 
>= m_scrollPosX 
) 
2971         GetClientSize( &cw
, &ch 
); 
2973         x 
= m_colRights
[col
] - m_colWidths
[col
]; 
2974         if ( x 
>= cw 
) return; 
2976         y 
= m_rowBottoms
[row
] - m_rowHeights
[row
]; 
2977         if ( y 
>= ch 
) return; 
2979         dc
.SetLogicalFunction( wxXOR 
); 
2980         dc
.SetPen( wxPen(GetCellHighlightColour(), 2, wxSOLID
) ); 
2981         dc
.SetBrush( *wxTRANSPARENT_BRUSH 
); 
2983         dc
.DrawRectangle( x
, y
, 
2984                           m_colWidths
[col
] + 2, 
2985                           m_rowHeights
[row
] + 2 ); 
2987         dc
.SetLogicalFunction( wxCOPY 
); 
2992 // This function is handy when you just want to update one or a few 
2993 // cells.  For example, it is used by SetCellValue() 
2995 void wxGrid::DrawCell( int row
, int col 
) 
2997     if ( !GetBatchCount() ) 
2999         if ( !IsVisible( wxGridCellCoords(row
, col
) ) ) return; 
3002         GetClientSize( &cw
, &ch 
); 
3004         wxRect 
rect( CellToRect( row
, col 
) ); 
3008             wxClientDC 
dc( this ); 
3009             DrawCellBackground( dc
, rect
, row
, col 
); 
3010             DrawCellValue( dc
, rect
, row
, col 
); 
3016 // this is just to make other code more obvious 
3018 void wxGrid::HideCurrentCellHighlight( wxDC
& dc 
) 
3020     if ( m_currentCellHighlighted  
&& 
3021          m_currentCellCoords 
!= wxGridNoCellCoords 
) 
3023         DrawCellHighlight( dc
, m_currentCellCoords 
); 
3024         m_currentCellHighlighted 
= FALSE
; 
3029 // this is just to make other code more obvious 
3031 void wxGrid::ShowCurrentCellHighlight( wxDC
& dc 
) 
3033     if ( !m_currentCellHighlighted  
&& 
3034          m_currentCellCoords 
!= wxGridNoCellCoords 
) 
3036         DrawCellHighlight( dc
, m_currentCellCoords 
); 
3037         m_currentCellHighlighted 
= TRUE
; 
3042 void wxGrid::DrawTextRectangle( wxDC
& dc
, 
3043                                 const wxString
& value
, 
3049     long textWidth
, textHeight
; 
3050     long lineWidth
, lineHeight
; 
3051     wxArrayString lines
; 
3053     // see if we are already clipping 
3056     dc
.GetClippingBox( clipRect 
); 
3058     bool alreadyClipping 
= TRUE
; 
3059     wxRect intersectRect
; 
3061     if ( clipRect
.x 
== 0 && clipRect
.y 
== 0 && 
3062          clipRect
.width 
== 0 && clipRect
.height 
== 0) 
3064         alreadyClipping 
= FALSE
; 
3065         intersectRect 
= rect
; 
3069         // Find the intersection of the clipping rectangle and our 
3072         wxRegion 
region( rect 
); 
3073         region
.Intersect( clipRect 
); 
3074         if ( region
.IsEmpty() ) 
3080         intersectRect 
= region
.GetBox(); 
3083     if ( alreadyClipping 
) dc
.DestroyClippingRegion(); 
3085     dc
.SetClippingRegion( intersectRect 
); 
3087     StringToLines( value
, lines 
); 
3088     if ( lines
.GetCount() ) 
3090         GetTextBoxSize( dc
, lines
, &textWidth
, &textHeight 
); 
3091         dc
.GetTextExtent( lines
[0], &lineWidth
, &lineHeight 
); 
3094         switch ( horizAlign 
) 
3097                 x 
= rect
.x 
+ (rect
.width 
- textWidth 
- 1.0); 
3101                 x 
= rect
.x 
+ ((rect
.width 
- textWidth
)/2.0); 
3110         switch ( vertAlign 
) 
3113                 y 
= rect
.y 
+ (rect
.height 
- textHeight 
- 1); 
3117                 y 
= rect
.y 
+ ((rect
.height 
- textHeight
)/2.0); 
3126         for ( i 
= 0;  i 
< lines
.GetCount();  i
++ ) 
3128             dc
.DrawText( lines
[i
], (long)x
, (long)y 
); 
3133     dc
.DestroyClippingRegion(); 
3134     if (alreadyClipping
) dc
.SetClippingRegion( clipRect 
); 
3138 // Split multi line text up into an array of strings.  Any existing 
3139 // contents of the string array are preserved. 
3141 void wxGrid::StringToLines( const wxString
& value
, wxArrayString
& lines 
) 
3143     // TODO: this won't work for WXMAC ? (lines end with '\r') 
3147     while ( startPos 
< value
.Length() ) 
3149         pos 
= value
.Mid(startPos
).Find( '\n' ); 
3154         else if ( pos 
== 0 ) 
3156             lines
.Add( wxEmptyString 
); 
3160             if ( value
[startPos
+pos
-1] == '\r' ) 
3162                 lines
.Add( value
.Mid(startPos
, pos
-1) ); 
3166                 lines
.Add( value
.Mid(startPos
, pos
) ); 
3171     if ( startPos 
< value
.Length() ) 
3173         lines
.Add( value
.Mid( startPos 
) ); 
3178 void wxGrid::GetTextBoxSize( wxDC
& dc
, 
3179                              wxArrayString
& lines
, 
3180                              long *width
, long *height 
) 
3187     for ( i 
= 0;  i 
< lines
.GetCount();  i
++ ) 
3189         dc
.GetTextExtent( lines
[i
], &lineW
, &lineH 
); 
3190         w 
= wxMax( w
, lineW 
); 
3200 // ------ functions to get/send data (see also public functions) 
3203 bool wxGrid::GetModelValues() 
3207         // all we need to do is repaint the grid 
3217 bool wxGrid::SetModelValues() 
3223         for ( row 
= m_scrollPosY
;  row 
< m_numRows
;  row
++ ) 
3225             for ( col 
= m_scrollPosX
;  col 
< m_numCols
;  col
++ ) 
3227                 m_table
->SetValue( row
, col
, GetCellValue(row
, col
) ); 
3239 // ------ public functions 
3242 bool wxGrid::CreateGrid( int numRows
, int numCols 
) 
3246         wxLogError( "wxGrid::CreateGrid(numRows, numCols) called more than once" ); 
3251         m_numRows 
= numRows
; 
3252         m_numCols 
= numCols
; 
3254         m_table 
= new wxGridStringTable( m_numRows
, m_numCols 
); 
3255         m_table
->SetView( this ); 
3264 // The behaviour of this function depends on the grid table class 
3265 // Clear() function.  For the default wxGridStringTable class the 
3266 // behavious is to replace all cell contents with wxEmptyString but 
3267 // not to change the number of rows or cols. 
3269 void wxGrid::ClearGrid() 
3274         SetEditControlValue(); 
3275         if ( !GetBatchCount() ) Refresh(); 
3280 bool wxGrid::InsertRows( int pos
, int numRows
, bool WXUNUSED(updateLabels
) ) 
3282     // TODO: something with updateLabels flag 
3286         wxLogError( "Called wxGrid::InsertRows() before calling CreateGrid()" ); 
3292         bool ok 
= m_table
->InsertRows( pos
, numRows 
); 
3294         // the table will have sent the results of the insert row 
3295         // operation to this view object as a grid table message 
3299             if ( !GetBatchCount() ) Refresh(); 
3301         SetEditControlValue(); 
3310 bool wxGrid::AppendRows( int numRows
, bool WXUNUSED(updateLabels
) ) 
3312     // TODO: something with updateLabels flag 
3316         wxLogError( "Called wxGrid::AppendRows() before calling CreateGrid()" ); 
3320     if ( m_table 
&& m_table
->AppendRows( numRows 
) ) 
3322         // the table will have sent the results of the append row 
3323         // operation to this view object as a grid table message 
3325         if ( !GetBatchCount() ) Refresh(); 
3334 bool wxGrid::DeleteRows( int pos
, int numRows
, bool WXUNUSED(updateLabels
) ) 
3336     // TODO: something with updateLabels flag 
3340         wxLogError( "Called wxGrid::DeleteRows() before calling CreateGrid()" ); 
3344     if ( m_table 
&& m_table
->DeleteRows( pos
, numRows 
) ) 
3346         // the table will have sent the results of the delete row 
3347         // operation to this view object as a grid table message 
3349         if ( m_numRows 
> 0 ) 
3350             SetEditControlValue(); 
3352             HideCellEditControl(); 
3354         if ( !GetBatchCount() ) Refresh(); 
3363 bool wxGrid::InsertCols( int pos
, int numCols
, bool WXUNUSED(updateLabels
) ) 
3365     // TODO: something with updateLabels flag 
3369         wxLogError( "Called wxGrid::InsertCols() before calling CreateGrid()" ); 
3375         HideCellEditControl(); 
3376         bool ok 
= m_table
->InsertCols( pos
, numCols 
); 
3379             // the table will have sent the results of the insert col 
3380             // operation to this view object as a grid table message 
3382             if ( !GetBatchCount() ) Refresh(); 
3384         SetEditControlValue(); 
3393 bool wxGrid::AppendCols( int numCols
, bool WXUNUSED(updateLabels
) ) 
3395     // TODO: something with updateLabels flag 
3399         wxLogError( "Called wxGrid::AppendCols() before calling CreateGrid()" ); 
3403     if ( m_table 
&& m_table
->AppendCols( numCols 
) ) 
3405         // the table will have sent the results of the append col 
3406         // operation to this view object as a grid table message 
3408         if ( !GetBatchCount() ) Refresh(); 
3417 bool wxGrid::DeleteCols( int pos
, int numCols
, bool WXUNUSED(updateLabels
) ) 
3419     // TODO: something with updateLabels flag 
3423         wxLogError( "Called wxGrid::DeleteCols() before calling CreateGrid()" ); 
3427     if ( m_table 
&& m_table
->DeleteCols( pos
, numCols 
) ) 
3429         // the table will have sent the results of the delete col 
3430         // operation to this view object as a grid table message 
3432         if ( m_numCols 
> 0 ) 
3433             SetEditControlValue(); 
3435             HideCellEditControl(); 
3437         if ( !GetBatchCount() ) Refresh(); 
3449 // ------ control panel and cell edit control 
3452 void wxGrid::EnableEditing( bool edit 
) 
3454     // TODO: improve this ? 
3456     if ( edit 
!= m_editable 
) 
3459         if ( !m_editable 
) HideCellEditControl(); 
3460         m_topEditCtrlEnabled 
= m_editable
; 
3461         m_cellEditCtrlEnabled 
= m_editable
; 
3462         if ( !m_editable 
) ShowCellEditControl();             
3467 void wxGrid::EnableTopEditControl( bool enable 
) 
3469     if ( enable 
!= m_topEditCtrlEnabled 
) 
3471         HideCellEditControl(); 
3472         m_topEditCtrlEnabled 
= enable
; 
3474         m_topEditCtrl
->Show( enable 
); 
3476         if ( m_currentCellCoords 
!= wxGridNoCellCoords 
) 
3477           SetEditControlValue(); 
3479         ShowCellEditControl(); 
3480         if ( !GetBatchCount() ) Refresh(); 
3484 void wxGrid::EnableCellEditControl( bool enable 
) 
3486     if ( m_cellEditCtrl 
&& 
3487          enable 
!= m_cellEditCtrlEnabled 
) 
3489         HideCellEditControl(); 
3490         SaveEditControlValue(); 
3492         m_cellEditCtrlEnabled 
= enable
; 
3494         SetEditControlValue(); 
3495         ShowCellEditControl(); 
3501 // ------ grid formatting functions 
3504 void wxGrid::GetRowLabelAlignment( int *horiz
, int *vert 
) 
3506     *horiz 
= m_rowLabelHorizAlign
; 
3507     *vert  
= m_rowLabelVertAlign
; 
3510 void wxGrid::GetColLabelAlignment( int *horiz
, int *vert 
) 
3512     *horiz 
= m_colLabelHorizAlign
; 
3513     *vert  
= m_colLabelVertAlign
; 
3516 wxString 
wxGrid::GetRowLabelValue( int row 
) 
3520         return m_table
->GetRowLabelValue( row 
); 
3530 wxString 
wxGrid::GetColLabelValue( int col 
) 
3534         return m_table
->GetColLabelValue( col 
); 
3544 void wxGrid::SetRowLabelSize( int width 
) 
3546     m_rowLabelWidth 
= wxMax( 0, width 
); 
3548     ShowCellEditControl(); 
3549     if ( !GetBatchCount() ) Refresh(); 
3552 void wxGrid::SetColLabelSize( int height 
) 
3554     m_colLabelHeight 
= wxMax( 0, height 
); 
3556     ShowCellEditControl(); 
3557     if ( !GetBatchCount() ) Refresh(); 
3560 void wxGrid::SetLabelBackgroundColour( const wxColour
& colour 
) 
3562     m_labelBackgroundColour 
= colour
; 
3563     if ( !GetBatchCount() ) Refresh(); 
3566 void wxGrid::SetLabelTextColour( const wxColour
& colour 
) 
3568     m_labelTextColour 
= colour
; 
3569     if ( !GetBatchCount() ) Refresh(); 
3572 void wxGrid::SetLabelFont( const wxFont
& font 
) 
3575     if ( !GetBatchCount() ) Refresh(); 
3578 void wxGrid::SetRowLabelAlignment( int horiz
, int vert 
) 
3580     if ( horiz 
== wxLEFT 
|| horiz 
== wxCENTRE 
|| horiz 
== wxRIGHT 
) 
3582         m_rowLabelHorizAlign 
= horiz
; 
3585     if ( vert 
== wxTOP 
|| vert 
== wxCENTRE 
|| vert 
== wxBOTTOM 
) 
3587         m_rowLabelVertAlign 
= vert
; 
3590     if ( !GetBatchCount() ) Refresh(); 
3593 void wxGrid::SetColLabelAlignment( int horiz
, int vert 
) 
3595     if ( horiz 
== wxLEFT 
|| horiz 
== wxCENTRE 
|| horiz 
== wxRIGHT 
) 
3597         m_colLabelHorizAlign 
= horiz
; 
3600     if ( vert 
== wxTOP 
|| vert 
== wxCENTRE 
|| vert 
== wxBOTTOM 
) 
3602         m_colLabelVertAlign 
= vert
; 
3605     if ( !GetBatchCount() ) Refresh(); 
3608 void wxGrid::SetRowLabelValue( int row
, const wxString
& s 
) 
3612         m_table
->SetRowLabelValue( row
, s 
); 
3613         if ( !GetBatchCount() ) Refresh(); 
3617 void wxGrid::SetColLabelValue( int col
, const wxString
& s 
) 
3621         m_table
->SetColLabelValue( col
, s 
); 
3622         if ( !GetBatchCount() ) Refresh(); 
3626 void wxGrid::SetGridLineColour( const wxColour
& colour 
) 
3628     m_gridLineColour 
= colour
; 
3630     wxClientDC 
dc( this ); 
3631     DrawGridLines( dc 
); 
3634 void wxGrid::EnableGridLines( bool enable 
) 
3636     if ( enable 
!= m_gridLinesEnabled 
) 
3638         m_gridLinesEnabled 
= enable
; 
3639         if ( !GetBatchCount() ) Refresh(); 
3644 int wxGrid::GetDefaultRowSize() 
3646     return m_defaultRowHeight
; 
3649 int wxGrid::GetRowSize( int row 
) 
3651     if ( row 
>= 0  &&  row 
< m_numRows 
) 
3652         return m_rowHeights
[row
]; 
3654         return 0;  // TODO: log an error here 
3657 int wxGrid::GetDefaultColSize() 
3659     return m_defaultColWidth
; 
3662 int wxGrid::GetColSize( int col 
) 
3664     if ( col 
>= 0  &&  col 
< m_numCols 
) 
3665         return m_colWidths
[col
]; 
3667         return 0;  // TODO: log an error here 
3670 wxColour 
wxGrid::GetDefaultCellBackgroundColour() 
3672     // TODO: replace this temp test code 
3674     return wxColour( 255, 255, 255 ); 
3677 wxColour 
wxGrid::GetCellBackgroundColour( int row
, int col 
) 
3679     // TODO: replace this temp test code 
3681     return wxColour( 255, 255, 255 );     
3684 wxColour 
wxGrid::GetDefaultCellTextColour() 
3686     // TODO: replace this temp test code 
3688     return wxColour( 0, 0, 0 );     
3691 wxColour 
wxGrid::GetCellTextColour( int row
, int col 
) 
3693     // TODO: replace this temp test code 
3695     return wxColour( 0, 0, 0 );     
3699 wxColour 
wxGrid::GetCellHighlightColour() 
3701     // TODO: replace this temp test code 
3703     return wxColour( 0, 0, 0 );     
3707 wxFont 
wxGrid::GetDefaultCellFont() 
3709     return m_defaultCellFont
; 
3712 wxFont 
wxGrid::GetCellFont( int row
, int col 
) 
3714     // TODO: replace this temp test code 
3716     return m_defaultCellFont
; 
3719 void wxGrid::GetDefaultCellAlignment( int *horiz
, int *vert 
) 
3721     // TODO: replace this temp test code 
3727 void wxGrid::GetCellAlignment( int row
, int col
, int *horiz
, int *vert 
) 
3729     // TODO: replace this temp test code 
3735 void wxGrid::SetDefaultRowSize( int height
, bool resizeExistingRows 
) 
3737     m_defaultRowHeight 
= wxMax( height
, WXGRID_MIN_ROW_HEIGHT 
); 
3739     if ( resizeExistingRows 
) 
3741         // TODO: what do we do about events here ? 
3742         // Generate an event for each resize ? 
3745         for ( row 
= 0;  row 
< m_numRows
;  row
++ ) 
3747             m_rowHeights
[row
] = m_defaultRowHeight
; 
3750         if ( !GetBatchCount() ) Refresh(); 
3754 void wxGrid::SetRowSize( int row
, int height 
) 
3756     if ( row 
>= 0  &&  row 
< m_numRows 
) 
3758         m_rowHeights
[row
] = wxMax( 0, height 
); 
3760         if ( !GetBatchCount() ) Refresh(); 
3762         // Note: we are ending the event *after* doing 
3763         // default processing in this case 
3765         SendEvent( EVT_WXGRID_ROW_SIZE
, 
3770         // TODO: log an error here 
3774 void wxGrid::SetDefaultColSize( int width
, bool resizeExistingCols 
) 
3776     m_defaultColWidth 
= wxMax( width
, WXGRID_MIN_COL_WIDTH 
); 
3778     if ( resizeExistingCols 
) 
3780         // TODO: what do we do about events here ? 
3781         // Generate an event for each resize ? 
3784         for ( col 
= 0;  col 
< m_numCols
;  col
++ ) 
3786             m_colWidths
[col
] = m_defaultColWidth
; 
3789         if ( !GetBatchCount() ) Refresh(); 
3793 void wxGrid::SetColSize( int col
, int width 
) 
3795     if ( col 
>= 0  &&  col 
< m_numCols 
) 
3797         m_colWidths
[col
] = wxMax( 0, width 
); 
3799         if ( !GetBatchCount() ) Refresh(); 
3801         // Note: we are ending the event *after* doing 
3802         // default processing in this case 
3804         SendEvent( EVT_WXGRID_COL_SIZE
, 
3809         // TODO: log an error here 
3813 void wxGrid::SetDefaultCellBackgroundColour( const wxColour
& ) 
3815     // TODO: everything !!! 
3819 void wxGrid::SetCellBackgroundColour( int row
, int col
, const wxColour
& ) 
3821     // TODO: everything !!! 
3825 void wxGrid::SetDefaultCellTextColour( const wxColour
& ) 
3827     // TODO: everything !!! 
3831 void wxGrid::SetCellTextColour( int row
, int col
, const wxColour
& ) 
3833     // TODO: everything !!! 
3837 void wxGrid::SetCellHighlightColour( const wxColour
& ) 
3839     // TODO: everything !!! 
3843 void wxGrid::SetDefaultCellFont( const wxFont
& ) 
3845     // TODO: everything !!! 
3849 void wxGrid::SetCellFont( int row
, int col
, const wxFont
& ) 
3851     // TODO: everything !!! 
3855 void wxGrid::SetDefaultCellAlignment( int horiz
, int vert 
) 
3857     // TODO: everything !!! 
3861 void wxGrid::SetCellAlignment( int row
, int col
, int horiz
, int vert 
) 
3863     // TODO: everything !!! 
3869 // ------ cell value accessor functions 
3872 void wxGrid::SetCellValue( int row
, int col
, const wxString
& s 
) 
3876         m_table
->SetValue( row
, col
, s
.c_str() ); 
3877         DrawCell( row
, col 
); 
3878         if ( m_currentCellCoords
.GetRow() == row 
&& 
3879              m_currentCellCoords
.GetCol() == col 
) 
3881             SetEditControlValue( s 
); 
3889 // ------ interaction with data model 
3891 bool wxGrid::ProcessTableMessage( wxGridTableMessage
& msg 
) 
3893     switch ( msg
.GetId() ) 
3895         case wxGRIDTABLE_REQUEST_VIEW_GET_VALUES
: 
3896             return GetModelValues(); 
3898         case wxGRIDTABLE_REQUEST_VIEW_SEND_VALUES
: 
3899             return SetModelValues(); 
3901         case wxGRIDTABLE_NOTIFY_ROWS_INSERTED
: 
3902         case wxGRIDTABLE_NOTIFY_ROWS_APPENDED
: 
3903         case wxGRIDTABLE_NOTIFY_ROWS_DELETED
: 
3904         case wxGRIDTABLE_NOTIFY_COLS_INSERTED
: 
3905         case wxGRIDTABLE_NOTIFY_COLS_APPENDED
: 
3906         case wxGRIDTABLE_NOTIFY_COLS_DELETED
: 
3907             return Redimension( msg 
); 
3916 // ------ Grid location functions 
3918 //  (see also inline functions in grid.h) 
3921 // check to see if a cell location is wholly visible 
3923 bool wxGrid::IsVisible( const wxGridCellCoords
& coords 
) 
3925     return ( coords
.GetRow() >= m_scrollPosY  
&& 
3926              coords
.GetRow() < m_scrollPosY 
+ m_wholeRowsVisible  
&& 
3927              coords
.GetCol() >= m_scrollPosX  
&& 
3928              coords
.GetCol() < m_scrollPosX 
+ m_wholeColsVisible 
); 
3932 // make the specified cell location visible by doing a minimal amount 
3935 void wxGrid::MakeCellVisible( int row
, int col 
) 
3937     int lastX 
= m_scrollPosX
; 
3938     int lastY 
= m_scrollPosY
; 
3940     if ( row 
>= 0  &&  row 
< m_numRows  
&& 
3941          col 
>= 0  &&  col 
< m_numCols 
) 
3943         if ( row 
< m_scrollPosY 
) 
3945             SetVerticalScrollPos( row 
); 
3947         else if ( row 
>= m_scrollPosY 
+ m_wholeRowsVisible 
) 
3950             int h 
= m_rowBottoms
[row
]; 
3951             for ( i 
= m_scrollPosY
; i 
< m_numRows 
&& h 
> m_bottom
; i
++ ) 
3953                 h 
-= m_rowHeights
[i
]; 
3955             SetVerticalScrollPos( i 
); 
3958         if ( col 
< m_scrollPosX 
) 
3960             SetHorizontalScrollPos( col 
); 
3962         else if ( col 
>= m_scrollPosX 
+ m_wholeColsVisible 
) 
3965             int w 
= m_colRights
[col
]; 
3966             for ( i 
= m_scrollPosX
; i 
< m_numCols 
&& w 
> m_right
; i
++ ) 
3968                 w 
-= m_colWidths
[i
]; 
3970             SetHorizontalScrollPos( i 
); 
3973         if ( m_scrollPosX 
!= lastX  
||  m_scrollPosY 
!= lastY 
) 
3975             // The cell was not visible before but not it is 
3977             ShowCellEditControl(); 
3982         // TODO: log an error 
3987 void wxGrid::SetVerticalScrollPos( int topMostRow 
) 
3989     if ( m_vertScrollBar 
&& topMostRow 
!= m_scrollPosY 
) 
3991         m_scrollPosY 
= topMostRow
; 
3999 void wxGrid::SetHorizontalScrollPos( int leftMostCol 
) 
4001     if ( m_horizScrollBar 
&& leftMostCol 
!= m_scrollPosX 
) 
4003         m_scrollPosX 
= leftMostCol
; 
4012 // ------ block, row and col selection 
4015 void wxGrid::SelectRow( int row
, bool addToSelected 
) 
4017     if ( IsSelection() && addToSelected 
) 
4019         if ( m_selectedTopLeft
.GetRow() > row 
) 
4020             m_selectedTopLeft
.SetRow( row 
); 
4022         m_selectedTopLeft
.SetCol( 0 ); 
4024         if ( m_selectedBottomRight
.GetRow() < row 
) 
4025             m_selectedBottomRight
.SetRow( row 
); 
4027         m_selectedBottomRight
.SetCol( m_numCols 
- 1 ); 
4032         m_selectedTopLeft
.Set( row
, 0 ); 
4033         m_selectedBottomRight
.Set( row
, m_numCols
-1 ); 
4036     if ( !GetBatchCount() ) 
4038         wxRect 
rect( SelectionToRect() ); 
4039         if ( rect 
!= wxGridNoCellRect 
) Refresh( TRUE
, &rect 
); 
4042     wxGridRangeSelectEvent 
gridEvt( GetId(), 
4043                                     EVT_WXGRID_RANGE_SELECT
, 
4046                                     m_selectedBottomRight 
); 
4048     GetEventHandler()->ProcessEvent(gridEvt
); 
4052 void wxGrid::SelectCol( int col
, bool addToSelected 
) 
4054     if ( addToSelected 
&& m_selectedTopLeft 
!= wxGridNoCellCoords 
) 
4056         if ( m_selectedTopLeft
.GetCol() > col 
) 
4057             m_selectedTopLeft
.SetCol( col 
); 
4059         m_selectedTopLeft
.SetRow( 0 ); 
4061         if ( m_selectedBottomRight
.GetCol() < col 
) 
4062             m_selectedBottomRight
.SetCol( col 
); 
4064         m_selectedBottomRight
.SetRow( m_numRows 
- 1 ); 
4069         m_selectedTopLeft
.Set( 0, col 
); 
4070         m_selectedBottomRight
.Set( m_numRows
-1, col 
); 
4073     if ( !GetBatchCount() ) 
4075         wxRect 
rect( SelectionToRect() ); 
4076         if ( rect 
!= wxGridNoCellRect 
) Refresh( TRUE
, &rect 
); 
4079     wxGridRangeSelectEvent 
gridEvt( GetId(), 
4080                                     EVT_WXGRID_RANGE_SELECT
, 
4083                                     m_selectedBottomRight 
); 
4085     GetEventHandler()->ProcessEvent(gridEvt
); 
4089 void wxGrid::SelectBlock( int topRow
, int leftCol
, int bottomRow
, int rightCol 
) 
4093     if ( topRow 
> bottomRow 
) 
4100     if ( leftCol 
> rightCol 
) 
4107     m_selectedTopLeft
.Set( topRow
, leftCol 
); 
4108     m_selectedBottomRight
.Set( bottomRow
, rightCol 
); 
4110     if ( !GetBatchCount() ) 
4112         wxRect 
rect( SelectionToRect() ); 
4113         if ( rect 
!= wxGridNoCellRect 
) Refresh( TRUE
, &rect 
); 
4116     // only generate an event if the block is not being selected by 
4117     // dragging the mouse (in which case the event will be generated in 
4119     if ( !m_isDragging 
) 
4121         wxGridRangeSelectEvent 
gridEvt( GetId(), 
4122                                         EVT_WXGRID_RANGE_SELECT
, 
4125                                         m_selectedBottomRight 
); 
4127         GetEventHandler()->ProcessEvent(gridEvt
); 
4131 void wxGrid::SelectAll() 
4133     m_selectedTopLeft
.Set( 0, 0 ); 
4134     m_selectedBottomRight
.Set( m_numRows
-1, m_numCols
-1 ); 
4136     if ( !GetBatchCount() ) Refresh(); 
4140 void wxGrid::ClearSelection() 
4142     if ( IsSelection() ) 
4144         wxRect 
rect( SelectionToRect() ); 
4145         if ( rect 
!= wxGridNoCellRect 
) 
4147             Refresh( TRUE
, &rect 
); 
4150         m_selectedTopLeft 
= wxGridNoCellCoords
; 
4151         m_selectedBottomRight 
= wxGridNoCellCoords
; 
4156 wxRect 
wxGrid::SelectionToRect() 
4161     if ( IsSelection() ) 
4163         cellRect 
= CellToRect( m_selectedTopLeft 
); 
4164         if ( cellRect 
!= wxGridNoCellRect 
) 
4170             rect 
= wxRect( m_left
, m_top
, 0, 0 ); 
4173         cellRect 
= CellToRect( m_selectedBottomRight 
); 
4174         if ( cellRect 
!= wxGridNoCellRect 
) 
4180             return wxGridNoCellRect
; 
4191 // ------ Grid event classes 
4194 IMPLEMENT_DYNAMIC_CLASS( wxGridEvent
, wxEvent 
) 
4196 wxGridEvent::wxGridEvent( int id
, wxEventType type
, wxObject
* obj
, 
4197                           int row
, int col
, int x
, int y
, 
4198                           bool control
, bool shift
, bool alt
, bool meta 
) 
4199         : wxNotifyEvent( type
, id 
) 
4205     m_control 
= control
; 
4210     SetEventObject(obj
); 
4214 IMPLEMENT_DYNAMIC_CLASS( wxGridSizeEvent
, wxEvent 
) 
4216 wxGridSizeEvent::wxGridSizeEvent( int id
, wxEventType type
, wxObject
* obj
, 
4217                                   int rowOrCol
, int x
, int y
, 
4218                                   bool control
, bool shift
, bool alt
, bool meta 
) 
4219         : wxNotifyEvent( type
, id 
) 
4221     m_rowOrCol 
= rowOrCol
; 
4224     m_control 
= control
; 
4229     SetEventObject(obj
); 
4233 IMPLEMENT_DYNAMIC_CLASS( wxGridRangeSelectEvent
, wxEvent 
) 
4235 wxGridRangeSelectEvent::wxGridRangeSelectEvent(int id
, wxEventType type
, wxObject
* obj
, 
4236                                                const wxGridCellCoords
& topLeft
, 
4237                                                const wxGridCellCoords
& bottomRight
, 
4238                                                bool control
, bool shift
, bool alt
, bool meta 
) 
4239         : wxNotifyEvent( type
, id 
) 
4241     m_topLeft     
= topLeft
; 
4242     m_bottomRight 
= bottomRight
; 
4243     m_control     
= control
; 
4248     SetEventObject(obj
); 
4252 #endif // ifndef wxUSE_NEW_GRID