1 ///////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/gridsel.cpp
3 // Purpose: wxGridSelection
8 // Copyright: (c) Stefan Neis (Stefan.Neis@t-online.de)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
19 // ============================================================================
21 // ============================================================================
23 // ----------------------------------------------------------------------------
25 // ----------------------------------------------------------------------------
29 #include "wx/generic/gridsel.h"
32 // Some explanation for the members of the class:
33 // m_cellSelection stores individual selected cells
34 // -- this is only used if m_selectionMode == wxGridSelectCells
35 // m_blockSelectionTopLeft and m_blockSelectionBottomRight
36 // store the upper left and lower right corner of selected Blocks
37 // m_rowSelection and m_colSelection store individual selected
38 // rows and columns; maybe those are superfluous and should be
41 wxGridSelection::wxGridSelection( wxGrid
* grid
,
42 wxGrid::wxGridSelectionModes sel
)
45 m_selectionMode
= sel
;
48 bool wxGridSelection::IsSelection()
50 return ( m_cellSelection
.GetCount() || m_blockSelectionTopLeft
.GetCount() ||
51 m_rowSelection
.GetCount() || m_colSelection
.GetCount() );
54 bool wxGridSelection::IsInSelection( int row
, int col
)
58 // First check whether the given cell is individually selected
59 // (if m_selectionMode is wxGridSelectCells).
60 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
62 count
= m_cellSelection
.GetCount();
63 for ( size_t n
= 0; n
< count
; n
++ )
65 wxGridCellCoords
& coords
= m_cellSelection
[n
];
66 if ( row
== coords
.GetRow() && col
== coords
.GetCol() )
71 // Now check whether the given cell is
72 // contained in one of the selected blocks.
73 count
= m_blockSelectionTopLeft
.GetCount();
74 for ( size_t n
= 0; n
< count
; n
++ )
76 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
77 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
78 if ( BlockContainsCell(coords1
.GetRow(), coords1
.GetCol(),
79 coords2
.GetRow(), coords2
.GetCol(),
84 // Now check whether the given cell is
85 // contained in one of the selected rows
86 // (unless we are in column selection mode).
87 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
89 count
= m_rowSelection
.GetCount();
90 for ( size_t n
= 0; n
< count
; n
++ )
92 if ( row
== m_rowSelection
[n
] )
97 // Now check whether the given cell is
98 // contained in one of the selected columns
99 // (unless we are in row selection mode).
100 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
102 count
= m_colSelection
.GetCount();
103 for ( size_t n
= 0; n
< count
; n
++ )
105 if ( col
== m_colSelection
[n
] )
113 // Change the selection mode
114 void wxGridSelection::SetSelectionMode( wxGrid::wxGridSelectionModes selmode
)
116 // if selection mode is unchanged return immediately
117 if (selmode
== m_selectionMode
)
120 if ( m_selectionMode
!= wxGrid::wxGridSelectCells
)
122 // if changing form row to column selection
123 // or vice versa, clear the selection.
124 if ( selmode
!= wxGrid::wxGridSelectCells
)
127 m_selectionMode
= selmode
;
131 // if changing from cell selection to something else,
132 // promote selected cells/blocks to whole rows/columns.
134 while ( ( n
= m_cellSelection
.GetCount() ) > 0 )
137 wxGridCellCoords
& coords
= m_cellSelection
[n
];
138 int row
= coords
.GetRow();
139 int col
= coords
.GetCol();
140 m_cellSelection
.RemoveAt(n
);
141 if (selmode
== wxGrid::wxGridSelectRows
)
143 else // selmode == wxGridSelectColumns)
147 // Note that m_blockSelectionTopLeft's size may be changing!
148 for (n
= 0; n
< m_blockSelectionTopLeft
.GetCount(); n
++)
150 wxGridCellCoords
& coords
= m_blockSelectionTopLeft
[n
];
151 int topRow
= coords
.GetRow();
152 int leftCol
= coords
.GetCol();
153 coords
= m_blockSelectionBottomRight
[n
];
154 int bottomRow
= coords
.GetRow();
155 int rightCol
= coords
.GetCol();
157 if (selmode
== wxGrid::wxGridSelectRows
)
159 if (leftCol
!= 0 || rightCol
!= m_grid
->GetNumberCols() - 1 )
161 m_blockSelectionTopLeft
.RemoveAt(n
);
162 m_blockSelectionBottomRight
.RemoveAt(n
);
163 SelectBlockNoEvent( topRow
, 0,
164 bottomRow
, m_grid
->GetNumberCols() - 1);
167 else // selmode == wxGridSelectColumns)
169 if (topRow
!= 0 || bottomRow
!= m_grid
->GetNumberRows() - 1 )
171 m_blockSelectionTopLeft
.RemoveAt(n
);
172 m_blockSelectionBottomRight
.RemoveAt(n
);
173 SelectBlockNoEvent(0, leftCol
,
174 m_grid
->GetNumberRows() - 1, rightCol
);
179 m_selectionMode
= selmode
;
183 void wxGridSelection::SelectRow(int row
, const wxKeyboardState
& kbd
)
185 if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
190 // Remove single cells contained in newly selected block.
191 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
193 count
= m_cellSelection
.GetCount();
194 for ( n
= 0; n
< count
; n
++ )
196 wxGridCellCoords
& coords
= m_cellSelection
[n
];
197 if ( BlockContainsCell( row
, 0, row
, m_grid
->GetNumberCols() - 1,
198 coords
.GetRow(), coords
.GetCol() ) )
200 m_cellSelection
.RemoveAt(n
);
207 // Simplify list of selected blocks (if possible)
208 count
= m_blockSelectionTopLeft
.GetCount();
211 for ( n
= 0; n
< count
; n
++ )
213 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
214 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
216 // Remove block if it is a subset of the row
217 if ( coords1
.GetRow() == row
&& row
== coords2
.GetRow() )
219 m_blockSelectionTopLeft
.RemoveAt(n
);
220 m_blockSelectionBottomRight
.RemoveAt(n
);
224 else if ( coords1
.GetCol() == 0 &&
225 coords2
.GetCol() == m_grid
->GetNumberCols() - 1 )
227 // silently return, if row is contained in block
228 if ( coords1
.GetRow() <= row
&& row
<= coords2
.GetRow() )
230 // expand block, if it touched row
231 else if ( coords1
.GetRow() == row
+ 1)
236 else if ( coords2
.GetRow() == row
- 1)
244 // Unless we successfully handled the row,
245 // check whether row is already selected.
248 count
= m_rowSelection
.GetCount();
249 for ( n
= 0; n
< count
; n
++ )
251 if ( row
== m_rowSelection
[n
] )
255 // Add row to selection
256 m_rowSelection
.Add(row
);
260 if ( !m_grid
->GetBatchCount() )
262 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
263 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
264 ((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 ),
276 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
279 void wxGridSelection::SelectCol(int col
, const wxKeyboardState
& kbd
)
281 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
285 // Remove single cells contained in newly selected block.
286 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
288 count
= m_cellSelection
.GetCount();
289 for ( n
= 0; n
< count
; n
++ )
291 wxGridCellCoords
& coords
= m_cellSelection
[n
];
292 if ( BlockContainsCell( 0, col
, m_grid
->GetNumberRows() - 1, col
,
293 coords
.GetRow(), coords
.GetCol() ) )
295 m_cellSelection
.RemoveAt(n
);
302 // Simplify list of selected blocks (if possible)
303 count
= m_blockSelectionTopLeft
.GetCount();
305 for ( n
= 0; n
< count
; n
++ )
307 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
308 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
310 // Remove block if it is a subset of the column
311 if ( coords1
.GetCol() == col
&& col
== coords2
.GetCol() )
313 m_blockSelectionTopLeft
.RemoveAt(n
);
314 m_blockSelectionBottomRight
.RemoveAt(n
);
318 else if ( coords1
.GetRow() == 0 &&
319 coords2
.GetRow() == m_grid
->GetNumberRows() - 1 )
321 // silently return, if row is contained in block
322 if ( coords1
.GetCol() <= col
&& col
<= coords2
.GetCol() )
324 // expand block, if it touched col
325 else if ( coords1
.GetCol() == col
+ 1)
330 else if ( coords2
.GetCol() == col
- 1)
338 // Unless we successfully handled the column,
339 // Check whether col is already selected.
342 count
= m_colSelection
.GetCount();
343 for ( n
= 0; n
< count
; n
++ )
345 if ( col
== m_colSelection
[n
] )
349 // Add col to selection
350 m_colSelection
.Add(col
);
354 if ( !m_grid
->GetBatchCount() )
356 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
357 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
358 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
362 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
363 wxEVT_GRID_RANGE_SELECT
,
365 wxGridCellCoords( 0, col
),
366 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
),
370 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
373 void wxGridSelection::SelectBlock( int topRow
, int leftCol
,
374 int bottomRow
, int rightCol
,
375 const wxKeyboardState
& kbd
,
378 // Fix the coordinates of the block if needed.
379 switch ( m_selectionMode
)
382 wxFAIL_MSG( "unknown selection mode" );
385 case wxGrid::wxGridSelectCells
:
386 // nothing to do -- in this mode arbitrary blocks can be selected
389 case wxGrid::wxGridSelectRows
:
391 rightCol
= m_grid
->GetNumberCols() - 1;
394 case wxGrid::wxGridSelectColumns
:
396 bottomRow
= m_grid
->GetNumberRows() - 1;
399 case wxGrid::wxGridSelectRowsOrColumns
:
400 // block selection doesn't make sense for this mode, we could only
401 // select the entire grid but this wouldn't be useful
405 if ( topRow
> bottomRow
)
412 if ( leftCol
> rightCol
)
419 // Handle single cell selection in SelectCell.
420 // (MB: added check for selection mode here to prevent
421 // crashes if, for example, we are select rows and the
422 // grid only has 1 col)
423 if ( m_selectionMode
== wxGrid::wxGridSelectCells
&&
424 topRow
== bottomRow
&& leftCol
== rightCol
)
426 SelectCell( topRow
, leftCol
, kbd
, sendEvent
);
431 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
433 // find out which rows are already selected:
434 wxArrayInt alreadyselected
;
435 alreadyselected
.Add(0,bottomRow
-topRow
+1);
436 for( n
= 0; n
< m_rowSelection
.GetCount(); n
++)
438 int row
= m_rowSelection
[n
];
439 if( (row
>= topRow
) && (row
<= bottomRow
) )
441 alreadyselected
[ row
- topRow
]=1;
445 // add the newly selected rows:
446 for ( int row
= topRow
; row
<= bottomRow
; row
++ )
448 if ( alreadyselected
[ row
- topRow
] == 0 )
450 m_rowSelection
.Add( row
);
454 else if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
456 // find out which columns are already selected:
457 wxArrayInt alreadyselected
;
458 alreadyselected
.Add(0,rightCol
-leftCol
+1);
459 for( n
= 0; n
< m_colSelection
.GetCount(); n
++)
461 int col
= m_colSelection
[n
];
462 if( (col
>= leftCol
) && (col
<= rightCol
) )
464 alreadyselected
[ col
- leftCol
]=1;
468 // add the newly selected columns:
469 for ( int col
= leftCol
; col
<= rightCol
; col
++ )
471 if ( alreadyselected
[ col
- leftCol
] == 0 )
473 m_colSelection
.Add( col
);
479 // Remove single cells contained in newly selected block.
480 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
482 count
= m_cellSelection
.GetCount();
483 for ( n
= 0; n
< count
; n
++ )
485 wxGridCellCoords
& coords
= m_cellSelection
[n
];
486 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
,
487 coords
.GetRow(), coords
.GetCol() ) )
489 m_cellSelection
.RemoveAt(n
);
496 // If a block containing the selection is already selected, return,
497 // if a block contained in the selection is found, remove it.
499 count
= m_blockSelectionTopLeft
.GetCount();
500 for ( n
= 0; n
< count
; n
++ )
502 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
503 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
505 switch ( BlockContain( coords1
.GetRow(), coords1
.GetCol(),
506 coords2
.GetRow(), coords2
.GetCol(),
507 topRow
, leftCol
, bottomRow
, rightCol
) )
513 m_blockSelectionTopLeft
.RemoveAt(n
);
514 m_blockSelectionBottomRight
.RemoveAt(n
);
524 // If a row containing the selection is already selected, return,
525 // if a row contained in newly selected block is found, remove it.
526 count
= m_rowSelection
.GetCount();
527 for ( n
= 0; n
< count
; n
++ )
529 switch ( BlockContain( m_rowSelection
[n
], 0,
530 m_rowSelection
[n
], m_grid
->GetNumberCols() - 1,
531 topRow
, leftCol
, bottomRow
, rightCol
) )
537 m_rowSelection
.RemoveAt(n
);
548 count
= m_colSelection
.GetCount();
549 for ( n
= 0; n
< count
; n
++ )
551 switch ( BlockContain( 0, m_colSelection
[n
],
552 m_grid
->GetNumberRows() - 1, m_colSelection
[n
],
553 topRow
, leftCol
, bottomRow
, rightCol
) )
559 m_colSelection
.RemoveAt(n
);
569 m_blockSelectionTopLeft
.Add( wxGridCellCoords( topRow
, leftCol
) );
570 m_blockSelectionBottomRight
.Add( wxGridCellCoords( bottomRow
, rightCol
) );
573 if ( !m_grid
->GetBatchCount() )
575 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( topRow
, leftCol
),
576 wxGridCellCoords( bottomRow
, rightCol
) );
577 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
580 // Send Event, if not disabled.
583 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
584 wxEVT_GRID_RANGE_SELECT
,
586 wxGridCellCoords( topRow
, leftCol
),
587 wxGridCellCoords( bottomRow
, rightCol
),
590 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
594 void wxGridSelection::SelectCell( int row
, int col
,
595 const wxKeyboardState
& kbd
,
598 if ( IsInSelection ( row
, col
) )
601 wxGridCellCoords selectedTopLeft
, selectedBottomRight
;
602 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
604 m_rowSelection
.Add( row
);
605 selectedTopLeft
= wxGridCellCoords( row
, 0 );
606 selectedBottomRight
= wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 );
608 else if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
610 m_colSelection
.Add( col
);
611 selectedTopLeft
= wxGridCellCoords( 0, col
);
612 selectedBottomRight
= wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
);
616 m_cellSelection
.Add( wxGridCellCoords( row
, col
) );
617 selectedTopLeft
= wxGridCellCoords( row
, col
);
618 selectedBottomRight
= wxGridCellCoords( row
, col
);
622 if ( !m_grid
->GetBatchCount() )
624 wxRect r
= m_grid
->BlockToDeviceRect(
626 selectedBottomRight
);
627 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
633 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
634 wxEVT_GRID_RANGE_SELECT
,
640 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
645 wxGridSelection::ToggleCellSelection(int row
, int col
,
646 const wxKeyboardState
& kbd
)
648 // if the cell is not selected, select it
649 if ( !IsInSelection ( row
, col
) )
651 SelectCell(row
, col
, kbd
);
656 // otherwise deselect it. This can be simple or more or
657 // less difficult, depending on how the cell is selected.
660 // The simplest case: The cell is contained in m_cellSelection
661 // Then it can't be contained in rows/cols/block (since those
662 // would remove the cell from m_cellSelection on creation), so
663 // we just have to remove it from m_cellSelection.
665 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
667 count
= m_cellSelection
.GetCount();
668 for ( n
= 0; n
< count
; n
++ )
670 const wxGridCellCoords
& sel
= m_cellSelection
[n
];
671 if ( row
== sel
.GetRow() && col
== sel
.GetCol() )
673 wxGridCellCoords coords
= m_cellSelection
[n
];
674 m_cellSelection
.RemoveAt(n
);
675 if ( !m_grid
->GetBatchCount() )
677 wxRect r
= m_grid
->BlockToDeviceRect( coords
, coords
);
678 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
682 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
683 wxEVT_GRID_RANGE_SELECT
,
685 wxGridCellCoords( row
, col
),
686 wxGridCellCoords( row
, col
),
689 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
696 // The most difficult case: The cell is member of one or even several
697 // blocks. Split each such block in up to 4 new parts, that don't
698 // contain the cell to be selected, like this:
699 // |---------------------------|
703 // |---------------------------|
704 // | part 3 |x| part 4 |
705 // |---------------------------|
709 // |---------------------------|
710 // (The x marks the newly deselected cell).
711 // Note: in row selection mode, we only need part1 and part2;
712 // in column selection mode, we only need part 3 and part4,
713 // which are expanded to whole columns automatically!
715 count
= m_blockSelectionTopLeft
.GetCount();
716 for ( n
= 0; n
< count
; n
++ )
718 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
719 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
720 int topRow
= coords1
.GetRow();
721 int leftCol
= coords1
.GetCol();
722 int bottomRow
= coords2
.GetRow();
723 int rightCol
= coords2
.GetCol();
725 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
, row
, col
) )
728 m_blockSelectionTopLeft
.RemoveAt(n
);
729 m_blockSelectionBottomRight
.RemoveAt(n
);
733 // add up to 4 smaller blocks and set update region
734 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
737 SelectBlockNoEvent(topRow
, leftCol
, row
- 1, rightCol
);
738 if ( bottomRow
> row
)
739 SelectBlockNoEvent(row
+ 1, leftCol
, bottomRow
, rightCol
);
742 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
745 SelectBlockNoEvent(row
, leftCol
, row
, col
- 1);
746 if ( rightCol
> col
)
747 SelectBlockNoEvent(row
, col
+ 1, row
, rightCol
);
752 bool rowSelectionWasChanged
= false;
753 // remove a cell from a row, adding up to two new blocks
754 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
756 count
= m_rowSelection
.GetCount();
757 for ( n
= 0; n
< count
; n
++ )
759 if ( m_rowSelection
[n
] == row
)
761 m_rowSelection
.RemoveAt(n
);
765 rowSelectionWasChanged
= true;
767 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
770 SelectBlockNoEvent(row
, 0, row
, col
- 1);
771 if ( col
< m_grid
->GetNumberCols() - 1 )
772 SelectBlockNoEvent( row
, col
+ 1,
773 row
, m_grid
->GetNumberCols() - 1);
779 bool colSelectionWasChanged
= false;
780 // remove a cell from a column, adding up to two new blocks
781 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
783 count
= m_colSelection
.GetCount();
784 for ( n
= 0; n
< count
; n
++ )
786 if ( m_colSelection
[n
] == col
)
788 m_colSelection
.RemoveAt(n
);
792 colSelectionWasChanged
= true;
794 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
797 SelectBlockNoEvent(0, col
, row
- 1, col
);
798 if ( row
< m_grid
->GetNumberRows() - 1 )
799 SelectBlockNoEvent(row
+ 1, col
,
800 m_grid
->GetNumberRows() - 1, col
);
806 // Refresh the screen and send the event; according to m_selectionMode,
807 // we need to either update only the cell, or the whole row/column.
809 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
811 if ( !m_grid
->GetBatchCount() )
813 r
= m_grid
->BlockToDeviceRect(
814 wxGridCellCoords( row
, col
),
815 wxGridCellCoords( row
, col
) );
816 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
819 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
820 wxEVT_GRID_RANGE_SELECT
,
822 wxGridCellCoords( row
, col
),
823 wxGridCellCoords( row
, col
),
826 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
828 else // rows/columns selection mode
830 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
&&
831 rowSelectionWasChanged
)
833 int numCols
= m_grid
->GetNumberCols();
834 for ( int colFrom
= 0, colTo
= 0; colTo
<= numCols
; ++colTo
)
836 if ( m_colSelection
.Index(colTo
) >= 0 || colTo
== numCols
)
838 if ( colFrom
< colTo
)
840 if ( !m_grid
->GetBatchCount() )
842 r
= m_grid
->BlockToDeviceRect(
843 wxGridCellCoords( row
, colFrom
),
844 wxGridCellCoords( row
, colTo
-1 ) );
845 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
848 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
849 wxEVT_GRID_RANGE_SELECT
,
851 wxGridCellCoords( row
, colFrom
),
852 wxGridCellCoords( row
, colTo
- 1 ),
855 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
863 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
&&
864 colSelectionWasChanged
)
866 int numRows
= m_grid
->GetNumberRows();
867 for ( int rowFrom
= 0, rowTo
= 0; rowTo
<= numRows
; ++rowTo
)
869 if ( m_rowSelection
.Index(rowTo
) >= 0 || rowTo
== numRows
)
873 if ( !m_grid
->GetBatchCount() )
875 r
= m_grid
->BlockToDeviceRect(
876 wxGridCellCoords( rowFrom
, col
),
877 wxGridCellCoords( rowTo
- 1, col
) );
878 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
881 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
882 wxEVT_GRID_RANGE_SELECT
,
884 wxGridCellCoords( rowFrom
, col
),
885 wxGridCellCoords( rowTo
- 1, col
),
888 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
898 void wxGridSelection::ClearSelection()
902 wxGridCellCoords coords1
, coords2
;
904 // deselect all individual cells and update the screen
905 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
907 while ( ( n
= m_cellSelection
.GetCount() ) > 0)
910 coords1
= m_cellSelection
[n
];
911 m_cellSelection
.RemoveAt(n
);
912 if ( !m_grid
->GetBatchCount() )
914 r
= m_grid
->BlockToDeviceRect( coords1
, coords1
);
915 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
918 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
924 // deselect all blocks and update the screen
925 while ( ( n
= m_blockSelectionTopLeft
.GetCount() ) > 0)
928 coords1
= m_blockSelectionTopLeft
[n
];
929 coords2
= m_blockSelectionBottomRight
[n
];
930 m_blockSelectionTopLeft
.RemoveAt(n
);
931 m_blockSelectionBottomRight
.RemoveAt(n
);
932 if ( !m_grid
->GetBatchCount() )
934 r
= m_grid
->BlockToDeviceRect( coords1
, coords2
);
935 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
938 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
943 // deselect all rows and update the screen
944 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
946 while ( ( n
= m_rowSelection
.GetCount() ) > 0)
949 int row
= m_rowSelection
[n
];
950 m_rowSelection
.RemoveAt(n
);
951 if ( !m_grid
->GetBatchCount() )
953 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
954 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
955 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
958 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
964 // deselect all columns and update the screen
965 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
967 while ( ( n
= m_colSelection
.GetCount() ) > 0)
970 int col
= m_colSelection
[n
];
971 m_colSelection
.RemoveAt(n
);
972 if ( !m_grid
->GetBatchCount() )
974 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
975 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
976 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
979 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
985 // One deselection event, indicating deselection of _all_ cells.
986 // (No finer grained events for each of the smaller regions
987 // deselected above!)
988 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
989 wxEVT_GRID_RANGE_SELECT
,
991 wxGridCellCoords( 0, 0 ),
993 m_grid
->GetNumberRows() - 1,
994 m_grid
->GetNumberCols() - 1 ),
997 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
1001 void wxGridSelection::UpdateRows( size_t pos
, int numRows
)
1003 size_t count
= m_cellSelection
.GetCount();
1005 for ( n
= 0; n
< count
; n
++ )
1007 wxGridCellCoords
& coords
= m_cellSelection
[n
];
1008 wxCoord row
= coords
.GetRow();
1009 if ((size_t)row
>= pos
)
1013 // If rows inserted, increase row counter where necessary
1014 coords
.SetRow(row
+ numRows
);
1016 else if (numRows
< 0)
1018 // If rows deleted ...
1019 if ((size_t)row
>= pos
- numRows
)
1021 // ...either decrement row counter (if row still exists)...
1022 coords
.SetRow(row
+ numRows
);
1026 // ...or remove the attribute
1027 m_cellSelection
.RemoveAt(n
);
1035 count
= m_blockSelectionTopLeft
.GetCount();
1036 for ( n
= 0; n
< count
; n
++ )
1038 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
1039 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
1040 wxCoord row1
= coords1
.GetRow();
1041 wxCoord row2
= coords2
.GetRow();
1043 if ((size_t)row2
>= pos
)
1047 // If rows inserted, increase row counter where necessary
1048 coords2
.SetRow( row2
+ numRows
);
1049 if ((size_t)row1
>= pos
)
1050 coords1
.SetRow( row1
+ numRows
);
1052 else if (numRows
< 0)
1054 // If rows deleted ...
1055 if ((size_t)row2
>= pos
- numRows
)
1057 // ...either decrement row counter (if row still exists)...
1058 coords2
.SetRow( row2
+ numRows
);
1059 if ((size_t)row1
>= pos
)
1060 coords1
.SetRow( wxMax(row1
+ numRows
, (int)pos
) );
1065 if ((size_t)row1
>= pos
)
1067 // ...or remove the attribute
1068 m_blockSelectionTopLeft
.RemoveAt(n
);
1069 m_blockSelectionBottomRight
.RemoveAt(n
);
1074 coords2
.SetRow( pos
);
1080 count
= m_rowSelection
.GetCount();
1081 for ( n
= 0; n
< count
; n
++ )
1083 int rowOrCol_
= m_rowSelection
[n
];
1085 if ((size_t) rowOrCol_
>= pos
)
1089 m_rowSelection
[n
] += numRows
;
1091 else if ( numRows
< 0 )
1093 if ((size_t)rowOrCol_
>= (pos
- numRows
))
1094 m_rowSelection
[n
] += numRows
;
1097 m_rowSelection
.RemoveAt( n
);
1104 // No need to touch selected columns, unless we removed _all_
1105 // rows, in this case, we remove all columns from the selection.
1107 if ( !m_grid
->GetNumberRows() )
1108 m_colSelection
.Clear();
1112 void wxGridSelection::UpdateCols( size_t pos
, int numCols
)
1114 size_t count
= m_cellSelection
.GetCount();
1117 for ( n
= 0; n
< count
; n
++ )
1119 wxGridCellCoords
& coords
= m_cellSelection
[n
];
1120 wxCoord col
= coords
.GetCol();
1121 if ((size_t)col
>= pos
)
1125 // If rows inserted, increase row counter where necessary
1126 coords
.SetCol(col
+ numCols
);
1128 else if (numCols
< 0)
1130 // If rows deleted ...
1131 if ((size_t)col
>= pos
- numCols
)
1133 // ...either decrement row counter (if row still exists)...
1134 coords
.SetCol(col
+ numCols
);
1138 // ...or remove the attribute
1139 m_cellSelection
.RemoveAt(n
);
1147 count
= m_blockSelectionTopLeft
.GetCount();
1148 for ( n
= 0; n
< count
; n
++ )
1150 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
1151 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
1152 wxCoord col1
= coords1
.GetCol();
1153 wxCoord col2
= coords2
.GetCol();
1155 if ((size_t)col2
>= pos
)
1159 // If rows inserted, increase row counter where necessary
1160 coords2
.SetCol(col2
+ numCols
);
1161 if ((size_t)col1
>= pos
)
1162 coords1
.SetCol(col1
+ numCols
);
1164 else if (numCols
< 0)
1166 // If cols deleted ...
1167 if ((size_t)col2
>= pos
- numCols
)
1169 // ...either decrement col counter (if col still exists)...
1170 coords2
.SetCol(col2
+ numCols
);
1171 if ( (size_t) col1
>= pos
)
1172 coords1
.SetCol( wxMax(col1
+ numCols
, (int)pos
) );
1177 if ((size_t)col1
>= pos
)
1179 // ...or remove the attribute
1180 m_blockSelectionTopLeft
.RemoveAt(n
);
1181 m_blockSelectionBottomRight
.RemoveAt(n
);
1186 coords2
.SetCol(pos
);
1192 count
= m_colSelection
.GetCount();
1193 for ( n
= 0; n
< count
; n
++ )
1195 int rowOrCol
= m_colSelection
[n
];
1197 if ((size_t)rowOrCol
>= pos
)
1200 m_colSelection
[n
] += numCols
;
1201 else if ( numCols
< 0 )
1203 if ((size_t)rowOrCol
>= (pos
- numCols
))
1204 m_colSelection
[n
] += numCols
;
1207 m_colSelection
.RemoveAt( n
);
1215 // No need to touch selected rows, unless we removed _all_
1216 // columns, in this case, we remove all rows from the selection.
1217 if ( !m_grid
->GetNumberCols() )
1218 m_rowSelection
.Clear();
1221 int wxGridSelection::BlockContain( int topRow1
, int leftCol1
,
1222 int bottomRow1
, int rightCol1
,
1223 int topRow2
, int leftCol2
,
1224 int bottomRow2
, int rightCol2
)
1225 // returns 1, if Block1 contains Block2,
1226 // -1, if Block2 contains Block1,
1229 if ( topRow1
<= topRow2
&& bottomRow2
<= bottomRow1
&&
1230 leftCol1
<= leftCol2
&& rightCol2
<= rightCol1
)
1232 else if ( topRow2
<= topRow1
&& bottomRow1
<= bottomRow2
&&
1233 leftCol2
<= leftCol1
&& rightCol1
<= rightCol2
)