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 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/generic/gridsel.h"
33 // Some explanation for the members of the class:
34 // m_cellSelection stores individual selected cells
35 // -- this is only used if m_selectionMode == wxGridSelectCells
36 // m_blockSelectionTopLeft and m_blockSelectionBottomRight
37 // store the upper left and lower right corner of selected Blocks
38 // m_rowSelection and m_colSelection store individual selected
39 // rows and columns; maybe those are superfluous and should be
42 wxGridSelection::wxGridSelection( wxGrid
* grid
,
43 wxGrid::wxGridSelectionModes sel
)
46 m_selectionMode
= sel
;
49 bool wxGridSelection::IsSelection()
51 return ( m_cellSelection
.GetCount() || m_blockSelectionTopLeft
.GetCount() ||
52 m_rowSelection
.GetCount() || m_colSelection
.GetCount() );
55 bool wxGridSelection::IsInSelection ( int row
, int col
)
59 // First check whether the given cell is individually selected
60 // (if m_selectionMode is wxGridSelectCells).
61 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
63 count
= m_cellSelection
.GetCount();
64 for ( size_t n
= 0; n
< count
; n
++ )
66 wxGridCellCoords
& coords
= m_cellSelection
[n
];
67 if ( row
== coords
.GetRow() && col
== coords
.GetCol() )
72 // Now check whether the given cell is
73 // contained in one of the selected blocks.
74 count
= m_blockSelectionTopLeft
.GetCount();
75 for ( size_t n
= 0; n
< count
; n
++ )
77 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
78 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
79 if ( BlockContainsCell(coords1
.GetRow(), coords1
.GetCol(),
80 coords2
.GetRow(), coords2
.GetCol(),
85 // Now check whether the given cell is
86 // contained in one of the selected rows
87 // (unless we are in column selection mode).
88 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
90 count
= m_rowSelection
.GetCount();
91 for ( size_t n
= 0; n
< count
; n
++ )
93 if ( row
== m_rowSelection
[n
] )
98 // Now check whether the given cell is
99 // contained in one of the selected columns
100 // (unless we are in row selection mode).
101 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
103 count
= m_colSelection
.GetCount();
104 for ( size_t n
= 0; n
< count
; n
++ )
106 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 for (n
= 0; n
< m_blockSelectionTopLeft
.GetCount(); n
++)
148 // Note that m_blockSelectionTopLeft's size may be changing!
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();
156 if (selmode
== wxGrid::wxGridSelectRows
)
158 if (leftCol
!= 0 || rightCol
!= m_grid
->GetNumberCols() - 1 )
160 m_blockSelectionTopLeft
.RemoveAt(n
);
161 m_blockSelectionBottomRight
.RemoveAt(n
);
162 SelectBlock( topRow
, 0,
163 bottomRow
, m_grid
->GetNumberCols() - 1,
164 false, false, false, false, false );
167 else // selmode == wxGridSelectColumns)
169 if (topRow
!= 0 || bottomRow
!= m_grid
->GetNumberRows() - 1 )
171 m_blockSelectionTopLeft
.RemoveAt(n
);
172 m_blockSelectionBottomRight
.RemoveAt(n
);
173 SelectBlock( 0, leftCol
,
174 m_grid
->GetNumberRows() - 1, rightCol
,
175 false, false, false, false, false );
179 m_selectionMode
= selmode
;
183 void wxGridSelection::SelectRow( int row
,
184 bool ControlDown
, bool ShiftDown
,
185 bool AltDown
, bool MetaDown
)
187 if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
191 // Remove single cells contained in newly selected block.
192 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
194 count
= m_cellSelection
.GetCount();
195 for ( n
= 0; n
< count
; n
++ )
197 wxGridCellCoords
& coords
= m_cellSelection
[n
];
198 if ( BlockContainsCell( row
, 0, row
, m_grid
->GetNumberCols() - 1,
199 coords
.GetRow(), coords
.GetCol() ) )
201 m_cellSelection
.RemoveAt(n
);
207 // Simplify list of selected blocks (if possible)
208 count
= m_blockSelectionTopLeft
.GetCount();
210 for ( n
= 0; n
< count
; n
++ )
212 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
213 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
215 // Remove block if it is a subset of the row
216 if ( coords1
.GetRow() == row
&& row
== coords2
.GetRow() )
218 m_blockSelectionTopLeft
.RemoveAt(n
);
219 m_blockSelectionBottomRight
.RemoveAt(n
);
222 else if ( coords1
.GetCol() == 0 &&
223 coords2
.GetCol() == m_grid
->GetNumberCols() - 1 )
225 // silently return, if row is contained in block
226 if ( coords1
.GetRow() <= row
&& row
<= coords2
.GetRow() )
228 // expand block, if it touched row
229 else if ( coords1
.GetRow() == row
+ 1)
234 else if ( coords2
.GetRow() == row
- 1)
242 // Unless we successfully handled the row,
243 // check whether row is already selected.
246 count
= m_rowSelection
.GetCount();
247 for ( n
= 0; n
< count
; n
++ )
249 if ( row
== m_rowSelection
[n
] )
253 // Add row to selection
254 m_rowSelection
.Add(row
);
258 if ( !m_grid
->GetBatchCount() )
260 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
261 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
262 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
266 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
267 wxEVT_GRID_RANGE_SELECT
,
269 wxGridCellCoords( row
, 0 ),
270 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ),
272 ControlDown
, ShiftDown
,
275 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
278 void wxGridSelection::SelectCol( int col
,
279 bool ControlDown
, bool ShiftDown
,
280 bool AltDown
, bool MetaDown
)
282 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
286 // Remove single cells contained in newly selected block.
287 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
289 count
= m_cellSelection
.GetCount();
290 for ( n
= 0; n
< count
; n
++ )
292 wxGridCellCoords
& coords
= m_cellSelection
[n
];
293 if ( BlockContainsCell( 0, col
, m_grid
->GetNumberRows() - 1, col
,
294 coords
.GetRow(), coords
.GetCol() ) )
296 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
);
317 else if ( coords1
.GetRow() == 0 &&
318 coords2
.GetRow() == m_grid
->GetNumberRows() - 1 )
320 // silently return, if row is contained in block
321 if ( coords1
.GetCol() <= col
&& col
<= coords2
.GetCol() )
323 // expand block, if it touched col
324 else if ( coords1
.GetCol() == col
+ 1)
329 else if ( coords2
.GetCol() == col
- 1)
337 // Unless we successfully handled the column,
338 // Check whether col is already selected.
341 count
= m_colSelection
.GetCount();
342 for ( n
= 0; n
< count
; n
++ )
344 if ( col
== m_colSelection
[n
] )
348 // Add col to selection
349 m_colSelection
.Add(col
);
353 if ( !m_grid
->GetBatchCount() )
355 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
356 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
357 ((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
) )
446 m_blockSelectionTopLeft
.RemoveAt(n
);
447 m_blockSelectionBottomRight
.RemoveAt(n
);
456 // If a row containing the selection is already selected, return,
457 // if a row contained in newly selected block is found, remove it.
458 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
460 count
= m_rowSelection
.GetCount();
461 for ( n
= 0; n
< count
; n
++ )
463 switch ( BlockContain( m_rowSelection
[n
], 0,
464 m_rowSelection
[n
], m_grid
->GetNumberCols()-1,
465 topRow
, leftCol
, bottomRow
, rightCol
) )
471 m_rowSelection
.RemoveAt(n
);
480 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
482 count
= m_colSelection
.GetCount();
483 for ( n
= 0; n
< count
; n
++ )
485 switch ( BlockContain( 0, m_colSelection
[n
],
486 m_grid
->GetNumberRows()-1, m_colSelection
[n
],
487 topRow
, leftCol
, bottomRow
, rightCol
) )
493 m_colSelection
.RemoveAt(n
);
502 m_blockSelectionTopLeft
.Add( wxGridCellCoords( topRow
, leftCol
) );
503 m_blockSelectionBottomRight
.Add( wxGridCellCoords( bottomRow
, rightCol
) );
506 if ( !m_grid
->GetBatchCount() )
508 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( topRow
, leftCol
),
509 wxGridCellCoords( bottomRow
, rightCol
) );
510 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
513 // Send Event, if not disabled.
516 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
517 wxEVT_GRID_RANGE_SELECT
,
519 wxGridCellCoords( topRow
, leftCol
),
520 wxGridCellCoords( bottomRow
, rightCol
),
522 ControlDown
, ShiftDown
,
524 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
528 void wxGridSelection::SelectCell( int row
, int col
,
529 bool ControlDown
, bool ShiftDown
,
530 bool AltDown
, bool MetaDown
,
533 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
535 SelectBlock(row
, 0, row
, m_grid
->GetNumberCols() - 1,
536 ControlDown
, ShiftDown
, AltDown
, MetaDown
, sendEvent
);
539 else if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
541 SelectBlock(0, col
, m_grid
->GetNumberRows() - 1, col
,
542 ControlDown
, ShiftDown
, AltDown
, MetaDown
, sendEvent
);
545 else if ( IsInSelection ( row
, col
) )
547 m_cellSelection
.Add( wxGridCellCoords( row
, col
) );
550 if ( !m_grid
->GetBatchCount() )
552 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, col
),
553 wxGridCellCoords( row
, col
) );
554 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
560 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
561 wxEVT_GRID_RANGE_SELECT
,
563 wxGridCellCoords( row
, col
),
564 wxGridCellCoords( row
, col
),
566 ControlDown
, ShiftDown
,
568 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
572 void wxGridSelection::ToggleCellSelection( int row
, int col
,
573 bool ControlDown
, bool ShiftDown
,
574 bool AltDown
, bool MetaDown
)
576 // if the cell is not selected, select it
577 if ( !IsInSelection ( row
, col
) )
579 SelectCell( row
, col
, ControlDown
, ShiftDown
,
584 // otherwise deselect it. This can be simple or more or
585 // less difficult, depending on how the cell is selected.
588 // The simplest case: The cell is contained in m_cellSelection
589 // Then it can't be contained in rows/cols/block (since those
590 // would remove the cell from m_cellSelection on creation), so
591 // we just have to remove it from m_cellSelection.
593 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
595 count
= m_cellSelection
.GetCount();
596 for ( n
= 0; n
< count
; n
++ )
598 const wxGridCellCoords
& sel
= m_cellSelection
[n
];
599 if ( row
== sel
.GetRow() && col
== sel
.GetCol() )
601 wxGridCellCoords coords
= m_cellSelection
[n
];
602 m_cellSelection
.RemoveAt(n
);
603 if ( !m_grid
->GetBatchCount() )
605 wxRect r
= m_grid
->BlockToDeviceRect( coords
, coords
);
606 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
610 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
611 wxEVT_GRID_RANGE_SELECT
,
613 wxGridCellCoords( row
, col
),
614 wxGridCellCoords( row
, col
),
616 ControlDown
, ShiftDown
,
618 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
624 // The most difficult case: The cell is member of one or even several
625 // blocks. Split each such block in up to 4 new parts, that don't
626 // contain the cell to be selected, like this:
627 // |---------------------------|
631 // |---------------------------|
632 // | part 3 |x| part 4 |
633 // |---------------------------|
637 // |---------------------------|
638 // (The x marks the newly deselected cell).
639 // Note: in row selection mode, we only need part1 and part2;
640 // in column selection mode, we only need part 3 and part4,
641 // which are expanded to whole columns automatically!
643 count
= m_blockSelectionTopLeft
.GetCount();
644 for ( n
= 0; n
< count
; n
++ )
646 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
647 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
648 int topRow
= coords1
.GetRow();
649 int leftCol
= coords1
.GetCol();
650 int bottomRow
= coords2
.GetRow();
651 int rightCol
= coords2
.GetCol();
652 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
,
656 m_blockSelectionTopLeft
.RemoveAt(n
);
657 m_blockSelectionBottomRight
.RemoveAt(n
);
659 // add up to 4 smaller blocks and set update region
660 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
663 SelectBlock( topRow
, leftCol
, row
- 1, rightCol
,
664 false, false, false, false, false );
665 if ( bottomRow
> row
)
666 SelectBlock( row
+ 1, leftCol
, bottomRow
, rightCol
,
667 false, false, false, false, false );
669 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
672 SelectBlock( row
, leftCol
, row
, col
- 1,
673 false, false, false, false, false );
674 if ( rightCol
> col
)
675 SelectBlock( row
, col
+ 1, row
, rightCol
,
676 false, false, false, false, false );
681 // remove a cell from a row, adding up to two new blocks
682 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
684 count
= m_rowSelection
.GetCount();
685 for ( n
= 0; n
< count
; n
++ )
687 if ( m_rowSelection
[n
] == row
)
689 m_rowSelection
.RemoveAt(n
);
691 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
694 SelectBlock( row
, 0, row
, col
- 1,
695 false, false, false, false, false );
696 if ( col
< m_grid
->GetNumberCols() - 1 )
697 SelectBlock( row
, col
+ 1,
698 row
, m_grid
->GetNumberCols() - 1,
699 false, false, false, false, false );
705 // remove a cell from a column, adding up to two new blocks
706 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
708 count
= m_colSelection
.GetCount();
709 for ( n
= 0; n
< count
; n
++ )
711 if ( m_colSelection
[n
] == col
)
713 m_colSelection
.RemoveAt(n
);
715 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
718 SelectBlock( 0, col
, row
- 1, col
,
719 false, false, false, false, false );
720 if ( row
< m_grid
->GetNumberRows() - 1 )
721 SelectBlock( row
+ 1, col
,
722 m_grid
->GetNumberRows() - 1, col
,
723 false, false, false, false, false );
729 // Refresh the screen and send the event; according to m_selectionMode,
730 // we need to either update only the cell, or the whole row/column.
732 switch (m_selectionMode
)
734 case wxGrid::wxGridSelectCells
:
736 if ( !m_grid
->GetBatchCount() )
738 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, col
),
739 wxGridCellCoords( row
, col
) );
740 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
743 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
744 wxEVT_GRID_RANGE_SELECT
,
746 wxGridCellCoords( row
, col
),
747 wxGridCellCoords( row
, col
),
749 ControlDown
, ShiftDown
,
751 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
754 case wxGrid::wxGridSelectRows
:
756 if ( !m_grid
->GetBatchCount() )
758 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
759 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
760 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
763 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
764 wxEVT_GRID_RANGE_SELECT
,
766 wxGridCellCoords( row
, 0 ),
767 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ),
769 ControlDown
, ShiftDown
,
771 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
774 case wxGrid::wxGridSelectColumns
:
776 if ( !m_grid
->GetBatchCount() )
778 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
779 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
780 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
783 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
784 wxEVT_GRID_RANGE_SELECT
,
786 wxGridCellCoords( 0, col
),
787 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
),
789 ControlDown
, ShiftDown
,
791 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
797 void wxGridSelection::ClearSelection()
801 wxGridCellCoords coords1
, coords2
;
803 // deselect all individual cells and update the screen
804 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
806 while ( ( n
= m_cellSelection
.GetCount() ) > 0)
809 coords1
= m_cellSelection
[n
];
810 m_cellSelection
.RemoveAt(n
);
811 if ( !m_grid
->GetBatchCount() )
813 r
= m_grid
->BlockToDeviceRect( coords1
, coords1
);
814 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
816 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
822 // deselect all blocks and update the screen
823 while ( ( n
= m_blockSelectionTopLeft
.GetCount() ) > 0)
826 coords1
= m_blockSelectionTopLeft
[n
];
827 coords2
= m_blockSelectionBottomRight
[n
];
828 m_blockSelectionTopLeft
.RemoveAt(n
);
829 m_blockSelectionBottomRight
.RemoveAt(n
);
830 if ( !m_grid
->GetBatchCount() )
832 r
= m_grid
->BlockToDeviceRect( coords1
, coords2
);
833 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
835 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
840 // deselect all rows and update the screen
841 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
843 while ( ( n
= m_rowSelection
.GetCount() ) > 0)
846 int row
= m_rowSelection
[n
];
847 m_rowSelection
.RemoveAt(n
);
848 if ( !m_grid
->GetBatchCount() )
850 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
851 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
852 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
854 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
860 // deselect all columns and update the screen
861 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
863 while ( ( n
= m_colSelection
.GetCount() ) > 0)
866 int col
= m_colSelection
[n
];
867 m_colSelection
.RemoveAt(n
);
868 if ( !m_grid
->GetBatchCount() )
870 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
871 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
872 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
874 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
880 // One deselection event, indicating deselection of _all_ cells.
881 // (No finer grained events for each of the smaller regions
882 // deselected above!)
883 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
884 wxEVT_GRID_RANGE_SELECT
,
886 wxGridCellCoords( 0, 0 ),
887 wxGridCellCoords( m_grid
->GetNumberRows() - 1,
888 m_grid
->GetNumberCols() - 1 ),
891 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
895 void wxGridSelection::UpdateRows( size_t pos
, int numRows
)
897 size_t count
= m_cellSelection
.GetCount();
899 for ( n
= 0; n
< count
; n
++ )
901 wxGridCellCoords
& coords
= m_cellSelection
[n
];
902 wxCoord row
= coords
.GetRow();
903 if ((size_t)row
>= pos
)
907 // If rows inserted, increase row counter where necessary
908 coords
.SetRow(row
+ numRows
);
910 else if (numRows
< 0)
912 // If rows deleted ...
913 if ((size_t)row
>= pos
- numRows
)
915 // ...either decrement row counter (if row still exists)...
916 coords
.SetRow(row
+ numRows
);
920 // ...or remove the attribute
921 m_cellSelection
.RemoveAt(n
);
928 count
= m_blockSelectionTopLeft
.GetCount();
929 for ( n
= 0; n
< count
; n
++ )
931 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
932 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
933 wxCoord row1
= coords1
.GetRow();
934 wxCoord row2
= coords2
.GetRow();
935 if ((size_t)row2
>= pos
)
939 // If rows inserted, increase row counter where necessary
940 coords2
.SetRow(row2
+ numRows
);
941 if ( (size_t)row1
>= pos
)
942 coords1
.SetRow(row1
+ numRows
);
944 else if (numRows
< 0)
946 // If rows deleted ...
947 if ((size_t)row2
>= pos
- numRows
)
949 // ...either decrement row counter (if row still exists)...
950 coords2
.SetRow(row2
+ numRows
);
951 if ( (size_t) row1
>= pos
)
952 coords1
.SetRow( wxMax(row1
+ numRows
, (int) pos
) );
957 if ( (size_t) row1
>= pos
)
959 // ...or remove the attribute
960 m_blockSelectionTopLeft
.RemoveAt(n
);
961 m_blockSelectionBottomRight
.RemoveAt(n
);
971 count
= m_rowSelection
.GetCount();
972 for ( n
= 0; n
< count
; n
++ )
974 int rowOrCol_
= m_rowSelection
[ n
];
976 if ( ( size_t ) rowOrCol_
>= pos
)
980 m_rowSelection
[ n
] += numRows
;
982 else if ( numRows
< 0 )
984 if ( ( size_t ) rowOrCol_
>= ( pos
- numRows
) )
985 m_rowSelection
[ n
] += numRows
;
988 m_rowSelection
.RemoveAt ( n
);
995 // No need to touch selected columns, unless we removed _all_
996 // rows, in this case, we remove all columns from the selection.
998 if ( !m_grid
->GetNumberRows() )
999 m_colSelection
.Clear();
1003 void wxGridSelection::UpdateCols( size_t pos
, int numCols
)
1005 size_t count
= m_cellSelection
.GetCount();
1007 for ( n
= 0; n
< count
; n
++ )
1009 wxGridCellCoords
& coords
= m_cellSelection
[n
];
1010 wxCoord col
= coords
.GetCol();
1011 if ((size_t)col
>= pos
)
1015 // If rows inserted, increase row counter where necessary
1016 coords
.SetCol(col
+ numCols
);
1018 else if (numCols
< 0)
1020 // If rows deleted ...
1021 if ((size_t)col
>= pos
- numCols
)
1023 // ...either decrement row counter (if row still exists)...
1024 coords
.SetCol(col
+ numCols
);
1028 // ...or remove the attribute
1029 m_cellSelection
.RemoveAt(n
);
1036 count
= m_blockSelectionTopLeft
.GetCount();
1037 for ( n
= 0; n
< count
; n
++ )
1039 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
1040 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
1041 wxCoord col1
= coords1
.GetCol();
1042 wxCoord col2
= coords2
.GetCol();
1043 if ((size_t)col2
>= pos
)
1047 // If rows inserted, increase row counter where necessary
1048 coords2
.SetCol(col2
+ numCols
);
1049 if ( (size_t)col1
>= pos
)
1050 coords1
.SetCol(col1
+ numCols
);
1052 else if (numCols
< 0)
1054 // If cols deleted ...
1055 if ((size_t)col2
>= pos
- numCols
)
1057 // ...either decrement col counter (if col still exists)...
1058 coords2
.SetCol(col2
+ numCols
);
1059 if ( (size_t) col1
>= pos
)
1060 coords1
.SetCol( wxMax(col1
+ numCols
, (int) pos
) );
1065 if ( (size_t) col1
>= pos
)
1067 // ...or remove the attribute
1068 m_blockSelectionTopLeft
.RemoveAt(n
);
1069 m_blockSelectionBottomRight
.RemoveAt(n
);
1073 coords2
.SetCol(pos
);
1079 count
= m_colSelection
.GetCount();
1080 for ( n
= 0; n
< count
; n
++ )
1083 int rowOrCol
= m_colSelection
[ n
];
1084 if ( ( size_t ) rowOrCol
>= pos
)
1087 m_colSelection
[ n
] += numCols
;
1088 else if ( numCols
< 0 )
1090 if ( ( size_t ) rowOrCol
>= ( pos
-numCols
) )
1091 m_colSelection
[ n
] += numCols
;
1094 m_colSelection
.RemoveAt ( n
);
1103 // No need to touch selected rows, unless we removed _all_
1104 // columns, in this case, we remove all rows from the selection.
1105 if ( !m_grid
->GetNumberCols() )
1106 m_rowSelection
.Clear();
1110 int wxGridSelection::BlockContain( int topRow1
, int leftCol1
,
1111 int bottomRow1
, int rightCol1
,
1112 int topRow2
, int leftCol2
,
1113 int bottomRow2
, int rightCol2
)
1114 // returns 1, if Block1 contains Block2,
1115 // -1, if Block2 contains Block1,
1118 if ( topRow1
<= topRow2
&& bottomRow2
<= bottomRow1
&&
1119 leftCol1
<= leftCol2
&& rightCol2
<= rightCol1
)
1121 else if ( topRow2
<= topRow1
&& bottomRow1
<= bottomRow2
&&
1122 leftCol2
<= leftCol1
&& rightCol1
<= rightCol2
)