]> git.saurik.com Git - wxWidgets.git/blob - src/generic/gridsel.cpp
Changed Shift+Arrow handling
[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 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
280 void wxGridSelection::SelectCol( int col, bool addToSelected,
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
373 void 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
513 void 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 return;
522 }
523 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
524 {
525 SelectBlock(0, col, m_grid->GetNumberRows() - 1, col );
526 return;
527 }
528 else if ( IsInSelection ( row, col ) )
529 return;
530 m_cellSelection.Add( wxGridCellCoords( row, col ) );
531
532 // Update View:
533 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
534 wxGridCellCoords( row, col ) );
535 if ( !m_grid->GetBatchCount() )
536 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
537
538 // Send event
539 if (sendEvent)
540 {
541 wxGridEvent gridEvt( m_grid->GetId(),
542 wxEVT_GRID_SELECT_CELL,
543 m_grid,
544 row, col,
545 -1, -1,
546 TRUE,
547 ControlDown, ShiftDown,
548 AltDown, MetaDown);
549 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
550 }
551 }
552
553 void wxGridSelection::ToggleCellSelection( int row, int col,
554 bool ControlDown, bool ShiftDown,
555 bool AltDown, bool MetaDown )
556 {
557 // if the cell is not selected, select it
558 if ( !IsInSelection ( row, col ) )
559 {
560 SelectCell( row, col, ControlDown, ShiftDown,
561 AltDown, MetaDown );
562 return;
563 }
564
565 // otherwise deselect it. This can be simple or more or
566 // less difficult, depending on how the cell is selected.
567 size_t count, n;
568
569 // The simplest case: The cell is contained in m_cellSelection
570 // Then it can't be contained in rows/cols/block (since those
571 // would remove the cell from m_cellSelection on creation), so
572 // we just have to remove it from m_cellSelection.
573
574 if ( m_selectionMode == wxGrid::wxGridSelectCells )
575 {
576 count = m_cellSelection.GetCount();
577 for ( n = 0; n < count; n++ )
578 {
579 wxGridCellCoords& coords = m_cellSelection[n];
580 if ( row == coords.GetRow() && col == coords.GetCol() )
581 {
582 wxRect r;
583 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
584 m_cellSelection[n] );
585 m_cellSelection.RemoveAt(n);
586 n--; count--;
587 if ( !m_grid->GetBatchCount() )
588 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
589 return;
590
591 // Send event
592 wxGridEvent gridEvt( m_grid->GetId(),
593 wxEVT_GRID_SELECT_CELL,
594 m_grid,
595 row, col, -1, -1, FALSE,
596 ControlDown, ShiftDown,
597 AltDown, MetaDown );
598 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
599 }
600 }
601 }
602
603 // The most difficult case: The cell is member of one or even several
604 // blocks. Split each such block in up to 4 new parts, that don't
605 // contain the cell to be selected, like this:
606 // |---------------------------|
607 // | |
608 // | part 1 |
609 // | |
610 // |---------------------------|
611 // | part 3 |x| part 4 |
612 // |---------------------------|
613 // | |
614 // | part 2 |
615 // | |
616 // |---------------------------|
617 // (The x marks the newly deselected cell).
618 // Note: in row selection mode, we only need part1 and part2;
619 // in column selection mode, we only need part 3 and part4,
620 // which are expanded to whole columns automatically!
621
622 count = m_blockSelectionTopLeft.GetCount();
623 for ( n = 0; n < count; n++ )
624 {
625 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
626 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
627 int topRow = coords1.GetRow();
628 int leftCol = coords1.GetCol();
629 int bottomRow = coords2.GetRow();
630 int rightCol = coords2.GetCol();
631 if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
632 row, col ) )
633 {
634 // remove the block
635 m_blockSelectionTopLeft.RemoveAt(n);
636 m_blockSelectionBottomRight.RemoveAt(n);
637 n--; count--;
638 // add up to 4 smaller blocks and set update region
639 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
640 {
641 if ( topRow < row )
642 SelectBlock( topRow, leftCol,
643 row - 1, rightCol, 0, FALSE );
644 if ( bottomRow > row )
645 SelectBlock( row + 1, leftCol,
646 bottomRow, rightCol, 0, FALSE );
647 }
648 if ( m_selectionMode != wxGrid::wxGridSelectRows )
649 {
650 if ( leftCol < col )
651 SelectBlock( row, leftCol, row, col - 1, 0, FALSE );
652 if ( rightCol > col )
653 SelectBlock( row, col + 1, row, rightCol, 0, FALSE );
654 }
655 }
656 }
657
658 // remove a cell from a row, adding up to two new blocks
659 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
660 {
661 count = m_rowSelection.GetCount();
662 for ( n = 0; n < count; n++ )
663 {
664 if ( m_rowSelection[n] == row )
665 {
666 m_rowSelection.RemoveAt(n);
667 n--; count--;
668 if (m_selectionMode == wxGrid::wxGridSelectCells)
669 {
670 if ( col > 0 )
671 SelectBlock( row, 0, row, col - 1, 0, FALSE );
672 if ( col < m_grid->GetNumberCols() - 1 )
673 SelectBlock( row, col + 1,
674 row, m_grid->GetNumberCols() - 1,
675 0, FALSE );
676 }
677 }
678 }
679 }
680
681 // remove a cell from a column, adding up to two new blocks
682 if ( m_selectionMode != wxGrid::wxGridSelectRows )
683 {
684 count = m_colSelection.GetCount();
685 for ( n = 0; n < count; n++ )
686 {
687 if ( m_colSelection[n] == col )
688 {
689 m_colSelection.RemoveAt(n);
690 n--; count--;
691 if (m_selectionMode == wxGrid::wxGridSelectCells)
692 {
693 if ( row > 0 )
694 SelectBlock( 0, col, row - 1, col, 0, FALSE );
695 if ( row < m_grid->GetNumberRows() - 1 )
696 SelectBlock( row + 1, col,
697 m_grid->GetNumberRows() - 1, col,
698 0, FALSE );
699 }
700 }
701 }
702 }
703
704 // Refresh the screen and send the event; according to m_selectionMode,
705 // we need to either update only the cell, or the whole row/column.
706 wxRect r;
707 switch (m_selectionMode)
708 {
709 case wxGrid::wxGridSelectCells:
710 {
711 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
712 wxGridCellCoords( row, col ) );
713 if ( !m_grid->GetBatchCount() )
714 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
715 wxGridEvent gridEvt( m_grid->GetId(),
716 wxEVT_GRID_SELECT_CELL,
717 m_grid,
718 row, col, -1, -1, FALSE,
719 ControlDown, ShiftDown,
720 AltDown, MetaDown );
721 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
722 break;
723 }
724 case wxGrid::wxGridSelectRows:
725 {
726 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
727 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
728 if ( !m_grid->GetBatchCount() )
729 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
730 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
731 wxEVT_GRID_RANGE_SELECT,
732 m_grid,
733 wxGridCellCoords( row, 0 ),
734 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ),
735 FALSE,
736 ControlDown, ShiftDown,
737 AltDown, MetaDown );
738 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
739 break;
740 }
741 case wxGrid::wxGridSelectColumns:
742 {
743 r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
744 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
745 if ( !m_grid->GetBatchCount() )
746 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
747 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
748 wxEVT_GRID_RANGE_SELECT,
749 m_grid,
750 wxGridCellCoords( 0, col ),
751 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ),
752 FALSE,
753 ControlDown, ShiftDown,
754 AltDown, MetaDown );
755 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
756 break;
757 }
758 }
759 }
760
761 void wxGridSelection::ClearSelection()
762 {
763 // Should this send deselection events?
764 size_t n;
765
766 // deselect all invidiual cells and update the screen
767 if ( m_selectionMode == wxGrid::wxGridSelectCells )
768 {
769
770 while( ( n = m_cellSelection.GetCount() ) > 0)
771 {
772 wxRect r;
773 n--;
774 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
775 m_cellSelection[n] );
776 m_cellSelection.RemoveAt(n);
777 if ( !m_grid->GetBatchCount() )
778 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
779 }
780 }
781
782 // deselect all blocks and update the screen
783 while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
784 {
785 wxRect r;
786 n--;
787 r = m_grid->BlockToDeviceRect( m_blockSelectionTopLeft[n],
788 m_blockSelectionBottomRight[n] );
789 m_blockSelectionTopLeft.RemoveAt(n);
790 m_blockSelectionBottomRight.RemoveAt(n);
791 if ( !m_grid->GetBatchCount() )
792 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
793 }
794
795 // deselect all rows and update the screen
796 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
797 {
798 while( ( n = m_rowSelection.GetCount() ) > 0)
799 {
800 n--;
801 int & row = m_rowSelection[n];
802 wxRect r;
803 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
804 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
805 m_rowSelection.RemoveAt(n);
806 if ( !m_grid->GetBatchCount() )
807 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
808 }
809 }
810
811 // deselect all columns and update the screen
812 if ( m_selectionMode != wxGrid::wxGridSelectRows )
813 {
814 while( ( n = m_colSelection.GetCount() ) > 0)
815 {
816 n--;
817 int & col = m_colSelection[n];
818 wxRect r;
819 r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
820 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
821 m_colSelection.RemoveAt(n);
822 if ( !m_grid->GetBatchCount() )
823 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
824 }
825 }
826 }
827
828
829 void wxGridSelection::UpdateRows( size_t pos, int numRows )
830 {
831 size_t count = m_cellSelection.GetCount();
832 size_t n;
833 for ( n = 0; n < count; n++ )
834 {
835 wxGridCellCoords& coords = m_cellSelection[n];
836 wxCoord row = coords.GetRow();
837 if ((size_t)row >= pos)
838 {
839 if (numRows > 0)
840 {
841 // If rows inserted, increase row counter where necessary
842 coords.SetRow(row + numRows);
843 }
844 else if (numRows < 0)
845 {
846 // If rows deleted ...
847 if ((size_t)row >= pos - numRows)
848 {
849 // ...either decrement row counter (if row still exists)...
850 coords.SetRow(row + numRows);
851 }
852 else
853 {
854 // ...or remove the attribute
855 m_cellSelection.RemoveAt(n);
856 n--; count--;
857 }
858 }
859 }
860 }
861
862 count = m_blockSelectionTopLeft.GetCount();
863 for ( n = 0; n < count; n++ )
864 {
865 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
866 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
867 wxCoord row1 = coords1.GetRow();
868 wxCoord row2 = coords2.GetRow();
869 if ((size_t)row2 >= pos)
870 {
871 if (numRows > 0)
872 {
873 // If rows inserted, increase row counter where necessary
874 coords2.SetRow(row2 + numRows);
875 if ( (size_t)row1 >= pos )
876 coords1.SetRow(row1 + numRows);
877 }
878 else if (numRows < 0)
879 {
880 // If rows deleted ...
881 if ((size_t)row2 >= pos - numRows)
882 {
883 // ...either decrement row counter (if row still exists)...
884 coords2.SetRow(row2 + numRows);
885 if ( (size_t) row1 >= pos)
886 coords1.SetRow( wxMax(row1 + numRows, (int) pos) );
887
888 }
889 else
890 {
891 if ( (size_t) row1 >= pos)
892 {
893 // ...or remove the attribute
894 m_blockSelectionTopLeft.RemoveAt(n);
895 m_blockSelectionBottomRight.RemoveAt(n);
896 n--; count--;
897 }
898 else
899 coords2.SetRow(pos);
900 }
901 }
902 }
903 }
904
905 count = m_rowSelection.GetCount();
906 for ( n = 0; n < count; n++ )
907 {
908 int & rowOrCol = m_rowSelection[n];
909 if ( (size_t)rowOrCol >= pos )
910 {
911 if ( numRows > 0 )
912 {
913 // If rows inserted, include row counter where necessary
914 rowOrCol += numRows;
915 }
916 else if ( numRows < 0)
917 {
918 // If rows deleted, either decrement row counter (if row still exists)
919 if ((size_t)rowOrCol >= pos - numRows)
920 rowOrCol += numRows;
921 else
922 {
923 m_rowSelection.RemoveAt(n);
924 n--; count--;
925 }
926 }
927 }
928 }
929 }
930
931 void wxGridSelection::UpdateCols( size_t pos, int numCols )
932 {
933 size_t count = m_cellSelection.GetCount();
934 size_t n;
935 for ( n = 0; n < count; n++ )
936 {
937 wxGridCellCoords& coords = m_cellSelection[n];
938 wxCoord col = coords.GetCol();
939 if ((size_t)col >= pos)
940 {
941 if (numCols > 0)
942 {
943 // If rows inserted, increase row counter where necessary
944 coords.SetCol(col + numCols);
945 }
946 else if (numCols < 0)
947 {
948 // If rows deleted ...
949 if ((size_t)col >= pos - numCols)
950 {
951 // ...either decrement row counter (if row still exists)...
952 coords.SetCol(col + numCols);
953 }
954 else
955 {
956 // ...or remove the attribute
957 m_cellSelection.RemoveAt(n);
958 n--; count--;
959 }
960 }
961 }
962 }
963
964 count = m_blockSelectionTopLeft.GetCount();
965 for ( n = 0; n < count; n++ )
966 {
967 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
968 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
969 wxCoord col1 = coords1.GetCol();
970 wxCoord col2 = coords2.GetCol();
971 if ((size_t)col2 >= pos)
972 {
973 if (numCols > 0)
974 {
975 // If rows inserted, increase row counter where necessary
976 coords2.SetCol(col2 + numCols);
977 if ( (size_t)col1 >= pos )
978 coords1.SetCol(col1 + numCols);
979 }
980 else if (numCols < 0)
981 {
982 // If cols deleted ...
983 if ((size_t)col2 >= pos - numCols)
984 {
985 // ...either decrement col counter (if col still exists)...
986 coords2.SetCol(col2 + numCols);
987 if ( (size_t) col1 >= pos)
988 coords1.SetCol( wxMax(col1 + numCols, (int) pos) );
989
990 }
991 else
992 {
993 if ( (size_t) col1 >= pos)
994 {
995 // ...or remove the attribute
996 m_blockSelectionTopLeft.RemoveAt(n);
997 m_blockSelectionBottomRight.RemoveAt(n);
998 n--; count--;
999 }
1000 else
1001 coords2.SetCol(pos);
1002 }
1003 }
1004 }
1005 }
1006
1007 count = m_colSelection.GetCount();
1008 for ( n = 0; n < count; n++ )
1009 {
1010 int & rowOrCol = m_colSelection[n];
1011 if ( (size_t)rowOrCol >= pos )
1012 {
1013 if ( numCols > 0 )
1014 {
1015 // If cols inserted, include col counter where necessary
1016 rowOrCol += numCols;
1017 }
1018 else if ( numCols < 0)
1019 {
1020 // If cols deleted, either decrement col counter (if col still exists)
1021 if ((size_t)rowOrCol >= pos - numCols)
1022 rowOrCol += numCols;
1023 else
1024 {
1025 m_colSelection.RemoveAt(n);
1026 n--; count--;
1027 }
1028 }
1029 }
1030 }
1031 }
1032
1033 int wxGridSelection::BlockContain( int topRow1, int leftCol1,
1034 int bottomRow1, int rightCol1,
1035 int topRow2, int leftCol2,
1036 int bottomRow2, int rightCol2 )
1037 // returns 1, if Block1 contains Block2,
1038 // -1, if Block2 contains Block1,
1039 // 0, otherwise
1040 {
1041 if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 &&
1042 leftCol1 <= leftCol2 && rightCol2 <= rightCol1 )
1043 return 1;
1044 else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 &&
1045 leftCol2 <= leftCol1 && rightCol1 <= rightCol2 )
1046 return -1;
1047 return 0;
1048 }
1049
1050 #endif