Compilation fixes (true->TRUE, false->FALSE)
[wxWidgets.git] / src / generic / gridsel.cpp
1 ///////////////////////////////////////////////////////////////////////////
2 // Name: generic/gridsel.cpp
3 // Purpose: wxGridSelection
4 // Author: Stefan Neis
5 // Modified by:
6 // Created: 20/02/1999
7 // RCS-ID: $$
8 // Copyright: (c) Stefan Neis (Stefan.Neis@t-online.de)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "gridsel.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx/wx.h".
25 #include "wx/wxprec.h"
26
27 #include "wx/defs.h"
28
29 #ifdef __BORLANDC__
30 #pragma hdrstop
31 #endif
32
33 #if defined(wxUSE_NEW_GRID) && (wxUSE_NEW_GRID)
34
35 #include "wx/generic/gridsel.h"
36
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
44 // treated as blocks?
45
46 wxGridSelection::wxGridSelection( wxGrid * grid,
47 wxGrid::wxGridSelectionModes sel )
48 {
49 m_grid = grid;
50 m_selectionMode = sel;
51 }
52
53 bool wxGridSelection::IsSelection()
54 {
55 return ( m_cellSelection.GetCount() || m_blockSelectionTopLeft.GetCount() ||
56 m_rowSelection.GetCount() || m_colSelection.GetCount() );
57 }
58
59 bool wxGridSelection::IsInSelection ( int row, int col )
60 {
61 size_t count;
62
63 // First check whether the given cell is individually selected
64 // (if m_selectionMode is wxGridSelectCells).
65 if ( m_selectionMode == wxGrid::wxGridSelectCells )
66 {
67 count = m_cellSelection.GetCount();
68 for ( size_t n = 0; n < count; n++ )
69 {
70 wxGridCellCoords& coords = m_cellSelection[n];
71 if ( row == coords.GetRow() && col == coords.GetCol() )
72 return TRUE;
73 }
74 }
75
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++ )
80 {
81 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
82 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
83 if ( BlockContainsCell(coords1.GetRow(), coords1.GetCol(),
84 coords2.GetRow(), coords2.GetCol(),
85 row, col ) )
86 return TRUE;
87 }
88
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 )
93 {
94 size_t count = m_rowSelection.GetCount();
95 for ( size_t n = 0; n < count; n++ )
96 {
97 if ( row == m_rowSelection[n] )
98 return TRUE;
99 }
100 }
101
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 )
106 {
107 size_t count = m_colSelection.GetCount();
108 for ( size_t n = 0; n < count; n++ )
109 {
110 if ( col == m_colSelection[n] )
111 return TRUE;
112 }
113 }
114 return FALSE;
115 }
116
117 // Change the selection mode
118 void wxGridSelection::SetSelectionMode(wxGrid::wxGridSelectionModes selmode)
119 {
120 // if selection mode is unchanged return immediately
121 if (selmode == m_selectionMode)
122 return;
123
124 if ( m_selectionMode != wxGrid::wxGridSelectCells )
125 {
126 // if changing form row to column selection
127 // or vice versa, clear the selection.
128 if ( selmode != wxGrid::wxGridSelectCells )
129 ClearSelection();
130
131 m_selectionMode = selmode;
132 }
133 else
134 {
135 // if changing from cell selection to something else,
136 // promote selected cells/blocks to whole rows/columns.
137 size_t n;
138 while ( ( n = m_cellSelection.GetCount() ) > 0 )
139 {
140 n--;
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)
146 SelectRow( row );
147 else // selmode == wxGridSelectColumns)
148 SelectCol( col );
149 }
150
151 for (n = 0; n < m_blockSelectionTopLeft.GetCount(); n++)
152 // Note that m_blockSelectionTopLeft's size may be changing!
153 {
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)
161 {
162 if (leftCol != 0 || rightCol != m_grid->GetNumberCols() - 1 )
163 {
164 m_blockSelectionTopLeft.RemoveAt(n);
165 m_blockSelectionBottomRight.RemoveAt(n);
166 SelectBlock( topRow, 0,
167 bottomRow, m_grid->GetNumberCols() - 1,
168 0, FALSE );
169 }
170 }
171 else // selmode == wxGridSelectColumns)
172 {
173 if (topRow != 0 || bottomRow != m_grid->GetNumberRows() - 1 )
174 {
175 m_blockSelectionTopLeft.RemoveAt(n);
176 m_blockSelectionBottomRight.RemoveAt(n);
177 SelectBlock( 0, leftCol,
178 m_grid->GetNumberRows() - 1, rightCol,
179 0, FALSE );
180 }
181 }
182 }
183 m_selectionMode = selmode;
184 }
185 }
186
187 void wxGridSelection::SelectRow( int row, bool addToSelected )
188 {
189 if ( m_selectionMode == wxGrid::wxGridSelectColumns )
190 return;
191 size_t count, n;
192
193 // Remove single cells contained in newly selected block.
194 if ( m_selectionMode == wxGrid::wxGridSelectCells )
195 {
196 count = m_cellSelection.GetCount();
197 for ( n = 0; n < count; n++ )
198 {
199 wxGridCellCoords& coords = m_cellSelection[n];
200 if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() - 1,
201 coords.GetRow(), coords.GetCol() ) )
202 {
203 m_cellSelection.RemoveAt(n);
204 n--; count--;
205 }
206 }
207 }
208
209 // Simplify list of selected blocks (if possible)
210 count = m_blockSelectionTopLeft.GetCount();
211 bool done = FALSE;
212 for ( n = 0; n < count; n++ )
213 {
214 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
215 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
216
217 // Remove block if it is a subset of the row
218 if ( coords1.GetRow() == row && row == coords2.GetRow() )
219 {
220 m_blockSelectionTopLeft.RemoveAt(n);
221 m_blockSelectionBottomRight.RemoveAt(n);
222 n--; count--;
223 }
224 else if ( coords1.GetCol() == 0 &&
225 coords2.GetCol() == m_grid->GetNumberCols() - 1 )
226 {
227 // silently return, if row is contained in block
228 if ( coords1.GetRow() <= row && row <= coords2.GetRow() )
229 return;
230 // expand block, if it touched row
231 else if ( coords1.GetRow() == row + 1)
232 {
233 coords1.SetRow(row);
234 done = TRUE;
235 }
236 else if ( coords2.GetRow() == row - 1)
237 {
238 coords2.SetRow(row);
239 done = TRUE;
240 }
241 }
242 }
243
244 // Unless we successfully handled the row,
245 // check whether row is already selected.
246 if ( !done )
247 {
248 count = m_rowSelection.GetCount();
249 for ( n = 0; n < count; n++ )
250 {
251 if ( row == m_rowSelection[n] )
252 return;
253 }
254
255 // Add row to selection
256 m_rowSelection.Add(row);
257 }
258
259 // Update View:
260 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
261 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
262 if ( !m_grid->GetBatchCount() )
263 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
264
265 // Send Event
266 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
267 wxEVT_GRID_RANGE_SELECT,
268 m_grid,
269 wxGridCellCoords( row, 0 ),
270 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
271
272 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
273 }
274
275 void wxGridSelection::SelectCol( int col, bool addToSelected )
276 {
277 if ( m_selectionMode == wxGrid::wxGridSelectRows )
278 return;
279 size_t count, n;
280
281 // Remove single cells contained in newly selected block.
282 if ( m_selectionMode == wxGrid::wxGridSelectCells )
283 {
284 count = m_cellSelection.GetCount();
285 for ( n = 0; n < count; n++ )
286 {
287 wxGridCellCoords& coords = m_cellSelection[n];
288 if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1, col,
289 coords.GetRow(), coords.GetCol() ) )
290 {
291 m_cellSelection.RemoveAt(n);
292 n--; count--;
293 }
294 }
295 }
296
297 // Simplify list of selected blocks (if possible)
298 count = m_blockSelectionTopLeft.GetCount();
299 bool done = FALSE;
300 for ( n = 0; n < count; n++ )
301 {
302 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
303 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
304
305 // Remove block if it is a subset of the column
306 if ( coords1.GetCol() == col && col == coords2.GetCol() )
307 {
308 m_blockSelectionTopLeft.RemoveAt(n);
309 m_blockSelectionBottomRight.RemoveAt(n);
310 n--; count--;
311 }
312 else if ( coords1.GetRow() == 0 &&
313 coords2.GetRow() == m_grid->GetNumberRows() - 1 )
314 {
315 // silently return, if row is contained in block
316 if ( coords1.GetCol() <= col && col <= coords2.GetCol() )
317 return;
318 // expand block, if it touched col
319 else if ( coords1.GetCol() == col + 1)
320 {
321 coords1.SetCol(col);
322 done = TRUE;
323 }
324 else if ( coords2.GetCol() == col - 1)
325 {
326 coords2.SetCol(col);
327 done = TRUE;
328 }
329 }
330 }
331
332 // Unless we successfully handled the column,
333 // Check whether col is already selected.
334 if ( !done )
335 {
336 count = m_colSelection.GetCount();
337 for ( n = 0; n < count; n++ )
338 {
339 if ( col == m_colSelection[n] )
340 return;
341 }
342
343 // Add col to selection
344 m_colSelection.Add(col);
345 }
346
347 // Update View:
348 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
349 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
350 if ( !m_grid->GetBatchCount() )
351 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
352
353 // Send Event
354 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
355 wxEVT_GRID_RANGE_SELECT,
356 m_grid,
357 wxGridCellCoords( 0, col ),
358 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
359
360 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
361 }
362
363 void wxGridSelection::SelectBlock( int topRow, int leftCol,
364 int bottomRow, int rightCol,
365 wxMouseEvent* mouseEv, bool sendEvent )
366 {
367 // Fix the coordinates of the block if needed.
368 if ( m_selectionMode == wxGrid::wxGridSelectRows )
369 {
370 leftCol = 0;
371 rightCol = m_grid->GetNumberCols() - 1;
372 }
373 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
374 {
375 topRow = 0;
376 bottomRow = m_grid->GetNumberRows() - 1;
377 }
378 if ( topRow > bottomRow )
379 {
380 int temp = topRow;
381 topRow = bottomRow;
382 bottomRow = temp;
383 }
384
385 if ( leftCol > rightCol )
386 {
387 int temp = leftCol;
388 leftCol = rightCol;
389 rightCol = temp;
390 }
391
392 // Handle single cell selection in SelectCell.
393 if ( topRow == bottomRow && leftCol == rightCol )
394 SelectCell( topRow, leftCol, sendEvent );
395
396 size_t count, n;
397 // Remove single cells contained in newly selected block.
398 if ( m_selectionMode == wxGrid::wxGridSelectCells )
399 {
400 count = m_cellSelection.GetCount();
401 for ( n = 0; n < count; n++ )
402 {
403 wxGridCellCoords& coords = m_cellSelection[n];
404 if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
405 coords.GetRow(), coords.GetCol() ) )
406 {
407 m_cellSelection.RemoveAt(n);
408 n--; count--;
409 }
410 }
411 }
412
413 // If a block containing the selection is already selected, return,
414 // if a block contained in the selection is found, remove it.
415
416 count = m_blockSelectionTopLeft.GetCount();
417 for ( n = 0; n < count; n++ )
418 {
419 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
420 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
421 switch ( BlockContain( coords1.GetRow(), coords1.GetCol(),
422 coords2.GetRow(), coords2.GetCol(),
423 topRow, leftCol, bottomRow, rightCol ) )
424 {
425 case 1:
426 return;
427 case -1:
428 m_blockSelectionTopLeft.RemoveAt(n);
429 m_blockSelectionBottomRight.RemoveAt(n);
430 n--; count--;
431 default:
432 ;
433 }
434 }
435
436 // If a row containing the selection is already selected, return,
437 // if a row contained in newly selected block is found, remove it.
438 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
439 {
440 count = m_rowSelection.GetCount();
441 for ( n = 0; n < count; n++ )
442 {
443 switch ( BlockContain( m_rowSelection[n], 0,
444 m_rowSelection[n], m_grid->GetNumberCols()-1,
445 topRow, leftCol, bottomRow, rightCol ) )
446 {
447 case 1:
448 return;
449 case -1:
450 m_rowSelection.RemoveAt(n);
451 n--; count--;
452 default:
453 ;
454 }
455 }
456 }
457 if ( m_selectionMode != wxGrid::wxGridSelectRows )
458 {
459 count = m_colSelection.GetCount();
460 for ( n = 0; n < count; n++ )
461 {
462 switch ( BlockContain( 0, m_colSelection[n],
463 m_grid->GetNumberRows()-1, m_colSelection[n],
464 topRow, leftCol, bottomRow, rightCol ) )
465 {
466 case 1:
467 return;
468 case -1:
469 m_colSelection.RemoveAt(n);
470 n--; count--;
471 default:
472 ;
473 }
474 }
475 }
476 m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) );
477 m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) );
478
479 // Update View:
480 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( topRow, leftCol ),
481 wxGridCellCoords( bottomRow, rightCol ) );
482 if ( !m_grid->GetBatchCount() )
483 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
484
485 // Send Event, if not disabled.
486 if ( sendEvent )
487 {
488 if ( mouseEv == 0)
489 {
490 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
491 wxEVT_GRID_RANGE_SELECT,
492 m_grid,
493 wxGridCellCoords( topRow, leftCol ),
494 wxGridCellCoords( bottomRow, rightCol ) );
495 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
496 }
497 else
498 {
499 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
500 wxEVT_GRID_RANGE_SELECT,
501 m_grid,
502 wxGridCellCoords( topRow, leftCol ),
503 wxGridCellCoords( bottomRow, rightCol ),
504 TRUE,
505 mouseEv->ControlDown(),
506 mouseEv->ShiftDown(),
507 mouseEv->AltDown(),
508 mouseEv->MetaDown() );
509 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
510 }
511 }
512 }
513
514 void wxGridSelection::SelectCell( int row, int col, bool sendEvent )
515 {
516 if ( m_selectionMode == wxGrid::wxGridSelectRows )
517 {
518 SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1 );
519 return;
520 }
521 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
522 {
523 SelectBlock(0, col, m_grid->GetNumberRows() - 1, col );
524 return;
525 }
526 else if ( IsInSelection ( row, col ) )
527 return;
528 m_cellSelection.Add( wxGridCellCoords( row, col ) );
529
530 // Update View:
531 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
532 wxGridCellCoords( row, col ) );
533 if ( !m_grid->GetBatchCount() )
534 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
535
536 // Send event
537 wxGridEvent gridEvt( m_grid->GetId(),
538 wxEVT_GRID_SELECT_CELL,
539 m_grid,
540 row, col );
541 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
542 }
543
544 void wxGridSelection::ToggleCellSelection( int row, int col)
545 {
546 // if the cell is not selected, select it
547 if ( !IsInSelection ( row, col ) )
548 {
549 SelectCell( row, col );
550 return;
551 }
552
553 // otherwise deselect it. This can be simple or more or
554 // less difficult, depending on how the cell is selected.
555 size_t count, n;
556
557 // The simplest case: The cell is contained in m_cellSelection
558 // Then it can't be contained in rows/cols/block (since those
559 // would remove the cell from m_cellSelection on creation), so
560 // we just have to remove it from m_cellSelection.
561
562 if ( m_selectionMode == wxGrid::wxGridSelectCells )
563 {
564 count = m_cellSelection.GetCount();
565 for ( n = 0; n < count; n++ )
566 {
567 wxGridCellCoords& coords = m_cellSelection[n];
568 if ( row == coords.GetRow() && col == coords.GetCol() )
569 {
570 wxRect r;
571 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
572 m_cellSelection[n] );
573 m_cellSelection.RemoveAt(n);
574 n--; count--;
575 if ( !m_grid->GetBatchCount() )
576 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
577 return;
578
579 // Send event
580 wxGridEvent gridEvt( m_grid->GetId(),
581 wxEVT_GRID_SELECT_CELL,
582 m_grid,
583 row, col, -1, -1, FALSE );
584 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
585 }
586 }
587 }
588
589 // The most difficult case: The cell is member of one or even several
590 // blocks. Split each such block in up to 4 new parts, that don't
591 // contain the cell to be selected, like this:
592 // |---------------------------|
593 // | |
594 // | part 1 |
595 // | |
596 // |---------------------------|
597 // | part 3 |x| part 4 |
598 // |---------------------------|
599 // | |
600 // | part 2 |
601 // | |
602 // |---------------------------|
603 // (The x marks the newly deselected cell).
604 // Note: in row selection mode, we only need part1 and part2;
605 // in column selection mode, we only need part 3 and part4,
606 // which are expanded to whole columns automatically!
607
608 count = m_blockSelectionTopLeft.GetCount();
609 for ( n = 0; n < count; n++ )
610 {
611 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
612 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
613 int topRow = coords1.GetRow();
614 int leftCol = coords1.GetCol();
615 int bottomRow = coords2.GetRow();
616 int rightCol = coords2.GetCol();
617 if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
618 row, col ) )
619 {
620 // remove the block
621 m_blockSelectionTopLeft.RemoveAt(n);
622 m_blockSelectionBottomRight.RemoveAt(n);
623 n--; count--;
624 // add up to 4 smaller blocks and set update region
625 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
626 {
627 if ( topRow < row )
628 SelectBlock( topRow, leftCol,
629 row - 1, rightCol, 0, FALSE );
630 if ( bottomRow > row )
631 SelectBlock( row + 1, leftCol,
632 bottomRow, rightCol, 0, FALSE );
633 }
634 if ( m_selectionMode != wxGrid::wxGridSelectRows )
635 {
636 if ( leftCol < col )
637 SelectBlock( row, leftCol, row, col - 1, 0, FALSE );
638 if ( rightCol > col )
639 SelectBlock( row, col + 1, row, rightCol, 0, FALSE );
640 }
641 }
642 }
643
644 // remove a cell from a row, adding up to two new blocks
645 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
646 {
647 count = m_rowSelection.GetCount();
648 for ( n = 0; n < count; n++ )
649 {
650 if ( m_rowSelection[n] == row )
651 {
652 m_rowSelection.RemoveAt(n);
653 n--; count--;
654 if (m_selectionMode == wxGrid::wxGridSelectCells)
655 {
656 if ( col > 0 )
657 SelectBlock( row, 0, row, col - 1, 0, FALSE );
658 if ( col < m_grid->GetNumberCols() - 1 )
659 SelectBlock( row, col + 1,
660 row, m_grid->GetNumberCols() - 1,
661 0, FALSE );
662 }
663 }
664 }
665 }
666
667 // remove a cell from a column, adding up to two new blocks
668 if ( m_selectionMode != wxGrid::wxGridSelectRows )
669 {
670 count = m_colSelection.GetCount();
671 for ( n = 0; n < count; n++ )
672 {
673 if ( m_colSelection[n] == col )
674 {
675 m_colSelection.RemoveAt(n);
676 n--; count--;
677 if (m_selectionMode == wxGrid::wxGridSelectCells)
678 {
679 if ( row > 0 )
680 SelectBlock( 0, col, row - 1, col, 0, FALSE );
681 if ( row < m_grid->GetNumberRows() - 1 )
682 SelectBlock( row + 1, col,
683 m_grid->GetNumberRows() - 1, col,
684 0, FALSE );
685 }
686 }
687 }
688 }
689
690 // Refresh the screen and send the event; according to m_selectionMode,
691 // we need to either update only the cell, or the whole row/column.
692 wxRect r;
693 switch (m_selectionMode)
694 {
695 case wxGrid::wxGridSelectCells:
696 {
697 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
698 wxGridCellCoords( row, col ) );
699 if ( !m_grid->GetBatchCount() )
700 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
701 wxGridEvent gridEvt( m_grid->GetId(),
702 wxEVT_GRID_SELECT_CELL,
703 m_grid,
704 row, col, -1, -1, FALSE );
705 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
706 break;
707 }
708 case wxGrid::wxGridSelectRows:
709 {
710 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
711 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
712 if ( !m_grid->GetBatchCount() )
713 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
714 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
715 wxEVT_GRID_RANGE_SELECT,
716 m_grid,
717 wxGridCellCoords( row, 0 ),
718 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ),
719 FALSE );
720 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
721 break;
722 }
723 case wxGrid::wxGridSelectColumns:
724 {
725 r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
726 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
727 if ( !m_grid->GetBatchCount() )
728 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
729 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
730 wxEVT_GRID_RANGE_SELECT,
731 m_grid,
732 wxGridCellCoords( 0, col ),
733 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ),
734 FALSE );
735 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
736 break;
737 }
738 }
739 }
740
741 void wxGridSelection::ClearSelection()
742 {
743 // Should this send deselection events?
744 size_t n;
745
746 // deselect all invidiual cells and update the screen
747 if ( m_selectionMode == wxGrid::wxGridSelectCells )
748 {
749
750 while( ( n = m_cellSelection.GetCount() ) > 0)
751 {
752 wxRect r;
753 n--;
754 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
755 m_cellSelection[n] );
756 m_cellSelection.RemoveAt(n);
757 if ( !m_grid->GetBatchCount() )
758 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
759 }
760 }
761
762 // deselect all blocks and update the screen
763 while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
764 {
765 wxRect r;
766 n--;
767 r = m_grid->BlockToDeviceRect( m_blockSelectionTopLeft[n],
768 m_blockSelectionBottomRight[n] );
769 m_blockSelectionTopLeft.RemoveAt(n);
770 m_blockSelectionBottomRight.RemoveAt(n);
771 if ( !m_grid->GetBatchCount() )
772 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
773 }
774
775 // deselect all rows and update the screen
776 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
777 {
778 while( ( n = m_rowSelection.GetCount() ) > 0)
779 {
780 n--;
781 int & row = m_rowSelection[n];
782 wxRect r;
783 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
784 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
785 m_rowSelection.RemoveAt(n);
786 if ( !m_grid->GetBatchCount() )
787 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
788 }
789 }
790
791 // deselect all columns and update the screen
792 if ( m_selectionMode != wxGrid::wxGridSelectRows )
793 {
794 while( ( n = m_colSelection.GetCount() ) > 0)
795 {
796 n--;
797 int & col = m_colSelection[n];
798 wxRect r;
799 r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
800 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
801 m_colSelection.RemoveAt(n);
802 if ( !m_grid->GetBatchCount() )
803 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
804 }
805 }
806 }
807
808
809 void wxGridSelection::UpdateRows( size_t pos, int numRows )
810 {
811 size_t count = m_cellSelection.GetCount();
812 size_t n;
813 for ( n = 0; n < count; n++ )
814 {
815 wxGridCellCoords& coords = m_cellSelection[n];
816 wxCoord row = coords.GetRow();
817 if ((size_t)row >= pos)
818 {
819 if (numRows > 0)
820 {
821 // If rows inserted, increase row counter where necessary
822 coords.SetRow(row + numRows);
823 }
824 else if (numRows < 0)
825 {
826 // If rows deleted ...
827 if ((size_t)row >= pos - numRows)
828 {
829 // ...either decrement row counter (if row still exists)...
830 coords.SetRow(row + numRows);
831 }
832 else
833 {
834 // ...or remove the attribute
835 m_cellSelection.RemoveAt(n);
836 n--; count--;
837 }
838 }
839 }
840 }
841
842 count = m_blockSelectionTopLeft.GetCount();
843 for ( n = 0; n < count; n++ )
844 {
845 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
846 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
847 wxCoord row1 = coords1.GetRow();
848 wxCoord row2 = coords2.GetRow();
849 if ((size_t)row2 >= pos)
850 {
851 if (numRows > 0)
852 {
853 // If rows inserted, increase row counter where necessary
854 coords2.SetRow(row2 + numRows);
855 if ( (size_t)row1 >= pos )
856 coords1.SetRow(row1 + numRows);
857 }
858 else if (numRows < 0)
859 {
860 // If rows deleted ...
861 if ((size_t)row2 >= pos - numRows)
862 {
863 // ...either decrement row counter (if row still exists)...
864 coords2.SetRow(row2 + numRows);
865 if ( (size_t) row1 >= pos)
866 coords1.SetRow( wxMax(row1 + numRows, (int) pos) );
867
868 }
869 else
870 {
871 if ( (size_t) row1 >= pos)
872 {
873 // ...or remove the attribute
874 m_blockSelectionTopLeft.RemoveAt(n);
875 m_blockSelectionBottomRight.RemoveAt(n);
876 n--; count--;
877 }
878 else
879 coords2.SetRow(pos);
880 }
881 }
882 }
883 }
884
885 count = m_rowSelection.GetCount();
886 for ( n = 0; n < count; n++ )
887 {
888 int & rowOrCol = m_rowSelection[n];
889 if ( (size_t)rowOrCol >= pos )
890 {
891 if ( numRows > 0 )
892 {
893 // If rows inserted, include row counter where necessary
894 rowOrCol += numRows;
895 }
896 else if ( numRows < 0)
897 {
898 // If rows deleted, either decrement row counter (if row still exists)
899 if ((size_t)rowOrCol >= pos - numRows)
900 rowOrCol += numRows;
901 else
902 {
903 m_rowSelection.RemoveAt(n);
904 n--; count--;
905 }
906 }
907 }
908 }
909 }
910
911 void wxGridSelection::UpdateCols( size_t pos, int numCols )
912 {
913 size_t count = m_cellSelection.GetCount();
914 size_t n;
915 for ( n = 0; n < count; n++ )
916 {
917 wxGridCellCoords& coords = m_cellSelection[n];
918 wxCoord col = coords.GetCol();
919 if ((size_t)col >= pos)
920 {
921 if (numCols > 0)
922 {
923 // If rows inserted, increase row counter where necessary
924 coords.SetCol(col + numCols);
925 }
926 else if (numCols < 0)
927 {
928 // If rows deleted ...
929 if ((size_t)col >= pos - numCols)
930 {
931 // ...either decrement row counter (if row still exists)...
932 coords.SetCol(col + numCols);
933 }
934 else
935 {
936 // ...or remove the attribute
937 m_cellSelection.RemoveAt(n);
938 n--; count--;
939 }
940 }
941 }
942 }
943
944 count = m_blockSelectionTopLeft.GetCount();
945 for ( n = 0; n < count; n++ )
946 {
947 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
948 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
949 wxCoord col1 = coords1.GetCol();
950 wxCoord col2 = coords2.GetCol();
951 if ((size_t)col2 >= pos)
952 {
953 if (numCols > 0)
954 {
955 // If rows inserted, increase row counter where necessary
956 coords2.SetCol(col2 + numCols);
957 if ( (size_t)col1 >= pos )
958 coords1.SetCol(col1 + numCols);
959 }
960 else if (numCols < 0)
961 {
962 // If cols deleted ...
963 if ((size_t)col2 >= pos - numCols)
964 {
965 // ...either decrement col counter (if col still exists)...
966 coords2.SetCol(col2 + numCols);
967 if ( (size_t) col1 >= pos)
968 coords1.SetCol( wxMax(col1 + numCols, (int) pos) );
969
970 }
971 else
972 {
973 if ( (size_t) col1 >= pos)
974 {
975 // ...or remove the attribute
976 m_blockSelectionTopLeft.RemoveAt(n);
977 m_blockSelectionBottomRight.RemoveAt(n);
978 n--; count--;
979 }
980 else
981 coords2.SetCol(pos);
982 }
983 }
984 }
985 }
986
987 count = m_colSelection.GetCount();
988 for ( n = 0; n < count; n++ )
989 {
990 int & rowOrCol = m_colSelection[n];
991 if ( (size_t)rowOrCol >= pos )
992 {
993 if ( numCols > 0 )
994 {
995 // If cols inserted, include col counter where necessary
996 rowOrCol += numCols;
997 }
998 else if ( numCols < 0)
999 {
1000 // If cols deleted, either decrement col counter (if col still exists)
1001 if ((size_t)rowOrCol >= pos - numCols)
1002 rowOrCol += numCols;
1003 else
1004 {
1005 m_colSelection.RemoveAt(n);
1006 n--; count--;
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013 int wxGridSelection::BlockContain( int topRow1, int leftCol1,
1014 int bottomRow1, int rightCol1,
1015 int topRow2, int leftCol2,
1016 int bottomRow2, int rightCol2 )
1017 // returns 1, if Block1 contains Block2,
1018 // -1, if Block2 contains Block1,
1019 // 0, otherwise
1020 {
1021 if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 &&
1022 leftCol1 <= leftCol2 && rightCol2 <= rightCol1 )
1023 return 1;
1024 else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 &&
1025 leftCol2 <= leftCol1 && rightCol1 <= rightCol2 )
1026 return -1;
1027 return 0;
1028 }
1029
1030 #endif