]> git.saurik.com Git - wxWidgets.git/blame - src/generic/gridsel.cpp
removed extern from inline function declarations
[wxWidgets.git] / src / generic / gridsel.cpp
CommitLineData
294f6bcb
SN
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
f1567cdd
SN
33#if defined(wxUSE_NEW_GRID) && (wxUSE_NEW_GRID)
34
294f6bcb
SN
35#include "wx/generic/gridsel.h"
36
f1567cdd
SN
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
294f6bcb 46wxGridSelection::wxGridSelection( wxGrid * grid,
b5808881 47 wxGrid::wxGridSelectionModes sel )
294f6bcb
SN
48{
49 m_grid = grid;
50 m_selectionMode = sel;
51}
52
53bool wxGridSelection::IsSelection()
54{
55 return ( m_cellSelection.GetCount() || m_blockSelectionTopLeft.GetCount() ||
b5808881 56 m_rowSelection.GetCount() || m_colSelection.GetCount() );
294f6bcb
SN
57}
58
59bool wxGridSelection::IsInSelection ( int row, int col )
60{
f1567cdd
SN
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 )
294f6bcb
SN
66 {
67 count = m_cellSelection.GetCount();
b5808881
SN
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 }
294f6bcb 74 }
f1567cdd
SN
75
76 // Now check whether the given cell is
77 // contained in one of the selected blocks.
294f6bcb
SN
78 count = m_blockSelectionTopLeft.GetCount();
79 for ( size_t n = 0; n < count; n++ )
80 {
b5808881
SN
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 }
f1567cdd
SN
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).
b5808881 92 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
294f6bcb 93 {
b5808881
SN
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 }
f1567cdd
SN
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).
b5808881 105 if ( m_selectionMode != wxGrid::wxGridSelectRows )
294f6bcb 106 {
b5808881
SN
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 }
294f6bcb
SN
113 }
114 return false;
115}
116
f1567cdd
SN
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 }
043d16b2
SN
150
151 for (n = 0; n < m_blockSelectionTopLeft.GetCount(); n++)
152 // Note that m_blockSelectionTopLeft's size may be changing!
f1567cdd 153 {
f1567cdd
SN
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 }
043d16b2 181 m_selectionMode = selmode;
f1567cdd
SN
182 }
183}
184
b14159f7 185void wxGridSelection::SelectRow( int row, bool addToSelected )
294f6bcb 186{
b5808881 187 if ( m_selectionMode == wxGrid::wxGridSelectColumns )
294f6bcb 188 return;
f1567cdd 189 size_t count, n;
294f6bcb
SN
190
191 // Remove single cells contained in newly selected block.
f1567cdd 192 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
193 {
194 count = m_cellSelection.GetCount();
f1567cdd 195 for ( n = 0; n < count; n++ )
b5808881
SN
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 }
294f6bcb
SN
205 }
206
f1567cdd 207 // Simplify list of selected blocks (if possible)
294f6bcb 208 count = m_blockSelectionTopLeft.GetCount();
f1567cdd 209 bool done = false;
b14159f7 210 for ( n = 0; n < count; n++ )
294f6bcb 211 {
b5808881
SN
212 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
213 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
f1567cdd
SN
214
215 // Remove block if it is a subset of the row
b5808881
SN
216 if ( coords1.GetRow() == row && row == coords2.GetRow() )
217 {
218 m_blockSelectionTopLeft.RemoveAt(n);
219 m_blockSelectionBottomRight.RemoveAt(n);
220 n--; count--;
f1567cdd 221 }
b5808881
SN
222 else if ( coords1.GetCol() == 0 &&
223 coords2.GetCol() == m_grid->GetNumberCols() - 1 )
224 {
f1567cdd 225 // silently return, if row is contained in block
b5808881
SN
226 if ( coords1.GetRow() <= row && row <= coords2.GetRow() )
227 return;
f1567cdd 228 // expand block, if it touched row
b5808881
SN
229 else if ( coords1.GetRow() == row + 1)
230 {
231 coords1.SetRow(row);
f1567cdd 232 done = true;
b5808881
SN
233 }
234 else if ( coords2.GetRow() == row - 1)
235 {
236 coords2.SetRow(row);
f1567cdd 237 done = true;
b5808881
SN
238 }
239 }
294f6bcb
SN
240 }
241
f1567cdd
SN
242 // Unless we successfully handled the row,
243 // check whether row is already selected.
244 if ( !done )
294f6bcb 245 {
f1567cdd
SN
246 count = m_rowSelection.GetCount();
247 for ( n = 0; n < count; n++ )
248 {
249 if ( row == m_rowSelection[n] )
250 return;
251 }
294f6bcb 252
f1567cdd
SN
253 // Add row to selection
254 m_rowSelection.Add(row);
255 }
b5808881
SN
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 );
f1567cdd
SN
262
263 // Possibly send event here? This would imply that no event is sent,
264 // if the row already was part of the selection.
294f6bcb
SN
265}
266
b14159f7 267void wxGridSelection::SelectCol( int col, bool addToSelected )
294f6bcb 268{
b5808881 269 if ( m_selectionMode == wxGrid::wxGridSelectRows )
294f6bcb 270 return;
f1567cdd 271 size_t count, n;
294f6bcb
SN
272
273 // Remove single cells contained in newly selected block.
f1567cdd 274 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
275 {
276 count = m_cellSelection.GetCount();
f1567cdd 277 for ( n = 0; n < count; n++ )
b5808881
SN
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 }
294f6bcb
SN
287 }
288
f1567cdd 289 // Simplify list of selected blocks (if possible)
294f6bcb 290 count = m_blockSelectionTopLeft.GetCount();
f1567cdd 291 bool done = false;
b14159f7 292 for ( n = 0; n < count; n++ )
294f6bcb 293 {
b5808881
SN
294 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
295 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
f1567cdd
SN
296
297 // Remove block if it is a subset of the column
b5808881
SN
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 {
f1567cdd 307 // silently return, if row is contained in block
b5808881
SN
308 if ( coords1.GetCol() <= col && col <= coords2.GetCol() )
309 return;
f1567cdd 310 // expand block, if it touched col
b5808881
SN
311 else if ( coords1.GetCol() == col + 1)
312 {
313 coords1.SetCol(col);
f1567cdd 314 done = true;
b5808881
SN
315 }
316 else if ( coords2.GetCol() == col - 1)
317 {
318 coords2.SetCol(col);
f1567cdd 319 done = true;
b5808881
SN
320 }
321 }
294f6bcb
SN
322 }
323
f1567cdd 324 // Unless we successfully handled the column,
294f6bcb 325 // Check whether col is already selected.
f1567cdd 326 if ( !done )
294f6bcb 327 {
f1567cdd
SN
328 count = m_colSelection.GetCount();
329 for ( n = 0; n < count; n++ )
330 {
331 if ( col == m_colSelection[n] )
332 return;
333 }
294f6bcb 334
f1567cdd
SN
335 // Add col to selection
336 m_colSelection.Add(col);
337 }
b5808881
SN
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 );
f1567cdd
SN
344
345 // Possibly send event here? This would imply that no event is sent,
346 // if the row already was part of the selection.
294f6bcb
SN
347}
348
349void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol )
350{
351 // Fix the coordinates of the block if potentially needed
b5808881 352 if ( m_selectionMode == wxGrid::wxGridSelectRows )
294f6bcb 353 {
b5808881
SN
354 leftCol = 0;
355 rightCol = m_grid->GetNumberCols() - 1;
294f6bcb 356 }
b5808881 357 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
294f6bcb 358 {
b5808881
SN
359 topRow = 0;
360 bottomRow = m_grid->GetNumberRows() - 1;
294f6bcb
SN
361 }
362
363 // Handle single cell selection in SelectCell.
364 if ( topRow == bottomRow && leftCol == rightCol )
365 SelectCell( topRow, leftCol );
366
f1567cdd 367 size_t count, n;
294f6bcb 368 // Remove single cells contained in newly selected block.
f1567cdd 369 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
370 {
371 count = m_cellSelection.GetCount();
f1567cdd 372 for ( n = 0; n < count; n++ )
b5808881
SN
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 }
294f6bcb
SN
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();
f1567cdd 388 for ( n = 0; n < count; n++ )
294f6bcb 389 {
b5808881
SN
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 }
294f6bcb
SN
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.
b5808881 409 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
294f6bcb 410 {
f1567cdd
SN
411 count = m_rowSelection.GetCount();
412 for ( n = 0; n < count; n++ )
b5808881
SN
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 )
294f6bcb 429 {
f1567cdd
SN
430 count = m_colSelection.GetCount();
431 for ( n = 0; n < count; n++ )
b5808881
SN
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 }
294f6bcb
SN
446 }
447 m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) );
448 m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) );
b5808881
SN
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 );
f1567cdd
SN
455
456 // Possibly send event?
294f6bcb
SN
457}
458
459void wxGridSelection::SelectCell( int row, int col)
460{
b5808881 461 if ( m_selectionMode == wxGrid::wxGridSelectRows )
043d16b2 462 {
294f6bcb 463 SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1 );
043d16b2
SN
464 return;
465 }
b5808881 466 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
043d16b2 467 {
294f6bcb 468 SelectBlock(0, col, m_grid->GetNumberRows() - 1, col );
043d16b2
SN
469 return;
470 }
294f6bcb
SN
471 else if ( IsInSelection ( row, col ) )
472 return;
473 m_cellSelection.Add( wxGridCellCoords( row, col ) );
b5808881 474
f1567cdd 475 // Update View:
b5808881
SN
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 );
f1567cdd
SN
480
481 // Possibly send event?
294f6bcb
SN
482}
483
484void wxGridSelection::ToggleCellSelection( int row, int col)
485{
f1567cdd 486 // if the cell is not selected, select it
294f6bcb 487 if ( !IsInSelection ( row, col ) )
b5808881 488 {
294f6bcb 489 SelectCell( row, col );
b5808881
SN
490 return;
491 }
294f6bcb 492
f1567cdd
SN
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.
294f6bcb 501
f1567cdd 502 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
503 {
504 count = m_cellSelection.GetCount();
f1567cdd 505 for ( n = 0; n < count; n++ )
b5808881
SN
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 }
294f6bcb
SN
520 }
521
f1567cdd
SN
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
294f6bcb 541 count = m_blockSelectionTopLeft.GetCount();
f1567cdd 542 for ( n = 0; n < count; n++ )
294f6bcb 543 {
b5808881
SN
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 }
294f6bcb
SN
573 }
574
575 // remove a cell from a row, adding up to two new blocks
b5808881 576 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
294f6bcb 577 {
f1567cdd
SN
578 count = m_rowSelection.GetCount();
579 for ( n = 0; n < count; n++ )
b5808881
SN
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 }
294f6bcb
SN
594 }
595
596 // remove a cell from a column, adding up to two new blocks
b5808881 597 if ( m_selectionMode != wxGrid::wxGridSelectRows )
294f6bcb 598 {
f1567cdd
SN
599 count = m_colSelection.GetCount();
600 for ( n = 0; n < count; n++ )
b5808881
SN
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 }
294f6bcb 615 }
f1567cdd
SN
616
617 // Refresh the screen; according to m_selectionMode, we
618 // need to either update only the cell, or the whole row/column.
294f6bcb
SN
619 wxRect r;
620 switch (m_selectionMode)
621 {
b5808881
SN
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;
294f6bcb
SN
634 }
635 if ( !m_grid->GetBatchCount() )
636 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
637}
638
639void wxGridSelection::ClearSelection()
640{
f1567cdd 641 // Should this send deselection events?
294f6bcb 642 size_t n;
f1567cdd
SN
643
644 // deselect all invidiual cells and update the screen
645 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
646 {
647
b5808881
SN
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 }
294f6bcb 658 }
f1567cdd
SN
659
660 // deselect all blocks and update the screen
294f6bcb
SN
661 while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
662 {
663 wxRect r;
b5808881
SN
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 }
f1567cdd
SN
672
673 // deselect all rows and update the screen
b5808881 674 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
294f6bcb 675 {
b5808881
SN
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 }
f1567cdd
SN
688
689 // deselect all columns and update the screen
b5808881 690 if ( m_selectionMode != wxGrid::wxGridSelectRows )
294f6bcb 691 {
b5808881
SN
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 }
294f6bcb
SN
703 }
704}
705
706
707void wxGridSelection::UpdateRows( size_t pos, int numRows )
708{
709 size_t count = m_cellSelection.GetCount();
b14159f7
JS
710 size_t n;
711 for ( n = 0; n < count; n++ )
294f6bcb
SN
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();
b14159f7 741 for ( n = 0; n < count; n++ )
294f6bcb
SN
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);
b5808881
SN
753 if ( (size_t)row1 >= pos )
754 coords1.SetRow(row1 + numRows);
294f6bcb
SN
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);
b5808881
SN
763 if ( (size_t) row1 >= pos)
764 coords1.SetRow( wxMax(row1 + numRows, (int) pos) );
765
294f6bcb
SN
766 }
767 else
768 {
b5808881
SN
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);
294f6bcb
SN
778 }
779 }
780 }
781 }
782
783 count = m_rowSelection.GetCount();
b14159f7 784 for ( n = 0; n < count; n++ )
294f6bcb
SN
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
809void wxGridSelection::UpdateCols( size_t pos, int numCols )
810{
811 size_t count = m_cellSelection.GetCount();
b14159f7
JS
812 size_t n;
813 for ( n = 0; n < count; n++ )
294f6bcb
SN
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();
b14159f7 843 for ( n = 0; n < count; n++ )
294f6bcb
SN
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);
b5808881
SN
855 if ( (size_t)col1 >= pos )
856 coords1.SetCol(col1 + numCols);
294f6bcb
SN
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);
b5808881
SN
865 if ( (size_t) col1 >= pos)
866 coords1.SetCol( wxMax(col1 + numCols, (int) pos) );
867
294f6bcb
SN
868 }
869 else
870 {
b5808881
SN
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);
294f6bcb
SN
880 }
881 }
882 }
883 }
884
885 count = m_colSelection.GetCount();
b14159f7 886 for ( n = 0; n < count; n++ )
294f6bcb
SN
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
911int wxGridSelection::BlockContain( int topRow1, int leftCol1,
b5808881
SN
912 int bottomRow1, int rightCol1,
913 int topRow2, int leftCol2,
914 int bottomRow2, int rightCol2 )
294f6bcb
SN
915// returns 1, if Block1 contains Block2,
916// -1, if Block2 contains Block1,
917// 0, otherwise
918{
919 if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 &&
b5808881 920 leftCol1 <= leftCol2 && rightCol2 <= rightCol1 )
294f6bcb
SN
921 return 1;
922 else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 &&
b5808881 923 leftCol2 <= leftCol1 && rightCol1 <= rightCol2 )
294f6bcb
SN
924 return -1;
925 return 0;
926}
f1567cdd
SN
927
928#endif