Added SetSelectionMode
[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 while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
151 {
152 n--;
153 wxGridCellCoords& coords = m_blockSelectionTopLeft[n];
154 int topRow = coords.GetRow();
155 int leftCol = coords.GetCol();
156 coords = m_blockSelectionBottomRight[n];
157 int bottomRow = coords.GetRow();
158 int rightCol = coords.GetCol();
159 if (selmode == wxGrid::wxGridSelectRows)
160 {
161 if (leftCol != 0 || rightCol != m_grid->GetNumberCols() - 1 )
162 {
163 m_blockSelectionTopLeft.RemoveAt(n);
164 m_blockSelectionBottomRight.RemoveAt(n);
165 SelectBlock( topRow, 0,
166 bottomRow, m_grid->GetNumberCols() - 1 );
167 }
168 }
169 else // selmode == wxGridSelectColumns)
170 {
171 if (topRow != 0 || bottomRow != m_grid->GetNumberRows() - 1 )
172 {
173 m_blockSelectionTopLeft.RemoveAt(n);
174 m_blockSelectionBottomRight.RemoveAt(n);
175 SelectBlock( 0, leftCol,
176 m_grid->GetNumberRows() - 1, rightCol );
177 }
178 }
179 }
180 }
181 }
182
183 void wxGridSelection::SelectRow( int row, bool addToSelected )
184 {
185 if ( m_selectionMode == wxGrid::wxGridSelectColumns )
186 return;
187 size_t count, n;
188
189 // Remove single cells contained in newly selected block.
190 if ( m_selectionMode == wxGrid::wxGridSelectCells )
191 {
192 count = m_cellSelection.GetCount();
193 for ( n = 0; n < count; n++ )
194 {
195 wxGridCellCoords& coords = m_cellSelection[n];
196 if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() - 1,
197 coords.GetRow(), coords.GetCol() ) )
198 {
199 m_cellSelection.RemoveAt(n);
200 n--; count--;
201 }
202 }
203 }
204
205 // Simplify list of selected blocks (if possible)
206 count = m_blockSelectionTopLeft.GetCount();
207 bool done = false;
208 for ( n = 0; n < count; n++ )
209 {
210 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
211 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
212
213 // Remove block if it is a subset of the row
214 if ( coords1.GetRow() == row && row == coords2.GetRow() )
215 {
216 m_blockSelectionTopLeft.RemoveAt(n);
217 m_blockSelectionBottomRight.RemoveAt(n);
218 n--; count--;
219 }
220 else if ( coords1.GetCol() == 0 &&
221 coords2.GetCol() == m_grid->GetNumberCols() - 1 )
222 {
223 // silently return, if row is contained in block
224 if ( coords1.GetRow() <= row && row <= coords2.GetRow() )
225 return;
226 // expand block, if it touched row
227 else if ( coords1.GetRow() == row + 1)
228 {
229 coords1.SetRow(row);
230 done = true;
231 }
232 else if ( coords2.GetRow() == row - 1)
233 {
234 coords2.SetRow(row);
235 done = true;
236 }
237 }
238 }
239
240 // Unless we successfully handled the row,
241 // check whether row is already selected.
242 if ( !done )
243 {
244 count = m_rowSelection.GetCount();
245 for ( n = 0; n < count; n++ )
246 {
247 if ( row == m_rowSelection[n] )
248 return;
249 }
250
251 // Add row to selection
252 m_rowSelection.Add(row);
253 }
254
255 // Update View:
256 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
257 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
258 if ( !m_grid->GetBatchCount() )
259 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
260
261 // Possibly send event here? This would imply that no event is sent,
262 // if the row already was part of the selection.
263 }
264
265 void wxGridSelection::SelectCol( int col, bool addToSelected )
266 {
267 if ( m_selectionMode == wxGrid::wxGridSelectRows )
268 return;
269 size_t count, n;
270
271 // Remove single cells contained in newly selected block.
272 if ( m_selectionMode == wxGrid::wxGridSelectCells )
273 {
274 count = m_cellSelection.GetCount();
275 for ( n = 0; n < count; n++ )
276 {
277 wxGridCellCoords& coords = m_cellSelection[n];
278 if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1, col,
279 coords.GetRow(), coords.GetCol() ) )
280 {
281 m_cellSelection.RemoveAt(n);
282 n--; count--;
283 }
284 }
285 }
286
287 // Simplify list of selected blocks (if possible)
288 count = m_blockSelectionTopLeft.GetCount();
289 bool done = false;
290 for ( n = 0; n < count; n++ )
291 {
292 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
293 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
294
295 // Remove block if it is a subset of the column
296 if ( coords1.GetCol() == col && col == coords2.GetCol() )
297 {
298 m_blockSelectionTopLeft.RemoveAt(n);
299 m_blockSelectionBottomRight.RemoveAt(n);
300 n--; count--;
301 }
302 else if ( coords1.GetRow() == 0 &&
303 coords2.GetRow() == m_grid->GetNumberRows() - 1 )
304 {
305 // silently return, if row is contained in block
306 if ( coords1.GetCol() <= col && col <= coords2.GetCol() )
307 return;
308 // expand block, if it touched col
309 else if ( coords1.GetCol() == col + 1)
310 {
311 coords1.SetCol(col);
312 done = true;
313 }
314 else if ( coords2.GetCol() == col - 1)
315 {
316 coords2.SetCol(col);
317 done = true;
318 }
319 }
320 }
321
322 // Unless we successfully handled the column,
323 // Check whether col is already selected.
324 if ( !done )
325 {
326 count = m_colSelection.GetCount();
327 for ( n = 0; n < count; n++ )
328 {
329 if ( col == m_colSelection[n] )
330 return;
331 }
332
333 // Add col to selection
334 m_colSelection.Add(col);
335 }
336
337 // Update View:
338 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
339 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
340 if ( !m_grid->GetBatchCount() )
341 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
342
343 // Possibly send event here? This would imply that no event is sent,
344 // if the row already was part of the selection.
345 }
346
347 void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol )
348 {
349 // Fix the coordinates of the block if potentially needed
350 if ( m_selectionMode == wxGrid::wxGridSelectRows )
351 {
352 leftCol = 0;
353 rightCol = m_grid->GetNumberCols() - 1;
354 }
355 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
356 {
357 topRow = 0;
358 bottomRow = m_grid->GetNumberRows() - 1;
359 }
360
361 // Handle single cell selection in SelectCell.
362 if ( topRow == bottomRow && leftCol == rightCol )
363 SelectCell( topRow, leftCol );
364
365 size_t count, n;
366 // Remove single cells contained in newly selected block.
367 if ( m_selectionMode == wxGrid::wxGridSelectCells )
368 {
369 count = m_cellSelection.GetCount();
370 for ( n = 0; n < count; n++ )
371 {
372 wxGridCellCoords& coords = m_cellSelection[n];
373 if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
374 coords.GetRow(), coords.GetCol() ) )
375 {
376 m_cellSelection.RemoveAt(n);
377 n--; count--;
378 }
379 }
380 }
381
382 // If a block containing the selection is already selected, return,
383 // if a block contained in the selection is found, remove it.
384
385 count = m_blockSelectionTopLeft.GetCount();
386 for ( n = 0; n < count; n++ )
387 {
388 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
389 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
390 switch ( BlockContain( coords1.GetRow(), coords1.GetCol(),
391 coords2.GetRow(), coords2.GetCol(),
392 topRow, leftCol, bottomRow, rightCol ) )
393 {
394 case 1:
395 return;
396 case -1:
397 m_blockSelectionTopLeft.RemoveAt(n);
398 m_blockSelectionBottomRight.RemoveAt(n);
399 n--; count--;
400 default:
401 ;
402 }
403 }
404
405 // If a row containing the selection is already selected, return,
406 // if a row contained in newly selected block is found, remove it.
407 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
408 {
409 count = m_rowSelection.GetCount();
410 for ( n = 0; n < count; n++ )
411 {
412 switch ( BlockContain( m_rowSelection[n], 0,
413 m_rowSelection[n], m_grid->GetNumberCols()-1,
414 topRow, leftCol, bottomRow, rightCol ) )
415 {
416 case 1:
417 return;
418 case -1:
419 m_rowSelection.RemoveAt(n);
420 n--; count--;
421 default:
422 ;
423 }
424 }
425 }
426 if ( m_selectionMode != wxGrid::wxGridSelectRows )
427 {
428 count = m_colSelection.GetCount();
429 for ( n = 0; n < count; n++ )
430 {
431 switch ( BlockContain( 0, m_colSelection[n],
432 m_grid->GetNumberRows()-1, m_colSelection[n],
433 topRow, leftCol, bottomRow, rightCol ) )
434 {
435 case 1:
436 return;
437 case -1:
438 m_colSelection.RemoveAt(n);
439 n--; count--;
440 default:
441 ;
442 }
443 }
444 }
445 m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) );
446 m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) );
447
448 // Update View:
449 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( topRow, leftCol ),
450 wxGridCellCoords( bottomRow, rightCol ) );
451 if ( !m_grid->GetBatchCount() )
452 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
453
454 // Possibly send event?
455 }
456
457 void wxGridSelection::SelectCell( int row, int col)
458 {
459 if ( m_selectionMode == wxGrid::wxGridSelectRows )
460 SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1 );
461 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
462 SelectBlock(0, col, m_grid->GetNumberRows() - 1, col );
463 else if ( IsInSelection ( row, col ) )
464 return;
465 m_cellSelection.Add( wxGridCellCoords( row, col ) );
466
467 // Update View:
468 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
469 wxGridCellCoords( row, col ) );
470 if ( !m_grid->GetBatchCount() )
471 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
472
473 // Possibly send event?
474 }
475
476 void wxGridSelection::ToggleCellSelection( int row, int col)
477 {
478 // if the cell is not selected, select it
479 if ( !IsInSelection ( row, col ) )
480 {
481 SelectCell( row, col );
482 return;
483 }
484
485 // otherwise deselect it. This can be simple or more or
486 // less difficult, depending on how the cell is selected.
487 size_t count, n;
488
489 // The simplest case: The cell is contained in m_cellSelection
490 // Then it can't be contained in rows/cols/block (since those
491 // would remove the cell from m_cellSelection on creation), so
492 // we just have to remove it from m_cellSelection.
493
494 if ( m_selectionMode == wxGrid::wxGridSelectCells )
495 {
496 count = m_cellSelection.GetCount();
497 for ( n = 0; n < count; n++ )
498 {
499 wxGridCellCoords& coords = m_cellSelection[n];
500 if ( row == coords.GetRow() && col == coords.GetCol() )
501 {
502 wxRect r;
503 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
504 m_cellSelection[n] );
505 m_cellSelection.RemoveAt(n);
506 n--; count--;
507 if ( !m_grid->GetBatchCount() )
508 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
509 return;
510 }
511 }
512 }
513
514 // The most difficult case: The cell is member of one or even several
515 // blocks. Split each such block in up to 4 new parts, that don't
516 // contain the cell to be selected, like this:
517 // |---------------------------|
518 // | |
519 // | part 1 |
520 // | |
521 // |---------------------------|
522 // | part 3 |x| part 4 |
523 // |---------------------------|
524 // | |
525 // | part 2 |
526 // | |
527 // |---------------------------|
528 // (The x marks the newly deselected cell).
529 // Note: in row selection mode, we only need part1 and part2;
530 // in column selection mode, we only need part 3 and part4,
531 // which are expanded to whole columns automatically!
532
533 count = m_blockSelectionTopLeft.GetCount();
534 for ( n = 0; n < count; n++ )
535 {
536 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
537 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
538 int topRow = coords1.GetRow();
539 int leftCol = coords1.GetCol();
540 int bottomRow = coords2.GetRow();
541 int rightCol = coords2.GetCol();
542 if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
543 row, col ) )
544 {
545 // remove the block
546 m_blockSelectionTopLeft.RemoveAt(n);
547 m_blockSelectionBottomRight.RemoveAt(n);
548 n--; count--;
549 // add up to 4 smaller blocks and set update region
550 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
551 {
552 if ( topRow < row )
553 SelectBlock( topRow, leftCol, row - 1, rightCol );
554 if ( bottomRow > row )
555 SelectBlock( row + 1, leftCol, bottomRow, rightCol );
556 }
557 if ( m_selectionMode != wxGrid::wxGridSelectRows )
558 {
559 if ( leftCol < col )
560 SelectBlock( row, leftCol, row, col - 1 );
561 if ( rightCol > col )
562 SelectBlock( row, col + 1, row, rightCol );
563 }
564 }
565 }
566
567 // remove a cell from a row, adding up to two new blocks
568 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
569 {
570 count = m_rowSelection.GetCount();
571 for ( n = 0; n < count; n++ )
572 {
573 if ( m_rowSelection[n] == row )
574 {
575 m_rowSelection.RemoveAt(n);
576 n--; count--;
577 if (m_selectionMode == wxGrid::wxGridSelectCells)
578 {
579 if ( col > 0 )
580 SelectBlock( row, 0, row, col - 1 );
581 if ( col < m_grid->GetNumberCols() - 1 )
582 SelectBlock( row, col + 1, row, m_grid->GetNumberCols() - 1 );
583 }
584 }
585 }
586 }
587
588 // remove a cell from a column, adding up to two new blocks
589 if ( m_selectionMode != wxGrid::wxGridSelectRows )
590 {
591 count = m_colSelection.GetCount();
592 for ( n = 0; n < count; n++ )
593 {
594 if ( m_colSelection[n] == col )
595 {
596 m_colSelection.RemoveAt(n);
597 n--; count--;
598 if (m_selectionMode == wxGrid::wxGridSelectCells)
599 {
600 if ( row > 0 )
601 SelectBlock( 0, col, row - 1, col );
602 if ( row < m_grid->GetNumberRows() - 1 )
603 SelectBlock( row + 1, col, m_grid->GetNumberRows() - 1, col );
604 }
605 }
606 }
607 }
608
609 // Refresh the screen; according to m_selectionMode, we
610 // need to either update only the cell, or the whole row/column.
611 wxRect r;
612 switch (m_selectionMode)
613 {
614 case wxGrid::wxGridSelectCells:
615 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
616 wxGridCellCoords( row, col ) );
617 break;
618 case wxGrid::wxGridSelectRows:
619 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
620 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
621 break;
622 case wxGrid::wxGridSelectColumns:
623 r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
624 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
625 break;
626 }
627 if ( !m_grid->GetBatchCount() )
628 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
629 }
630
631 void wxGridSelection::ClearSelection()
632 {
633 // Should this send deselection events?
634 size_t n;
635
636 // deselect all invidiual cells and update the screen
637 if ( m_selectionMode == wxGrid::wxGridSelectCells )
638 {
639
640 while( ( n = m_cellSelection.GetCount() ) > 0)
641 {
642 wxRect r;
643 n--;
644 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
645 m_cellSelection[n] );
646 m_cellSelection.RemoveAt(n);
647 if ( !m_grid->GetBatchCount() )
648 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
649 }
650 }
651
652 // deselect all blocks and update the screen
653 while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
654 {
655 wxRect r;
656 n--;
657 r = m_grid->BlockToDeviceRect( m_blockSelectionTopLeft[n],
658 m_blockSelectionBottomRight[n] );
659 m_blockSelectionTopLeft.RemoveAt(n);
660 m_blockSelectionBottomRight.RemoveAt(n);
661 if ( !m_grid->GetBatchCount() )
662 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
663 }
664
665 // deselect all rows and update the screen
666 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
667 {
668 while( ( n = m_rowSelection.GetCount() ) > 0)
669 {
670 n--;
671 int & row = m_rowSelection[n];
672 wxRect r;
673 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
674 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
675 m_rowSelection.RemoveAt(n);
676 if ( !m_grid->GetBatchCount() )
677 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
678 }
679 }
680
681 // deselect all columns and update the screen
682 if ( m_selectionMode != wxGrid::wxGridSelectRows )
683 {
684 while( ( n = m_colSelection.GetCount() ) > 0)
685 {
686 n--;
687 int & col = m_colSelection[n];
688 wxRect r;
689 r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
690 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
691 m_colSelection.RemoveAt(n);
692 if ( !m_grid->GetBatchCount() )
693 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
694 }
695 }
696 }
697
698
699 void wxGridSelection::UpdateRows( size_t pos, int numRows )
700 {
701 size_t count = m_cellSelection.GetCount();
702 size_t n;
703 for ( n = 0; n < count; n++ )
704 {
705 wxGridCellCoords& coords = m_cellSelection[n];
706 wxCoord row = coords.GetRow();
707 if ((size_t)row >= pos)
708 {
709 if (numRows > 0)
710 {
711 // If rows inserted, increase row counter where necessary
712 coords.SetRow(row + numRows);
713 }
714 else if (numRows < 0)
715 {
716 // If rows deleted ...
717 if ((size_t)row >= pos - numRows)
718 {
719 // ...either decrement row counter (if row still exists)...
720 coords.SetRow(row + numRows);
721 }
722 else
723 {
724 // ...or remove the attribute
725 m_cellSelection.RemoveAt(n);
726 n--; count--;
727 }
728 }
729 }
730 }
731
732 count = m_blockSelectionTopLeft.GetCount();
733 for ( n = 0; n < count; n++ )
734 {
735 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
736 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
737 wxCoord row1 = coords1.GetRow();
738 wxCoord row2 = coords2.GetRow();
739 if ((size_t)row2 >= pos)
740 {
741 if (numRows > 0)
742 {
743 // If rows inserted, increase row counter where necessary
744 coords2.SetRow(row2 + numRows);
745 if ( (size_t)row1 >= pos )
746 coords1.SetRow(row1 + numRows);
747 }
748 else if (numRows < 0)
749 {
750 // If rows deleted ...
751 if ((size_t)row2 >= pos - numRows)
752 {
753 // ...either decrement row counter (if row still exists)...
754 coords2.SetRow(row2 + numRows);
755 if ( (size_t) row1 >= pos)
756 coords1.SetRow( wxMax(row1 + numRows, (int) pos) );
757
758 }
759 else
760 {
761 if ( (size_t) row1 >= pos)
762 {
763 // ...or remove the attribute
764 m_blockSelectionTopLeft.RemoveAt(n);
765 m_blockSelectionBottomRight.RemoveAt(n);
766 n--; count--;
767 }
768 else
769 coords2.SetRow(pos);
770 }
771 }
772 }
773 }
774
775 count = m_rowSelection.GetCount();
776 for ( n = 0; n < count; n++ )
777 {
778 int & rowOrCol = m_rowSelection[n];
779 if ( (size_t)rowOrCol >= pos )
780 {
781 if ( numRows > 0 )
782 {
783 // If rows inserted, include row counter where necessary
784 rowOrCol += numRows;
785 }
786 else if ( numRows < 0)
787 {
788 // If rows deleted, either decrement row counter (if row still exists)
789 if ((size_t)rowOrCol >= pos - numRows)
790 rowOrCol += numRows;
791 else
792 {
793 m_rowSelection.RemoveAt(n);
794 n--; count--;
795 }
796 }
797 }
798 }
799 }
800
801 void wxGridSelection::UpdateCols( size_t pos, int numCols )
802 {
803 size_t count = m_cellSelection.GetCount();
804 size_t n;
805 for ( n = 0; n < count; n++ )
806 {
807 wxGridCellCoords& coords = m_cellSelection[n];
808 wxCoord col = coords.GetCol();
809 if ((size_t)col >= pos)
810 {
811 if (numCols > 0)
812 {
813 // If rows inserted, increase row counter where necessary
814 coords.SetCol(col + numCols);
815 }
816 else if (numCols < 0)
817 {
818 // If rows deleted ...
819 if ((size_t)col >= pos - numCols)
820 {
821 // ...either decrement row counter (if row still exists)...
822 coords.SetCol(col + numCols);
823 }
824 else
825 {
826 // ...or remove the attribute
827 m_cellSelection.RemoveAt(n);
828 n--; count--;
829 }
830 }
831 }
832 }
833
834 count = m_blockSelectionTopLeft.GetCount();
835 for ( n = 0; n < count; n++ )
836 {
837 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
838 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
839 wxCoord col1 = coords1.GetCol();
840 wxCoord col2 = coords2.GetCol();
841 if ((size_t)col2 >= pos)
842 {
843 if (numCols > 0)
844 {
845 // If rows inserted, increase row counter where necessary
846 coords2.SetCol(col2 + numCols);
847 if ( (size_t)col1 >= pos )
848 coords1.SetCol(col1 + numCols);
849 }
850 else if (numCols < 0)
851 {
852 // If cols deleted ...
853 if ((size_t)col2 >= pos - numCols)
854 {
855 // ...either decrement col counter (if col still exists)...
856 coords2.SetCol(col2 + numCols);
857 if ( (size_t) col1 >= pos)
858 coords1.SetCol( wxMax(col1 + numCols, (int) pos) );
859
860 }
861 else
862 {
863 if ( (size_t) col1 >= pos)
864 {
865 // ...or remove the attribute
866 m_blockSelectionTopLeft.RemoveAt(n);
867 m_blockSelectionBottomRight.RemoveAt(n);
868 n--; count--;
869 }
870 else
871 coords2.SetCol(pos);
872 }
873 }
874 }
875 }
876
877 count = m_colSelection.GetCount();
878 for ( n = 0; n < count; n++ )
879 {
880 int & rowOrCol = m_colSelection[n];
881 if ( (size_t)rowOrCol >= pos )
882 {
883 if ( numCols > 0 )
884 {
885 // If cols inserted, include col counter where necessary
886 rowOrCol += numCols;
887 }
888 else if ( numCols < 0)
889 {
890 // If cols deleted, either decrement col counter (if col still exists)
891 if ((size_t)rowOrCol >= pos - numCols)
892 rowOrCol += numCols;
893 else
894 {
895 m_colSelection.RemoveAt(n);
896 n--; count--;
897 }
898 }
899 }
900 }
901 }
902
903 int wxGridSelection::BlockContain( int topRow1, int leftCol1,
904 int bottomRow1, int rightCol1,
905 int topRow2, int leftCol2,
906 int bottomRow2, int rightCol2 )
907 // returns 1, if Block1 contains Block2,
908 // -1, if Block2 contains Block1,
909 // 0, otherwise
910 {
911 if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 &&
912 leftCol1 <= leftCol2 && rightCol2 <= rightCol1 )
913 return 1;
914 else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 &&
915 leftCol2 <= leftCol1 && rightCol1 <= rightCol2 )
916 return -1;
917 return 0;
918 }
919
920 #endif