From d031ef154a97effd7772007acbb3879eb90d7758 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 5 Apr 2020 02:03:55 +0200 Subject: [PATCH] Simplify wxGrid::SetSelectionMode() selection updating logic Don't try to extend the existing selected blocks to rows/columns, this contradicts the documented behaviour which is to discard the selected blocks that become invalid in the new mode. Do handle switching to wxGridSelectRowsOrColumns mode, as there doesn't seem to be any reason not to. Update the tests to check for the expected selection update behaviour. --- src/generic/gridsel.cpp | 46 +++++++++++++++++++++---------------- tests/controls/gridtest.cpp | 13 ++++++++++- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/generic/gridsel.cpp b/src/generic/gridsel.cpp index 588fa1c586..a7957bd777 100644 --- a/src/generic/gridsel.cpp +++ b/src/generic/gridsel.cpp @@ -81,8 +81,6 @@ void wxGridSelection::SetSelectionMode( wxGrid::wxGridSelectionModes selmode ) if (selmode == m_selectionMode) return; - // TODO: wxGridSelectRowsOrColumns? - if ( m_selectionMode != wxGrid::wxGridSelectCells ) { // if changing form row to column selection @@ -94,6 +92,11 @@ void wxGridSelection::SetSelectionMode( wxGrid::wxGridSelectionModes selmode ) } else { + // Preserve only fully selected rows/columns when switching from cell + // selection mode and discard the selected blocks that are invalid in + // the new selection mode. + const int lastCol = m_grid->GetNumberCols() - 1; + const int lastRow = m_grid->GetNumberRows() - 1; for ( size_t n = m_selection.size(); n > 0; ) { n--; @@ -103,26 +106,29 @@ void wxGridSelection::SetSelectionMode( wxGrid::wxGridSelectionModes selmode ) const int bottomRow = block.GetBottomRow(); const int rightCol = block.GetRightCol(); - if (selmode == wxGrid::wxGridSelectRows) + bool valid = false; + switch ( selmode ) { - if (leftCol != 0 || rightCol != m_grid->GetNumberCols() - 1 ) - { - m_selection.erase(m_selection.begin() + n); - SelectBlockNoEvent( - wxGridBlockCoords(topRow, 0, - bottomRow, m_grid->GetNumberCols() - 1)); - } - } - else // selmode == wxGridSelectColumns) - { - if (topRow != 0 || bottomRow != m_grid->GetNumberRows() - 1 ) - { - m_selection.erase(m_selection.begin() + n); - SelectBlockNoEvent( - wxGridBlockCoords(0, leftCol, - m_grid->GetNumberRows() - 1, rightCol)); - } + case wxGrid::wxGridSelectCells: + wxFAIL_MSG("unreachable"); + break; + + case wxGrid::wxGridSelectRows: + valid = leftCol == 0 && rightCol == lastCol; + break; + + case wxGrid::wxGridSelectColumns: + valid = topRow == 0 && bottomRow == lastRow; + break; + + case wxGrid::wxGridSelectRowsOrColumns: + valid = (leftCol == 0 && rightCol == lastCol) || + (topRow == 0 && bottomRow == lastRow); + break; } + + if ( !valid ) + m_selection.erase(m_selection.begin() + n); } m_selectionMode = selmode; diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 708f42cd18..67892326eb 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -862,9 +862,20 @@ TEST_CASE_METHOD(GridTestCase, "Grid::SelectionMode", "[grid]") //We already test this mode in Select CHECK(m_grid->GetSelectionMode() == wxGrid::wxGridSelectCells); + // Select an individual cell and an entire row. + m_grid->SelectBlock(3, 1, 3, 1); + m_grid->SelectRow(5, true /* add to selection */); + + // Test that after switching to row selection mode only the row remains + // selected. + m_grid->SetSelectionMode(wxGrid::wxGridSelectRows); + CHECK( m_grid->IsInSelection(5, 0) ); + CHECK( m_grid->IsInSelection(5, 1) ); + CHECK( !m_grid->IsInSelection(3, 1) ); + //Test row selection be selecting a single cell and checking the whole //row is selected - m_grid->SetSelectionMode(wxGrid::wxGridSelectRows); + m_grid->ClearSelection(); m_grid->SelectBlock(3, 1, 3, 1); wxArrayInt selectedRows = m_grid->GetSelectedRows();