From ff79db8ac1d8cd997f7491945ed8ff985259cfdf Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Mon, 28 Dec 2020 00:10:02 +0100 Subject: [PATCH 1/2] wxGrid: Add test for auto-wrapped multi-line cells Check that a row's height doesn't change when auto-sizing a column with an auto-wrapping cell containing newlines. Also currently will cause an infinite loop which will be fixed in the next commit. See #15943. --- tests/controls/gridtest.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 3eeb1bc4a8..87e5475749 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -1405,6 +1405,22 @@ TEST_CASE_METHOD(GridTestCase, "Grid::AutoSizeColumn", "[grid]") // so just calculate the maximum width. CheckFirstColAutoSize( wxMax(labelWidth, cellWidth) ); } + + SECTION("Column with auto wrapping contents taller than row") + { + // Verify row height remains unchanged with an auto-wrapping multi-line + // cell. + // Also shouldn't continuously try to fit the multi-line content into + // a single line, which is not possible. See + // https://trac.wxwidgets.org/ticket/15943 . + + m_grid->SetCellValue(0, 0, multilineStr); + m_grid->SetCellRenderer(0 , 0, new wxGridCellAutoWrapStringRenderer); + m_grid->AutoSizeColumn(0); + + wxYield(); + CHECK( m_grid->GetRowSize(0) == m_grid->GetDefaultRowSize() ); + } } // Test wxGridBlockCoords here because it'a a part of grid sources. From c6a588424d382909e17f343eddeee82e0f2d202b Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Mon, 28 Dec 2020 00:14:37 +0100 Subject: [PATCH 2/2] wxGrid: Fix potential infinite loop with auto-wrap When using wxGridCellAutoWrapStringRenderer::GetBestWidth() with a cell containing more newlines than fit, the function never exits because it keeps on trying to wrap fit into the number of lines based on available height only. Fix by also taking into account the number of newlines a cell's text value has. Closes #15943. --- src/generic/gridctrl.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index f1e83880d8..11d4de5442 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -546,10 +546,16 @@ wxGridCellAutoWrapStringRenderer::GetBestWidth(wxGrid& grid, { const int lineHeight = dc.GetCharHeight(); - // Maximal number of lines that fully fit but at least 1. - const size_t maxLines = height - AUTOWRAP_Y_MARGIN < lineHeight - ? 1 - : (height - AUTOWRAP_Y_MARGIN)/lineHeight; + // Base the maximal number of lines either on how many fit or how many + // (new)lines the cell's text contains, whichever results in the most lines. + // + // It's important to take the newlines into account as GetTextLines() splits + // based on them and the number of lines returned can never drop below that, + // resulting in the while loop below never exiting if there are already more + // lines in the text than can fit in the available height. + const size_t maxLines = wxMax( + (height - AUTOWRAP_Y_MARGIN)/lineHeight, + 1 + grid.GetCellValue(row, col).Freq(wxS('\n'))); // Increase width until all the text fits. //