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