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 SelectBlock( topRow
, 0,
164 bottomRow
, m_grid
->GetNumberCols() - 1,
165 false, false, false, false, false );
168 else // selmode == wxGridSelectColumns)
170 if (topRow
!= 0 || bottomRow
!= m_grid
->GetNumberRows() - 1 )
172 m_blockSelectionTopLeft
.RemoveAt(n
);
173 m_blockSelectionBottomRight
.RemoveAt(n
);
174 SelectBlock( 0, leftCol
,
175 m_grid
->GetNumberRows() - 1, rightCol
,
176 false, false, false, false, false );
181 m_selectionMode
= selmode
;
185 void wxGridSelection::SelectRow( int row
,
186 bool ControlDown
, bool ShiftDown
,
187 bool AltDown
, bool MetaDown
)
189 if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
194 // Remove single cells contained in newly selected block.
195 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
197 count
= m_cellSelection
.GetCount();
198 for ( n
= 0; n
< count
; n
++ )
200 wxGridCellCoords
& coords
= m_cellSelection
[n
];
201 if ( BlockContainsCell( row
, 0, row
, m_grid
->GetNumberCols() - 1,
202 coords
.GetRow(), coords
.GetCol() ) )
204 m_cellSelection
.RemoveAt(n
);
211 // Simplify list of selected blocks (if possible)
212 count
= m_blockSelectionTopLeft
.GetCount();
215 for ( n
= 0; n
< count
; n
++ )
217 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
218 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
220 // Remove block if it is a subset of the row
221 if ( coords1
.GetRow() == row
&& row
== coords2
.GetRow() )
223 m_blockSelectionTopLeft
.RemoveAt(n
);
224 m_blockSelectionBottomRight
.RemoveAt(n
);
228 else if ( coords1
.GetCol() == 0 &&
229 coords2
.GetCol() == m_grid
->GetNumberCols() - 1 )
231 // silently return, if row is contained in block
232 if ( coords1
.GetRow() <= row
&& row
<= coords2
.GetRow() )
234 // expand block, if it touched row
235 else if ( coords1
.GetRow() == row
+ 1)
240 else if ( coords2
.GetRow() == row
- 1)
248 // Unless we successfully handled the row,
249 // check whether row is already selected.
252 count
= m_rowSelection
.GetCount();
253 for ( n
= 0; n
< count
; n
++ )
255 if ( row
== m_rowSelection
[n
] )
259 // Add row to selection
260 m_rowSelection
.Add(row
);
264 if ( !m_grid
->GetBatchCount() )
266 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
267 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
268 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
272 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
273 wxEVT_GRID_RANGE_SELECT
,
275 wxGridCellCoords( row
, 0 ),
276 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ),
278 ControlDown
, ShiftDown
,
281 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
284 void wxGridSelection::SelectCol( int col
,
285 bool ControlDown
, bool ShiftDown
,
286 bool AltDown
, bool MetaDown
)
288 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
292 // Remove single cells contained in newly selected block.
293 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
295 count
= m_cellSelection
.GetCount();
296 for ( n
= 0; n
< count
; n
++ )
298 wxGridCellCoords
& coords
= m_cellSelection
[n
];
299 if ( BlockContainsCell( 0, col
, m_grid
->GetNumberRows() - 1, col
,
300 coords
.GetRow(), coords
.GetCol() ) )
302 m_cellSelection
.RemoveAt(n
);
309 // Simplify list of selected blocks (if possible)
310 count
= m_blockSelectionTopLeft
.GetCount();
312 for ( n
= 0; n
< count
; n
++ )
314 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
315 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
317 // Remove block if it is a subset of the column
318 if ( coords1
.GetCol() == col
&& col
== coords2
.GetCol() )
320 m_blockSelectionTopLeft
.RemoveAt(n
);
321 m_blockSelectionBottomRight
.RemoveAt(n
);
325 else if ( coords1
.GetRow() == 0 &&
326 coords2
.GetRow() == m_grid
->GetNumberRows() - 1 )
328 // silently return, if row is contained in block
329 if ( coords1
.GetCol() <= col
&& col
<= coords2
.GetCol() )
331 // expand block, if it touched col
332 else if ( coords1
.GetCol() == col
+ 1)
337 else if ( coords2
.GetCol() == col
- 1)
345 // Unless we successfully handled the column,
346 // Check whether col is already selected.
349 count
= m_colSelection
.GetCount();
350 for ( n
= 0; n
< count
; n
++ )
352 if ( col
== m_colSelection
[n
] )
356 // Add col to selection
357 m_colSelection
.Add(col
);
361 if ( !m_grid
->GetBatchCount() )
363 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
364 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
365 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
369 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
370 wxEVT_GRID_RANGE_SELECT
,
372 wxGridCellCoords( 0, col
),
373 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
),
375 ControlDown
, ShiftDown
,
378 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
381 void wxGridSelection::SelectBlock( int topRow
, int leftCol
,
382 int bottomRow
, int rightCol
,
383 bool ControlDown
, bool ShiftDown
,
384 bool AltDown
, bool MetaDown
,
387 // Fix the coordinates of the block if needed.
388 switch ( m_selectionMode
)
391 wxFAIL_MSG( "unknown selection mode" );
394 case wxGrid::wxGridSelectCells
:
395 // nothing to do -- in this mode arbitrary blocks can be selected
398 case wxGrid::wxGridSelectRows
:
400 rightCol
= m_grid
->GetNumberCols() - 1;
403 case wxGrid::wxGridSelectColumns
:
405 bottomRow
= m_grid
->GetNumberRows() - 1;
408 case wxGrid::wxGridSelectRowsOrColumns
:
409 // block selection doesn't make sense for this mode, we could only
410 // select the entire grid but this wouldn't be useful
414 if ( topRow
> bottomRow
)
421 if ( leftCol
> rightCol
)
428 // Handle single cell selection in SelectCell.
429 // (MB: added check for selection mode here to prevent
430 // crashes if, for example, we are select rows and the
431 // grid only has 1 col)
432 if ( m_selectionMode
== wxGrid::wxGridSelectCells
&&
433 topRow
== bottomRow
&& leftCol
== rightCol
)
435 SelectCell( topRow
, leftCol
, ControlDown
, ShiftDown
,
436 AltDown
, MetaDown
, sendEvent
);
441 // Remove single cells contained in newly selected block.
442 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
444 count
= m_cellSelection
.GetCount();
445 for ( n
= 0; n
< count
; n
++ )
447 wxGridCellCoords
& coords
= m_cellSelection
[n
];
448 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
,
449 coords
.GetRow(), coords
.GetCol() ) )
451 m_cellSelection
.RemoveAt(n
);
458 // If a block containing the selection is already selected, return,
459 // if a block contained in the selection is found, remove it.
461 count
= m_blockSelectionTopLeft
.GetCount();
462 for ( n
= 0; n
< count
; n
++ )
464 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
465 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
467 switch ( BlockContain( coords1
.GetRow(), coords1
.GetCol(),
468 coords2
.GetRow(), coords2
.GetCol(),
469 topRow
, leftCol
, bottomRow
, rightCol
) )
475 m_blockSelectionTopLeft
.RemoveAt(n
);
476 m_blockSelectionBottomRight
.RemoveAt(n
);
486 // If a row containing the selection is already selected, return,
487 // if a row contained in newly selected block is found, remove it.
488 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
490 count
= m_rowSelection
.GetCount();
491 for ( n
= 0; n
< count
; n
++ )
493 switch ( BlockContain( m_rowSelection
[n
], 0,
494 m_rowSelection
[n
], m_grid
->GetNumberCols() - 1,
495 topRow
, leftCol
, bottomRow
, rightCol
) )
501 m_rowSelection
.RemoveAt(n
);
512 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
514 count
= m_colSelection
.GetCount();
515 for ( n
= 0; n
< count
; n
++ )
517 switch ( BlockContain( 0, m_colSelection
[n
],
518 m_grid
->GetNumberRows() - 1, m_colSelection
[n
],
519 topRow
, leftCol
, bottomRow
, rightCol
) )
525 m_colSelection
.RemoveAt(n
);
536 m_blockSelectionTopLeft
.Add( wxGridCellCoords( topRow
, leftCol
) );
537 m_blockSelectionBottomRight
.Add( wxGridCellCoords( bottomRow
, rightCol
) );
540 if ( !m_grid
->GetBatchCount() )
542 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( topRow
, leftCol
),
543 wxGridCellCoords( bottomRow
, rightCol
) );
544 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
547 // Send Event, if not disabled.
550 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
551 wxEVT_GRID_RANGE_SELECT
,
553 wxGridCellCoords( topRow
, leftCol
),
554 wxGridCellCoords( bottomRow
, rightCol
),
556 ControlDown
, ShiftDown
,
558 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
562 void wxGridSelection::SelectCell( int row
, int col
,
563 bool ControlDown
, bool ShiftDown
,
564 bool AltDown
, bool MetaDown
,
567 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
569 SelectBlock(row
, 0, row
, m_grid
->GetNumberCols() - 1,
570 ControlDown
, ShiftDown
, AltDown
, MetaDown
, sendEvent
);
574 else if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
576 SelectBlock(0, col
, m_grid
->GetNumberRows() - 1, col
,
577 ControlDown
, ShiftDown
, AltDown
, MetaDown
, sendEvent
);
581 else if ( IsInSelection ( row
, col
) )
584 m_cellSelection
.Add( wxGridCellCoords( row
, col
) );
587 if ( !m_grid
->GetBatchCount() )
589 wxRect r
= m_grid
->BlockToDeviceRect(
590 wxGridCellCoords( row
, col
),
591 wxGridCellCoords( row
, col
) );
592 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
598 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
599 wxEVT_GRID_RANGE_SELECT
,
601 wxGridCellCoords( row
, col
),
602 wxGridCellCoords( row
, col
),
604 ControlDown
, ShiftDown
,
606 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
610 void wxGridSelection::ToggleCellSelection( int row
, int col
,
611 bool ControlDown
, bool ShiftDown
,
612 bool AltDown
, bool MetaDown
)
614 // if the cell is not selected, select it
615 if ( !IsInSelection ( row
, col
) )
617 SelectCell( row
, col
, ControlDown
, ShiftDown
, AltDown
, MetaDown
);
622 // otherwise deselect it. This can be simple or more or
623 // less difficult, depending on how the cell is selected.
626 // The simplest case: The cell is contained in m_cellSelection
627 // Then it can't be contained in rows/cols/block (since those
628 // would remove the cell from m_cellSelection on creation), so
629 // we just have to remove it from m_cellSelection.
631 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
633 count
= m_cellSelection
.GetCount();
634 for ( n
= 0; n
< count
; n
++ )
636 const wxGridCellCoords
& sel
= m_cellSelection
[n
];
637 if ( row
== sel
.GetRow() && col
== sel
.GetCol() )
639 wxGridCellCoords coords
= m_cellSelection
[n
];
640 m_cellSelection
.RemoveAt(n
);
641 if ( !m_grid
->GetBatchCount() )
643 wxRect r
= m_grid
->BlockToDeviceRect( coords
, coords
);
644 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
648 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
649 wxEVT_GRID_RANGE_SELECT
,
651 wxGridCellCoords( row
, col
),
652 wxGridCellCoords( row
, col
),
654 ControlDown
, ShiftDown
,
656 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
663 // The most difficult case: The cell is member of one or even several
664 // blocks. Split each such block in up to 4 new parts, that don't
665 // contain the cell to be selected, like this:
666 // |---------------------------|
670 // |---------------------------|
671 // | part 3 |x| part 4 |
672 // |---------------------------|
676 // |---------------------------|
677 // (The x marks the newly deselected cell).
678 // Note: in row selection mode, we only need part1 and part2;
679 // in column selection mode, we only need part 3 and part4,
680 // which are expanded to whole columns automatically!
682 count
= m_blockSelectionTopLeft
.GetCount();
683 for ( n
= 0; n
< count
; n
++ )
685 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
686 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
687 int topRow
= coords1
.GetRow();
688 int leftCol
= coords1
.GetCol();
689 int bottomRow
= coords2
.GetRow();
690 int rightCol
= coords2
.GetCol();
692 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
, row
, col
) )
695 m_blockSelectionTopLeft
.RemoveAt(n
);
696 m_blockSelectionBottomRight
.RemoveAt(n
);
700 // add up to 4 smaller blocks and set update region
701 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
704 SelectBlock( topRow
, leftCol
, row
- 1, rightCol
,
705 false, false, false, false, false );
706 if ( bottomRow
> row
)
707 SelectBlock( row
+ 1, leftCol
, bottomRow
, rightCol
,
708 false, false, false, false, false );
711 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
714 SelectBlock( row
, leftCol
, row
, col
- 1,
715 false, false, false, false, false );
716 if ( rightCol
> col
)
717 SelectBlock( row
, col
+ 1, row
, rightCol
,
718 false, false, false, false, false );
723 // remove a cell from a row, adding up to two new blocks
724 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
726 count
= m_rowSelection
.GetCount();
727 for ( n
= 0; n
< count
; n
++ )
729 if ( m_rowSelection
[n
] == row
)
731 m_rowSelection
.RemoveAt(n
);
735 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
738 SelectBlock( row
, 0, row
, col
- 1,
739 false, false, false, false, false );
740 if ( col
< m_grid
->GetNumberCols() - 1 )
741 SelectBlock( row
, col
+ 1,
742 row
, m_grid
->GetNumberCols() - 1,
743 false, false, false, false, false );
749 // remove a cell from a column, adding up to two new blocks
750 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
752 count
= m_colSelection
.GetCount();
753 for ( n
= 0; n
< count
; n
++ )
755 if ( m_colSelection
[n
] == col
)
757 m_colSelection
.RemoveAt(n
);
761 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
764 SelectBlock( 0, col
, row
- 1, col
,
765 false, false, false, false, false );
766 if ( row
< m_grid
->GetNumberRows() - 1 )
767 SelectBlock( row
+ 1, col
,
768 m_grid
->GetNumberRows() - 1, col
,
769 false, false, false, false, false );
775 // Refresh the screen and send the event; according to m_selectionMode,
776 // we need to either update only the cell, or the whole row/column.
778 switch (m_selectionMode
)
780 case wxGrid::wxGridSelectCells
:
782 if ( !m_grid
->GetBatchCount() )
784 r
= m_grid
->BlockToDeviceRect(
785 wxGridCellCoords( row
, col
),
786 wxGridCellCoords( row
, col
) );
787 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
790 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
791 wxEVT_GRID_RANGE_SELECT
,
793 wxGridCellCoords( row
, col
),
794 wxGridCellCoords( row
, col
),
796 ControlDown
, ShiftDown
,
798 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
802 case wxGrid::wxGridSelectRows
:
804 if ( !m_grid
->GetBatchCount() )
806 r
= m_grid
->BlockToDeviceRect(
807 wxGridCellCoords( row
, 0 ),
808 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
809 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
812 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
813 wxEVT_GRID_RANGE_SELECT
,
815 wxGridCellCoords( row
, 0 ),
816 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ),
818 ControlDown
, ShiftDown
,
820 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
824 case wxGrid::wxGridSelectColumns
:
826 if ( !m_grid
->GetBatchCount() )
828 r
= m_grid
->BlockToDeviceRect(
829 wxGridCellCoords( 0, col
),
830 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
831 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
834 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
835 wxEVT_GRID_RANGE_SELECT
,
837 wxGridCellCoords( 0, col
),
838 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
),
840 ControlDown
, ShiftDown
,
842 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
851 void wxGridSelection::ClearSelection()
855 wxGridCellCoords coords1
, coords2
;
857 // deselect all individual cells and update the screen
858 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
860 while ( ( n
= m_cellSelection
.GetCount() ) > 0)
863 coords1
= m_cellSelection
[n
];
864 m_cellSelection
.RemoveAt(n
);
865 if ( !m_grid
->GetBatchCount() )
867 r
= m_grid
->BlockToDeviceRect( coords1
, coords1
);
868 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
871 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
877 // deselect all blocks and update the screen
878 while ( ( n
= m_blockSelectionTopLeft
.GetCount() ) > 0)
881 coords1
= m_blockSelectionTopLeft
[n
];
882 coords2
= m_blockSelectionBottomRight
[n
];
883 m_blockSelectionTopLeft
.RemoveAt(n
);
884 m_blockSelectionBottomRight
.RemoveAt(n
);
885 if ( !m_grid
->GetBatchCount() )
887 r
= m_grid
->BlockToDeviceRect( coords1
, coords2
);
888 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
891 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
896 // deselect all rows and update the screen
897 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
899 while ( ( n
= m_rowSelection
.GetCount() ) > 0)
902 int row
= m_rowSelection
[n
];
903 m_rowSelection
.RemoveAt(n
);
904 if ( !m_grid
->GetBatchCount() )
906 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
907 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
908 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
911 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
917 // deselect all columns and update the screen
918 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
920 while ( ( n
= m_colSelection
.GetCount() ) > 0)
923 int col
= m_colSelection
[n
];
924 m_colSelection
.RemoveAt(n
);
925 if ( !m_grid
->GetBatchCount() )
927 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
928 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
929 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
932 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
938 // One deselection event, indicating deselection of _all_ cells.
939 // (No finer grained events for each of the smaller regions
940 // deselected above!)
941 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
942 wxEVT_GRID_RANGE_SELECT
,
944 wxGridCellCoords( 0, 0 ),
946 m_grid
->GetNumberRows() - 1,
947 m_grid
->GetNumberCols() - 1 ),
950 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
954 void wxGridSelection::UpdateRows( size_t pos
, int numRows
)
956 size_t count
= m_cellSelection
.GetCount();
958 for ( n
= 0; n
< count
; n
++ )
960 wxGridCellCoords
& coords
= m_cellSelection
[n
];
961 wxCoord row
= coords
.GetRow();
962 if ((size_t)row
>= pos
)
966 // If rows inserted, increase row counter where necessary
967 coords
.SetRow(row
+ numRows
);
969 else if (numRows
< 0)
971 // If rows deleted ...
972 if ((size_t)row
>= pos
- numRows
)
974 // ...either decrement row counter (if row still exists)...
975 coords
.SetRow(row
+ numRows
);
979 // ...or remove the attribute
980 m_cellSelection
.RemoveAt(n
);
988 count
= m_blockSelectionTopLeft
.GetCount();
989 for ( n
= 0; n
< count
; n
++ )
991 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
992 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
993 wxCoord row1
= coords1
.GetRow();
994 wxCoord row2
= coords2
.GetRow();
996 if ((size_t)row2
>= pos
)
1000 // If rows inserted, increase row counter where necessary
1001 coords2
.SetRow( row2
+ numRows
);
1002 if ((size_t)row1
>= pos
)
1003 coords1
.SetRow( row1
+ numRows
);
1005 else if (numRows
< 0)
1007 // If rows deleted ...
1008 if ((size_t)row2
>= pos
- numRows
)
1010 // ...either decrement row counter (if row still exists)...
1011 coords2
.SetRow( row2
+ numRows
);
1012 if ((size_t)row1
>= pos
)
1013 coords1
.SetRow( wxMax(row1
+ numRows
, (int)pos
) );
1018 if ((size_t)row1
>= pos
)
1020 // ...or remove the attribute
1021 m_blockSelectionTopLeft
.RemoveAt(n
);
1022 m_blockSelectionBottomRight
.RemoveAt(n
);
1027 coords2
.SetRow( pos
);
1033 count
= m_rowSelection
.GetCount();
1034 for ( n
= 0; n
< count
; n
++ )
1036 int rowOrCol_
= m_rowSelection
[n
];
1038 if ((size_t) rowOrCol_
>= pos
)
1042 m_rowSelection
[n
] += numRows
;
1044 else if ( numRows
< 0 )
1046 if ((size_t)rowOrCol_
>= (pos
- numRows
))
1047 m_rowSelection
[n
] += numRows
;
1050 m_rowSelection
.RemoveAt( n
);
1057 // No need to touch selected columns, unless we removed _all_
1058 // rows, in this case, we remove all columns from the selection.
1060 if ( !m_grid
->GetNumberRows() )
1061 m_colSelection
.Clear();
1065 void wxGridSelection::UpdateCols( size_t pos
, int numCols
)
1067 size_t count
= m_cellSelection
.GetCount();
1070 for ( n
= 0; n
< count
; n
++ )
1072 wxGridCellCoords
& coords
= m_cellSelection
[n
];
1073 wxCoord col
= coords
.GetCol();
1074 if ((size_t)col
>= pos
)
1078 // If rows inserted, increase row counter where necessary
1079 coords
.SetCol(col
+ numCols
);
1081 else if (numCols
< 0)
1083 // If rows deleted ...
1084 if ((size_t)col
>= pos
- numCols
)
1086 // ...either decrement row counter (if row still exists)...
1087 coords
.SetCol(col
+ numCols
);
1091 // ...or remove the attribute
1092 m_cellSelection
.RemoveAt(n
);
1100 count
= m_blockSelectionTopLeft
.GetCount();
1101 for ( n
= 0; n
< count
; n
++ )
1103 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
1104 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
1105 wxCoord col1
= coords1
.GetCol();
1106 wxCoord col2
= coords2
.GetCol();
1108 if ((size_t)col2
>= pos
)
1112 // If rows inserted, increase row counter where necessary
1113 coords2
.SetCol(col2
+ numCols
);
1114 if ((size_t)col1
>= pos
)
1115 coords1
.SetCol(col1
+ numCols
);
1117 else if (numCols
< 0)
1119 // If cols deleted ...
1120 if ((size_t)col2
>= pos
- numCols
)
1122 // ...either decrement col counter (if col still exists)...
1123 coords2
.SetCol(col2
+ numCols
);
1124 if ( (size_t) col1
>= pos
)
1125 coords1
.SetCol( wxMax(col1
+ numCols
, (int)pos
) );
1130 if ((size_t)col1
>= pos
)
1132 // ...or remove the attribute
1133 m_blockSelectionTopLeft
.RemoveAt(n
);
1134 m_blockSelectionBottomRight
.RemoveAt(n
);
1139 coords2
.SetCol(pos
);
1145 count
= m_colSelection
.GetCount();
1146 for ( n
= 0; n
< count
; n
++ )
1148 int rowOrCol
= m_colSelection
[n
];
1150 if ((size_t)rowOrCol
>= pos
)
1153 m_colSelection
[n
] += numCols
;
1154 else if ( numCols
< 0 )
1156 if ((size_t)rowOrCol
>= (pos
- numCols
))
1157 m_colSelection
[n
] += numCols
;
1160 m_colSelection
.RemoveAt( n
);
1168 // No need to touch selected rows, unless we removed _all_
1169 // columns, in this case, we remove all rows from the selection.
1170 if ( !m_grid
->GetNumberCols() )
1171 m_rowSelection
.Clear();
1174 int wxGridSelection::BlockContain( int topRow1
, int leftCol1
,
1175 int bottomRow1
, int rightCol1
,
1176 int topRow2
, int leftCol2
,
1177 int bottomRow2
, int rightCol2
)
1178 // returns 1, if Block1 contains Block2,
1179 // -1, if Block2 contains Block1,
1182 if ( topRow1
<= topRow2
&& bottomRow2
<= bottomRow1
&&
1183 leftCol1
<= leftCol2
&& rightCol2
<= rightCol1
)
1185 else if ( topRow2
<= topRow1
&& bottomRow1
<= bottomRow2
&&
1186 leftCol2
<= leftCol1
&& rightCol1
<= rightCol2
)