From faad429b0f3bf2824d9764072e8edc42b62fb29e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2017 14:12:48 +0100 Subject: [PATCH] Fix wxTextCtrl::XYToPosition() for last position in wxGTK Change this method to consider the coordinates corresponding to the last position (i.e. the one beyond the last text character) as valid, for consistency with wxMSW and to conform to the documented behaviour. Also give more information about the failures in the corresponding unit test to make debugging problems with this function simpler. --- src/gtk/textctrl.cpp | 20 ++++++++++++++++++-- tests/controls/textctrltest.cpp | 5 +++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 255544eeda..2495c498df 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -1198,13 +1198,29 @@ long wxTextCtrl::XYToPosition(long x, long y ) const return x; } + const gint numLines = gtk_text_buffer_get_line_count (m_buffer); + GtkTextIter iter; - if (y >= gtk_text_buffer_get_line_count (m_buffer)) + if (y >= numLines) return -1; gtk_text_buffer_get_iter_at_line(m_buffer, &iter, y); - if (x >= gtk_text_iter_get_chars_in_line (&iter)) + + const gint lineLength = gtk_text_iter_get_chars_in_line (&iter); + if (x > lineLength) + { + // This coordinate is always invalid. return -1; + } + + if (x == lineLength) + { + // In this case the coordinate is considered to be valid by wx if this + // is the last line, as it corresponds to the last position beyond the + // last character of the text, and invalid otherwise. + if (y != numLines - 1) + return -1; + } return gtk_text_iter_get_offset(&iter) + x; } diff --git a/tests/controls/textctrltest.cpp b/tests/controls/textctrltest.cpp index 175d46d011..89ff430cd3 100644 --- a/tests/controls/textctrltest.cpp +++ b/tests/controls/textctrltest.cpp @@ -935,6 +935,7 @@ void TextCtrlTestCase::DoXYToPositionMultiLine(long style) for( long x = 0; x < maxLineLength_0+1; x++ ) { long p = m_text->XYToPosition(x, y); + INFO("x=" << x << ", y=" << y); CPPUNIT_ASSERT_EQUAL( pos_0[y][x], p ); } @@ -951,6 +952,7 @@ void TextCtrlTestCase::DoXYToPositionMultiLine(long style) for( long x = 0; x < maxLineLength_1+1; x++ ) { long p = m_text->XYToPosition(x, y); + INFO("x=" << x << ", y=" << y); CPPUNIT_ASSERT_EQUAL( pos_1[y][x], p ); } @@ -985,6 +987,7 @@ void TextCtrlTestCase::DoXYToPositionMultiLine(long style) for( long x = 0; x < maxLineLength_2+1; x++ ) { long p = m_text->XYToPosition(x, y); + INFO("x=" << x << ", y=" << y); CPPUNIT_ASSERT_EQUAL( ref_pos_2[y][x], p ); } @@ -1021,6 +1024,7 @@ void TextCtrlTestCase::DoXYToPositionMultiLine(long style) for( long x = 0; x < maxLineLength_3+1; x++ ) { long p = m_text->XYToPosition(x, y); + INFO("x=" << x << ", y=" << y); CPPUNIT_ASSERT_EQUAL( ref_pos_3[y][x], p ); } @@ -1061,6 +1065,7 @@ void TextCtrlTestCase::DoXYToPositionMultiLine(long style) for( long x = 0; x < maxLineLength_4+1; x++ ) { long p = m_text->XYToPosition(x, y); + INFO("x=" << x << ", y=" << y); CPPUNIT_ASSERT_EQUAL( ref_pos_4[y][x], p ); } }