1 ///////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/gridsel.cpp
3 // Purpose: wxGridSelection
7 // Copyright: (c) Stefan Neis (Stefan.Neis@t-online.de)
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
18 // ============================================================================
20 // ============================================================================
22 // ----------------------------------------------------------------------------
24 // ----------------------------------------------------------------------------
28 #include "wx/generic/gridsel.h"
31 // Some explanation for the members of the class:
32 // m_cellSelection stores individual selected cells
33 // -- this is only used if m_selectionMode == wxGridSelectCells
34 // m_blockSelectionTopLeft and m_blockSelectionBottomRight
35 // store the upper left and lower right corner of selected Blocks
36 // m_rowSelection and m_colSelection store individual selected
37 // rows and columns; maybe those are superfluous and should be
40 wxGridSelection::wxGridSelection( wxGrid
* grid
,
41 wxGrid::wxGridSelectionModes sel
)
44 m_selectionMode
= sel
;
47 bool wxGridSelection::IsSelection()
49 return ( m_cellSelection
.GetCount() || m_blockSelectionTopLeft
.GetCount() ||
50 m_rowSelection
.GetCount() || m_colSelection
.GetCount() );
53 bool wxGridSelection::IsInSelection( int row
, int col
)
57 // First check whether the given cell is individually selected
58 // (if m_selectionMode is wxGridSelectCells).
59 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
61 count
= m_cellSelection
.GetCount();
62 for ( size_t n
= 0; n
< count
; n
++ )
64 wxGridCellCoords
& coords
= m_cellSelection
[n
];
65 if ( row
== coords
.GetRow() && col
== coords
.GetCol() )
70 // Now check whether the given cell is
71 // contained in one of the selected blocks.
72 count
= m_blockSelectionTopLeft
.GetCount();
73 for ( size_t n
= 0; n
< count
; n
++ )
75 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
76 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
77 if ( BlockContainsCell(coords1
.GetRow(), coords1
.GetCol(),
78 coords2
.GetRow(), coords2
.GetCol(),
83 // Now check whether the given cell is
84 // contained in one of the selected rows
85 // (unless we are in column selection mode).
86 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
88 count
= m_rowSelection
.GetCount();
89 for ( size_t n
= 0; n
< count
; n
++ )
91 if ( row
== m_rowSelection
[n
] )
96 // Now check whether the given cell is
97 // contained in one of the selected columns
98 // (unless we are in row selection mode).
99 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
101 count
= m_colSelection
.GetCount();
102 for ( size_t n
= 0; n
< count
; n
++ )
104 if ( col
== m_colSelection
[n
] )
112 // Change the selection mode
113 void wxGridSelection::SetSelectionMode( wxGrid::wxGridSelectionModes selmode
)
115 // if selection mode is unchanged return immediately
116 if (selmode
== m_selectionMode
)
119 if ( m_selectionMode
!= wxGrid::wxGridSelectCells
)
121 // if changing form row to column selection
122 // or vice versa, clear the selection.
123 if ( selmode
!= wxGrid::wxGridSelectCells
)
126 m_selectionMode
= selmode
;
130 // if changing from cell selection to something else,
131 // promote selected cells/blocks to whole rows/columns.
133 while ( ( n
= m_cellSelection
.GetCount() ) > 0 )
136 wxGridCellCoords
& coords
= m_cellSelection
[n
];
137 int row
= coords
.GetRow();
138 int col
= coords
.GetCol();
139 m_cellSelection
.RemoveAt(n
);
140 if (selmode
== wxGrid::wxGridSelectRows
)
142 else // selmode == wxGridSelectColumns)
146 // Note that m_blockSelectionTopLeft's size may be changing!
147 for (n
= 0; n
< m_blockSelectionTopLeft
.GetCount(); n
++)
149 wxGridCellCoords
& coords
= m_blockSelectionTopLeft
[n
];
150 int topRow
= coords
.GetRow();
151 int leftCol
= coords
.GetCol();
152 coords
= m_blockSelectionBottomRight
[n
];
153 int bottomRow
= coords
.GetRow();
154 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 SelectBlockNoEvent( topRow
, 0,
163 bottomRow
, m_grid
->GetNumberCols() - 1);
166 else // selmode == wxGridSelectColumns)
168 if (topRow
!= 0 || bottomRow
!= m_grid
->GetNumberRows() - 1 )
170 m_blockSelectionTopLeft
.RemoveAt(n
);
171 m_blockSelectionBottomRight
.RemoveAt(n
);
172 SelectBlockNoEvent(0, leftCol
,
173 m_grid
->GetNumberRows() - 1, rightCol
);
178 m_selectionMode
= selmode
;
182 void wxGridSelection::SelectRow(int row
, const wxKeyboardState
& kbd
)
184 if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
189 // Remove single cells contained in newly selected block.
190 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
192 count
= m_cellSelection
.GetCount();
193 for ( n
= 0; n
< count
; n
++ )
195 wxGridCellCoords
& coords
= m_cellSelection
[n
];
196 if ( BlockContainsCell( row
, 0, row
, m_grid
->GetNumberCols() - 1,
197 coords
.GetRow(), coords
.GetCol() ) )
199 m_cellSelection
.RemoveAt(n
);
206 // Simplify list of selected blocks (if possible)
207 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
);
223 else if ( coords1
.GetCol() == 0 &&
224 coords2
.GetCol() == m_grid
->GetNumberCols() - 1 )
226 // silently return, if row is contained in block
227 if ( coords1
.GetRow() <= row
&& row
<= coords2
.GetRow() )
229 // expand block, if it touched row
230 else if ( coords1
.GetRow() == row
+ 1)
235 else if ( coords2
.GetRow() == row
- 1)
243 // Unless we successfully handled the row,
244 // check whether row is already selected.
247 count
= m_rowSelection
.GetCount();
248 for ( n
= 0; n
< count
; n
++ )
250 if ( row
== m_rowSelection
[n
] )
254 // Add row to selection
255 m_rowSelection
.Add(row
);
259 if ( !m_grid
->GetBatchCount() )
261 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
262 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
263 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
267 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
268 wxEVT_GRID_RANGE_SELECT
,
270 wxGridCellCoords( row
, 0 ),
271 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ),
275 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
278 void wxGridSelection::SelectCol(int col
, const wxKeyboardState
& kbd
)
280 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
284 // Remove single cells contained in newly selected block.
285 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
287 count
= m_cellSelection
.GetCount();
288 for ( n
= 0; n
< count
; n
++ )
290 wxGridCellCoords
& coords
= m_cellSelection
[n
];
291 if ( BlockContainsCell( 0, col
, m_grid
->GetNumberRows() - 1, col
,
292 coords
.GetRow(), coords
.GetCol() ) )
294 m_cellSelection
.RemoveAt(n
);
301 // Simplify list of selected blocks (if possible)
302 count
= m_blockSelectionTopLeft
.GetCount();
304 for ( n
= 0; n
< count
; n
++ )
306 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
307 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
309 // Remove block if it is a subset of the column
310 if ( coords1
.GetCol() == col
&& col
== coords2
.GetCol() )
312 m_blockSelectionTopLeft
.RemoveAt(n
);
313 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
),
369 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
372 void wxGridSelection::SelectBlock( int topRow
, int leftCol
,
373 int bottomRow
, int rightCol
,
374 const wxKeyboardState
& kbd
,
377 // Fix the coordinates of the block if needed.
378 switch ( m_selectionMode
)
381 wxFAIL_MSG( "unknown selection mode" );
384 case wxGrid::wxGridSelectCells
:
385 // nothing to do -- in this mode arbitrary blocks can be selected
388 case wxGrid::wxGridSelectRows
:
390 rightCol
= m_grid
->GetNumberCols() - 1;
393 case wxGrid::wxGridSelectColumns
:
395 bottomRow
= m_grid
->GetNumberRows() - 1;
398 case wxGrid::wxGridSelectRowsOrColumns
:
399 // block selection doesn't make sense for this mode, we could only
400 // select the entire grid but this wouldn't be useful
404 if ( topRow
> bottomRow
)
411 if ( leftCol
> rightCol
)
418 // Handle single cell selection in SelectCell.
419 // (MB: added check for selection mode here to prevent
420 // crashes if, for example, we are select rows and the
421 // grid only has 1 col)
422 if ( m_selectionMode
== wxGrid::wxGridSelectCells
&&
423 topRow
== bottomRow
&& leftCol
== rightCol
)
425 SelectCell( topRow
, leftCol
, kbd
, sendEvent
);
430 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
432 // find out which rows are already selected:
433 wxArrayInt alreadyselected
;
434 alreadyselected
.Add(0,bottomRow
-topRow
+1);
435 for( n
= 0; n
< m_rowSelection
.GetCount(); n
++)
437 int row
= m_rowSelection
[n
];
438 if( (row
>= topRow
) && (row
<= bottomRow
) )
440 alreadyselected
[ row
- topRow
]=1;
444 // add the newly selected rows:
445 for ( int row
= topRow
; row
<= bottomRow
; row
++ )
447 if ( alreadyselected
[ row
- topRow
] == 0 )
449 m_rowSelection
.Add( row
);
453 else if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
455 // find out which columns are already selected:
456 wxArrayInt alreadyselected
;
457 alreadyselected
.Add(0,rightCol
-leftCol
+1);
458 for( n
= 0; n
< m_colSelection
.GetCount(); n
++)
460 int col
= m_colSelection
[n
];
461 if( (col
>= leftCol
) && (col
<= rightCol
) )
463 alreadyselected
[ col
- leftCol
]=1;
467 // add the newly selected columns:
468 for ( int col
= leftCol
; col
<= rightCol
; col
++ )
470 if ( alreadyselected
[ col
- leftCol
] == 0 )
472 m_colSelection
.Add( col
);
478 // Remove single cells contained in newly selected block.
479 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
481 count
= m_cellSelection
.GetCount();
482 for ( n
= 0; n
< count
; n
++ )
484 wxGridCellCoords
& coords
= m_cellSelection
[n
];
485 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
,
486 coords
.GetRow(), coords
.GetCol() ) )
488 m_cellSelection
.RemoveAt(n
);
495 // If a block containing the selection is already selected, return,
496 // if a block contained in the selection is found, remove it.
498 count
= m_blockSelectionTopLeft
.GetCount();
499 for ( n
= 0; n
< count
; n
++ )
501 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
502 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
504 switch ( BlockContain( coords1
.GetRow(), coords1
.GetCol(),
505 coords2
.GetRow(), coords2
.GetCol(),
506 topRow
, leftCol
, bottomRow
, rightCol
) )
512 m_blockSelectionTopLeft
.RemoveAt(n
);
513 m_blockSelectionBottomRight
.RemoveAt(n
);
523 // If a row containing the selection is already selected, return,
524 // if a row contained in newly selected block is found, remove it.
525 count
= m_rowSelection
.GetCount();
526 for ( n
= 0; n
< count
; n
++ )
528 switch ( BlockContain( m_rowSelection
[n
], 0,
529 m_rowSelection
[n
], m_grid
->GetNumberCols() - 1,
530 topRow
, leftCol
, bottomRow
, rightCol
) )
536 m_rowSelection
.RemoveAt(n
);
547 count
= m_colSelection
.GetCount();
548 for ( n
= 0; n
< count
; n
++ )
550 switch ( BlockContain( 0, m_colSelection
[n
],
551 m_grid
->GetNumberRows() - 1, m_colSelection
[n
],
552 topRow
, leftCol
, bottomRow
, rightCol
) )
558 m_colSelection
.RemoveAt(n
);
568 m_blockSelectionTopLeft
.Add( wxGridCellCoords( topRow
, leftCol
) );
569 m_blockSelectionBottomRight
.Add( wxGridCellCoords( bottomRow
, rightCol
) );
572 if ( !m_grid
->GetBatchCount() )
574 wxRect r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( topRow
, leftCol
),
575 wxGridCellCoords( bottomRow
, rightCol
) );
576 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
579 // Send Event, if not disabled.
582 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
583 wxEVT_GRID_RANGE_SELECT
,
585 wxGridCellCoords( topRow
, leftCol
),
586 wxGridCellCoords( bottomRow
, rightCol
),
589 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
593 void wxGridSelection::SelectCell( int row
, int col
,
594 const wxKeyboardState
& kbd
,
597 if ( IsInSelection ( row
, col
) )
600 wxGridCellCoords selectedTopLeft
, selectedBottomRight
;
601 if ( m_selectionMode
== wxGrid::wxGridSelectRows
)
603 m_rowSelection
.Add( row
);
604 selectedTopLeft
= wxGridCellCoords( row
, 0 );
605 selectedBottomRight
= wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 );
607 else if ( m_selectionMode
== wxGrid::wxGridSelectColumns
)
609 m_colSelection
.Add( col
);
610 selectedTopLeft
= wxGridCellCoords( 0, col
);
611 selectedBottomRight
= wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
);
615 m_cellSelection
.Add( wxGridCellCoords( row
, col
) );
616 selectedTopLeft
= wxGridCellCoords( row
, col
);
617 selectedBottomRight
= wxGridCellCoords( row
, col
);
621 if ( !m_grid
->GetBatchCount() )
623 wxRect r
= m_grid
->BlockToDeviceRect(
625 selectedBottomRight
);
626 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
632 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
633 wxEVT_GRID_RANGE_SELECT
,
639 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
644 wxGridSelection::ToggleCellSelection(int row
, int col
,
645 const wxKeyboardState
& kbd
)
647 // if the cell is not selected, select it
648 if ( !IsInSelection ( row
, col
) )
650 SelectCell(row
, col
, kbd
);
655 // otherwise deselect it. This can be simple or more or
656 // less difficult, depending on how the cell is selected.
659 // The simplest case: The cell is contained in m_cellSelection
660 // Then it can't be contained in rows/cols/block (since those
661 // would remove the cell from m_cellSelection on creation), so
662 // we just have to remove it from m_cellSelection.
664 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
666 count
= m_cellSelection
.GetCount();
667 for ( n
= 0; n
< count
; n
++ )
669 const wxGridCellCoords
& sel
= m_cellSelection
[n
];
670 if ( row
== sel
.GetRow() && col
== sel
.GetCol() )
672 wxGridCellCoords coords
= m_cellSelection
[n
];
673 m_cellSelection
.RemoveAt(n
);
674 if ( !m_grid
->GetBatchCount() )
676 wxRect r
= m_grid
->BlockToDeviceRect( coords
, coords
);
677 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
681 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
682 wxEVT_GRID_RANGE_SELECT
,
684 wxGridCellCoords( row
, col
),
685 wxGridCellCoords( row
, col
),
688 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
695 // The most difficult case: The cell is member of one or even several
696 // blocks. Split each such block in up to 4 new parts, that don't
697 // contain the cell to be selected, like this:
698 // |---------------------------|
702 // |---------------------------|
703 // | part 3 |x| part 4 |
704 // |---------------------------|
708 // |---------------------------|
709 // (The x marks the newly deselected cell).
710 // Note: in row selection mode, we only need part1 and part2;
711 // in column selection mode, we only need part 3 and part4,
712 // which are expanded to whole columns automatically!
714 count
= m_blockSelectionTopLeft
.GetCount();
715 for ( n
= 0; n
< count
; n
++ )
717 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
718 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
719 int topRow
= coords1
.GetRow();
720 int leftCol
= coords1
.GetCol();
721 int bottomRow
= coords2
.GetRow();
722 int rightCol
= coords2
.GetCol();
724 if ( BlockContainsCell( topRow
, leftCol
, bottomRow
, rightCol
, row
, col
) )
727 m_blockSelectionTopLeft
.RemoveAt(n
);
728 m_blockSelectionBottomRight
.RemoveAt(n
);
732 // add up to 4 smaller blocks and set update region
733 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
736 SelectBlockNoEvent(topRow
, leftCol
, row
- 1, rightCol
);
737 if ( bottomRow
> row
)
738 SelectBlockNoEvent(row
+ 1, leftCol
, bottomRow
, rightCol
);
741 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
744 SelectBlockNoEvent(row
, leftCol
, row
, col
- 1);
745 if ( rightCol
> col
)
746 SelectBlockNoEvent(row
, col
+ 1, row
, rightCol
);
751 bool rowSelectionWasChanged
= false;
752 // remove a cell from a row, adding up to two new blocks
753 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
755 count
= m_rowSelection
.GetCount();
756 for ( n
= 0; n
< count
; n
++ )
758 if ( m_rowSelection
[n
] == row
)
760 m_rowSelection
.RemoveAt(n
);
764 rowSelectionWasChanged
= true;
766 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
769 SelectBlockNoEvent(row
, 0, row
, col
- 1);
770 if ( col
< m_grid
->GetNumberCols() - 1 )
771 SelectBlockNoEvent( row
, col
+ 1,
772 row
, m_grid
->GetNumberCols() - 1);
778 bool colSelectionWasChanged
= false;
779 // remove a cell from a column, adding up to two new blocks
780 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
782 count
= m_colSelection
.GetCount();
783 for ( n
= 0; n
< count
; n
++ )
785 if ( m_colSelection
[n
] == col
)
787 m_colSelection
.RemoveAt(n
);
791 colSelectionWasChanged
= true;
793 if (m_selectionMode
== wxGrid::wxGridSelectCells
)
796 SelectBlockNoEvent(0, col
, row
- 1, col
);
797 if ( row
< m_grid
->GetNumberRows() - 1 )
798 SelectBlockNoEvent(row
+ 1, col
,
799 m_grid
->GetNumberRows() - 1, col
);
805 // Refresh the screen and send the event; according to m_selectionMode,
806 // we need to either update only the cell, or the whole row/column.
808 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
810 if ( !m_grid
->GetBatchCount() )
812 r
= m_grid
->BlockToDeviceRect(
813 wxGridCellCoords( row
, col
),
814 wxGridCellCoords( row
, col
) );
815 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
818 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
819 wxEVT_GRID_RANGE_SELECT
,
821 wxGridCellCoords( row
, col
),
822 wxGridCellCoords( row
, col
),
825 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
827 else // rows/columns selection mode
829 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
&&
830 rowSelectionWasChanged
)
832 int numCols
= m_grid
->GetNumberCols();
833 for ( int colFrom
= 0, colTo
= 0; colTo
<= numCols
; ++colTo
)
835 if ( m_colSelection
.Index(colTo
) >= 0 || colTo
== numCols
)
837 if ( colFrom
< colTo
)
839 if ( !m_grid
->GetBatchCount() )
841 r
= m_grid
->BlockToDeviceRect(
842 wxGridCellCoords( row
, colFrom
),
843 wxGridCellCoords( row
, colTo
-1 ) );
844 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
847 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
848 wxEVT_GRID_RANGE_SELECT
,
850 wxGridCellCoords( row
, colFrom
),
851 wxGridCellCoords( row
, colTo
- 1 ),
854 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
862 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
&&
863 colSelectionWasChanged
)
865 int numRows
= m_grid
->GetNumberRows();
866 for ( int rowFrom
= 0, rowTo
= 0; rowTo
<= numRows
; ++rowTo
)
868 if ( m_rowSelection
.Index(rowTo
) >= 0 || rowTo
== numRows
)
872 if ( !m_grid
->GetBatchCount() )
874 r
= m_grid
->BlockToDeviceRect(
875 wxGridCellCoords( rowFrom
, col
),
876 wxGridCellCoords( rowTo
- 1, col
) );
877 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
880 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
881 wxEVT_GRID_RANGE_SELECT
,
883 wxGridCellCoords( rowFrom
, col
),
884 wxGridCellCoords( rowTo
- 1, col
),
887 m_grid
->GetEventHandler()->ProcessEvent( gridEvt
);
897 void wxGridSelection::ClearSelection()
901 wxGridCellCoords coords1
, coords2
;
903 // deselect all individual cells and update the screen
904 if ( m_selectionMode
== wxGrid::wxGridSelectCells
)
906 while ( ( n
= m_cellSelection
.GetCount() ) > 0)
909 coords1
= m_cellSelection
[n
];
910 m_cellSelection
.RemoveAt(n
);
911 if ( !m_grid
->GetBatchCount() )
913 r
= m_grid
->BlockToDeviceRect( coords1
, coords1
);
914 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
917 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
923 // deselect all blocks and update the screen
924 while ( ( n
= m_blockSelectionTopLeft
.GetCount() ) > 0)
927 coords1
= m_blockSelectionTopLeft
[n
];
928 coords2
= m_blockSelectionBottomRight
[n
];
929 m_blockSelectionTopLeft
.RemoveAt(n
);
930 m_blockSelectionBottomRight
.RemoveAt(n
);
931 if ( !m_grid
->GetBatchCount() )
933 r
= m_grid
->BlockToDeviceRect( coords1
, coords2
);
934 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
937 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
942 // deselect all rows and update the screen
943 if ( m_selectionMode
!= wxGrid::wxGridSelectColumns
)
945 while ( ( n
= m_rowSelection
.GetCount() ) > 0)
948 int row
= m_rowSelection
[n
];
949 m_rowSelection
.RemoveAt(n
);
950 if ( !m_grid
->GetBatchCount() )
952 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( row
, 0 ),
953 wxGridCellCoords( row
, m_grid
->GetNumberCols() - 1 ) );
954 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
957 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
963 // deselect all columns and update the screen
964 if ( m_selectionMode
!= wxGrid::wxGridSelectRows
)
966 while ( ( n
= m_colSelection
.GetCount() ) > 0)
969 int col
= m_colSelection
[n
];
970 m_colSelection
.RemoveAt(n
);
971 if ( !m_grid
->GetBatchCount() )
973 r
= m_grid
->BlockToDeviceRect( wxGridCellCoords( 0, col
),
974 wxGridCellCoords( m_grid
->GetNumberRows() - 1, col
) );
975 ((wxWindow
*)m_grid
->m_gridWin
)->Refresh( false, &r
);
978 ((wxWindow
*)m_grid
->m_gridWin
)->Update();
984 // One deselection event, indicating deselection of _all_ cells.
985 // (No finer grained events for each of the smaller regions
986 // deselected above!)
987 wxGridRangeSelectEvent
gridEvt( m_grid
->GetId(),
988 wxEVT_GRID_RANGE_SELECT
,
990 wxGridCellCoords( 0, 0 ),
992 m_grid
->GetNumberRows() - 1,
993 m_grid
->GetNumberCols() - 1 ),
996 m_grid
->GetEventHandler()->ProcessEvent(gridEvt
);
1000 void wxGridSelection::UpdateRows( size_t pos
, int numRows
)
1002 size_t count
= m_cellSelection
.GetCount();
1004 for ( n
= 0; n
< count
; n
++ )
1006 wxGridCellCoords
& coords
= m_cellSelection
[n
];
1007 wxCoord row
= coords
.GetRow();
1008 if ((size_t)row
>= pos
)
1012 // If rows inserted, increase row counter where necessary
1013 coords
.SetRow(row
+ numRows
);
1015 else if (numRows
< 0)
1017 // If rows deleted ...
1018 if ((size_t)row
>= pos
- numRows
)
1020 // ...either decrement row counter (if row still exists)...
1021 coords
.SetRow(row
+ numRows
);
1025 // ...or remove the attribute
1026 m_cellSelection
.RemoveAt(n
);
1034 count
= m_blockSelectionTopLeft
.GetCount();
1035 for ( n
= 0; n
< count
; n
++ )
1037 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
1038 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
1039 wxCoord row1
= coords1
.GetRow();
1040 wxCoord row2
= coords2
.GetRow();
1042 if ((size_t)row2
>= pos
)
1046 // If rows inserted, increase row counter where necessary
1047 coords2
.SetRow( row2
+ numRows
);
1048 if ((size_t)row1
>= pos
)
1049 coords1
.SetRow( row1
+ numRows
);
1051 else if (numRows
< 0)
1053 // If rows deleted ...
1054 if ((size_t)row2
>= pos
- numRows
)
1056 // ...either decrement row counter (if row still exists)...
1057 coords2
.SetRow( row2
+ numRows
);
1058 if ((size_t)row1
>= pos
)
1059 coords1
.SetRow( wxMax(row1
+ numRows
, (int)pos
) );
1064 if ((size_t)row1
>= pos
)
1066 // ...or remove the attribute
1067 m_blockSelectionTopLeft
.RemoveAt(n
);
1068 m_blockSelectionBottomRight
.RemoveAt(n
);
1073 coords2
.SetRow( pos
);
1079 count
= m_rowSelection
.GetCount();
1080 for ( n
= 0; n
< count
; n
++ )
1082 int rowOrCol_
= m_rowSelection
[n
];
1084 if ((size_t) rowOrCol_
>= pos
)
1088 m_rowSelection
[n
] += numRows
;
1090 else if ( numRows
< 0 )
1092 if ((size_t)rowOrCol_
>= (pos
- numRows
))
1093 m_rowSelection
[n
] += numRows
;
1096 m_rowSelection
.RemoveAt( n
);
1103 // No need to touch selected columns, unless we removed _all_
1104 // rows, in this case, we remove all columns from the selection.
1106 if ( !m_grid
->GetNumberRows() )
1107 m_colSelection
.Clear();
1111 void wxGridSelection::UpdateCols( size_t pos
, int numCols
)
1113 size_t count
= m_cellSelection
.GetCount();
1116 for ( n
= 0; n
< count
; n
++ )
1118 wxGridCellCoords
& coords
= m_cellSelection
[n
];
1119 wxCoord col
= coords
.GetCol();
1120 if ((size_t)col
>= pos
)
1124 // If rows inserted, increase row counter where necessary
1125 coords
.SetCol(col
+ numCols
);
1127 else if (numCols
< 0)
1129 // If rows deleted ...
1130 if ((size_t)col
>= pos
- numCols
)
1132 // ...either decrement row counter (if row still exists)...
1133 coords
.SetCol(col
+ numCols
);
1137 // ...or remove the attribute
1138 m_cellSelection
.RemoveAt(n
);
1146 count
= m_blockSelectionTopLeft
.GetCount();
1147 for ( n
= 0; n
< count
; n
++ )
1149 wxGridCellCoords
& coords1
= m_blockSelectionTopLeft
[n
];
1150 wxGridCellCoords
& coords2
= m_blockSelectionBottomRight
[n
];
1151 wxCoord col1
= coords1
.GetCol();
1152 wxCoord col2
= coords2
.GetCol();
1154 if ((size_t)col2
>= pos
)
1158 // If rows inserted, increase row counter where necessary
1159 coords2
.SetCol(col2
+ numCols
);
1160 if ((size_t)col1
>= pos
)
1161 coords1
.SetCol(col1
+ numCols
);
1163 else if (numCols
< 0)
1165 // If cols deleted ...
1166 if ((size_t)col2
>= pos
- numCols
)
1168 // ...either decrement col counter (if col still exists)...
1169 coords2
.SetCol(col2
+ numCols
);
1170 if ( (size_t) col1
>= pos
)
1171 coords1
.SetCol( wxMax(col1
+ numCols
, (int)pos
) );
1176 if ((size_t)col1
>= pos
)
1178 // ...or remove the attribute
1179 m_blockSelectionTopLeft
.RemoveAt(n
);
1180 m_blockSelectionBottomRight
.RemoveAt(n
);
1185 coords2
.SetCol(pos
);
1191 count
= m_colSelection
.GetCount();
1192 for ( n
= 0; n
< count
; n
++ )
1194 int rowOrCol
= m_colSelection
[n
];
1196 if ((size_t)rowOrCol
>= pos
)
1199 m_colSelection
[n
] += numCols
;
1200 else if ( numCols
< 0 )
1202 if ((size_t)rowOrCol
>= (pos
- numCols
))
1203 m_colSelection
[n
] += numCols
;
1206 m_colSelection
.RemoveAt( n
);
1214 // No need to touch selected rows, unless we removed _all_
1215 // columns, in this case, we remove all rows from the selection.
1216 if ( !m_grid
->GetNumberCols() )
1217 m_rowSelection
.Clear();
1220 int wxGridSelection::BlockContain( int topRow1
, int leftCol1
,
1221 int bottomRow1
, int rightCol1
,
1222 int topRow2
, int leftCol2
,
1223 int bottomRow2
, int rightCol2
)
1224 // returns 1, if Block1 contains Block2,
1225 // -1, if Block2 contains Block1,
1228 if ( topRow1
<= topRow2
&& bottomRow2
<= bottomRow1
&&
1229 leftCol1
<= leftCol2
&& rightCol2
<= rightCol1
)
1231 else if ( topRow2
<= topRow1
&& bottomRow1
<= bottomRow2
&&
1232 leftCol2
<= leftCol1
&& rightCol1
<= rightCol2
)