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