From 4cd28a7f8c6abb7a33d19b0c87152d85370373d1 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Fri, 3 Feb 2012 12:36:10 +1000 Subject: [PATCH] Fix vertical offset of TextInput.positionToRectangle. Offset the y value of the rectangle by the vertical scroll and line offset. Task-number: QTBUG-23934 Change-Id: I43815b480f43a089a9a03b0aec32dfc0598b6154 Reviewed-by: Martin Jones --- src/quick/items/qquicktextinput.cpp | 8 ++-- .../qquicktextinput/tst_qquicktextinput.cpp | 54 +++++++++++++++++++++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 65850b9..39dcc11 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1299,11 +1299,13 @@ void QQuickTextInput::createCursor() QRectF QQuickTextInput::positionToRectangle(int pos) const { Q_D(const QQuickTextInput); - if (pos > d->m_cursor) + if (d->m_echoMode == NoEcho) + pos = 0; + else if (pos > d->m_cursor) pos += d->preeditAreaText().length(); - QTextLine l = d->m_textLayout.lineAt(0); + QTextLine l = d->m_textLayout.lineForTextPosition(pos); return l.isValid() - ? QRectF(l.cursorToX(pos) - d->hscroll, 0.0, d->m_cursorWidth, l.height()) + ? QRectF(l.cursorToX(pos) - d->hscroll, l.y() - d->vscroll, d->m_cursorWidth, l.height()) : QRectF(); } diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp index ee1a3bb..1be49a1 100644 --- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp @@ -1411,17 +1411,25 @@ void tst_qquicktextinput::verticalAlignment() QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignTop); QVERIFY(textInputPrivate->boundingRect.bottom() - textInputPrivate->vscroll < canvas.height() / 2); + QVERIFY(textInput->cursorRectangle().bottom() < canvas.height() / 2); + QVERIFY(textInput->positionToRectangle(0).bottom() < canvas.height() / 2); // bottom aligned textInput->setVAlign(QQuickTextInput::AlignBottom); QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignBottom); QVERIFY(textInputPrivate->boundingRect.top() - textInputPrivate->vscroll > canvas.height() / 2); + QVERIFY(textInput->cursorRectangle().top() > canvas.height() / 2); + QVERIFY(textInput->positionToRectangle(0).top() > canvas.height() / 2); // explicitly center aligned textInput->setVAlign(QQuickTextInput::AlignVCenter); QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignVCenter); QVERIFY(textInputPrivate->boundingRect.top() - textInputPrivate->vscroll < canvas.height() / 2); QVERIFY(textInputPrivate->boundingRect.bottom() - textInputPrivate->vscroll > canvas.height() / 2); + QVERIFY(textInput->cursorRectangle().top() < canvas.height() / 2); + QVERIFY(textInput->cursorRectangle().bottom() > canvas.height() / 2); + QVERIFY(textInput->positionToRectangle(0).top() < canvas.height() / 2); + QVERIFY(textInput->positionToRectangle(0).bottom() > canvas.height() / 2); } void tst_qquicktextinput::boundingRect() @@ -2374,6 +2382,9 @@ void tst_qquicktextinput::cursorVisible() QCOMPARE(spy.count(), 7); } +static QRect round(const QRectF &r) { + return QRect(qRound(r.left()), qRound(r.top()), qCeil(r.width()), qCeil(r.height())); } + void tst_qquicktextinput::cursorRectangle() { @@ -2413,6 +2424,7 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); } // Check the cursor rectangle remains within the input bounding rect when auto scrolling. @@ -2423,6 +2435,7 @@ void tst_qquicktextinput::cursorRectangle() input.setCursorPosition(i); QCOMPARE(r, input.cursorRectangle()); QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); } for (int i = text.length() - 2; i >= 0; --i) { @@ -2431,10 +2444,40 @@ void tst_qquicktextinput::cursorRectangle() QCOMPARE(r.top(), 0); QVERIFY(r.right() >= 0); QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); } - // Check vertical scrolling with word wrap. + // Check position with word wrap. input.setWrapMode(QQuickTextInput::WordWrap); + input.setAutoScroll(false); + for (int i = 0; i <= 5; ++i) { + input.setCursorPosition(i); + r = input.cursorRectangle(); + + QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); + QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); + QCOMPARE(r.top(), 0); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); + } + + input.setCursorPosition(6); + r = input.cursorRectangle(); + QCOMPARE(r.left(), 0); + QVERIFY(r.top() > line.height() - error); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(6)), r); + + for (int i = 7; i < text.length(); ++i) { + input.setCursorPosition(i); + r = input.cursorRectangle(); + QVERIFY(r.top() > line.height() - error); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); + } + + // Check vertical scrolling with word wrap. + input.setAutoScroll(true); for (int i = 0; i <= 5; ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); @@ -2443,29 +2486,38 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); QCOMPARE(r.top(), 0); QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(round(input.positionToRectangle(i))), r); } input.setCursorPosition(6); r = input.cursorRectangle(); QCOMPARE(r.left(), 0); QVERIFY(r.bottom() >= input.height() - error); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(6)), r); for (int i = 7; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height() - error); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); } for (int i = text.length() - 2; i >= 6; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height() - error); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); } for (int i = 5; i >= 0; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); QCOMPARE(r.top(), 0); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + QCOMPARE(round(input.positionToRectangle(i)), r); } input.setText("Hi!"); -- 2.7.4