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.
This commit is contained in:
Vadim Zeitlin 2017-11-07 14:12:48 +01:00
parent 6d55a533a3
commit faad429b0f
2 changed files with 23 additions and 2 deletions

View File

@ -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;
}

View File

@ -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 );
}
}