From 9b820b74b2564eecc0a5f03432d463c15c25ee19 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Oct 2021 19:41:06 +0100 Subject: [PATCH 1/2] Fix handling selection in wxGrid::Render() Temporarily reset the m_selection pointer itself instead of clearing the selection, this is much more efficient, especially for big grids, and also more correct, as the old code simply lost the original selection in non-block selection modes. --- src/generic/grid.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 9e99ef2d74..cd121aa2b6 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -2301,17 +2301,12 @@ void wxGrid::Render( wxDC& dc, // remove grid selection, don't paint selection colour // unless we have wxGRID_DRAW_SELECTION - // block selections are the only ones catered for here - wxGridCellCoordsArray selectedCells; - bool hasSelection = IsSelection(); - if ( hasSelection && !( style & wxGRID_DRAW_SELECTION ) ) + wxGridSelection* selectionOrig = NULL; + if ( m_selection && !( style & wxGRID_DRAW_SELECTION ) ) { - selectedCells = GetSelectionBlockTopLeft(); - // non block selections may not have a bottom right - if ( GetSelectionBlockBottomRight().size() ) - selectedCells.Add( GetSelectionBlockBottomRight()[ 0 ] ); - - ClearSelection(); + // remove the selection temporarily, it will be restored below + selectionOrig = m_selection; + m_selection = NULL; } // store user device origin @@ -2437,12 +2432,9 @@ void wxGrid::Render( wxDC& dc, dc.SetDeviceOrigin( userOriginX, userOriginY ); dc.SetUserScale( scaleUserX, scaleUserY ); - if ( selectedCells.size() && !( style & wxGRID_DRAW_SELECTION ) ) + if ( selectionOrig ) { - SelectBlock( selectedCells[ 0 ].GetRow(), - selectedCells[ 0 ].GetCol(), - selectedCells[ selectedCells.size() -1 ].GetRow(), - selectedCells[ selectedCells.size() -1 ].GetCol() ); + m_selection = selectionOrig; } } From c28c7edbb453f383b0326703d0a83287463f31a7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Oct 2021 19:51:26 +0100 Subject: [PATCH 2/2] Let wxGrid::GetSelectionBlockTopLeft/BottomRight work in any mode These functions used to work in any mode until the changes of 02509cbc39 (Refactor wxGridSelection to store selection as blocks only, 2020-03-03) and should continue to do so, if only for compatibility. --- src/generic/gridsel.cpp | 7 ------- tests/controls/gridtest.cpp | 10 ++++++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/generic/gridsel.cpp b/src/generic/gridsel.cpp index b336bb4df0..81ee2a4641 100644 --- a/src/generic/gridsel.cpp +++ b/src/generic/gridsel.cpp @@ -746,10 +746,6 @@ wxGridCellCoordsArray wxGridSelection::GetCellSelection() const wxGridCellCoordsArray wxGridSelection::GetBlockSelectionTopLeft() const { - // return blocks only in wxGridSelectCells selection mode - if ( m_selectionMode != wxGrid::wxGridSelectCells ) - return wxGridCellCoordsArray(); - wxGridCellCoordsArray coords; const size_t count = m_selection.size(); coords.reserve(count); @@ -762,9 +758,6 @@ wxGridCellCoordsArray wxGridSelection::GetBlockSelectionTopLeft() const wxGridCellCoordsArray wxGridSelection::GetBlockSelectionBottomRight() const { - if ( m_selectionMode != wxGrid::wxGridSelectCells ) - return wxGridCellCoordsArray(); - wxGridCellCoordsArray coords; const size_t count = m_selection.size(); coords.reserve(count); diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index cd0fba8f50..934586b657 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -1163,6 +1163,16 @@ TEST_CASE_METHOD(GridTestCase, "Grid::SelectionMode", "[grid]") CHECK( m_grid->IsInSelection(5, 1) ); CHECK( !m_grid->IsInSelection(3, 1) ); + // Check that top left/bottom right selection functions still work in row + // selection mode. + wxGridCellCoordsArray arr = m_grid->GetSelectionBlockTopLeft(); + REQUIRE( arr.size() == 1 ); + CHECK( arr[0] == wxGridCellCoords(5, 0) ); + + arr = m_grid->GetSelectionBlockBottomRight(); + REQUIRE( arr.size() == 1 ); + CHECK( arr[0] == wxGridCellCoords(5, 1) ); + //Test row selection be selecting a single cell and checking the whole //row is selected m_grid->ClearSelection();