From be8fbbff6637fbbc011f48e8b41d291467b95d61 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 29 Dec 2011 22:05:23 +0000 Subject: [PATCH] Store row/column selection more appropriately in wxGrid. Use wxGridSelection::m_rowSelection and m_colSelection for storing the selected rows/columns respectively instead of storing them in m_blockXXX arrays. This makes more sense and allows to easily implement the proper handling of Ctrl-clicking in the row or column selection modes. Closes #12638. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70177 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + src/generic/gridsel.cpp | 161 ++++++++++++++++++++++++++-------------- 2 files changed, 106 insertions(+), 56 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 6e56743fa5..94f2001b70 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -460,6 +460,7 @@ All (GUI): - Fix item alignment in icon view in the generic wxListCtrl. - Support font-family/style, text-decoration in wxHtmlWindow (Blake Oleander). - Show ribbon tools help strings in tooltips (John Roberts). +- Improve row/column selection modes in wxGrid (joostn). GTK: diff --git a/src/generic/gridsel.cpp b/src/generic/gridsel.cpp index 495478bb05..bf449f7c42 100644 --- a/src/generic/gridsel.cpp +++ b/src/generic/gridsel.cpp @@ -428,55 +428,101 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, size_t count, n; - // Remove single cells contained in newly selected block. - if ( m_selectionMode == wxGrid::wxGridSelectCells ) + if ( m_selectionMode == wxGrid::wxGridSelectRows ) { - count = m_cellSelection.GetCount(); - for ( n = 0; n < count; n++ ) + // find out which rows are already selected: + wxArrayInt alreadyselected; + alreadyselected.Add(0,bottomRow-topRow+1); + for( n = 0; n < m_rowSelection.GetCount(); n++) { - wxGridCellCoords& coords = m_cellSelection[n]; - if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol, - coords.GetRow(), coords.GetCol() ) ) + int row = m_rowSelection[n]; + if( (row >= topRow) && (row <= bottomRow) ) { - m_cellSelection.RemoveAt(n); - n--; - count--; + alreadyselected[ row - topRow ]=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 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; + } + } - count = m_blockSelectionTopLeft.GetCount(); - for ( n = 0; n < count; n++ ) + // add the newly selected columns: + for ( int col = leftCol; col <= rightCol; col++ ) + { + if ( alreadyselected[ col - leftCol ] == 0 ) + { + m_colSelection.Add( col ); + } + } + } + else { - wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; - wxGridCellCoords& coords2 = m_blockSelectionBottomRight[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--; + } + } + } - switch ( BlockContain( coords1.GetRow(), coords1.GetCol(), - coords2.GetRow(), coords2.GetCol(), - topRow, leftCol, bottomRow, rightCol ) ) + // 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++ ) { - case 1: - return; + wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n]; + wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n]; - case -1: - m_blockSelectionTopLeft.RemoveAt(n); - m_blockSelectionBottomRight.RemoveAt(n); - n--; - count--; - break; + 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; + 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 ) - { + // 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++ ) { @@ -497,10 +543,8 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, break; } } - } - if ( m_selectionMode != wxGrid::wxGridSelectRows ) - { + // Same for columns. count = m_colSelection.GetCount(); for ( n = 0; n < count; n++ ) { @@ -521,11 +565,10 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol, break; } } - } - - m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) ); - m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) ); + m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) ); + m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) ); + } // Update View: if ( !m_grid->GetBatchCount() ) { @@ -552,29 +595,35 @@ void wxGridSelection::SelectCell( int row, int col, const wxKeyboardState& kbd, bool sendEvent ) { + if ( IsInSelection ( row, col ) ) + return; + + wxGridCellCoords selectedTopLeft, selectedBottomRight; if ( m_selectionMode == wxGrid::wxGridSelectRows ) { - SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1, kbd, sendEvent); - - return; + m_rowSelection.Add( row ); + selectedTopLeft = wxGridCellCoords( row, 0 ); + selectedBottomRight = wxGridCellCoords( row, m_grid->GetNumberCols() - 1 ); } else if ( m_selectionMode == wxGrid::wxGridSelectColumns ) { - SelectBlock(0, col, m_grid->GetNumberRows() - 1, col, kbd, sendEvent); - - return; + 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 ); } - else if ( IsInSelection ( row, col ) ) - return; - - m_cellSelection.Add( wxGridCellCoords( row, col ) ); // Update View: if ( !m_grid->GetBatchCount() ) { wxRect r = m_grid->BlockToDeviceRect( - wxGridCellCoords( row, col ), - wxGridCellCoords( row, col ) ); + selectedTopLeft, + selectedBottomRight ); ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r ); } @@ -584,8 +633,8 @@ void wxGridSelection::SelectCell( int row, int col, wxGridRangeSelectEvent gridEvt( m_grid->GetId(), wxEVT_GRID_RANGE_SELECT, m_grid, - wxGridCellCoords( row, col ), - wxGridCellCoords( row, col ), + selectedTopLeft, + selectedBottomRight, true, kbd); m_grid->GetEventHandler()->ProcessEvent( gridEvt ); -- 2.45.2