1 /////////////////////////////////////////////////////////////////////////// 
   2 // Name:        generic/gridsel.cpp 
   3 // Purpose:     wxGridSelection 
   8 // Copyright:   (c) Stefan Neis (Stefan.Neis@t-online.de) 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "gridsel.h" 
  24 // For compilers that support precompilation, includes "wx/wx.h". 
  25 #include "wx/wxprec.h" 
  33 #if defined(wxUSE_NEW_GRID) && (wxUSE_NEW_GRID) 
  35 #include "wx/generic/gridsel.h" 
  37 // Some explanation for the members of the class: 
  38 // m_cellSelection stores individual selected cells 
  39 //   -- this is only used if m_selectionMode == wxGridSelectCells 
  40 // m_blockSelectionTopLeft and m_blockSelectionBottomRight 
  41 //   store the upper left and lower right corner of selected Blocks 
  42 // m_rowSelection and m_colSelection store individual selected 
  43 //   rows and columns; maybe those are superfluous and should be 
  46 wxGridSelection::wxGridSelection( wxGrid 
* grid
, 
  47                                   wxGrid::wxGridSelectionModes sel 
) 
  50     m_selectionMode 
= sel
; 
  53 bool wxGridSelection::IsSelection() 
  55   return ( m_cellSelection
.GetCount() || m_blockSelectionTopLeft
.GetCount() || 
  56            m_rowSelection
.GetCount() || m_colSelection
.GetCount() ); 
  59 bool wxGridSelection::IsInSelection ( int row
, int col 
) 
  63     // First check whether the given cell is individually selected 
  64     // (if m_selectionMode is wxGridSelectCells). 
  65     if ( m_selectionMode 
== wxGrid::wxGridSelectCells 
) 
  67         count 
= m_cellSelection
.GetCount(); 
  68         for ( size_t n 
= 0; n 
< count
; n
++ ) 
  70             wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
  71             if ( row 
== coords
.GetRow() && col 
== coords
.GetCol() ) 
  76     // Now check whether the given cell is 
  77     // contained in one of the selected blocks. 
  78     count 
= m_blockSelectionTopLeft
.GetCount(); 
  79     for ( size_t n 
= 0; n 
< count
; n
++ ) 
  81         wxGridCellCoords
& coords1 
= m_blockSelectionTopLeft
[n
]; 
  82         wxGridCellCoords
& coords2 
= m_blockSelectionBottomRight
[n
]; 
  83         if ( BlockContainsCell(coords1
.GetRow(), coords1
.GetCol(), 
  84                                coords2
.GetRow(), coords2
.GetCol(), 
  89     // Now check whether the given cell is 
  90     // contained in one of the selected rows 
  91     // (unless we are in column selection mode). 
  92     if ( m_selectionMode 
!= wxGrid::wxGridSelectColumns 
) 
  94         size_t count 
= m_rowSelection
.GetCount(); 
  95         for ( size_t n 
= 0; n 
< count
; n
++ ) 
  97             if ( row 
== m_rowSelection
[n
] ) 
 102     // Now check whether the given cell is 
 103     // contained in one of the selected columns 
 104     // (unless we are in row selection mode). 
 105     if ( m_selectionMode 
!= wxGrid::wxGridSelectRows 
) 
 107         size_t count 
= m_colSelection
.GetCount(); 
 108         for ( size_t n 
= 0; n 
< count
; n
++ ) 
 110             if ( col 
== m_colSelection
[n
] ) 
 117 // Change the selection mode 
 118 void wxGridSelection::SetSelectionMode(wxGrid::wxGridSelectionModes selmode
) 
 120     // if selection mode is unchanged return immediately 
 121     if (selmode 
== m_selectionMode
) 
 124     if ( m_selectionMode 
!= wxGrid::wxGridSelectCells 
) 
 126         // if changing form row to column selection 
 127         // or vice versa, clear the selection. 
 128         if ( selmode 
!= wxGrid::wxGridSelectCells 
) 
 131         m_selectionMode 
= selmode
; 
 135         // if changing from cell selection to something else, 
 136         // promote selected cells/blocks to whole rows/columns. 
 138         while ( ( n 
= m_cellSelection
.GetCount() ) > 0 ) 
 141             wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
 142             int row 
= coords
.GetRow(); 
 143             int col 
= coords
.GetCol(); 
 144             m_cellSelection
.RemoveAt(n
); 
 145             if (selmode 
== wxGrid::wxGridSelectRows
) 
 147             else // selmode == wxGridSelectColumns) 
 151         for (n 
= 0; n 
< m_blockSelectionTopLeft
.GetCount(); n
++) 
 152         // Note that m_blockSelectionTopLeft's size may be changing! 
 154             wxGridCellCoords
& coords 
= m_blockSelectionTopLeft
[n
]; 
 155             int topRow 
= coords
.GetRow(); 
 156             int leftCol 
= coords
.GetCol(); 
 157             coords 
= m_blockSelectionBottomRight
[n
]; 
 158             int bottomRow 
= coords
.GetRow(); 
 159             int rightCol 
= coords
.GetCol(); 
 160             if (selmode 
== wxGrid::wxGridSelectRows
) 
 162                 if (leftCol 
!= 0 || rightCol 
!= m_grid
->GetNumberCols() - 1 ) 
 164                     m_blockSelectionTopLeft
.RemoveAt(n
); 
 165                     m_blockSelectionBottomRight
.RemoveAt(n
); 
 166                     SelectBlock( topRow
, 0, 
 167                                  bottomRow
, m_grid
->GetNumberCols() - 1, 
 171             else // selmode == wxGridSelectColumns) 
 173                 if (topRow 
!= 0 || bottomRow 
!= m_grid
->GetNumberRows() - 1 ) 
 175                     m_blockSelectionTopLeft
.RemoveAt(n
); 
 176                     m_blockSelectionBottomRight
.RemoveAt(n
); 
 177                     SelectBlock( 0, leftCol
, 
 178                                  m_grid
->GetNumberRows() - 1, rightCol
, 
 183         m_selectionMode 
= selmode
; 
 187 void wxGridSelection::SelectRow( int row
, 
 188                                  bool ControlDown
,  bool ShiftDown
, 
 189                                  bool AltDown
, bool MetaDown 
) 
 191     if ( m_selectionMode 
== wxGrid::wxGridSelectColumns 
) 
 195     // Remove single cells contained in newly selected block. 
 196     if ( m_selectionMode 
== wxGrid::wxGridSelectCells 
) 
 198         count 
= m_cellSelection
.GetCount(); 
 199         for ( n 
= 0; n 
< count
; n
++ ) 
 201             wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
 202             if ( BlockContainsCell( row
, 0, row
, m_grid
->GetNumberCols() - 1, 
 203                                     coords
.GetRow(), coords
.GetCol() ) ) 
 205                 m_cellSelection
.RemoveAt(n
); 
 211     // Simplify list of selected blocks (if possible) 
 212     count 
= m_blockSelectionTopLeft
.GetCount(); 
 214     for ( n 
= 0; n 
< count
; n
++ ) 
 216         wxGridCellCoords
& coords1 
= m_blockSelectionTopLeft
[n
]; 
 217         wxGridCellCoords
& coords2 
= m_blockSelectionBottomRight
[n
]; 
 219         // Remove block if it is a subset of the row 
 220         if ( coords1
.GetRow() == row 
&& row 
== coords2
.GetRow() ) 
 222             m_blockSelectionTopLeft
.RemoveAt(n
); 
 223             m_blockSelectionBottomRight
.RemoveAt(n
); 
 226         else if ( coords1
.GetCol() == 0  && 
 227                   coords2
.GetCol() == m_grid
->GetNumberCols() - 1 ) 
 229             // silently return, if row is contained in block 
 230             if ( coords1
.GetRow() <= row 
&& row 
<= coords2
.GetRow() ) 
 232             // expand block, if it touched row 
 233             else if ( coords1
.GetRow() == row 
+ 1) 
 238             else if ( coords2
.GetRow() == row 
- 1) 
 246     // Unless we successfully handled the row, 
 247     // check whether row is already selected. 
 250         count 
= m_rowSelection
.GetCount(); 
 251         for ( n 
= 0; n 
< count
; n
++ ) 
 253             if ( row 
== m_rowSelection
[n
] ) 
 257         // Add row to selection 
 258         m_rowSelection
.Add(row
); 
 262     wxRect r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ), 
 263                                           wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) ); 
 264     if ( !m_grid
->GetBatchCount() ) 
 265         ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 268     wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 269                                     wxEVT_GRID_RANGE_SELECT
, 
 271                                     wxGridCellCoords( row
, 0 ), 
 272                                     wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ), 
 274                                     ControlDown
,  ShiftDown
, 
 277     m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 280 void wxGridSelection::SelectCol( int col
, 
 281                                  bool ControlDown
,  bool ShiftDown
, 
 282                                  bool AltDown
, bool MetaDown 
) 
 284     if ( m_selectionMode 
== wxGrid::wxGridSelectRows 
) 
 288     // Remove single cells contained in newly selected block. 
 289     if ( m_selectionMode 
== wxGrid::wxGridSelectCells 
) 
 291         count 
= m_cellSelection
.GetCount(); 
 292         for ( n 
= 0; n 
< count
; n
++ ) 
 294             wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
 295             if ( BlockContainsCell( 0, col
, m_grid
->GetNumberRows() - 1, col
, 
 296                                     coords
.GetRow(), coords
.GetCol() ) ) 
 298                 m_cellSelection
.RemoveAt(n
); 
 304     // Simplify list of selected blocks (if possible) 
 305     count 
= m_blockSelectionTopLeft
.GetCount(); 
 307     for ( n 
= 0; n 
< count
; n
++ ) 
 309         wxGridCellCoords
& coords1 
= m_blockSelectionTopLeft
[n
]; 
 310         wxGridCellCoords
& coords2 
= m_blockSelectionBottomRight
[n
]; 
 312         // Remove block if it is a subset of the column 
 313         if ( coords1
.GetCol() == col 
&& col 
== coords2
.GetCol() ) 
 315             m_blockSelectionTopLeft
.RemoveAt(n
); 
 316             m_blockSelectionBottomRight
.RemoveAt(n
); 
 319         else if ( coords1
.GetRow() == 0  && 
 320                   coords2
.GetRow() == m_grid
->GetNumberRows() - 1 ) 
 322             // silently return, if row is contained in block 
 323             if ( coords1
.GetCol() <= col 
&& col 
<= coords2
.GetCol() ) 
 325             // expand block, if it touched col 
 326             else if ( coords1
.GetCol() == col 
+ 1) 
 331             else if ( coords2
.GetCol() == col 
- 1) 
 339     // Unless we successfully handled the column, 
 340     // Check whether col is already selected. 
 343         count 
= m_colSelection
.GetCount(); 
 344         for ( n 
= 0; n 
< count
; n
++ ) 
 346             if ( col 
== m_colSelection
[n
] ) 
 350         // Add col to selection 
 351         m_colSelection
.Add(col
); 
 355     wxRect r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col 
), 
 356                                           wxGridCellCoords( m_grid
->GetNumberRows() - 1, col 
) ); 
 357     if ( !m_grid
->GetBatchCount() ) 
 358         ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 361     wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 362                                     wxEVT_GRID_RANGE_SELECT
, 
 364                                     wxGridCellCoords( 0, col 
), 
 365                                     wxGridCellCoords( m_grid
->GetNumberRows() - 1, col 
), 
 367                                     ControlDown
,  ShiftDown
, 
 370     m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 373 void wxGridSelection::SelectBlock( int topRow
, int leftCol
, 
 374                                    int bottomRow
, int rightCol
, 
 375                                    bool ControlDown
, bool ShiftDown
, 
 376                                    bool AltDown
, bool MetaDown
,  
 379     // Fix the coordinates of the block if needed. 
 380     if ( m_selectionMode 
== wxGrid::wxGridSelectRows 
) 
 383         rightCol 
= m_grid
->GetNumberCols() - 1; 
 385     else if ( m_selectionMode 
== wxGrid::wxGridSelectColumns 
) 
 388         bottomRow 
= m_grid
->GetNumberRows() - 1; 
 390     if ( topRow 
> bottomRow 
) 
 397     if ( leftCol 
> rightCol 
) 
 404     // Handle single cell selection in SelectCell. 
 405     // (MB: added check for selection mode here to prevent 
 406     //  crashes if, for example, we are select rows and the 
 407     //  grid only has 1 col) 
 408     if ( m_selectionMode 
== wxGrid::wxGridSelectCells 
&& 
 409          topRow 
== bottomRow 
&& leftCol 
== rightCol 
) 
 410         SelectCell( topRow
, leftCol
, ControlDown
,  ShiftDown
, 
 411                     AltDown
, MetaDown
, sendEvent 
); 
 414     // Remove single cells contained in newly selected block. 
 415     if ( m_selectionMode 
== wxGrid::wxGridSelectCells 
) 
 417         count 
= m_cellSelection
.GetCount(); 
 418         for ( n 
= 0; n 
< count
; n
++ ) 
 420             wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
 421             if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
, 
 422                                     coords
.GetRow(), coords
.GetCol() ) ) 
 424                 m_cellSelection
.RemoveAt(n
); 
 430     // If a block containing the selection is already selected, return, 
 431     // if a block contained in the selection is found, remove it. 
 433     count 
= m_blockSelectionTopLeft
.GetCount(); 
 434     for ( n 
= 0; n 
< count
; n
++ ) 
 436         wxGridCellCoords
& coords1 
= m_blockSelectionTopLeft
[n
]; 
 437         wxGridCellCoords
& coords2 
= m_blockSelectionBottomRight
[n
]; 
 438         switch ( BlockContain( coords1
.GetRow(), coords1
.GetCol(), 
 439                                coords2
.GetRow(), coords2
.GetCol(), 
 440                                topRow
, leftCol
, bottomRow
, rightCol 
) ) 
 445             m_blockSelectionTopLeft
.RemoveAt(n
); 
 446             m_blockSelectionBottomRight
.RemoveAt(n
); 
 453     // If a row containing the selection is already selected, return, 
 454     // if a row contained in newly selected block is found, remove it. 
 455     if ( m_selectionMode 
!= wxGrid::wxGridSelectColumns 
) 
 457         count 
= m_rowSelection
.GetCount(); 
 458         for ( n 
= 0; n 
< count
; n
++ ) 
 460             switch ( BlockContain( m_rowSelection
[n
], 0, 
 461                                    m_rowSelection
[n
], m_grid
->GetNumberCols()-1, 
 462                                    topRow
, leftCol
, bottomRow
, rightCol 
) ) 
 467                 m_rowSelection
.RemoveAt(n
); 
 474     if ( m_selectionMode 
!= wxGrid::wxGridSelectRows 
) 
 476         count 
= m_colSelection
.GetCount(); 
 477         for ( n 
= 0; n 
< count
; n
++ ) 
 479             switch ( BlockContain( 0, m_colSelection
[n
], 
 480                                    m_grid
->GetNumberRows()-1, m_colSelection
[n
],  
 481                                    topRow
, leftCol
, bottomRow
, rightCol 
) ) 
 486                 m_colSelection
.RemoveAt(n
); 
 493     m_blockSelectionTopLeft
.Add( wxGridCellCoords( topRow
, leftCol 
) ); 
 494     m_blockSelectionBottomRight
.Add( wxGridCellCoords( bottomRow
, rightCol 
) ); 
 497     wxRect r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( topRow
, leftCol 
), 
 498                                           wxGridCellCoords( bottomRow
, rightCol 
) ); 
 499     if ( !m_grid
->GetBatchCount() ) 
 500         ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 502     // Send Event, if not disabled. 
 505         wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 506                                         wxEVT_GRID_RANGE_SELECT
, 
 508                                         wxGridCellCoords( topRow
, leftCol 
), 
 509                                         wxGridCellCoords( bottomRow
, rightCol 
), 
 511                                         ControlDown
, ShiftDown
, 
 513         m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 517 void wxGridSelection::SelectCell( int row
, int col
, 
 518                                   bool ControlDown
, bool ShiftDown
, 
 519                                   bool AltDown
, bool MetaDown
, 
 522     if ( m_selectionMode 
== wxGrid::wxGridSelectRows 
) 
 524         SelectBlock(row
, 0, row
, m_grid
->GetNumberCols() - 1, 
 525                     ControlDown
, ShiftDown
, AltDown
, MetaDown
); 
 528     else if ( m_selectionMode 
== wxGrid::wxGridSelectColumns 
) 
 530         SelectBlock(0, col
, m_grid
->GetNumberRows() - 1, col
, 
 531                     ControlDown
, ShiftDown
, AltDown
, MetaDown
); 
 534     else if ( IsInSelection ( row
, col 
) ) 
 536     m_cellSelection
.Add( wxGridCellCoords( row
, col 
) ); 
 539     wxRect r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, col 
), 
 540                                           wxGridCellCoords( row
, col 
) ); 
 541     if ( !m_grid
->GetBatchCount() ) 
 542         ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 547         wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 548                                         wxEVT_GRID_RANGE_SELECT
, 
 550                                         wxGridCellCoords( row
, col 
), 
 551                                         wxGridCellCoords( row
, col 
), 
 553                                         ControlDown
, ShiftDown
, 
 555         m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 559 void wxGridSelection::ToggleCellSelection( int row
, int col
, 
 560                                            bool ControlDown
, bool ShiftDown
, 
 561                                            bool AltDown
, bool MetaDown 
) 
 563     // if the cell is not selected, select it 
 564     if ( !IsInSelection ( row
, col 
) ) 
 566         SelectCell( row
, col
, ControlDown
, ShiftDown
, 
 571     // otherwise deselect it. This can be simple or more or 
 572     // less difficult, depending on how the cell is selected. 
 575     // The simplest case: The cell is contained in m_cellSelection 
 576     // Then it can't be contained in rows/cols/block (since those 
 577     // would remove the cell from m_cellSelection on creation), so 
 578     // we just have to remove it from m_cellSelection. 
 580     if ( m_selectionMode 
== wxGrid::wxGridSelectCells 
) 
 582         count 
= m_cellSelection
.GetCount(); 
 583         for ( n 
= 0; n 
< count
; n
++ ) 
 585             wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
 586             if ( row 
== coords
.GetRow() && col 
== coords
.GetCol() ) 
 589                 r 
= m_grid
->BlockToDeviceRect( m_cellSelection
[n
], 
 590                                                m_cellSelection
[n
] ); 
 591                 m_cellSelection
.RemoveAt(n
); 
 593                 if ( !m_grid
->GetBatchCount() ) 
 594                     ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 597                 wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 598                                                 wxEVT_GRID_RANGE_SELECT
, 
 600                                                 wxGridCellCoords( row
, col 
), 
 601                                                 wxGridCellCoords( row
, col 
), 
 603                                                 ControlDown
, ShiftDown
, 
 605                 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 611     // The most difficult case: The cell is member of one or even several 
 612     // blocks. Split each such block in up to 4 new parts, that don't 
 613     // contain the cell to be selected, like this: 
 614     // |---------------------------| 
 618     // |---------------------------| 
 619     // |   part 3   |x|   part 4   | 
 620     // |---------------------------| 
 624     // |---------------------------| 
 625     //   (The x marks the newly deselected cell). 
 626     // Note: in row selection mode, we only need part1 and part2; 
 627     //       in column selection mode, we only need part 3 and part4, 
 628     //          which are expanded to whole columns automatically! 
 630     count 
= m_blockSelectionTopLeft
.GetCount(); 
 631     for ( n 
= 0; n 
< count
; n
++ ) 
 633         wxGridCellCoords
& coords1 
= m_blockSelectionTopLeft
[n
]; 
 634         wxGridCellCoords
& coords2 
= m_blockSelectionBottomRight
[n
]; 
 635         int topRow 
= coords1
.GetRow(); 
 636         int leftCol 
= coords1
.GetCol(); 
 637         int bottomRow 
= coords2
.GetRow(); 
 638         int rightCol 
= coords2
.GetCol(); 
 639         if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
, 
 643             m_blockSelectionTopLeft
.RemoveAt(n
); 
 644             m_blockSelectionBottomRight
.RemoveAt(n
); 
 646             // add up to 4 smaller blocks and set update region 
 647             if ( m_selectionMode 
!= wxGrid::wxGridSelectColumns 
) 
 650                     SelectBlock( topRow
, leftCol
, 
 651                                  row 
- 1, rightCol
, 0, FALSE 
); 
 652                 if ( bottomRow 
> row 
) 
 653                     SelectBlock( row 
+ 1, leftCol
, 
 654                                  bottomRow
, rightCol
, 0, FALSE 
); 
 656             if ( m_selectionMode 
!= wxGrid::wxGridSelectRows 
) 
 659                     SelectBlock( row
, leftCol
, row
, col 
- 1, 0, FALSE 
); 
 660                 if ( rightCol 
> col 
) 
 661                     SelectBlock( row
, col 
+ 1, row
, rightCol
, 0, FALSE 
); 
 666     // remove a cell from a row, adding up to two new blocks 
 667     if ( m_selectionMode 
!= wxGrid::wxGridSelectColumns 
) 
 669         count 
= m_rowSelection
.GetCount(); 
 670         for ( n 
= 0; n 
< count
; n
++ ) 
 672             if ( m_rowSelection
[n
] == row 
) 
 674                 m_rowSelection
.RemoveAt(n
); 
 676                 if (m_selectionMode 
== wxGrid::wxGridSelectCells
) 
 679                         SelectBlock( row
, 0, row
, col 
- 1, 0, FALSE 
); 
 680                     if ( col 
< m_grid
->GetNumberCols() - 1 ) 
 681                         SelectBlock( row
, col 
+ 1, 
 682                                      row
, m_grid
->GetNumberCols() - 1, 
 689     // remove a cell from a column, adding up to two new blocks 
 690     if ( m_selectionMode 
!= wxGrid::wxGridSelectRows 
) 
 692         count 
= m_colSelection
.GetCount(); 
 693         for ( n 
= 0; n 
< count
; n
++ ) 
 695             if ( m_colSelection
[n
] == col 
) 
 697                 m_colSelection
.RemoveAt(n
); 
 699                 if (m_selectionMode 
== wxGrid::wxGridSelectCells
) 
 702                         SelectBlock( 0, col
, row 
- 1, col
, 0, FALSE 
); 
 703                     if ( row 
< m_grid
->GetNumberRows() - 1 ) 
 704                         SelectBlock( row 
+ 1, col
, 
 705                                      m_grid
->GetNumberRows() - 1, col
, 
 712     // Refresh the screen and send the event; according to m_selectionMode, 
 713     // we need to either update only the cell, or the whole row/column. 
 715     switch (m_selectionMode
) 
 717       case wxGrid::wxGridSelectCells
: 
 719           r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, col 
), 
 720                                          wxGridCellCoords( row
, col 
) ); 
 721           if ( !m_grid
->GetBatchCount() ) 
 722               ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 723           wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 724                                           wxEVT_GRID_RANGE_SELECT
, 
 726                                           wxGridCellCoords( row
, col 
), 
 727                                           wxGridCellCoords( row
, col 
), 
 729                                           ControlDown
, ShiftDown
, 
 731           m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 734       case wxGrid::wxGridSelectRows
: 
 736           r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ), 
 737                                          wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) ); 
 738           if ( !m_grid
->GetBatchCount() ) 
 739               ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 740           wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 741                                           wxEVT_GRID_RANGE_SELECT
, 
 743                                           wxGridCellCoords( row
, 0 ), 
 744                                           wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ), 
 746                                           ControlDown
, ShiftDown
, 
 748           m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 751       case wxGrid::wxGridSelectColumns
: 
 753           r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col 
), 
 754                                          wxGridCellCoords( m_grid
->GetNumberRows() - 1, col 
) ); 
 755           if ( !m_grid
->GetBatchCount() ) 
 756               ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 757           wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 758                                           wxEVT_GRID_RANGE_SELECT
, 
 760                                           wxGridCellCoords( 0, col 
), 
 761                                           wxGridCellCoords( m_grid
->GetNumberRows() - 1, col 
), 
 763                                           ControlDown
, ShiftDown
, 
 765           m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 771 void wxGridSelection::ClearSelection() 
 775     // deselect all invidiual cells and update the screen 
 776     if ( m_selectionMode 
== wxGrid::wxGridSelectCells 
) 
 779         while( ( n 
= m_cellSelection
.GetCount() ) > 0) 
 783             r 
= m_grid
->BlockToDeviceRect( m_cellSelection
[n
], 
 784                                            m_cellSelection
[n
] ); 
 785             m_cellSelection
.RemoveAt(n
); 
 786             if ( !m_grid
->GetBatchCount() ) 
 787                 ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
); 
 791     // deselect all blocks and update the screen 
 792     while( ( n 
= m_blockSelectionTopLeft
.GetCount() ) > 0) 
 796         r 
= m_grid
->BlockToDeviceRect( m_blockSelectionTopLeft
[n
], 
 797                                        m_blockSelectionBottomRight
[n
] ); 
 798         m_blockSelectionTopLeft
.RemoveAt(n
); 
 799         m_blockSelectionBottomRight
.RemoveAt(n
); 
 800         if ( !m_grid
->GetBatchCount() ) 
 801             ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
);    
 804     // deselect all rows and update the screen 
 805     if ( m_selectionMode 
!= wxGrid::wxGridSelectColumns 
) 
 807         while( ( n 
= m_rowSelection
.GetCount() ) > 0) 
 810             int & row 
= m_rowSelection
[n
]; 
 812             r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ), 
 813                                            wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) ); 
 814             m_rowSelection
.RemoveAt(n
); 
 815             if ( !m_grid
->GetBatchCount() ) 
 816                 ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
);    
 820     // deselect all columns and update the screen 
 821     if ( m_selectionMode 
!= wxGrid::wxGridSelectRows 
) 
 823         while( ( n 
= m_colSelection
.GetCount() ) > 0) 
 826             int & col 
= m_colSelection
[n
]; 
 828             r 
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col 
), 
 829                                            wxGridCellCoords( m_grid
->GetNumberRows() - 1, col 
) ); 
 830             m_colSelection
.RemoveAt(n
); 
 831             if ( !m_grid
->GetBatchCount() ) 
 832                 ((wxWindow 
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r 
);    
 836     // One deselection event, indicating deselection of _all_ cells. 
 837     // (No finer grained events for each of the smaller regions 
 838     //  deselected above!) 
 839     wxGridRangeSelectEvent 
gridEvt( m_grid
->GetId(), 
 840                                     wxEVT_GRID_RANGE_SELECT
, 
 842                                     wxGridCellCoords( 0, 0 ), 
 843                                     wxGridCellCoords( m_grid
->GetNumberRows() - 1, 
 844                                                       m_grid
->GetNumberCols() - 1 ), 
 847     m_grid
->GetEventHandler()->ProcessEvent(gridEvt
); 
 851 void wxGridSelection::UpdateRows( size_t pos
, int numRows 
) 
 853     size_t count 
= m_cellSelection
.GetCount(); 
 855     for ( n 
= 0; n 
< count
; n
++ ) 
 857         wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
 858         wxCoord row 
= coords
.GetRow(); 
 859         if ((size_t)row 
>= pos
) 
 863                 // If rows inserted, increase row counter where necessary 
 864                 coords
.SetRow(row 
+ numRows
); 
 866             else if (numRows 
< 0) 
 868                 // If rows deleted ... 
 869                 if ((size_t)row 
>= pos 
- numRows
) 
 871                     // ...either decrement row counter (if row still exists)... 
 872                     coords
.SetRow(row 
+ numRows
); 
 876                     // ...or remove the attribute 
 877                     m_cellSelection
.RemoveAt(n
); 
 884     count 
= m_blockSelectionTopLeft
.GetCount(); 
 885     for ( n 
= 0; n 
< count
; n
++ ) 
 887         wxGridCellCoords
& coords1 
= m_blockSelectionTopLeft
[n
]; 
 888         wxGridCellCoords
& coords2 
= m_blockSelectionBottomRight
[n
]; 
 889         wxCoord row1 
= coords1
.GetRow(); 
 890         wxCoord row2 
= coords2
.GetRow(); 
 891         if ((size_t)row2 
>= pos
) 
 895                 // If rows inserted, increase row counter where necessary 
 896                 coords2
.SetRow(row2 
+ numRows
); 
 897                 if ( (size_t)row1 
>= pos 
) 
 898                     coords1
.SetRow(row1 
+ numRows
); 
 900             else if (numRows 
< 0) 
 902                 // If rows deleted ... 
 903                 if ((size_t)row2 
>= pos 
- numRows
) 
 905                     // ...either decrement row counter (if row still exists)... 
 906                     coords2
.SetRow(row2 
+ numRows
); 
 907                     if ( (size_t) row1 
>= pos
) 
 908                         coords1
.SetRow( wxMax(row1 
+ numRows
, (int) pos
) ); 
 913                     if ( (size_t) row1 
>= pos
) 
 915                         // ...or remove the attribute 
 916                         m_blockSelectionTopLeft
.RemoveAt(n
); 
 917                         m_blockSelectionBottomRight
.RemoveAt(n
); 
 927     count 
= m_rowSelection
.GetCount(); 
 928     for ( n 
= 0; n 
< count
; n
++ ) 
 930         int & rowOrCol 
= m_rowSelection
[n
]; 
 931         if ( (size_t)rowOrCol 
>= pos 
) 
 935                 // If rows inserted, include row counter where necessary 
 938             else if ( numRows 
< 0) 
 940                 // If rows deleted, either decrement row counter (if row still exists) 
 941                 if ((size_t)rowOrCol 
>= pos 
- numRows
) 
 945                     m_rowSelection
.RemoveAt(n
); 
 951     // No need to touch selected columns, unless we removed _all_ 
 952     // rows, in this case, we remove all columns from the selection. 
 953     if ( !m_grid
->GetNumberRows() ) 
 954         m_colSelection
.Clear(); 
 957 void wxGridSelection::UpdateCols( size_t pos
, int numCols 
) 
 959     size_t count 
= m_cellSelection
.GetCount(); 
 961     for ( n 
= 0; n 
< count
; n
++ ) 
 963         wxGridCellCoords
& coords 
= m_cellSelection
[n
]; 
 964         wxCoord col 
= coords
.GetCol(); 
 965         if ((size_t)col 
>= pos
) 
 969                 // If rows inserted, increase row counter where necessary 
 970                 coords
.SetCol(col 
+ numCols
); 
 972             else if (numCols 
< 0) 
 974                 // If rows deleted ... 
 975                 if ((size_t)col 
>= pos 
- numCols
) 
 977                     // ...either decrement row counter (if row still exists)... 
 978                     coords
.SetCol(col 
+ numCols
); 
 982                     // ...or remove the attribute 
 983                     m_cellSelection
.RemoveAt(n
); 
 990     count 
= m_blockSelectionTopLeft
.GetCount(); 
 991     for ( n 
= 0; n 
< count
; n
++ ) 
 993         wxGridCellCoords
& coords1 
= m_blockSelectionTopLeft
[n
]; 
 994         wxGridCellCoords
& coords2 
= m_blockSelectionBottomRight
[n
]; 
 995         wxCoord col1 
= coords1
.GetCol(); 
 996         wxCoord col2 
= coords2
.GetCol(); 
 997         if ((size_t)col2 
>= pos
) 
1001                 // If rows inserted, increase row counter where necessary 
1002                 coords2
.SetCol(col2 
+ numCols
); 
1003                 if ( (size_t)col1 
>= pos 
) 
1004                     coords1
.SetCol(col1 
+ numCols
); 
1006             else if (numCols 
< 0) 
1008                 // If cols deleted ... 
1009                 if ((size_t)col2 
>= pos 
- numCols
) 
1011                     // ...either decrement col counter (if col still exists)... 
1012                     coords2
.SetCol(col2 
+ numCols
); 
1013                     if ( (size_t) col1 
>= pos
) 
1014                         coords1
.SetCol( wxMax(col1 
+ numCols
, (int) pos
) ); 
1019                     if ( (size_t) col1 
>= pos
) 
1021                         // ...or remove the attribute 
1022                         m_blockSelectionTopLeft
.RemoveAt(n
); 
1023                         m_blockSelectionBottomRight
.RemoveAt(n
); 
1027                         coords2
.SetCol(pos
); 
1033     count 
= m_colSelection
.GetCount(); 
1034     for ( n 
= 0; n 
< count
; n
++ ) 
1036         int & rowOrCol 
= m_colSelection
[n
]; 
1037         if ( (size_t)rowOrCol 
>= pos 
) 
1041                 // If cols inserted, include col counter where necessary 
1042                 rowOrCol 
+= numCols
; 
1044             else if ( numCols 
< 0) 
1046                 // If cols deleted, either decrement col counter (if col still exists) 
1047                 if ((size_t)rowOrCol 
>= pos 
- numCols
) 
1048                     rowOrCol 
+= numCols
; 
1051                     m_colSelection
.RemoveAt(n
); 
1058     // No need to touch selected rows, unless we removed _all_ 
1059     // columns, in this case, we remove all rows from the selection. 
1060     if ( !m_grid
->GetNumberCols() ) 
1061         m_rowSelection
.Clear(); 
1064 int wxGridSelection::BlockContain( int topRow1
, int leftCol1
, 
1065                                    int bottomRow1
, int rightCol1
, 
1066                                    int topRow2
, int leftCol2
, 
1067                                    int bottomRow2
, int rightCol2 
) 
1068 // returns 1, if Block1 contains Block2, 
1069 //        -1, if Block2 contains Block1, 
1072     if ( topRow1 
<= topRow2 
&& bottomRow2 
<= bottomRow1 
&& 
1073          leftCol1 
<= leftCol2 
&& rightCol2 
<= rightCol1 
) 
1075     else if ( topRow2 
<= topRow1 
&& bottomRow1 
<= bottomRow2 
&& 
1076               leftCol2 
<= leftCol1 
&& rightCol1 
<= rightCol2 
)