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