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