X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b58088819ba72c430ad028490fc45e1fc79694f0..1978421a6d8b81c1f8a961da4b8ddf544fec7b1b:/src/generic/gridsel.cpp diff --git a/src/generic/gridsel.cpp b/src/generic/gridsel.cpp index 74b5214df1..8fcdcde92f 100644 --- a/src/generic/gridsel.cpp +++ b/src/generic/gridsel.cpp @@ -4,7 +4,7 @@ // Author: Stefan Neis // Modified by: // Created: 20/02/1999 -// RCS-ID: $$ +// RCS-ID: $Id$ // Copyright: (c) Stefan Neis (Stefan.Neis@t-online.de) // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -17,7 +17,7 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "gridsel.h" #endif @@ -30,8 +30,19 @@ #pragma hdrstop #endif +#if wxUSE_GRID + #include "wx/generic/gridsel.h" +// Some explanation for the members of the class: +// m_cellSelection stores individual selected cells +// -- this is only used if m_selectionMode == wxGridSelectCells +// m_blockSelectionTopLeft and m_blockSelectionBottomRight +// store the upper left and lower right corner of selected Blocks +// m_rowSelection and m_colSelection store individual selected +// rows and columns; maybe those are superfluous and should be +// treated as blocks? + wxGridSelection::wxGridSelection( wxGrid * grid, wxGrid::wxGridSelectionModes sel ) { @@ -47,18 +58,23 @@ bool wxGridSelection::IsSelection() bool wxGridSelection::IsInSelection ( int row, int col ) { - size_t count; - if ( m_selectionMode != wxGrid::wxGridSelectRows && - m_selectionMode != wxGrid::wxGridSelectColumns ) + size_t count; + + // First check whether the given cell is individually selected + // (if m_selectionMode is wxGridSelectCells). + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { count = m_cellSelection.GetCount(); for ( size_t n = 0; n < count; n++ ) { wxGridCellCoords& coords = m_cellSelection[n]; if ( row == coords.GetRow() && col == coords.GetCol() ) - return true; + return TRUE; } } + + // Now check whether the given cell is + // contained in one of the selected blocks. count = m_blockSelectionTopLeft.GetCount(); for ( size_t n = 0; n < count; n++ ) { @@ -67,41 +83,120 @@ bool wxGridSelection::IsInSelection ( int row, int col ) if ( BlockContainsCell(coords1.GetRow(), coords1.GetCol(), coords2.GetRow(), coords2.GetCol(), row, col ) ) - return true; + return TRUE; } + + // Now check whether the given cell is + // contained in one of the selected rows + // (unless we are in column selection mode). if ( m_selectionMode != wxGrid::wxGridSelectColumns ) { size_t count = m_rowSelection.GetCount(); for ( size_t n = 0; n < count; n++ ) { if ( row == m_rowSelection[n] ) - return true; + return TRUE; } } + + // Now check whether the given cell is + // contained in one of the selected columns + // (unless we are in row selection mode). if ( m_selectionMode != wxGrid::wxGridSelectRows ) { size_t count = m_colSelection.GetCount(); for ( size_t n = 0; n < count; n++ ) { if ( col == m_colSelection[n] ) - return true; + return TRUE; + } + } + return FALSE; +} + +// Change the selection mode +void wxGridSelection::SetSelectionMode(wxGrid::wxGridSelectionModes selmode) +{ + // if selection mode is unchanged return immediately + if (selmode == m_selectionMode) + return; + + if ( m_selectionMode != wxGrid::wxGridSelectCells ) + { + // if changing form row to column selection + // or vice versa, clear the selection. + if ( selmode != wxGrid::wxGridSelectCells ) + ClearSelection(); + + m_selectionMode = selmode; + } + else + { + // if changing from cell selection to something else, + // promote selected cells/blocks to whole rows/columns. + size_t n; + while ( ( n = m_cellSelection.GetCount() ) > 0 ) + { + n--; + wxGridCellCoords& coords = m_cellSelection[n]; + int row = coords.GetRow(); + int col = coords.GetCol(); + m_cellSelection.RemoveAt(n); + if (selmode == wxGrid::wxGridSelectRows) + SelectRow( row ); + else // selmode == wxGridSelectColumns) + SelectCol( col ); + } + + for (n = 0; n < m_blockSelectionTopLeft.GetCount(); n++) + // Note that m_blockSelectionTopLeft's size may be changing! + { + wxGridCellCoords& coords = m_blockSelectionTopLeft[n]; + int topRow = coords.GetRow(); + int leftCol = coords.GetCol(); + coords = m_blockSelectionBottomRight[n]; + int bottomRow = coords.GetRow(); + int rightCol = coords.GetCol(); + if (selmode == wxGrid::wxGridSelectRows) + { + if (leftCol != 0 || rightCol != m_grid->GetNumberCols() - 1 ) + { + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + SelectBlock( topRow, 0, + bottomRow, m_grid->GetNumberCols() - 1, + FALSE, FALSE, FALSE, FALSE, FALSE ); + } + } + else // selmode == wxGridSelectColumns) + { + if (topRow != 0 || bottomRow != m_grid->GetNumberRows() - 1 ) + { + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + SelectBlock( 0, leftCol, + m_grid->GetNumberRows() - 1, rightCol, + FALSE, FALSE, FALSE, FALSE, FALSE ); + } + } } + m_selectionMode = selmode; } - return false; } -void wxGridSelection::SelectRow( int row, bool addToSelected = FALSE ) +void wxGridSelection::SelectRow( int row, + bool ControlDown, bool ShiftDown, + bool AltDown, bool MetaDown ) { if ( m_selectionMode == wxGrid::wxGridSelectColumns ) return; - size_t count; + size_t count, n; // Remove single cells contained in newly selected block. - if ( m_selectionMode != wxGrid::wxGridSelectRows && - m_selectionMode != wxGrid::wxGridSelectColumns ) + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords = m_cellSelection[n]; if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() - 1, @@ -113,66 +208,88 @@ void wxGridSelection::SelectRow( int row, bool addToSelected = FALSE ) } } - // If possible, merge row with existing selected block + // Simplify list of selected blocks (if possible) count = m_blockSelectionTopLeft.GetCount(); - for ( size_t n = 0; n < count; n++ ) + bool done = FALSE; + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; + + // Remove block if it is a subset of the row if ( coords1.GetRow() == row && row == coords2.GetRow() ) { m_blockSelectionTopLeft.RemoveAt(n); m_blockSelectionBottomRight.RemoveAt(n); n--; count--; - } + } else if ( coords1.GetCol() == 0 && coords2.GetCol() == m_grid->GetNumberCols() - 1 ) { + // silently return, if row is contained in block if ( coords1.GetRow() <= row && row <= coords2.GetRow() ) return; + // expand block, if it touched row else if ( coords1.GetRow() == row + 1) { coords1.SetRow(row); - return; + done = TRUE; } else if ( coords2.GetRow() == row - 1) { coords2.SetRow(row); - return; + done = TRUE; } } } - // Check whether row is already selected. - count = m_rowSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + // Unless we successfully handled the row, + // check whether row is already selected. + if ( !done ) { - if ( row == m_rowSelection[n] ) - return; - } + count = m_rowSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + if ( row == m_rowSelection[n] ) + return; + } - // Add row to selection - m_rowSelection.Add(row); + // Add row to selection + m_rowSelection.Add(row); + } // Update View: wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ), wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) ); if ( !m_grid->GetBatchCount() ) ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + + // Send Event + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( row, 0 ), + wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ), + TRUE, + ControlDown, ShiftDown, + AltDown, MetaDown ); + + m_grid->GetEventHandler()->ProcessEvent(gridEvt); } -void wxGridSelection::SelectCol( int col, bool addToSelected = FALSE ) +void wxGridSelection::SelectCol( int col, + bool ControlDown, bool ShiftDown, + bool AltDown, bool MetaDown ) { if ( m_selectionMode == wxGrid::wxGridSelectRows ) return; - size_t count; + size_t count, n; // Remove single cells contained in newly selected block. - if ( m_selectionMode != wxGrid::wxGridSelectRows && - m_selectionMode != wxGrid::wxGridSelectColumns ) + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords = m_cellSelection[n]; if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1, col, @@ -184,12 +301,15 @@ void wxGridSelection::SelectCol( int col, bool addToSelected = FALSE ) } } - // If possible, merge col with existing selected block + // Simplify list of selected blocks (if possible) count = m_blockSelectionTopLeft.GetCount(); - for ( size_t n = 0; n < count; n++ ) + bool done = FALSE; + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; + + // Remove block if it is a subset of the column if ( coords1.GetCol() == col && col == coords2.GetCol() ) { m_blockSelectionTopLeft.RemoveAt(n); @@ -199,42 +319,64 @@ void wxGridSelection::SelectCol( int col, bool addToSelected = FALSE ) else if ( coords1.GetRow() == 0 && coords2.GetRow() == m_grid->GetNumberRows() - 1 ) { + // silently return, if row is contained in block if ( coords1.GetCol() <= col && col <= coords2.GetCol() ) return; + // expand block, if it touched col else if ( coords1.GetCol() == col + 1) { coords1.SetCol(col); - return; + done = TRUE; } else if ( coords2.GetCol() == col - 1) { coords2.SetCol(col); - return; + done = TRUE; } } } + // Unless we successfully handled the column, // Check whether col is already selected. - count = m_colSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + if ( !done ) { - if ( col == m_colSelection[n] ) - return; - } + count = m_colSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + if ( col == m_colSelection[n] ) + return; + } - // Add col to selection - m_colSelection.Add(col); + // Add col to selection + m_colSelection.Add(col); + } // Update View: wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ), wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) ); if ( !m_grid->GetBatchCount() ) ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + + // Send Event + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( 0, col ), + wxGridCellCoords( m_grid->GetNumberRows() - 1, col ), + TRUE, + ControlDown, ShiftDown, + AltDown, MetaDown ); + + m_grid->GetEventHandler()->ProcessEvent(gridEvt); } -void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol ) +void wxGridSelection::SelectBlock( int topRow, int leftCol, + int bottomRow, int rightCol, + bool ControlDown, bool ShiftDown, + bool AltDown, bool MetaDown, + bool sendEvent ) { - // Fix the coordinates of the block if potentially needed + // Fix the coordinates of the block if needed. if ( m_selectionMode == wxGrid::wxGridSelectRows ) { leftCol = 0; @@ -245,18 +387,35 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int r topRow = 0; bottomRow = m_grid->GetNumberRows() - 1; } + if ( topRow > bottomRow ) + { + int temp = topRow; + topRow = bottomRow; + bottomRow = temp; + } + + if ( leftCol > rightCol ) + { + int temp = leftCol; + leftCol = rightCol; + rightCol = temp; + } // Handle single cell selection in SelectCell. - if ( topRow == bottomRow && leftCol == rightCol ) - SelectCell( topRow, leftCol ); + // (MB: added check for selection mode here to prevent + // crashes if, for example, we are select rows and the + // grid only has 1 col) + if ( m_selectionMode == wxGrid::wxGridSelectCells && + topRow == bottomRow && leftCol == rightCol ) + SelectCell( topRow, leftCol, ControlDown, ShiftDown, + AltDown, MetaDown, sendEvent ); - size_t count; + size_t count, n; // Remove single cells contained in newly selected block. - if ( m_selectionMode != wxGrid::wxGridSelectRows && - m_selectionMode != wxGrid::wxGridSelectColumns ) + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords = m_cellSelection[n]; if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol, @@ -272,7 +431,7 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int r // if a block contained in the selection is found, remove it. count = m_blockSelectionTopLeft.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; @@ -295,8 +454,8 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int r // if a row contained in newly selected block is found, remove it. if ( m_selectionMode != wxGrid::wxGridSelectColumns ) { - size_t count = m_rowSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + count = m_rowSelection.GetCount(); + for ( n = 0; n < count; n++ ) { switch ( BlockContain( m_rowSelection[n], 0, m_rowSelection[n], m_grid->GetNumberCols()-1, @@ -314,8 +473,8 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int r } if ( m_selectionMode != wxGrid::wxGridSelectRows ) { - size_t count = m_colSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + count = m_colSelection.GetCount(); + for ( n = 0; n < count; n++ ) { switch ( BlockContain( 0, m_colSelection[n], m_grid->GetNumberRows()-1, m_colSelection[n], @@ -339,42 +498,89 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int r wxGridCellCoords( bottomRow, rightCol ) ); if ( !m_grid->GetBatchCount() ) ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + + // Send Event, if not disabled. + if ( sendEvent ) + { + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( topRow, leftCol ), + wxGridCellCoords( bottomRow, rightCol ), + TRUE, + ControlDown, ShiftDown, + AltDown, MetaDown ); + m_grid->GetEventHandler()->ProcessEvent(gridEvt); + } } -void wxGridSelection::SelectCell( int row, int col) +void wxGridSelection::SelectCell( int row, int col, + bool ControlDown, bool ShiftDown, + bool AltDown, bool MetaDown, + bool sendEvent ) { if ( m_selectionMode == wxGrid::wxGridSelectRows ) - SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1 ); + { + SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1, + ControlDown, ShiftDown, AltDown, MetaDown, sendEvent); + return; + } else if ( m_selectionMode == wxGrid::wxGridSelectColumns ) - SelectBlock(0, col, m_grid->GetNumberRows() - 1, col ); + { + SelectBlock(0, col, m_grid->GetNumberRows() - 1, col, + ControlDown, ShiftDown, AltDown, MetaDown, sendEvent); + return; + } else if ( IsInSelection ( row, col ) ) return; m_cellSelection.Add( wxGridCellCoords( row, col ) ); + // Update View: wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ), wxGridCellCoords( row, col ) ); if ( !m_grid->GetBatchCount() ) ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + + // Send event + if (sendEvent) + { + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( row, col ), + wxGridCellCoords( row, col ), + TRUE, + ControlDown, ShiftDown, + AltDown, MetaDown); + m_grid->GetEventHandler()->ProcessEvent(gridEvt); + } } -void wxGridSelection::ToggleCellSelection( int row, int col) +void wxGridSelection::ToggleCellSelection( int row, int col, + bool ControlDown, bool ShiftDown, + bool AltDown, bool MetaDown ) { + // if the cell is not selected, select it if ( !IsInSelection ( row, col ) ) { - SelectCell( row, col ); + SelectCell( row, col, ControlDown, ShiftDown, + AltDown, MetaDown ); return; } - size_t count; - // Maybe we want to toggle a member of m_cellSelection. - // Then it can't be contained in rows/cols/block, and we - // just have to remove it from m_cellSelection. + // otherwise deselect it. This can be simple or more or + // less difficult, depending on how the cell is selected. + size_t count, n; - if ( m_selectionMode != wxGrid::wxGridSelectRows && - m_selectionMode != wxGrid::wxGridSelectColumns ) + // The simplest case: The cell is contained in m_cellSelection + // Then it can't be contained in rows/cols/block (since those + // would remove the cell from m_cellSelection on creation), so + // we just have to remove it from m_cellSelection. + + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords = m_cellSelection[n]; if ( row == coords.GetRow() && col == coords.GetCol() ) @@ -386,14 +592,43 @@ void wxGridSelection::ToggleCellSelection( int row, int col) n--; count--; if ( !m_grid->GetBatchCount() ) ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + + // Send event + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( row, col ), + wxGridCellCoords( row, col ), + FALSE, + ControlDown, ShiftDown, + AltDown, MetaDown ); + m_grid->GetEventHandler()->ProcessEvent(gridEvt); return; } } } - // remove a cell from the middle of a block (the really ugly case) + // The most difficult case: The cell is member of one or even several + // blocks. Split each such block in up to 4 new parts, that don't + // contain the cell to be selected, like this: + // |---------------------------| + // | | + // | part 1 | + // | | + // |---------------------------| + // | part 3 |x| part 4 | + // |---------------------------| + // | | + // | part 2 | + // | | + // |---------------------------| + // (The x marks the newly deselected cell). + // Note: in row selection mode, we only need part1 and part2; + // in column selection mode, we only need part 3 and part4, + // which are expanded to whole columns automatically! + count = m_blockSelectionTopLeft.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; @@ -412,16 +647,20 @@ void wxGridSelection::ToggleCellSelection( int row, int col) if ( m_selectionMode != wxGrid::wxGridSelectColumns ) { if ( topRow < row ) - SelectBlock( topRow, leftCol, row - 1, rightCol ); + SelectBlock( topRow, leftCol, row - 1, rightCol, + FALSE, FALSE, FALSE, FALSE, FALSE ); if ( bottomRow > row ) - SelectBlock( row + 1, leftCol, bottomRow, rightCol ); + SelectBlock( row + 1, leftCol, bottomRow, rightCol, + FALSE, FALSE, FALSE, FALSE, FALSE ); } if ( m_selectionMode != wxGrid::wxGridSelectRows ) { if ( leftCol < col ) - SelectBlock( row, leftCol, row, col - 1 ); + SelectBlock( row, leftCol, row, col - 1, + FALSE, FALSE, FALSE, FALSE, FALSE ); if ( rightCol > col ) - SelectBlock( row, col + 1, row, rightCol ); + SelectBlock( row, col + 1, row, rightCol, + FALSE, FALSE, FALSE, FALSE, FALSE ); } } } @@ -429,8 +668,8 @@ void wxGridSelection::ToggleCellSelection( int row, int col) // remove a cell from a row, adding up to two new blocks if ( m_selectionMode != wxGrid::wxGridSelectColumns ) { - size_t count = m_rowSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + count = m_rowSelection.GetCount(); + for ( n = 0; n < count; n++ ) { if ( m_rowSelection[n] == row ) { @@ -439,9 +678,12 @@ void wxGridSelection::ToggleCellSelection( int row, int col) if (m_selectionMode == wxGrid::wxGridSelectCells) { if ( col > 0 ) - SelectBlock( row, 0, row, col - 1 ); + SelectBlock( row, 0, row, col - 1, + FALSE, FALSE, FALSE, FALSE, FALSE ); if ( col < m_grid->GetNumberCols() - 1 ) - SelectBlock( row, col + 1, row, m_grid->GetNumberCols() - 1 ); + SelectBlock( row, col + 1, + row, m_grid->GetNumberCols() - 1, + FALSE, FALSE, FALSE, FALSE, FALSE ); } } } @@ -450,8 +692,8 @@ void wxGridSelection::ToggleCellSelection( int row, int col) // remove a cell from a column, adding up to two new blocks if ( m_selectionMode != wxGrid::wxGridSelectRows ) { - size_t count = m_colSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + count = m_colSelection.GetCount(); + for ( n = 0; n < count; n++ ) { if ( m_colSelection[n] == col ) { @@ -460,38 +702,82 @@ void wxGridSelection::ToggleCellSelection( int row, int col) if (m_selectionMode == wxGrid::wxGridSelectCells) { if ( row > 0 ) - SelectBlock( 0, col, row - 1, col ); + SelectBlock( 0, col, row - 1, col, + FALSE, FALSE, FALSE, FALSE, FALSE ); if ( row < m_grid->GetNumberRows() - 1 ) - SelectBlock( row + 1, col, m_grid->GetNumberRows() - 1, col ); + SelectBlock( row + 1, col, + m_grid->GetNumberRows() - 1, col, + FALSE, FALSE, FALSE, FALSE, FALSE ); } } } } + + // Refresh the screen and send the event; according to m_selectionMode, + // we need to either update only the cell, or the whole row/column. wxRect r; switch (m_selectionMode) { case wxGrid::wxGridSelectCells: - r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ), - wxGridCellCoords( row, col ) ); - break; + { + r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ), + wxGridCellCoords( row, col ) ); + if ( !m_grid->GetBatchCount() ) + ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( row, col ), + wxGridCellCoords( row, col ), + FALSE, + ControlDown, ShiftDown, + AltDown, MetaDown ); + m_grid->GetEventHandler()->ProcessEvent(gridEvt); + break; + } case wxGrid::wxGridSelectRows: - r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ), - wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) ); - break; + { + r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ), + wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) ); + if ( !m_grid->GetBatchCount() ) + ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( row, 0 ), + wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ), + FALSE, + ControlDown, ShiftDown, + AltDown, MetaDown ); + m_grid->GetEventHandler()->ProcessEvent(gridEvt); + break; + } case wxGrid::wxGridSelectColumns: - r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ), - wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) ); - break; + { + r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ), + wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) ); + if ( !m_grid->GetBatchCount() ) + ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( 0, col ), + wxGridCellCoords( m_grid->GetNumberRows() - 1, col ), + FALSE, + ControlDown, ShiftDown, + AltDown, MetaDown ); + m_grid->GetEventHandler()->ProcessEvent(gridEvt); + break; + } } - if ( !m_grid->GetBatchCount() ) - ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); } void wxGridSelection::ClearSelection() { size_t n; - if ( m_selectionMode != wxGrid::wxGridSelectRows && - m_selectionMode != wxGrid::wxGridSelectColumns ) + + // deselect all invidiual cells and update the screen + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { while( ( n = m_cellSelection.GetCount() ) > 0) @@ -505,6 +791,8 @@ void wxGridSelection::ClearSelection() ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); } } + + // deselect all blocks and update the screen while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0) { wxRect r; @@ -516,6 +804,8 @@ void wxGridSelection::ClearSelection() if ( !m_grid->GetBatchCount() ) ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); } + + // deselect all rows and update the screen if ( m_selectionMode != wxGrid::wxGridSelectColumns ) { while( ( n = m_rowSelection.GetCount() ) > 0) @@ -530,6 +820,8 @@ void wxGridSelection::ClearSelection() ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); } } + + // deselect all columns and update the screen if ( m_selectionMode != wxGrid::wxGridSelectRows ) { while( ( n = m_colSelection.GetCount() ) > 0) @@ -544,13 +836,27 @@ void wxGridSelection::ClearSelection() ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); } } + + // One deselection event, indicating deselection of _all_ cells. + // (No finer grained events for each of the smaller regions + // deselected above!) + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( 0, 0 ), + wxGridCellCoords( m_grid->GetNumberRows() - 1, + m_grid->GetNumberCols() - 1 ), + FALSE ); + + m_grid->GetEventHandler()->ProcessEvent(gridEvt); } void wxGridSelection::UpdateRows( size_t pos, int numRows ) { size_t count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + size_t n; + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords = m_cellSelection[n]; wxCoord row = coords.GetRow(); @@ -580,7 +886,7 @@ void wxGridSelection::UpdateRows( size_t pos, int numRows ) } count = m_blockSelectionTopLeft.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; @@ -623,7 +929,7 @@ void wxGridSelection::UpdateRows( size_t pos, int numRows ) } count = m_rowSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { int & rowOrCol = m_rowSelection[n]; if ( (size_t)rowOrCol >= pos ) @@ -646,12 +952,17 @@ void wxGridSelection::UpdateRows( size_t pos, int numRows ) } } } + // No need to touch selected columns, unless we removed _all_ + // rows, in this case, we remove all columns from the selection. + if ( !m_grid->GetNumberRows() ) + m_colSelection.Clear(); } void wxGridSelection::UpdateCols( size_t pos, int numCols ) { size_t count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + size_t n; + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords = m_cellSelection[n]; wxCoord col = coords.GetCol(); @@ -681,7 +992,7 @@ void wxGridSelection::UpdateCols( size_t pos, int numCols ) } count = m_blockSelectionTopLeft.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; @@ -724,7 +1035,7 @@ void wxGridSelection::UpdateCols( size_t pos, int numCols ) } count = m_colSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( n = 0; n < count; n++ ) { int & rowOrCol = m_colSelection[n]; if ( (size_t)rowOrCol >= pos ) @@ -747,6 +1058,11 @@ void wxGridSelection::UpdateCols( size_t pos, int numCols ) } } } + + // No need to touch selected rows, unless we removed _all_ + // columns, in this case, we remove all rows from the selection. + if ( !m_grid->GetNumberCols() ) + m_rowSelection.Clear(); } int wxGridSelection::BlockContain( int topRow1, int leftCol1, @@ -765,3 +1081,6 @@ int wxGridSelection::BlockContain( int topRow1, int leftCol1, return -1; return 0; } + +#endif +