]> git.saurik.com Git - wxWidgets.git/blame - src/generic/gridsel.cpp
Fix hit testing in generic wxDataViewToggleRenderer.
[wxWidgets.git] / src / generic / gridsel.cpp
CommitLineData
294f6bcb 1///////////////////////////////////////////////////////////////////////////
93763ad5 2// Name: src/generic/gridsel.cpp
294f6bcb
SN
3// Purpose: wxGridSelection
4// Author: Stefan Neis
5// Modified by:
6// Created: 20/02/1999
2b5f62a0 7// RCS-ID: $Id$
294f6bcb 8// Copyright: (c) Stefan Neis (Stefan.Neis@t-online.de)
65571936 9// Licence: wxWindows licence
294f6bcb
SN
10/////////////////////////////////////////////////////////////////////////////
11
93763ad5
WS
12// For compilers that support precompilation, includes "wx/wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
294f6bcb
SN
19// ============================================================================
20// declarations
21// ============================================================================
22
23// ----------------------------------------------------------------------------
24// headers
25// ----------------------------------------------------------------------------
26
f7556ff0 27#if wxUSE_GRID
f1567cdd 28
294f6bcb
SN
29#include "wx/generic/gridsel.h"
30
a0bd3147 31
f1567cdd
SN
32// Some explanation for the members of the class:
33// m_cellSelection stores individual selected cells
34// -- this is only used if m_selectionMode == wxGridSelectCells
35// m_blockSelectionTopLeft and m_blockSelectionBottomRight
36// store the upper left and lower right corner of selected Blocks
37// m_rowSelection and m_colSelection store individual selected
38// rows and columns; maybe those are superfluous and should be
39// treated as blocks?
40
294f6bcb 41wxGridSelection::wxGridSelection( wxGrid * grid,
b5808881 42 wxGrid::wxGridSelectionModes sel )
294f6bcb
SN
43{
44 m_grid = grid;
45 m_selectionMode = sel;
46}
47
48bool wxGridSelection::IsSelection()
49{
50 return ( m_cellSelection.GetCount() || m_blockSelectionTopLeft.GetCount() ||
b5808881 51 m_rowSelection.GetCount() || m_colSelection.GetCount() );
294f6bcb
SN
52}
53
a0bd3147 54bool wxGridSelection::IsInSelection( int row, int col )
294f6bcb 55{
f1567cdd
SN
56 size_t count;
57
58 // First check whether the given cell is individually selected
59 // (if m_selectionMode is wxGridSelectCells).
60 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
61 {
62 count = m_cellSelection.GetCount();
b5808881
SN
63 for ( size_t n = 0; n < count; n++ )
64 {
65 wxGridCellCoords& coords = m_cellSelection[n];
66 if ( row == coords.GetRow() && col == coords.GetCol() )
ca65c044 67 return true;
b5808881 68 }
294f6bcb 69 }
f1567cdd
SN
70
71 // Now check whether the given cell is
72 // contained in one of the selected blocks.
294f6bcb
SN
73 count = m_blockSelectionTopLeft.GetCount();
74 for ( size_t n = 0; n < count; n++ )
75 {
b5808881
SN
76 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
77 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
78 if ( BlockContainsCell(coords1.GetRow(), coords1.GetCol(),
79 coords2.GetRow(), coords2.GetCol(),
80 row, col ) )
ca65c044 81 return true;
b5808881 82 }
f1567cdd
SN
83
84 // Now check whether the given cell is
85 // contained in one of the selected rows
86 // (unless we are in column selection mode).
b5808881 87 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
294f6bcb 88 {
4e115ed2 89 count = m_rowSelection.GetCount();
b5808881
SN
90 for ( size_t n = 0; n < count; n++ )
91 {
92 if ( row == m_rowSelection[n] )
ca65c044 93 return true;
b5808881
SN
94 }
95 }
f1567cdd
SN
96
97 // Now check whether the given cell is
98 // contained in one of the selected columns
99 // (unless we are in row selection mode).
b5808881 100 if ( m_selectionMode != wxGrid::wxGridSelectRows )
294f6bcb 101 {
4e115ed2 102 count = m_colSelection.GetCount();
b5808881
SN
103 for ( size_t n = 0; n < count; n++ )
104 {
105 if ( col == m_colSelection[n] )
ca65c044 106 return true;
b5808881 107 }
294f6bcb 108 }
a0bd3147 109
ca65c044 110 return false;
294f6bcb
SN
111}
112
f1567cdd 113// Change the selection mode
a0bd3147 114void wxGridSelection::SetSelectionMode( wxGrid::wxGridSelectionModes selmode )
f1567cdd
SN
115{
116 // if selection mode is unchanged return immediately
117 if (selmode == m_selectionMode)
118 return;
119
120 if ( m_selectionMode != wxGrid::wxGridSelectCells )
121 {
122 // if changing form row to column selection
123 // or vice versa, clear the selection.
124 if ( selmode != wxGrid::wxGridSelectCells )
125 ClearSelection();
126
127 m_selectionMode = selmode;
128 }
129 else
130 {
131 // if changing from cell selection to something else,
132 // promote selected cells/blocks to whole rows/columns.
133 size_t n;
134 while ( ( n = m_cellSelection.GetCount() ) > 0 )
135 {
136 n--;
137 wxGridCellCoords& coords = m_cellSelection[n];
138 int row = coords.GetRow();
139 int col = coords.GetCol();
140 m_cellSelection.RemoveAt(n);
141 if (selmode == wxGrid::wxGridSelectRows)
142 SelectRow( row );
143 else // selmode == wxGridSelectColumns)
144 SelectCol( col );
145 }
043d16b2 146
043d16b2 147 // Note that m_blockSelectionTopLeft's size may be changing!
a0bd3147 148 for (n = 0; n < m_blockSelectionTopLeft.GetCount(); n++)
f1567cdd 149 {
f1567cdd
SN
150 wxGridCellCoords& coords = m_blockSelectionTopLeft[n];
151 int topRow = coords.GetRow();
152 int leftCol = coords.GetCol();
153 coords = m_blockSelectionBottomRight[n];
154 int bottomRow = coords.GetRow();
155 int rightCol = coords.GetCol();
a0bd3147 156
f1567cdd
SN
157 if (selmode == wxGrid::wxGridSelectRows)
158 {
159 if (leftCol != 0 || rightCol != m_grid->GetNumberCols() - 1 )
160 {
161 m_blockSelectionTopLeft.RemoveAt(n);
162 m_blockSelectionBottomRight.RemoveAt(n);
8b5f6d9d
VZ
163 SelectBlockNoEvent( topRow, 0,
164 bottomRow, m_grid->GetNumberCols() - 1);
f1567cdd
SN
165 }
166 }
167 else // selmode == wxGridSelectColumns)
168 {
169 if (topRow != 0 || bottomRow != m_grid->GetNumberRows() - 1 )
170 {
171 m_blockSelectionTopLeft.RemoveAt(n);
172 m_blockSelectionBottomRight.RemoveAt(n);
8b5f6d9d
VZ
173 SelectBlockNoEvent(0, leftCol,
174 m_grid->GetNumberRows() - 1, rightCol);
f1567cdd
SN
175 }
176 }
177 }
a0bd3147 178
043d16b2 179 m_selectionMode = selmode;
f1567cdd
SN
180 }
181}
182
8b5f6d9d 183void wxGridSelection::SelectRow(int row, const wxKeyboardState& kbd)
294f6bcb 184{
b5808881 185 if ( m_selectionMode == wxGrid::wxGridSelectColumns )
294f6bcb 186 return;
a0bd3147 187
f1567cdd 188 size_t count, n;
294f6bcb
SN
189
190 // Remove single cells contained in newly selected block.
f1567cdd 191 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
192 {
193 count = m_cellSelection.GetCount();
f1567cdd 194 for ( n = 0; n < count; n++ )
b5808881
SN
195 {
196 wxGridCellCoords& coords = m_cellSelection[n];
197 if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() - 1,
198 coords.GetRow(), coords.GetCol() ) )
199 {
200 m_cellSelection.RemoveAt(n);
a0bd3147
DS
201 n--;
202 count--;
b5808881
SN
203 }
204 }
294f6bcb
SN
205 }
206
f1567cdd 207 // Simplify list of selected blocks (if possible)
294f6bcb 208 count = m_blockSelectionTopLeft.GetCount();
ca65c044 209 bool done = false;
a0bd3147 210
b14159f7 211 for ( n = 0; n < count; n++ )
294f6bcb 212 {
b5808881
SN
213 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
214 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
f1567cdd
SN
215
216 // Remove block if it is a subset of the row
b5808881
SN
217 if ( coords1.GetRow() == row && row == coords2.GetRow() )
218 {
219 m_blockSelectionTopLeft.RemoveAt(n);
220 m_blockSelectionBottomRight.RemoveAt(n);
a0bd3147
DS
221 n--;
222 count--;
f1e26920 223 }
b5808881
SN
224 else if ( coords1.GetCol() == 0 &&
225 coords2.GetCol() == m_grid->GetNumberCols() - 1 )
226 {
f1567cdd 227 // silently return, if row is contained in block
b5808881
SN
228 if ( coords1.GetRow() <= row && row <= coords2.GetRow() )
229 return;
f1567cdd 230 // expand block, if it touched row
b5808881
SN
231 else if ( coords1.GetRow() == row + 1)
232 {
233 coords1.SetRow(row);
ca65c044 234 done = true;
b5808881
SN
235 }
236 else if ( coords2.GetRow() == row - 1)
237 {
238 coords2.SetRow(row);
ca65c044 239 done = true;
f1e26920 240 }
b5808881 241 }
294f6bcb
SN
242 }
243
f1567cdd
SN
244 // Unless we successfully handled the row,
245 // check whether row is already selected.
246 if ( !done )
294f6bcb 247 {
f1567cdd
SN
248 count = m_rowSelection.GetCount();
249 for ( n = 0; n < count; n++ )
250 {
251 if ( row == m_rowSelection[n] )
252 return;
253 }
294f6bcb 254
f1567cdd
SN
255 // Add row to selection
256 m_rowSelection.Add(row);
257 }
b5808881
SN
258
259 // Update View:
b5808881 260 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
261 {
262 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
263 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
ca65c044 264 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
3665f7d0 265 }
f1567cdd 266
5c8fc7c1
SN
267 // Send Event
268 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
269 wxEVT_GRID_RANGE_SELECT,
270 m_grid,
271 wxGridCellCoords( row, 0 ),
d95b0c2b 272 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ),
ca65c044 273 true,
8b5f6d9d 274 kbd);
5c8fc7c1 275
a0bd3147 276 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
294f6bcb
SN
277}
278
8b5f6d9d 279void wxGridSelection::SelectCol(int col, const wxKeyboardState& kbd)
294f6bcb 280{
b5808881 281 if ( m_selectionMode == wxGrid::wxGridSelectRows )
294f6bcb 282 return;
f1567cdd 283 size_t count, n;
294f6bcb
SN
284
285 // Remove single cells contained in newly selected block.
f1567cdd 286 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
287 {
288 count = m_cellSelection.GetCount();
f1567cdd 289 for ( n = 0; n < count; n++ )
b5808881
SN
290 {
291 wxGridCellCoords& coords = m_cellSelection[n];
292 if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1, col,
293 coords.GetRow(), coords.GetCol() ) )
294 {
295 m_cellSelection.RemoveAt(n);
a0bd3147
DS
296 n--;
297 count--;
b5808881
SN
298 }
299 }
294f6bcb
SN
300 }
301
f1567cdd 302 // Simplify list of selected blocks (if possible)
294f6bcb 303 count = m_blockSelectionTopLeft.GetCount();
ca65c044 304 bool done = false;
b14159f7 305 for ( n = 0; n < count; n++ )
294f6bcb 306 {
b5808881
SN
307 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
308 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
f1567cdd
SN
309
310 // Remove block if it is a subset of the column
b5808881
SN
311 if ( coords1.GetCol() == col && col == coords2.GetCol() )
312 {
313 m_blockSelectionTopLeft.RemoveAt(n);
314 m_blockSelectionBottomRight.RemoveAt(n);
a0bd3147
DS
315 n--;
316 count--;
b5808881
SN
317 }
318 else if ( coords1.GetRow() == 0 &&
319 coords2.GetRow() == m_grid->GetNumberRows() - 1 )
320 {
f1567cdd 321 // silently return, if row is contained in block
b5808881
SN
322 if ( coords1.GetCol() <= col && col <= coords2.GetCol() )
323 return;
f1567cdd 324 // expand block, if it touched col
b5808881
SN
325 else if ( coords1.GetCol() == col + 1)
326 {
327 coords1.SetCol(col);
ca65c044 328 done = true;
b5808881
SN
329 }
330 else if ( coords2.GetCol() == col - 1)
331 {
332 coords2.SetCol(col);
ca65c044 333 done = true;
f1e26920 334 }
b5808881 335 }
294f6bcb
SN
336 }
337
f1567cdd 338 // Unless we successfully handled the column,
294f6bcb 339 // Check whether col is already selected.
f1567cdd 340 if ( !done )
294f6bcb 341 {
f1567cdd
SN
342 count = m_colSelection.GetCount();
343 for ( n = 0; n < count; n++ )
344 {
345 if ( col == m_colSelection[n] )
346 return;
347 }
294f6bcb 348
f1567cdd
SN
349 // Add col to selection
350 m_colSelection.Add(col);
351 }
b5808881
SN
352
353 // Update View:
b5808881 354 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
355 {
356 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
357 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
ca65c044 358 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
3665f7d0 359 }
f1567cdd 360
5c8fc7c1
SN
361 // Send Event
362 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
363 wxEVT_GRID_RANGE_SELECT,
364 m_grid,
365 wxGridCellCoords( 0, col ),
d95b0c2b 366 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ),
ca65c044 367 true,
8b5f6d9d 368 kbd );
5c8fc7c1 369
a0bd3147 370 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
294f6bcb
SN
371}
372
5c8fc7c1
SN
373void wxGridSelection::SelectBlock( int topRow, int leftCol,
374 int bottomRow, int rightCol,
8b5f6d9d 375 const wxKeyboardState& kbd,
d95b0c2b 376 bool sendEvent )
294f6bcb 377{
5c8fc7c1 378 // Fix the coordinates of the block if needed.
8a3e536c 379 switch ( m_selectionMode )
294f6bcb 380 {
8a3e536c
VZ
381 default:
382 wxFAIL_MSG( "unknown selection mode" );
383 // fall through
384
385 case wxGrid::wxGridSelectCells:
386 // nothing to do -- in this mode arbitrary blocks can be selected
387 break;
388
389 case wxGrid::wxGridSelectRows:
390 leftCol = 0;
391 rightCol = m_grid->GetNumberCols() - 1;
392 break;
393
394 case wxGrid::wxGridSelectColumns:
395 topRow = 0;
396 bottomRow = m_grid->GetNumberRows() - 1;
397 break;
398
399 case wxGrid::wxGridSelectRowsOrColumns:
400 // block selection doesn't make sense for this mode, we could only
401 // select the entire grid but this wouldn't be useful
402 return;
294f6bcb 403 }
a0bd3147 404
5c8fc7c1
SN
405 if ( topRow > bottomRow )
406 {
407 int temp = topRow;
408 topRow = bottomRow;
409 bottomRow = temp;
410 }
411
412 if ( leftCol > rightCol )
413 {
414 int temp = leftCol;
415 leftCol = rightCol;
416 rightCol = temp;
417 }
294f6bcb
SN
418
419 // Handle single cell selection in SelectCell.
695a3263
MB
420 // (MB: added check for selection mode here to prevent
421 // crashes if, for example, we are select rows and the
422 // grid only has 1 col)
423 if ( m_selectionMode == wxGrid::wxGridSelectCells &&
424 topRow == bottomRow && leftCol == rightCol )
a0bd3147 425 {
8b5f6d9d 426 SelectCell( topRow, leftCol, kbd, sendEvent );
a0bd3147 427 }
294f6bcb 428
f1567cdd 429 size_t count, n;
a0bd3147 430
be8fbbff 431 if ( m_selectionMode == wxGrid::wxGridSelectRows )
294f6bcb 432 {
be8fbbff
VZ
433 // find out which rows are already selected:
434 wxArrayInt alreadyselected;
435 alreadyselected.Add(0,bottomRow-topRow+1);
436 for( n = 0; n < m_rowSelection.GetCount(); n++)
b5808881 437 {
be8fbbff
VZ
438 int row = m_rowSelection[n];
439 if( (row >= topRow) && (row <= bottomRow) )
b5808881 440 {
be8fbbff 441 alreadyselected[ row - topRow ]=1;
b5808881
SN
442 }
443 }
294f6bcb 444
be8fbbff
VZ
445 // add the newly selected rows:
446 for ( int row = topRow; row <= bottomRow; row++ )
447 {
448 if ( alreadyselected[ row - topRow ] == 0 )
449 {
450 m_rowSelection.Add( row );
451 }
452 }
453 }
454 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
455 {
456 // find out which columns are already selected:
457 wxArrayInt alreadyselected;
458 alreadyselected.Add(0,rightCol-leftCol+1);
459 for( n = 0; n < m_colSelection.GetCount(); n++)
460 {
461 int col = m_colSelection[n];
462 if( (col >= leftCol) && (col <= rightCol) )
463 {
464 alreadyselected[ col - leftCol ]=1;
465 }
466 }
294f6bcb 467
be8fbbff
VZ
468 // add the newly selected columns:
469 for ( int col = leftCol; col <= rightCol; col++ )
470 {
471 if ( alreadyselected[ col - leftCol ] == 0 )
472 {
473 m_colSelection.Add( col );
474 }
475 }
476 }
477 else
294f6bcb 478 {
be8fbbff
VZ
479 // Remove single cells contained in newly selected block.
480 if ( m_selectionMode == wxGrid::wxGridSelectCells )
481 {
482 count = m_cellSelection.GetCount();
483 for ( n = 0; n < count; n++ )
484 {
485 wxGridCellCoords& coords = m_cellSelection[n];
486 if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
487 coords.GetRow(), coords.GetCol() ) )
488 {
489 m_cellSelection.RemoveAt(n);
490 n--;
491 count--;
492 }
493 }
494 }
a0bd3147 495
be8fbbff
VZ
496 // If a block containing the selection is already selected, return,
497 // if a block contained in the selection is found, remove it.
498
499 count = m_blockSelectionTopLeft.GetCount();
500 for ( n = 0; n < count; n++ )
b5808881 501 {
be8fbbff
VZ
502 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
503 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
902725ee 504
be8fbbff
VZ
505 switch ( BlockContain( coords1.GetRow(), coords1.GetCol(),
506 coords2.GetRow(), coords2.GetCol(),
507 topRow, leftCol, bottomRow, rightCol ) )
508 {
509 case 1:
510 return;
902725ee 511
be8fbbff
VZ
512 case -1:
513 m_blockSelectionTopLeft.RemoveAt(n);
514 m_blockSelectionBottomRight.RemoveAt(n);
515 n--;
516 count--;
517 break;
518
519 default:
520 break;
521 }
b5808881 522 }
294f6bcb 523
be8fbbff
VZ
524 // If a row containing the selection is already selected, return,
525 // if a row contained in newly selected block is found, remove it.
f1567cdd
SN
526 count = m_rowSelection.GetCount();
527 for ( n = 0; n < count; n++ )
b5808881
SN
528 {
529 switch ( BlockContain( m_rowSelection[n], 0,
a0bd3147 530 m_rowSelection[n], m_grid->GetNumberCols() - 1,
b5808881
SN
531 topRow, leftCol, bottomRow, rightCol ) )
532 {
902725ee
WS
533 case 1:
534 return;
535
536 case -1:
537 m_rowSelection.RemoveAt(n);
a0bd3147
DS
538 n--;
539 count--;
902725ee
WS
540 break;
541
542 default:
543 break;
b5808881
SN
544 }
545 }
a0bd3147 546
be8fbbff 547 // Same for columns.
f1567cdd
SN
548 count = m_colSelection.GetCount();
549 for ( n = 0; n < count; n++ )
b5808881
SN
550 {
551 switch ( BlockContain( 0, m_colSelection[n],
a0bd3147 552 m_grid->GetNumberRows() - 1, m_colSelection[n],
b5808881
SN
553 topRow, leftCol, bottomRow, rightCol ) )
554 {
902725ee
WS
555 case 1:
556 return;
557
558 case -1:
559 m_colSelection.RemoveAt(n);
a0bd3147
DS
560 n--;
561 count--;
902725ee
WS
562 break;
563
564 default:
565 break;
b5808881
SN
566 }
567 }
b5808881 568
be8fbbff
VZ
569 m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) );
570 m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) );
571 }
b5808881 572 // Update View:
b5808881 573 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
574 {
575 wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( topRow, leftCol ),
576 wxGridCellCoords( bottomRow, rightCol ) );
ca65c044 577 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
3665f7d0 578 }
f1567cdd 579
5c8fc7c1
SN
580 // Send Event, if not disabled.
581 if ( sendEvent )
582 {
d95b0c2b 583 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
a0bd3147
DS
584 wxEVT_GRID_RANGE_SELECT,
585 m_grid,
586 wxGridCellCoords( topRow, leftCol ),
587 wxGridCellCoords( bottomRow, rightCol ),
588 true,
8b5f6d9d 589 kbd);
a0bd3147 590 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
5c8fc7c1 591 }
294f6bcb
SN
592}
593
d95b0c2b 594void wxGridSelection::SelectCell( int row, int col,
8b5f6d9d 595 const wxKeyboardState& kbd,
d95b0c2b 596 bool sendEvent )
294f6bcb 597{
be8fbbff
VZ
598 if ( IsInSelection ( row, col ) )
599 return;
600
601 wxGridCellCoords selectedTopLeft, selectedBottomRight;
b5808881 602 if ( m_selectionMode == wxGrid::wxGridSelectRows )
043d16b2 603 {
be8fbbff
VZ
604 m_rowSelection.Add( row );
605 selectedTopLeft = wxGridCellCoords( row, 0 );
606 selectedBottomRight = wxGridCellCoords( row, m_grid->GetNumberCols() - 1 );
043d16b2 607 }
b5808881 608 else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
043d16b2 609 {
be8fbbff
VZ
610 m_colSelection.Add( col );
611 selectedTopLeft = wxGridCellCoords( 0, col );
612 selectedBottomRight = wxGridCellCoords( m_grid->GetNumberRows() - 1, col );
613 }
614 else
615 {
616 m_cellSelection.Add( wxGridCellCoords( row, col ) );
617 selectedTopLeft = wxGridCellCoords( row, col );
618 selectedBottomRight = wxGridCellCoords( row, col );
043d16b2 619 }
b5808881 620
f1567cdd 621 // Update View:
b5808881 622 if ( !m_grid->GetBatchCount() )
3665f7d0 623 {
a0bd3147 624 wxRect r = m_grid->BlockToDeviceRect(
be8fbbff
VZ
625 selectedTopLeft,
626 selectedBottomRight );
ca65c044 627 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
3665f7d0 628 }
f1567cdd 629
5c8fc7c1 630 // Send event
d95b0c2b
SN
631 if (sendEvent)
632 {
f6bcfd97 633 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
a0bd3147
DS
634 wxEVT_GRID_RANGE_SELECT,
635 m_grid,
be8fbbff
VZ
636 selectedTopLeft,
637 selectedBottomRight,
a0bd3147 638 true,
8b5f6d9d 639 kbd);
a0bd3147 640 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
d95b0c2b 641 }
294f6bcb
SN
642}
643
8b5f6d9d
VZ
644void
645wxGridSelection::ToggleCellSelection(int row, int col,
646 const wxKeyboardState& kbd)
294f6bcb 647{
f1567cdd 648 // if the cell is not selected, select it
294f6bcb 649 if ( !IsInSelection ( row, col ) )
b5808881 650 {
8b5f6d9d 651 SelectCell(row, col, kbd);
a0bd3147 652
b5808881
SN
653 return;
654 }
294f6bcb 655
f1567cdd
SN
656 // otherwise deselect it. This can be simple or more or
657 // less difficult, depending on how the cell is selected.
658 size_t count, n;
659
660 // The simplest case: The cell is contained in m_cellSelection
661 // Then it can't be contained in rows/cols/block (since those
662 // would remove the cell from m_cellSelection on creation), so
663 // we just have to remove it from m_cellSelection.
294f6bcb 664
f1567cdd 665 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb
SN
666 {
667 count = m_cellSelection.GetCount();
f1567cdd 668 for ( n = 0; n < count; n++ )
b5808881 669 {
4e115ed2
VZ
670 const wxGridCellCoords& sel = m_cellSelection[n];
671 if ( row == sel.GetRow() && col == sel.GetCol() )
b5808881 672 {
3665f7d0 673 wxGridCellCoords coords = m_cellSelection[n];
b5808881 674 m_cellSelection.RemoveAt(n);
b5808881 675 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
676 {
677 wxRect r = m_grid->BlockToDeviceRect( coords, coords );
ca65c044 678 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
3665f7d0 679 }
5c8fc7c1
SN
680
681 // Send event
f6bcfd97
BP
682 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
683 wxEVT_GRID_RANGE_SELECT,
684 m_grid,
685 wxGridCellCoords( row, col ),
686 wxGridCellCoords( row, col ),
ca65c044 687 false,
8b5f6d9d 688 kbd );
a0bd3147
DS
689 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
690
723d1b1d 691 return;
b5808881
SN
692 }
693 }
294f6bcb
SN
694 }
695
f1567cdd
SN
696 // The most difficult case: The cell is member of one or even several
697 // blocks. Split each such block in up to 4 new parts, that don't
698 // contain the cell to be selected, like this:
699 // |---------------------------|
700 // | |
701 // | part 1 |
702 // | |
703 // |---------------------------|
704 // | part 3 |x| part 4 |
705 // |---------------------------|
706 // | |
707 // | part 2 |
708 // | |
709 // |---------------------------|
710 // (The x marks the newly deselected cell).
711 // Note: in row selection mode, we only need part1 and part2;
712 // in column selection mode, we only need part 3 and part4,
713 // which are expanded to whole columns automatically!
714
294f6bcb 715 count = m_blockSelectionTopLeft.GetCount();
f1567cdd 716 for ( n = 0; n < count; n++ )
a0bd3147 717 {
b5808881
SN
718 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
719 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
720 int topRow = coords1.GetRow();
721 int leftCol = coords1.GetCol();
722 int bottomRow = coords2.GetRow();
723 int rightCol = coords2.GetCol();
a0bd3147
DS
724
725 if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol, row, col ) )
b5808881
SN
726 {
727 // remove the block
728 m_blockSelectionTopLeft.RemoveAt(n);
729 m_blockSelectionBottomRight.RemoveAt(n);
a0bd3147
DS
730 n--;
731 count--;
732
b5808881
SN
733 // add up to 4 smaller blocks and set update region
734 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
735 {
736 if ( topRow < row )
8b5f6d9d 737 SelectBlockNoEvent(topRow, leftCol, row - 1, rightCol);
b5808881 738 if ( bottomRow > row )
8b5f6d9d 739 SelectBlockNoEvent(row + 1, leftCol, bottomRow, rightCol);
b5808881 740 }
a0bd3147 741
b5808881
SN
742 if ( m_selectionMode != wxGrid::wxGridSelectRows )
743 {
744 if ( leftCol < col )
8b5f6d9d 745 SelectBlockNoEvent(row, leftCol, row, col - 1);
b5808881 746 if ( rightCol > col )
8b5f6d9d 747 SelectBlockNoEvent(row, col + 1, row, rightCol);
b5808881
SN
748 }
749 }
294f6bcb
SN
750 }
751
475be9ce 752 bool rowSelectionWasChanged = false;
294f6bcb 753 // remove a cell from a row, adding up to two new blocks
b5808881 754 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
294f6bcb 755 {
f1567cdd
SN
756 count = m_rowSelection.GetCount();
757 for ( n = 0; n < count; n++ )
b5808881
SN
758 {
759 if ( m_rowSelection[n] == row )
760 {
761 m_rowSelection.RemoveAt(n);
a0bd3147
DS
762 n--;
763 count--;
764
475be9ce
VZ
765 rowSelectionWasChanged = true;
766
b5808881
SN
767 if (m_selectionMode == wxGrid::wxGridSelectCells)
768 {
769 if ( col > 0 )
8b5f6d9d 770 SelectBlockNoEvent(row, 0, row, col - 1);
b5808881 771 if ( col < m_grid->GetNumberCols() - 1 )
8b5f6d9d
VZ
772 SelectBlockNoEvent( row, col + 1,
773 row, m_grid->GetNumberCols() - 1);
b5808881
SN
774 }
775 }
776 }
294f6bcb
SN
777 }
778
475be9ce 779 bool colSelectionWasChanged = false;
294f6bcb 780 // remove a cell from a column, adding up to two new blocks
b5808881 781 if ( m_selectionMode != wxGrid::wxGridSelectRows )
294f6bcb 782 {
f1567cdd
SN
783 count = m_colSelection.GetCount();
784 for ( n = 0; n < count; n++ )
b5808881
SN
785 {
786 if ( m_colSelection[n] == col )
787 {
788 m_colSelection.RemoveAt(n);
a0bd3147
DS
789 n--;
790 count--;
791
475be9ce
VZ
792 colSelectionWasChanged = true;
793
b5808881
SN
794 if (m_selectionMode == wxGrid::wxGridSelectCells)
795 {
796 if ( row > 0 )
8b5f6d9d 797 SelectBlockNoEvent(0, col, row - 1, col);
b5808881 798 if ( row < m_grid->GetNumberRows() - 1 )
8b5f6d9d
VZ
799 SelectBlockNoEvent(row + 1, col,
800 m_grid->GetNumberRows() - 1, col);
b5808881
SN
801 }
802 }
803 }
294f6bcb 804 }
f1567cdd 805
5c8fc7c1
SN
806 // Refresh the screen and send the event; according to m_selectionMode,
807 // we need to either update only the cell, or the whole row/column.
294f6bcb 808 wxRect r;
475be9ce 809 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb 810 {
475be9ce 811 if ( !m_grid->GetBatchCount() )
a0bd3147 812 {
475be9ce 813 r = m_grid->BlockToDeviceRect(
a0bd3147 814 wxGridCellCoords( row, col ),
475be9ce
VZ
815 wxGridCellCoords( row, col ) );
816 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
a0bd3147 817 }
3665f7d0 818
475be9ce
VZ
819 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
820 wxEVT_GRID_RANGE_SELECT,
821 m_grid,
822 wxGridCellCoords( row, col ),
823 wxGridCellCoords( row, col ),
824 false,
825 kbd );
826 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
827 }
828 else // rows/columns selection mode
829 {
830 if ( m_selectionMode != wxGrid::wxGridSelectColumns &&
831 rowSelectionWasChanged )
a0bd3147 832 {
475be9ce
VZ
833 int numCols = m_grid->GetNumberCols();
834 for ( int colFrom = 0, colTo = 0; colTo <= numCols; ++colTo )
a0bd3147 835 {
475be9ce
VZ
836 if ( m_colSelection.Index(colTo) >= 0 || colTo == numCols )
837 {
838 if ( colFrom < colTo )
839 {
840 if ( !m_grid->GetBatchCount() )
841 {
842 r = m_grid->BlockToDeviceRect(
843 wxGridCellCoords( row, colFrom ),
844 wxGridCellCoords( row, colTo-1 ) );
845 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
846 }
847
848 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
849 wxEVT_GRID_RANGE_SELECT,
850 m_grid,
851 wxGridCellCoords( row, colFrom ),
852 wxGridCellCoords( row, colTo - 1 ),
853 false,
854 kbd );
855 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
856 }
857
858 colFrom = colTo + 1;
859 }
a0bd3147 860 }
a0bd3147 861 }
a0bd3147 862
475be9ce
VZ
863 if ( m_selectionMode != wxGrid::wxGridSelectRows &&
864 colSelectionWasChanged )
a0bd3147 865 {
475be9ce
VZ
866 int numRows = m_grid->GetNumberRows();
867 for ( int rowFrom = 0, rowTo = 0; rowTo <= numRows; ++rowTo )
a0bd3147 868 {
475be9ce
VZ
869 if ( m_rowSelection.Index(rowTo) >= 0 || rowTo == numRows )
870 {
871 if (rowFrom < rowTo)
872 {
873 if ( !m_grid->GetBatchCount() )
874 {
875 r = m_grid->BlockToDeviceRect(
876 wxGridCellCoords( rowFrom, col ),
877 wxGridCellCoords( rowTo - 1, col ) );
878 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
879 }
880
881 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
882 wxEVT_GRID_RANGE_SELECT,
883 m_grid,
884 wxGridCellCoords( rowFrom, col ),
885 wxGridCellCoords( rowTo - 1, col ),
886 false,
887 kbd );
888 m_grid->GetEventHandler()->ProcessEvent( gridEvt );
889 }
890
891 rowFrom = rowTo + 1;
892 }
a0bd3147 893 }
a0bd3147 894 }
294f6bcb 895 }
294f6bcb
SN
896}
897
898void wxGridSelection::ClearSelection()
899{
900 size_t n;
3665f7d0
SN
901 wxRect r;
902 wxGridCellCoords coords1, coords2;
f1567cdd 903
8862315b 904 // deselect all individual cells and update the screen
f1567cdd 905 if ( m_selectionMode == wxGrid::wxGridSelectCells )
294f6bcb 906 {
8862315b 907 while ( ( n = m_cellSelection.GetCount() ) > 0)
b5808881 908 {
b5808881 909 n--;
3665f7d0 910 coords1 = m_cellSelection[n];
b5808881
SN
911 m_cellSelection.RemoveAt(n);
912 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
913 {
914 r = m_grid->BlockToDeviceRect( coords1, coords1 );
ca65c044 915 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
a0bd3147 916
7d75e6c6
RD
917#ifdef __WXMAC__
918 ((wxWindow *)m_grid->m_gridWin)->Update();
919#endif
3665f7d0 920 }
b5808881 921 }
294f6bcb 922 }
f1567cdd
SN
923
924 // deselect all blocks and update the screen
8862315b 925 while ( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
294f6bcb 926 {
b5808881 927 n--;
3665f7d0
SN
928 coords1 = m_blockSelectionTopLeft[n];
929 coords2 = m_blockSelectionBottomRight[n];
b5808881
SN
930 m_blockSelectionTopLeft.RemoveAt(n);
931 m_blockSelectionBottomRight.RemoveAt(n);
932 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
933 {
934 r = m_grid->BlockToDeviceRect( coords1, coords2 );
ca65c044 935 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
a0bd3147 936
7d75e6c6
RD
937#ifdef __WXMAC__
938 ((wxWindow *)m_grid->m_gridWin)->Update();
939#endif
3665f7d0 940 }
b5808881 941 }
f1567cdd
SN
942
943 // deselect all rows and update the screen
b5808881 944 if ( m_selectionMode != wxGrid::wxGridSelectColumns )
294f6bcb 945 {
8862315b 946 while ( ( n = m_rowSelection.GetCount() ) > 0)
b5808881
SN
947 {
948 n--;
3665f7d0 949 int row = m_rowSelection[n];
b5808881
SN
950 m_rowSelection.RemoveAt(n);
951 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
952 {
953 r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
954 wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) );
ca65c044 955 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
a0bd3147 956
7d75e6c6
RD
957#ifdef __WXMAC__
958 ((wxWindow *)m_grid->m_gridWin)->Update();
959#endif
3665f7d0 960 }
b5808881
SN
961 }
962 }
f1567cdd
SN
963
964 // deselect all columns and update the screen
b5808881 965 if ( m_selectionMode != wxGrid::wxGridSelectRows )
294f6bcb 966 {
8862315b 967 while ( ( n = m_colSelection.GetCount() ) > 0)
b5808881
SN
968 {
969 n--;
3665f7d0 970 int col = m_colSelection[n];
b5808881
SN
971 m_colSelection.RemoveAt(n);
972 if ( !m_grid->GetBatchCount() )
3665f7d0
SN
973 {
974 r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
975 wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) );
ca65c044 976 ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
a0bd3147 977
7d75e6c6
RD
978#ifdef __WXMAC__
979 ((wxWindow *)m_grid->m_gridWin)->Update();
980#endif
3665f7d0 981 }
b5808881 982 }
294f6bcb 983 }
f6bcfd97
BP
984
985 // One deselection event, indicating deselection of _all_ cells.
986 // (No finer grained events for each of the smaller regions
987 // deselected above!)
988 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
989 wxEVT_GRID_RANGE_SELECT,
990 m_grid,
991 wxGridCellCoords( 0, 0 ),
a0bd3147
DS
992 wxGridCellCoords(
993 m_grid->GetNumberRows() - 1,
994 m_grid->GetNumberCols() - 1 ),
ca65c044 995 false );
f6bcfd97
BP
996
997 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
294f6bcb
SN
998}
999
1000
1001void wxGridSelection::UpdateRows( size_t pos, int numRows )
1002{
1003 size_t count = m_cellSelection.GetCount();
b14159f7
JS
1004 size_t n;
1005 for ( n = 0; n < count; n++ )
294f6bcb
SN
1006 {
1007 wxGridCellCoords& coords = m_cellSelection[n];
1008 wxCoord row = coords.GetRow();
1009 if ((size_t)row >= pos)
1010 {
1011 if (numRows > 0)
1012 {
1013 // If rows inserted, increase row counter where necessary
1014 coords.SetRow(row + numRows);
1015 }
1016 else if (numRows < 0)
1017 {
1018 // If rows deleted ...
1019 if ((size_t)row >= pos - numRows)
1020 {
1021 // ...either decrement row counter (if row still exists)...
1022 coords.SetRow(row + numRows);
1023 }
1024 else
1025 {
1026 // ...or remove the attribute
1027 m_cellSelection.RemoveAt(n);
a0bd3147
DS
1028 n--;
1029 count--;
294f6bcb
SN
1030 }
1031 }
1032 }
1033 }
1034
1035 count = m_blockSelectionTopLeft.GetCount();
b14159f7 1036 for ( n = 0; n < count; n++ )
294f6bcb
SN
1037 {
1038 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
1039 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
1040 wxCoord row1 = coords1.GetRow();
1041 wxCoord row2 = coords2.GetRow();
a0bd3147 1042
294f6bcb
SN
1043 if ((size_t)row2 >= pos)
1044 {
1045 if (numRows > 0)
1046 {
1047 // If rows inserted, increase row counter where necessary
a0bd3147
DS
1048 coords2.SetRow( row2 + numRows );
1049 if ((size_t)row1 >= pos)
1050 coords1.SetRow( row1 + numRows );
294f6bcb
SN
1051 }
1052 else if (numRows < 0)
1053 {
1054 // If rows deleted ...
1055 if ((size_t)row2 >= pos - numRows)
1056 {
1057 // ...either decrement row counter (if row still exists)...
a0bd3147
DS
1058 coords2.SetRow( row2 + numRows );
1059 if ((size_t)row1 >= pos)
1060 coords1.SetRow( wxMax(row1 + numRows, (int)pos) );
f1e26920 1061
294f6bcb
SN
1062 }
1063 else
1064 {
a0bd3147 1065 if ((size_t)row1 >= pos)
b5808881
SN
1066 {
1067 // ...or remove the attribute
1068 m_blockSelectionTopLeft.RemoveAt(n);
1069 m_blockSelectionBottomRight.RemoveAt(n);
a0bd3147
DS
1070 n--;
1071 count--;
b5808881
SN
1072 }
1073 else
a0bd3147 1074 coords2.SetRow( pos );
294f6bcb
SN
1075 }
1076 }
1077 }
1078 }
1079
1080 count = m_rowSelection.GetCount();
b14159f7 1081 for ( n = 0; n < count; n++ )
294f6bcb 1082 {
a0bd3147 1083 int rowOrCol_ = m_rowSelection[n];
f1e26920 1084
a0bd3147 1085 if ((size_t) rowOrCol_ >= pos)
f1e26920
CE
1086 {
1087 if ( numRows > 0 )
1088 {
a0bd3147 1089 m_rowSelection[n] += numRows;
f1e26920
CE
1090 }
1091 else if ( numRows < 0 )
1092 {
a0bd3147
DS
1093 if ((size_t)rowOrCol_ >= (pos - numRows))
1094 m_rowSelection[n] += numRows;
f1e26920
CE
1095 else
1096 {
a0bd3147 1097 m_rowSelection.RemoveAt( n );
f1e26920
CE
1098 n--;
1099 count--;
1100 }
1101 }
1102 }
294f6bcb 1103 }
f6bcfd97
BP
1104 // No need to touch selected columns, unless we removed _all_
1105 // rows, in this case, we remove all columns from the selection.
f1e26920 1106
f6bcfd97
BP
1107 if ( !m_grid->GetNumberRows() )
1108 m_colSelection.Clear();
294f6bcb
SN
1109}
1110
f1e26920 1111
294f6bcb
SN
1112void wxGridSelection::UpdateCols( size_t pos, int numCols )
1113{
1114 size_t count = m_cellSelection.GetCount();
b14159f7 1115 size_t n;
a0bd3147 1116
b14159f7 1117 for ( n = 0; n < count; n++ )
294f6bcb
SN
1118 {
1119 wxGridCellCoords& coords = m_cellSelection[n];
1120 wxCoord col = coords.GetCol();
1121 if ((size_t)col >= pos)
1122 {
1123 if (numCols > 0)
1124 {
1125 // If rows inserted, increase row counter where necessary
1126 coords.SetCol(col + numCols);
1127 }
1128 else if (numCols < 0)
1129 {
1130 // If rows deleted ...
1131 if ((size_t)col >= pos - numCols)
1132 {
1133 // ...either decrement row counter (if row still exists)...
1134 coords.SetCol(col + numCols);
1135 }
1136 else
1137 {
1138 // ...or remove the attribute
1139 m_cellSelection.RemoveAt(n);
a0bd3147
DS
1140 n--;
1141 count--;
294f6bcb
SN
1142 }
1143 }
1144 }
1145 }
1146
1147 count = m_blockSelectionTopLeft.GetCount();
b14159f7 1148 for ( n = 0; n < count; n++ )
294f6bcb
SN
1149 {
1150 wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
1151 wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
1152 wxCoord col1 = coords1.GetCol();
1153 wxCoord col2 = coords2.GetCol();
a0bd3147 1154
294f6bcb
SN
1155 if ((size_t)col2 >= pos)
1156 {
1157 if (numCols > 0)
1158 {
1159 // If rows inserted, increase row counter where necessary
1160 coords2.SetCol(col2 + numCols);
a0bd3147 1161 if ((size_t)col1 >= pos)
b5808881 1162 coords1.SetCol(col1 + numCols);
294f6bcb
SN
1163 }
1164 else if (numCols < 0)
1165 {
1166 // If cols deleted ...
1167 if ((size_t)col2 >= pos - numCols)
1168 {
1169 // ...either decrement col counter (if col still exists)...
1170 coords2.SetCol(col2 + numCols);
b5808881 1171 if ( (size_t) col1 >= pos)
a0bd3147 1172 coords1.SetCol( wxMax(col1 + numCols, (int)pos) );
f1e26920 1173
294f6bcb
SN
1174 }
1175 else
1176 {
a0bd3147 1177 if ((size_t)col1 >= pos)
b5808881
SN
1178 {
1179 // ...or remove the attribute
1180 m_blockSelectionTopLeft.RemoveAt(n);
1181 m_blockSelectionBottomRight.RemoveAt(n);
a0bd3147
DS
1182 n--;
1183 count--;
b5808881
SN
1184 }
1185 else
1186 coords2.SetCol(pos);
294f6bcb
SN
1187 }
1188 }
1189 }
1190 }
1191
1192 count = m_colSelection.GetCount();
b14159f7 1193 for ( n = 0; n < count; n++ )
294f6bcb 1194 {
a0bd3147 1195 int rowOrCol = m_colSelection[n];
f1e26920 1196
a0bd3147 1197 if ((size_t)rowOrCol >= pos)
294f6bcb
SN
1198 {
1199 if ( numCols > 0 )
a0bd3147 1200 m_colSelection[n] += numCols;
f1e26920 1201 else if ( numCols < 0 )
294f6bcb 1202 {
a0bd3147
DS
1203 if ((size_t)rowOrCol >= (pos - numCols))
1204 m_colSelection[n] += numCols;
294f6bcb
SN
1205 else
1206 {
a0bd3147 1207 m_colSelection.RemoveAt( n );
f1e26920
CE
1208 n--;
1209 count--;
294f6bcb
SN
1210 }
1211 }
1212 }
1213 }
f6bcfd97
BP
1214
1215 // No need to touch selected rows, unless we removed _all_
1216 // columns, in this case, we remove all rows from the selection.
1217 if ( !m_grid->GetNumberCols() )
1218 m_rowSelection.Clear();
294f6bcb
SN
1219}
1220
1221int wxGridSelection::BlockContain( int topRow1, int leftCol1,
b5808881
SN
1222 int bottomRow1, int rightCol1,
1223 int topRow2, int leftCol2,
1224 int bottomRow2, int rightCol2 )
294f6bcb
SN
1225// returns 1, if Block1 contains Block2,
1226// -1, if Block2 contains Block1,
1227// 0, otherwise
1228{
1229 if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 &&
b5808881 1230 leftCol1 <= leftCol2 && rightCol2 <= rightCol1 )
294f6bcb
SN
1231 return 1;
1232 else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 &&
b5808881 1233 leftCol2 <= leftCol1 && rightCol1 <= rightCol2 )
294f6bcb 1234 return -1;
a0bd3147 1235
294f6bcb
SN
1236 return 0;
1237}
f1567cdd
SN
1238
1239#endif