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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "gridsel.h"
24 // For compilers that support precompilation, includes "wx/wx.h".
25 #include "wx/wxprec.h"
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,
168 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
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
,
179 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
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
, sendEvent
);
528 else if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
530 SelectBlock(0, col
, m_grid
->GetNumberRows() - 1, col
,
531 ControlDown
, ShiftDown
, AltDown
, MetaDown
, sendEvent
);
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
);
592 if ( !m_grid
->GetBatchCount() )
593 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
596 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
597 wxEVT_GRID_RANGE_SELECT
,
599 wxGridCellCoords( row
, col
),
600 wxGridCellCoords( row
, col
),
602 ControlDown
, ShiftDown
,
604 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
610 // The most difficult case: The cell is member of one or even several
611 // blocks. Split each such block in up to 4 new parts, that don't
612 // contain the cell to be selected, like this:
613 // |---------------------------|
617 // |---------------------------|
618 // | part 3 |x| part 4 |
619 // |---------------------------|
623 // |---------------------------|
624 // (The x marks the newly deselected cell).
625 // Note: in row selection mode, we only need part1 and part2;
626 // in column selection mode, we only need part 3 and part4,
627 // which are expanded to whole columns automatically!
629 count
= m_blockSelectionTopLeft
.GetCount();
630 for ( n
= 0; n
< count
; n
++ )
632 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
633 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
634 int topRow
= coords1
.GetRow();
635 int leftCol
= coords1
.GetCol();
636 int bottomRow
= coords2
.GetRow();
637 int rightCol
= coords2
.GetCol();
638 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
,
642 m_blockSelectionTopLeft
.RemoveAt(n
);
643 m_blockSelectionBottomRight
.RemoveAt(n
);
645 // add up to 4 smaller blocks and set update region
646 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
649 SelectBlock( topRow
, leftCol
, row
- 1, rightCol
,
650 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
651 if ( bottomRow
> row
)
652 SelectBlock( row
+ 1, leftCol
, bottomRow
, rightCol
,
653 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
655 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
658 SelectBlock( row
, leftCol
, row
, col
- 1,
659 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
660 if ( rightCol
> col
)
661 SelectBlock( row
, col
+ 1, row
, rightCol
,
662 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
667 // remove a cell from a row, adding up to two new blocks
668 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
670 count
= m_rowSelection
.GetCount();
671 for ( n
= 0; n
< count
; n
++ )
673 if ( m_rowSelection
[n
] == row
)
675 m_rowSelection
.RemoveAt(n
);
677 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
680 SelectBlock( row
, 0, row
, col
- 1,
681 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
682 if ( col
< m_grid
->GetNumberCols() - 1 )
683 SelectBlock( row
, col
+ 1,
684 row
, m_grid
->GetNumberCols() - 1,
685 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
691 // remove a cell from a column, adding up to two new blocks
692 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
694 count
= m_colSelection
.GetCount();
695 for ( n
= 0; n
< count
; n
++ )
697 if ( m_colSelection
[n
] == col
)
699 m_colSelection
.RemoveAt(n
);
701 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
704 SelectBlock( 0, col
, row
- 1, col
,
705 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
706 if ( row
< m_grid
->GetNumberRows() - 1 )
707 SelectBlock( row
+ 1, col
,
708 m_grid
->GetNumberRows() - 1, col
,
709 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
);
715 // Refresh the screen and send the event; according to m_selectionMode,
716 // we need to either update only the cell, or the whole row/column.
718 switch (m_selectionMode
)
720 case wxGrid::wxGridSelectCells
:
722 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, col
),
723 wxGridCellCoords( row
, col
) );
724 if ( !m_grid
->GetBatchCount() )
725 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
726 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
727 wxEVT_GRID_RANGE_SELECT
,
729 wxGridCellCoords( row
, col
),
730 wxGridCellCoords( row
, col
),
732 ControlDown
, ShiftDown
,
734 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
737 case wxGrid::wxGridSelectRows
:
739 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
740 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
741 if ( !m_grid
->GetBatchCount() )
742 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
743 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
744 wxEVT_GRID_RANGE_SELECT
,
746 wxGridCellCoords( row
, 0 ),
747 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ),
749 ControlDown
, ShiftDown
,
751 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
754 case wxGrid::wxGridSelectColumns
:
756 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
757 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
758 if ( !m_grid
->GetBatchCount() )
759 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
760 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
761 wxEVT_GRID_RANGE_SELECT
,
763 wxGridCellCoords( 0, col
),
764 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
),
766 ControlDown
, ShiftDown
,
768 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
774 void wxGridSelection::ClearSelection()
778 // deselect all invidiual cells and update the screen
779 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
782 while( ( n
= m_cellSelection
.GetCount() ) > 0)
786 r
= m_grid
->BlockToDeviceRect( m_cellSelection
[n
],
787 m_cellSelection
[n
] );
788 m_cellSelection
.RemoveAt(n
);
789 if ( !m_grid
->GetBatchCount() )
790 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
794 // deselect all blocks and update the screen
795 while( ( n
= m_blockSelectionTopLeft
.GetCount() ) > 0)
799 r
= m_grid
->BlockToDeviceRect( m_blockSelectionTopLeft
[n
],
800 m_blockSelectionBottomRight
[n
] );
801 m_blockSelectionTopLeft
.RemoveAt(n
);
802 m_blockSelectionBottomRight
.RemoveAt(n
);
803 if ( !m_grid
->GetBatchCount() )
804 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
807 // deselect all rows and update the screen
808 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
810 while( ( n
= m_rowSelection
.GetCount() ) > 0)
813 int & row
= m_rowSelection
[n
];
815 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
816 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
817 m_rowSelection
.RemoveAt(n
);
818 if ( !m_grid
->GetBatchCount() )
819 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
823 // deselect all columns and update the screen
824 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
826 while( ( n
= m_colSelection
.GetCount() ) > 0)
829 int & col
= m_colSelection
[n
];
831 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
832 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
833 m_colSelection
.RemoveAt(n
);
834 if ( !m_grid
->GetBatchCount() )
835 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( FALSE
, &r
);
839 // One deselection event, indicating deselection of _all_ cells.
840 // (No finer grained events for each of the smaller regions
841 // deselected above!)
842 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
843 wxEVT_GRID_RANGE_SELECT
,
845 wxGridCellCoords( 0, 0 ),
846 wxGridCellCoords( m_grid
->GetNumberRows() - 1,
847 m_grid
->GetNumberCols() - 1 ),
850 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
854 void wxGridSelection::UpdateRows( size_t pos
, int numRows
)
856 size_t count
= m_cellSelection
.GetCount();
858 for ( n
= 0; n
< count
; n
++ )
860 wxGridCellCoords
& coords
= m_cellSelection
[n
];
861 wxCoord row
= coords
.GetRow();
862 if ((size_t)row
>= pos
)
866 // If rows inserted, increase row counter where necessary
867 coords
.SetRow(row
+ numRows
);
869 else if (numRows
< 0)
871 // If rows deleted ...
872 if ((size_t)row
>= pos
- numRows
)
874 // ...either decrement row counter (if row still exists)...
875 coords
.SetRow(row
+ numRows
);
879 // ...or remove the attribute
880 m_cellSelection
.RemoveAt(n
);
887 count
= m_blockSelectionTopLeft
.GetCount();
888 for ( n
= 0; n
< count
; n
++ )
890 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
891 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
892 wxCoord row1
= coords1
.GetRow();
893 wxCoord row2
= coords2
.GetRow();
894 if ((size_t)row2
>= pos
)
898 // If rows inserted, increase row counter where necessary
899 coords2
.SetRow(row2
+ numRows
);
900 if ( (size_t)row1
>= pos
)
901 coords1
.SetRow(row1
+ numRows
);
903 else if (numRows
< 0)
905 // If rows deleted ...
906 if ((size_t)row2
>= pos
- numRows
)
908 // ...either decrement row counter (if row still exists)...
909 coords2
.SetRow(row2
+ numRows
);
910 if ( (size_t) row1
>= pos
)
911 coords1
.SetRow( wxMax(row1
+ numRows
, (int) pos
) );
916 if ( (size_t) row1
>= pos
)
918 // ...or remove the attribute
919 m_blockSelectionTopLeft
.RemoveAt(n
);
920 m_blockSelectionBottomRight
.RemoveAt(n
);
930 count
= m_rowSelection
.GetCount();
931 for ( n
= 0; n
< count
; n
++ )
933 int rowOrCol_
= m_rowSelection
[ n
];
935 if ( ( size_t ) rowOrCol_
>= pos
)
939 m_rowSelection
[ n
] += numRows
;
941 else if ( numRows
< 0 )
943 if ( ( size_t ) rowOrCol_
>= ( pos
- numRows
) )
944 m_rowSelection
[ n
] += numRows
;
947 m_rowSelection
.RemoveAt ( n
);
954 // No need to touch selected columns, unless we removed _all_
955 // rows, in this case, we remove all columns from the selection.
957 if ( !m_grid
->GetNumberRows() )
958 m_colSelection
.Clear();
962 void wxGridSelection::UpdateCols( size_t pos
, int numCols
)
964 size_t count
= m_cellSelection
.GetCount();
966 for ( n
= 0; n
< count
; n
++ )
968 wxGridCellCoords
& coords
= m_cellSelection
[n
];
969 wxCoord col
= coords
.GetCol();
970 if ((size_t)col
>= pos
)
974 // If rows inserted, increase row counter where necessary
975 coords
.SetCol(col
+ numCols
);
977 else if (numCols
< 0)
979 // If rows deleted ...
980 if ((size_t)col
>= pos
- numCols
)
982 // ...either decrement row counter (if row still exists)...
983 coords
.SetCol(col
+ numCols
);
987 // ...or remove the attribute
988 m_cellSelection
.RemoveAt(n
);
995 count
= m_blockSelectionTopLeft
.GetCount();
996 for ( n
= 0; n
< count
; n
++ )
998 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
999 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
1000 wxCoord col1
= coords1
.GetCol();
1001 wxCoord col2
= coords2
.GetCol();
1002 if ((size_t)col2
>= pos
)
1006 // If rows inserted, increase row counter where necessary
1007 coords2
.SetCol(col2
+ numCols
);
1008 if ( (size_t)col1
>= pos
)
1009 coords1
.SetCol(col1
+ numCols
);
1011 else if (numCols
< 0)
1013 // If cols deleted ...
1014 if ((size_t)col2
>= pos
- numCols
)
1016 // ...either decrement col counter (if col still exists)...
1017 coords2
.SetCol(col2
+ numCols
);
1018 if ( (size_t) col1
>= pos
)
1019 coords1
.SetCol( wxMax(col1
+ numCols
, (int) pos
) );
1024 if ( (size_t) col1
>= pos
)
1026 // ...or remove the attribute
1027 m_blockSelectionTopLeft
.RemoveAt(n
);
1028 m_blockSelectionBottomRight
.RemoveAt(n
);
1032 coords2
.SetCol(pos
);
1038 count
= m_colSelection
.GetCount();
1039 for ( n
= 0; n
< count
; n
++ )
1042 int rowOrCol
= m_colSelection
[ n
];
1043 if ( ( size_t ) rowOrCol
>= pos
)
1046 m_colSelection
[ n
] += numCols
;
1047 else if ( numCols
< 0 )
1049 if ( ( size_t ) rowOrCol
>= ( pos
-numCols
) )
1050 m_colSelection
[ n
] += numCols
;
1053 m_colSelection
.RemoveAt ( n
);
1062 // No need to touch selected rows, unless we removed _all_
1063 // columns, in this case, we remove all rows from the selection.
1064 if ( !m_grid
->GetNumberCols() )
1065 m_rowSelection
.Clear();
1069 int wxGridSelection::BlockContain( int topRow1
, int leftCol1
,
1070 int bottomRow1
, int rightCol1
,
1071 int topRow2
, int leftCol2
,
1072 int bottomRow2
, int rightCol2
)
1073 // returns 1, if Block1 contains Block2,
1074 // -1, if Block2 contains Block1,
1077 if ( topRow1
<= topRow2
&& bottomRow2
<= bottomRow1
&&
1078 leftCol1
<= leftCol2
&& rightCol2
<= rightCol1
)
1080 else if ( topRow2
<= topRow1
&& bottomRow1
<= bottomRow2
&&
1081 leftCol2
<= leftCol1
&& rightCol1
<= rightCol2
)