X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/294f6bcbdb75d27785ee70472e63e53b4dc98e6b..6ba718d7aee2f519d9146b90424ccec9e2243479:/src/generic/gridsel.cpp diff --git a/src/generic/gridsel.cpp b/src/generic/gridsel.cpp index f8dd6cb3d5..e79f7f2031 100644 --- a/src/generic/gridsel.cpp +++ b/src/generic/gridsel.cpp @@ -1,14 +1,20 @@ /////////////////////////////////////////////////////////////////////////// -// Name: generic/gridsel.cpp +// Name: src/generic/gridsel.cpp // Purpose: wxGridSelection // Author: Stefan Neis // Modified by: // Created: 20/02/1999 -// RCS-ID: $$ // Copyright: (c) Stefan Neis (Stefan.Neis@t-online.de) // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + // ============================================================================ // declarations // ============================================================================ @@ -17,23 +23,22 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "gridsel.h" -#endif - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" +#if wxUSE_GRID -#include "wx/defs.h" +#include "wx/generic/gridsel.h" -#ifdef __BORLANDC__ - #pragma hdrstop -#endif -#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, - wxGridSelection::wxGridSelectionModes sel ) + wxGrid::wxGridSelectionModes sel ) { m_grid = grid; m_selectionMode = sel; @@ -42,485 +47,961 @@ wxGridSelection::wxGridSelection( wxGrid * grid, bool wxGridSelection::IsSelection() { return ( m_cellSelection.GetCount() || m_blockSelectionTopLeft.GetCount() || - m_rowSelection.GetCount() || m_colSelection.GetCount() ); + m_rowSelection.GetCount() || m_colSelection.GetCount() ); } -bool wxGridSelection::IsInSelection ( int row, int col ) +bool wxGridSelection::IsInSelection( int row, int col ) { - size_t count; - if ( m_selectionMode != wxGridSelection::wxGridSelectRows && - m_selectionMode != wxGridSelection::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; - } + for ( size_t n = 0; n < count; n++ ) + { + wxGridCellCoords& coords = m_cellSelection[n]; + if ( row == coords.GetRow() && col == coords.GetCol() ) + 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++ ) { - wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; - wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; - if ( BlockContainsCell(coords1.GetRow(), coords1.GetCol(), - coords2.GetRow(), coords2.GetCol(), - row, col ) ) - return true; + wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; + wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; + if ( BlockContainsCell(coords1.GetRow(), coords1.GetCol(), + coords2.GetRow(), coords2.GetCol(), + row, col ) ) + return true; } - if ( m_selectionMode != wxGridSelection::wxGridSelectColumns ) + + // 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; - } + count = m_rowSelection.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + if ( row == m_rowSelection[n] ) + return true; + } } - if ( m_selectionMode != wxGridSelection::wxGridSelectRows ) + + // 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; - } + count = m_colSelection.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + if ( col == m_colSelection[n] ) + return true; + } } + return false; } -void wxGridSelection::SelectRow( int row, bool addToSelected = FALSE ) +// Change the selection mode +void wxGridSelection::SetSelectionMode( wxGrid::wxGridSelectionModes selmode ) { - if ( m_selectionMode == wxGridSelection::wxGridSelectColumns ) + // if selection mode is unchanged return immediately + if (selmode == m_selectionMode) return; - size_t count; + + 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 ); + } + + // Note that m_blockSelectionTopLeft's size may be changing! + for (n = 0; n < m_blockSelectionTopLeft.GetCount(); n++) + { + 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); + SelectBlockNoEvent( topRow, 0, + bottomRow, m_grid->GetNumberCols() - 1); + } + } + else // selmode == wxGridSelectColumns) + { + if (topRow != 0 || bottomRow != m_grid->GetNumberRows() - 1 ) + { + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + SelectBlockNoEvent(0, leftCol, + m_grid->GetNumberRows() - 1, rightCol); + } + } + } + + m_selectionMode = selmode; + } +} + +void wxGridSelection::SelectRow(int row, const wxKeyboardState& kbd) +{ + if ( m_selectionMode == wxGrid::wxGridSelectColumns ) + return; + + size_t count, n; // Remove single cells contained in newly selected block. - if ( m_selectionMode != wxGridSelection::wxGridSelectRows && - m_selectionMode != wxGridSelection::wxGridSelectColumns ) + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - wxGridCellCoords& coords = m_cellSelection[n]; - if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() - 1, - coords.GetRow(), coords.GetCol() ) ) - { - m_cellSelection.RemoveAt(n); - n--; count--; - } - } - } - - // If possible, merge row with existing selected block + for ( n = 0; n < count; n++ ) + { + wxGridCellCoords& coords = m_cellSelection[n]; + if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() - 1, + coords.GetRow(), coords.GetCol() ) ) + { + m_cellSelection.RemoveAt(n); + n--; + count--; + } + } + } + + // 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]; - 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 ) - { - if ( coords1.GetRow() <= row && row <= coords2.GetRow() ) - return; - else if ( coords1.GetRow() == row + 1) - { - coords1.SetRow(row); - return; - } - else if ( coords2.GetRow() == row - 1) - { - coords2.SetRow(row); - return; - } - } - } - - // Check whether row is already selected. - count = m_rowSelection.GetCount(); - for ( size_t 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); + done = true; + } + else if ( coords2.GetRow() == row - 1) + { + coords2.SetRow(row); + done = true; + } + } + } + + // 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: + if ( !m_grid->GetBatchCount() ) + { + wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ), + wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) ); + ((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, + kbd); + + m_grid->GetEventHandler()->ProcessEvent( gridEvt ); } -void wxGridSelection::SelectCol( int col, bool addToSelected = FALSE ) +void wxGridSelection::SelectCol(int col, const wxKeyboardState& kbd) { - if ( m_selectionMode == wxGridSelection::wxGridSelectRows ) + if ( m_selectionMode == wxGrid::wxGridSelectRows ) return; - size_t count; + size_t count, n; // Remove single cells contained in newly selected block. - if ( m_selectionMode != wxGridSelection::wxGridSelectRows && - m_selectionMode != wxGridSelection::wxGridSelectColumns ) + if ( m_selectionMode == wxGrid::wxGridSelectCells ) { count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - wxGridCellCoords& coords = m_cellSelection[n]; - if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1, col, - coords.GetRow(), coords.GetCol() ) ) - { - m_cellSelection.RemoveAt(n); - n--; count--; - } - } - } - - // If possible, merge col with existing selected block + for ( n = 0; n < count; n++ ) + { + wxGridCellCoords& coords = m_cellSelection[n]; + if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1, col, + coords.GetRow(), coords.GetCol() ) ) + { + m_cellSelection.RemoveAt(n); + n--; + count--; + } + } + } + + // 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]; - if ( coords1.GetCol() == col && col == coords2.GetCol() ) - { - m_blockSelectionTopLeft.RemoveAt(n); - m_blockSelectionBottomRight.RemoveAt(n); - n--; count--; - } - else if ( coords1.GetRow() == 0 && - coords2.GetRow() == m_grid->GetNumberRows() - 1 ) - { - if ( coords1.GetCol() <= col && col <= coords2.GetCol() ) - return; - else if ( coords1.GetCol() == col + 1) - { - coords1.SetCol(col); - return; - } - else if ( coords2.GetCol() == col - 1) - { - coords2.SetCol(col); - return; - } - } + 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); + m_blockSelectionBottomRight.RemoveAt(n); + n--; + count--; + } + 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); + done = true; + } + else if ( coords2.GetCol() == col - 1) + { + coords2.SetCol(col); + 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 ) + { + count = m_colSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + if ( col == m_colSelection[n] ) + return; + } + + // Add col to selection + m_colSelection.Add(col); + } + + // Update View: + if ( !m_grid->GetBatchCount() ) { - if ( col == m_colSelection[n] ) - return; + wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ), + wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); } - // Add col to selection - m_colSelection.Add(col); + // Send Event + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( 0, col ), + wxGridCellCoords( m_grid->GetNumberRows() - 1, col ), + true, + kbd ); + + 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, + const wxKeyboardState& kbd, + bool sendEvent ) { - // Fix the coordinates of the block if potentially needed - if ( m_selectionMode == wxGridSelection::wxGridSelectRows ) + // Fix the coordinates of the block if needed. + switch ( m_selectionMode ) + { + default: + wxFAIL_MSG( "unknown selection mode" ); + // fall through + + case wxGrid::wxGridSelectCells: + // nothing to do -- in this mode arbitrary blocks can be selected + break; + + case wxGrid::wxGridSelectRows: + leftCol = 0; + rightCol = m_grid->GetNumberCols() - 1; + break; + + case wxGrid::wxGridSelectColumns: + topRow = 0; + bottomRow = m_grid->GetNumberRows() - 1; + break; + + case wxGrid::wxGridSelectRowsOrColumns: + // block selection doesn't make sense for this mode, we could only + // select the entire grid but this wouldn't be useful + return; + } + + if ( topRow > bottomRow ) { - leftCol = 0; - rightCol = m_grid->GetNumberCols() - 1; + int temp = topRow; + topRow = bottomRow; + bottomRow = temp; } - else if ( m_selectionMode == wxGridSelection::wxGridSelectColumns ) + + if ( leftCol > rightCol ) { - topRow = 0; - bottomRow = m_grid->GetNumberRows() - 1; + 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, kbd, sendEvent ); + } - size_t count; - // Remove single cells contained in newly selected block. - if ( m_selectionMode != wxGridSelection::wxGridSelectRows && - m_selectionMode != wxGridSelection::wxGridSelectColumns ) + size_t count, n; + + if ( m_selectionMode == wxGrid::wxGridSelectRows ) { - count = m_cellSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - wxGridCellCoords& coords = m_cellSelection[n]; - if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol, - coords.GetRow(), coords.GetCol() ) ) - { - m_cellSelection.RemoveAt(n); - n--; count--; - } - } + // find out which rows are already selected: + wxArrayInt alreadyselected; + alreadyselected.Add(0,bottomRow-topRow+1); + for( n = 0; n < m_rowSelection.GetCount(); n++) + { + int row = m_rowSelection[n]; + if( (row >= topRow) && (row <= bottomRow) ) + { + alreadyselected[ row - topRow ]=1; + } + } + + // add the newly selected rows: + for ( int row = topRow; row <= bottomRow; row++ ) + { + if ( alreadyselected[ row - topRow ] == 0 ) + { + m_rowSelection.Add( row ); + } + } } + else if ( m_selectionMode == wxGrid::wxGridSelectColumns ) + { + // find out which columns are already selected: + wxArrayInt alreadyselected; + alreadyselected.Add(0,rightCol-leftCol+1); + for( n = 0; n < m_colSelection.GetCount(); n++) + { + int col = m_colSelection[n]; + if( (col >= leftCol) && (col <= rightCol) ) + { + alreadyselected[ col - leftCol ]=1; + } + } - // If a block containing the selection is already selected, return, - // if a block contained in the selection is found, remove it. + // add the newly selected columns: + for ( int col = leftCol; col <= rightCol; col++ ) + { + if ( alreadyselected[ col - leftCol ] == 0 ) + { + m_colSelection.Add( col ); + } + } + } + else + { + // Remove single cells contained in newly selected block. + if ( m_selectionMode == wxGrid::wxGridSelectCells ) + { + count = m_cellSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + wxGridCellCoords& coords = m_cellSelection[n]; + if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol, + coords.GetRow(), coords.GetCol() ) ) + { + m_cellSelection.RemoveAt(n); + n--; + count--; + } + } + } - count = m_blockSelectionTopLeft.GetCount(); - for ( size_t n = 0; n < count; n++ ) + // If a block containing the selection is already selected, return, + // if a block contained in the selection is found, remove it. + + count = m_blockSelectionTopLeft.GetCount(); + for ( n = 0; n < count; n++ ) + { + wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; + wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; + + switch ( BlockContain( coords1.GetRow(), coords1.GetCol(), + coords2.GetRow(), coords2.GetCol(), + topRow, leftCol, bottomRow, rightCol ) ) + { + case 1: + return; + + case -1: + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + n--; + count--; + break; + + default: + break; + } + } + + // If a row containing the selection is already selected, return, + // if a row contained in newly selected block is found, remove it. + count = m_rowSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + switch ( BlockContain( m_rowSelection[n], 0, + m_rowSelection[n], m_grid->GetNumberCols() - 1, + topRow, leftCol, bottomRow, rightCol ) ) + { + case 1: + return; + + case -1: + m_rowSelection.RemoveAt(n); + n--; + count--; + break; + + default: + break; + } + } + + // Same for columns. + count = m_colSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + switch ( BlockContain( 0, m_colSelection[n], + m_grid->GetNumberRows() - 1, m_colSelection[n], + topRow, leftCol, bottomRow, rightCol ) ) + { + case 1: + return; + + case -1: + m_colSelection.RemoveAt(n); + n--; + count--; + break; + + default: + break; + } + } + + m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) ); + m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) ); + } + // Update View: + if ( !m_grid->GetBatchCount() ) + { + wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( topRow, leftCol ), + wxGridCellCoords( bottomRow, rightCol ) ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + } + + // Send Event, if not disabled. + if ( sendEvent ) { - wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; - wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; - switch ( BlockContain( coords1.GetRow(), coords1.GetCol(), - coords2.GetRow(), coords2.GetCol(), - topRow, leftCol, bottomRow, rightCol ) ) - { - case 1: - return; - case -1: - m_blockSelectionTopLeft.RemoveAt(n); - m_blockSelectionBottomRight.RemoveAt(n); - n--; count--; - default: - ; - } - } - - // If a row containing the selection is already selected, return, - // if a row contained in newly selected block is found, remove it. - if ( m_selectionMode != wxGridSelection::wxGridSelectColumns ) - { - size_t count = m_rowSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - switch ( BlockContain( m_rowSelection[n], 0, - m_rowSelection[n], m_grid->GetNumberCols()-1, - topRow, leftCol, bottomRow, rightCol ) ) - { - case 1: - return; - case -1: - m_rowSelection.RemoveAt(n); - n--; count--; - default: - ; - } - } - } - if ( m_selectionMode != wxGridSelection::wxGridSelectRows ) - { - size_t count = m_colSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - switch ( BlockContain( 0, m_colSelection[n], - m_grid->GetNumberRows()-1, m_colSelection[n], - topRow, leftCol, bottomRow, rightCol ) ) - { - case 1: - return; - case -1: - m_colSelection.RemoveAt(n); - n--; count--; - default: - ; - } - } - } - m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) ); - m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) ); + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( topRow, leftCol ), + wxGridCellCoords( bottomRow, rightCol ), + true, + kbd); + m_grid->GetEventHandler()->ProcessEvent( gridEvt ); + } } -void wxGridSelection::SelectCell( int row, int col) +void wxGridSelection::SelectCell( int row, int col, + const wxKeyboardState& kbd, + bool sendEvent ) { - if ( m_selectionMode == wxGridSelection::wxGridSelectRows ) - SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1 ); - else if ( m_selectionMode == wxGridSelection::wxGridSelectColumns ) - SelectBlock(0, col, m_grid->GetNumberRows() - 1, col ); - else if ( IsInSelection ( row, col ) ) + if ( IsInSelection ( row, col ) ) return; - m_cellSelection.Add( wxGridCellCoords( row, col ) ); + + wxGridCellCoords selectedTopLeft, selectedBottomRight; + if ( m_selectionMode == wxGrid::wxGridSelectRows ) + { + m_rowSelection.Add( row ); + selectedTopLeft = wxGridCellCoords( row, 0 ); + selectedBottomRight = wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ); + } + else if ( m_selectionMode == wxGrid::wxGridSelectColumns ) + { + m_colSelection.Add( col ); + selectedTopLeft = wxGridCellCoords( 0, col ); + selectedBottomRight = wxGridCellCoords( m_grid->GetNumberRows() - 1, col ); + } + else + { + m_cellSelection.Add( wxGridCellCoords( row, col ) ); + selectedTopLeft = wxGridCellCoords( row, col ); + selectedBottomRight = wxGridCellCoords( row, col ); + } + + // Update View: + if ( !m_grid->GetBatchCount() ) + { + wxRect r = m_grid->BlockToDeviceRect( + selectedTopLeft, + selectedBottomRight ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + } + + // Send event + if (sendEvent) + { + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + selectedTopLeft, + selectedBottomRight, + true, + kbd); + m_grid->GetEventHandler()->ProcessEvent( gridEvt ); + } } -void wxGridSelection::ToggleCellSelection( int row, int col) +void +wxGridSelection::ToggleCellSelection(int row, int col, + const wxKeyboardState& kbd) { + // if the cell is not selected, select it if ( !IsInSelection ( row, col ) ) - SelectCell( row, col ); - size_t count; + { + SelectCell(row, col, kbd); + + return; + } + + // otherwise deselect it. This can be simple or more or + // less difficult, depending on how the cell is selected. + size_t count, n; - // 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. + // 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 != wxGridSelection::wxGridSelectRows && - m_selectionMode != wxGridSelection::wxGridSelectColumns ) + 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() ) - { - m_cellSelection.RemoveAt(n); - n--; count--; - wxRect r; - r = m_grid->BlockToDeviceRect( m_cellSelection[n], - m_cellSelection[n] ); - if ( !m_grid->GetBatchCount() ) - ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); - return; - } - } - } - - // remove a cell from the middle of a block (the really ugly case) + for ( n = 0; n < count; n++ ) + { + const wxGridCellCoords& sel = m_cellSelection[n]; + if ( row == sel.GetRow() && col == sel.GetCol() ) + { + wxGridCellCoords coords = m_cellSelection[n]; + m_cellSelection.RemoveAt(n); + if ( !m_grid->GetBatchCount() ) + { + wxRect r = m_grid->BlockToDeviceRect( coords, coords ); + ((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, + kbd ); + m_grid->GetEventHandler()->ProcessEvent( gridEvt ); + + return; + } + } + } + + // 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++ ) - { - wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; - wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; - int topRow = coords1.GetRow(); - int leftCol = coords1.GetCol(); - int bottomRow = coords2.GetRow(); - int rightCol = coords2.GetCol(); - if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol, - row, col ) ) - { - // remove the block - m_blockSelectionTopLeft.RemoveAt(n); - m_blockSelectionBottomRight.RemoveAt(n); - n--; count--; - // add up to 4 smaller blocks and set update region - if ( m_selectionMode != wxGridSelection::wxGridSelectColumns ) - { - if ( topRow < row ) - SelectBlock( topRow, leftCol, row - 1, rightCol ); - if ( bottomRow > row ) - SelectBlock( row + 1, leftCol, bottomRow, rightCol ); - } - if ( m_selectionMode != wxGridSelection::wxGridSelectRows ) - { - if ( leftCol < col ) - SelectBlock( row, leftCol, row, col - 1 ); - if ( rightCol > col ) - SelectBlock( row, col + 1, row, rightCol ); - } - } + for ( n = 0; n < count; n++ ) + { + wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; + wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; + int topRow = coords1.GetRow(); + int leftCol = coords1.GetCol(); + int bottomRow = coords2.GetRow(); + int rightCol = coords2.GetCol(); + + if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol, row, col ) ) + { + // remove the block + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + n--; + count--; + + // add up to 4 smaller blocks and set update region + if ( m_selectionMode != wxGrid::wxGridSelectColumns ) + { + if ( topRow < row ) + SelectBlockNoEvent(topRow, leftCol, row - 1, rightCol); + if ( bottomRow > row ) + SelectBlockNoEvent(row + 1, leftCol, bottomRow, rightCol); + } + + if ( m_selectionMode != wxGrid::wxGridSelectRows ) + { + if ( leftCol < col ) + SelectBlockNoEvent(row, leftCol, row, col - 1); + if ( rightCol > col ) + SelectBlockNoEvent(row, col + 1, row, rightCol); + } + } } + bool rowSelectionWasChanged = false; // remove a cell from a row, adding up to two new blocks - if ( m_selectionMode != wxGridSelection::wxGridSelectColumns ) - { - size_t count = m_rowSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - if ( m_rowSelection[n] == row ) - { - m_rowSelection.RemoveAt(n); - n--; count--; - if (m_selectionMode == wxGridSelection::wxGridSelectCells) - { - if ( col > 0 ) - SelectBlock( row, 0, row, col - 1 ); - if ( col < m_grid->GetNumberCols() - 1 ) - SelectBlock( row, col + 1, row, m_grid->GetNumberCols() - 1 ); - } - } - } + if ( m_selectionMode != wxGrid::wxGridSelectColumns ) + { + count = m_rowSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + if ( m_rowSelection[n] == row ) + { + m_rowSelection.RemoveAt(n); + n--; + count--; + + rowSelectionWasChanged = true; + + if (m_selectionMode == wxGrid::wxGridSelectCells) + { + if ( col > 0 ) + SelectBlockNoEvent(row, 0, row, col - 1); + if ( col < m_grid->GetNumberCols() - 1 ) + SelectBlockNoEvent( row, col + 1, + row, m_grid->GetNumberCols() - 1); + } + } + } } + bool colSelectionWasChanged = false; // remove a cell from a column, adding up to two new blocks - if ( m_selectionMode != wxGridSelection::wxGridSelectRows ) - { - size_t count = m_colSelection.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - if ( m_colSelection[n] == col ) - { - m_colSelection.RemoveAt(n); - n--; count--; - if (m_selectionMode == wxGridSelection::wxGridSelectCells) - { - if ( row > 0 ) - SelectBlock( 0, col, row - 1, col ); - if ( row < m_grid->GetNumberRows() - 1 ) - SelectBlock( row + 1, col, m_grid->GetNumberRows() - 1, col ); - } - } - } + if ( m_selectionMode != wxGrid::wxGridSelectRows ) + { + count = m_colSelection.GetCount(); + for ( n = 0; n < count; n++ ) + { + if ( m_colSelection[n] == col ) + { + m_colSelection.RemoveAt(n); + n--; + count--; + + colSelectionWasChanged = true; + + if (m_selectionMode == wxGrid::wxGridSelectCells) + { + if ( row > 0 ) + SelectBlockNoEvent(0, col, row - 1, col); + if ( row < m_grid->GetNumberRows() - 1 ) + SelectBlockNoEvent(row + 1, col, + m_grid->GetNumberRows() - 1, col); + } + } + } } + + // 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 wxGridSelection::wxGridSelectCells: - r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ), - wxGridCellCoords( row, col ) ); - break; - case wxGridSelection::wxGridSelectRows: - r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ), - wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) ); - break; - case wxGridSelection::wxGridSelectColumns: - r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ), - wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) ); - break; + if ( m_selectionMode == wxGrid::wxGridSelectCells ) + { + if ( !m_grid->GetBatchCount() ) + { + r = m_grid->BlockToDeviceRect( + wxGridCellCoords( row, col ), + wxGridCellCoords( row, col ) ); + ((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, + kbd ); + m_grid->GetEventHandler()->ProcessEvent( gridEvt ); + } + else // rows/columns selection mode + { + if ( m_selectionMode != wxGrid::wxGridSelectColumns && + rowSelectionWasChanged ) + { + int numCols = m_grid->GetNumberCols(); + for ( int colFrom = 0, colTo = 0; colTo <= numCols; ++colTo ) + { + if ( m_colSelection.Index(colTo) >= 0 || colTo == numCols ) + { + if ( colFrom < colTo ) + { + if ( !m_grid->GetBatchCount() ) + { + r = m_grid->BlockToDeviceRect( + wxGridCellCoords( row, colFrom ), + wxGridCellCoords( row, colTo-1 ) ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + } + + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( row, colFrom ), + wxGridCellCoords( row, colTo - 1 ), + false, + kbd ); + m_grid->GetEventHandler()->ProcessEvent( gridEvt ); + } + + colFrom = colTo + 1; + } + } + } + + if ( m_selectionMode != wxGrid::wxGridSelectRows && + colSelectionWasChanged ) + { + int numRows = m_grid->GetNumberRows(); + for ( int rowFrom = 0, rowTo = 0; rowTo <= numRows; ++rowTo ) + { + if ( m_rowSelection.Index(rowTo) >= 0 || rowTo == numRows ) + { + if (rowFrom < rowTo) + { + if ( !m_grid->GetBatchCount() ) + { + r = m_grid->BlockToDeviceRect( + wxGridCellCoords( rowFrom, col ), + wxGridCellCoords( rowTo - 1, col ) ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + } + + wxGridRangeSelectEvent gridEvt( m_grid->GetId(), + wxEVT_GRID_RANGE_SELECT, + m_grid, + wxGridCellCoords( rowFrom, col ), + wxGridCellCoords( rowTo - 1, col ), + false, + kbd ); + m_grid->GetEventHandler()->ProcessEvent( gridEvt ); + } + + rowFrom = rowTo + 1; + } + } + } } - if ( !m_grid->GetBatchCount() ) - ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); } void wxGridSelection::ClearSelection() { size_t n; - if ( m_selectionMode != wxGridSelection::wxGridSelectRows && - m_selectionMode != wxGridSelection::wxGridSelectColumns ) - { - - while( ( n = m_cellSelection.GetCount() ) > 0) - { - wxRect r; - r = m_grid->BlockToDeviceRect( m_cellSelection[n], - m_cellSelection[n] ); - m_cellSelection.RemoveAt(n); - if ( !m_grid->GetBatchCount() ) - ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); - } - } - while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0) - { - wxRect r; - r = m_grid->BlockToDeviceRect( m_blockSelectionTopLeft[n], - m_blockSelectionBottomRight[n] ); - m_blockSelectionTopLeft.RemoveAt(n); - m_blockSelectionBottomRight.RemoveAt(n); - if ( !m_grid->GetBatchCount() ) - ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); - } - if ( m_selectionMode != wxGridSelection::wxGridSelectColumns ) - { - while( ( n = m_rowSelection.GetCount() ) > 0) - { - int & row = m_rowSelection[n]; - wxRect r; - r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ), - wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) ); - m_rowSelection.RemoveAt(n); - if ( !m_grid->GetBatchCount() ) - ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); - } - } - if ( m_selectionMode != wxGridSelection::wxGridSelectRows ) - { - while( ( n = m_colSelection.GetCount() ) > 0) - { - int & col = m_colSelection[n]; - wxRect r; - r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ), - wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) ); - m_colSelection.RemoveAt(n); - if ( !m_grid->GetBatchCount() ) - ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r ); - } + wxRect r; + wxGridCellCoords coords1, coords2; + + // deselect all individual cells and update the screen + if ( m_selectionMode == wxGrid::wxGridSelectCells ) + { + while ( ( n = m_cellSelection.GetCount() ) > 0) + { + n--; + coords1 = m_cellSelection[n]; + m_cellSelection.RemoveAt(n); + if ( !m_grid->GetBatchCount() ) + { + r = m_grid->BlockToDeviceRect( coords1, coords1 ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + +#ifdef __WXMAC__ + ((wxWindow *)m_grid->m_gridWin)->Update(); +#endif + } + } + } + + // deselect all blocks and update the screen + while ( ( n = m_blockSelectionTopLeft.GetCount() ) > 0) + { + n--; + coords1 = m_blockSelectionTopLeft[n]; + coords2 = m_blockSelectionBottomRight[n]; + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + if ( !m_grid->GetBatchCount() ) + { + r = m_grid->BlockToDeviceRect( coords1, coords2 ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + +#ifdef __WXMAC__ + ((wxWindow *)m_grid->m_gridWin)->Update(); +#endif + } + } + + // deselect all rows and update the screen + if ( m_selectionMode != wxGrid::wxGridSelectColumns ) + { + while ( ( n = m_rowSelection.GetCount() ) > 0) + { + n--; + int row = m_rowSelection[n]; + m_rowSelection.RemoveAt(n); + if ( !m_grid->GetBatchCount() ) + { + r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ), + wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ) ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + +#ifdef __WXMAC__ + ((wxWindow *)m_grid->m_gridWin)->Update(); +#endif + } + } } + + // deselect all columns and update the screen + if ( m_selectionMode != wxGrid::wxGridSelectRows ) + { + while ( ( n = m_colSelection.GetCount() ) > 0) + { + n--; + int col = m_colSelection[n]; + m_colSelection.RemoveAt(n); + if ( !m_grid->GetBatchCount() ) + { + r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ), + wxGridCellCoords( m_grid->GetNumberRows() - 1, col ) ); + ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); + +#ifdef __WXMAC__ + ((wxWindow *)m_grid->m_gridWin)->Update(); +#endif + } + } + } + + // 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(); @@ -543,27 +1024,29 @@ void wxGridSelection::UpdateRows( size_t pos, int numRows ) { // ...or remove the attribute m_cellSelection.RemoveAt(n); - n--; count--; + n--; + count--; } } } } 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]; wxCoord row1 = coords1.GetRow(); wxCoord row2 = coords2.GetRow(); + if ((size_t)row2 >= pos) { if (numRows > 0) { // If rows inserted, increase row counter where necessary - coords2.SetRow(row2 + numRows); - if ( (size_t)row1 >= pos ) - coords1.SetRow(row1 + numRows); + coords2.SetRow( row2 + numRows ); + if ((size_t)row1 >= pos) + coords1.SetRow( row1 + numRows ); } else if (numRows < 0) { @@ -571,57 +1054,66 @@ void wxGridSelection::UpdateRows( size_t pos, int numRows ) if ((size_t)row2 >= pos - numRows) { // ...either decrement row counter (if row still exists)... - coords2.SetRow(row2 + numRows); - if ( (size_t) row1 >= pos) - coords1.SetRow( wxMax(row1 + numRows, (int) pos) ); - + coords2.SetRow( row2 + numRows ); + if ((size_t)row1 >= pos) + coords1.SetRow( wxMax(row1 + numRows, (int)pos) ); + } else { - if ( (size_t) row1 >= pos) - { - // ...or remove the attribute - m_blockSelectionTopLeft.RemoveAt(n); - m_blockSelectionBottomRight.RemoveAt(n); - n--; count--; - } - else - coords2.SetRow(pos); + if ((size_t)row1 >= pos) + { + // ...or remove the attribute + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + n--; + count--; + } + else + coords2.SetRow( pos ); } } } } 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 ) - { - if ( numRows > 0 ) - { - // If rows inserted, include row counter where necessary - rowOrCol += numRows; - } - else if ( numRows < 0) - { - // If rows deleted, either decrement row counter (if row still exists) - if ((size_t)rowOrCol >= pos - numRows) - rowOrCol += numRows; - else - { - m_rowSelection.RemoveAt(n); - n--; count--; - } - } - } + int rowOrCol_ = m_rowSelection[n]; + + if ((size_t) rowOrCol_ >= pos) + { + if ( numRows > 0 ) + { + m_rowSelection[n] += numRows; + } + else if ( numRows < 0 ) + { + if ((size_t)rowOrCol_ >= (pos - numRows)) + m_rowSelection[n] += numRows; + else + { + m_rowSelection.RemoveAt( n ); + n--; + count--; + } + } + } } + // 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(); @@ -644,27 +1136,29 @@ void wxGridSelection::UpdateCols( size_t pos, int numCols ) { // ...or remove the attribute m_cellSelection.RemoveAt(n); - n--; count--; + n--; + count--; } } } } 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]; wxCoord col1 = coords1.GetCol(); wxCoord col2 = coords2.GetCol(); + if ((size_t)col2 >= pos) { if (numCols > 0) { // If rows inserted, increase row counter where necessary coords2.SetCol(col2 + numCols); - if ( (size_t)col1 >= pos ) - coords1.SetCol(col1 + numCols); + if ((size_t)col1 >= pos) + coords1.SetCol(col1 + numCols); } else if (numCols < 0) { @@ -673,65 +1167,72 @@ void wxGridSelection::UpdateCols( size_t pos, int numCols ) { // ...either decrement col counter (if col still exists)... coords2.SetCol(col2 + numCols); - if ( (size_t) col1 >= pos) - coords1.SetCol( wxMax(col1 + numCols, (int) pos) ); - + if ( (size_t) col1 >= pos) + coords1.SetCol( wxMax(col1 + numCols, (int)pos) ); + } else { - if ( (size_t) col1 >= pos) - { - // ...or remove the attribute - m_blockSelectionTopLeft.RemoveAt(n); - m_blockSelectionBottomRight.RemoveAt(n); - n--; count--; - } - else - coords2.SetCol(pos); + if ((size_t)col1 >= pos) + { + // ...or remove the attribute + m_blockSelectionTopLeft.RemoveAt(n); + m_blockSelectionBottomRight.RemoveAt(n); + n--; + count--; + } + else + coords2.SetCol(pos); } } } } 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 ) + int rowOrCol = m_colSelection[n]; + + if ((size_t)rowOrCol >= pos) { if ( numCols > 0 ) + m_colSelection[n] += numCols; + else if ( numCols < 0 ) { - // If cols inserted, include col counter where necessary - rowOrCol += numCols; - } - else if ( numCols < 0) - { - // If cols deleted, either decrement col counter (if col still exists) - if ((size_t)rowOrCol >= pos - numCols) - rowOrCol += numCols; + if ((size_t)rowOrCol >= (pos - numCols)) + m_colSelection[n] += numCols; else { - m_colSelection.RemoveAt(n); - n--; count--; + m_colSelection.RemoveAt( n ); + n--; + count--; } } } } + + // 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, - int bottomRow1, int rightCol1, - int topRow2, int leftCol2, - int bottomRow2, int rightCol2 ) + int bottomRow1, int rightCol1, + int topRow2, int leftCol2, + int bottomRow2, int rightCol2 ) // returns 1, if Block1 contains Block2, // -1, if Block2 contains Block1, // 0, otherwise { if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 && - leftCol1 <= leftCol2 && rightCol2 <= rightCol1 ) + leftCol1 <= leftCol2 && rightCol2 <= rightCol1 ) return 1; else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 && - leftCol2 <= leftCol1 && rightCol1 <= rightCol2 ) + leftCol2 <= leftCol1 && rightCol1 <= rightCol2 ) return -1; + return 0; } + +#endif