void wxGridSelection::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol, const wxKeyboardState& kbd, bool sendEvent ) { // 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 ) { int temp = topRow; topRow = bottomRow; bottomRow = temp; } if ( leftCol > rightCol ) { int temp = leftCol; leftCol = rightCol; rightCol = temp; } // Handle single cell selection in SelectCell. // (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, n; if ( m_selectionMode == wxGrid::wxGridSelectRows ) { // 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; } } // 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--; } } } // 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 ) { 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::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 needed. if ( m_selectionMode == wxGrid::wxGridSelectRows ) { leftCol = 0; rightCol = m_grid->GetNumberCols() - 1; } else if ( m_selectionMode == wxGrid::wxGridSelectColumns ) { 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. // (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, n; // 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--; } } } // 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. if ( m_selectionMode != wxGrid::wxGridSelectColumns ) { 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; } } } if ( m_selectionMode != wxGrid::wxGridSelectRows ) { 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 ) { 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); } }