From e826e578eaef3f05498124eb2057f41410696480 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Mon, 25 Jul 2011 12:55:57 +1000 Subject: [PATCH] Notify when the TextInput cursorRectangle property changes within pre-edit Apply 452e13b5407fa4c36f9a573c305d41f551762b93 to scene graph items. Task-number: QTBUG-19089 Change-Id: I4501bdc940cbac9ba2ef068b87ded83b1c86976f Reviewed-on: http://codereview.qt.nokia.com/2054 Reviewed-by: Qt Sanity Bot Reviewed-by: Andrew den Exter --- src/declarative/items/qsgtextinput.cpp | 54 ++++++++-------------- src/declarative/items/qsgtextinput_p.h | 5 +- .../qsgtextinput/data/inputMethodEvent.qml | 1 + .../declarative/qsgtextinput/tst_qsgtextinput.cpp | 10 ++++ 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp index ccd0125..a150b7e 100644 --- a/src/declarative/items/qsgtextinput.cpp +++ b/src/declarative/items/qsgtextinput.cpp @@ -103,11 +103,11 @@ void QSGTextInput::setFont(const QFont &font) } if (oldFont != d->font) { d->control->setFont(d->font); + updateSize(); + updateCursorRectangle(); if(d->cursorItem){ d->cursorItem->setHeight(QFontMetrics(d->font).height()); - moveCursor(); } - updateSize(); } emit fontChanged(d->sourceFont); } @@ -182,8 +182,7 @@ void QSGTextInput::setHAlign(HAlignment align) bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror; d->hAlignImplicit = false; if (d->setHAlign(align, forceAlign) && isComponentComplete()) { - updateRect(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } } @@ -192,8 +191,7 @@ void QSGTextInput::resetHAlign() Q_D(QSGTextInput); d->hAlignImplicit = true; if (d->determineHorizontalAlignment() && isComponentComplete()) { - updateRect(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } } @@ -246,8 +244,7 @@ void QSGTextInputPrivate::mirrorChange() Q_Q(QSGTextInput); if (q->isComponentComplete()) { if (!hAlignImplicit && (hAlign == QSGTextInput::AlignRight || hAlign == QSGTextInput::AlignLeft)) { - q->updateRect(); - updateHorizontalScroll(); + q->updateCursorRectangle(); emit q->effectiveHorizontalAlignmentChanged(); } } @@ -391,7 +388,7 @@ void QSGTextInput::setAutoScroll(bool b) d->autoScroll = b; //We need to repaint so that the scrolling is taking into account. updateSize(true); - d->updateHorizontalScroll(); + updateCursorRectangle(); emit autoScrollChanged(d->autoScroll); } @@ -502,10 +499,6 @@ void QSGTextInput::setCursorDelegate(QDeclarativeComponent* c) d->cursorComponent = c; if(!c){ //note that the components are owned by something else - disconnect(d->control, SIGNAL(cursorPositionChanged(int,int)), - this, SLOT(moveCursor())); - disconnect(d->control, SIGNAL(updateMicroFocus()), - this, SLOT(moveCursor())); delete d->cursorItem; }else{ d->startCreatingCursor(); @@ -517,10 +510,6 @@ void QSGTextInput::setCursorDelegate(QDeclarativeComponent* c) void QSGTextInputPrivate::startCreatingCursor() { Q_Q(QSGTextInput); - q->connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(moveCursor()), Qt::UniqueConnection); - q->connect(control, SIGNAL(updateMicroFocus()), - q, SLOT(moveCursor()), Qt::UniqueConnection); if(cursorComponent->isReady()){ q->createCursor(); }else if(cursorComponent->isLoading()){ @@ -556,15 +545,6 @@ void QSGTextInput::createCursor() d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text. } -void QSGTextInput::moveCursor() -{ - Q_D(QSGTextInput); - if(!d->cursorItem) - return; - d->updateHorizontalScroll(); - d->cursorItem->setX(d->control->cursorToX() - d->hscroll); -} - QRectF QSGTextInput::positionToRectangle(int pos) const { Q_D(const QSGTextInput); @@ -626,8 +606,6 @@ void QSGTextInput::inputMethodEvent(QInputMethodEvent *ev) ev->ignore(); } else { d->control->processInputMethodEvent(ev); - updateSize(); - d->updateHorizontalScroll(); } if (!ev->isAccepted()) QSGPaintedItem::inputMethodEvent(ev); @@ -790,7 +768,7 @@ void QSGTextInput::geometryChanged(const QRectF &newGeometry, Q_D(QSGTextInput); if (newGeometry.width() != oldGeometry.width()) { updateSize(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } QSGPaintedItem::geometryChanged(newGeometry, oldGeometry); } @@ -1033,7 +1011,6 @@ void QSGTextInput::moveCursorSelection(int position) { Q_D(QSGTextInput); d->control->moveCursor(position, true); - d->updateHorizontalScroll(); } void QSGTextInput::moveCursorSelection(int pos, SelectionMode mode) @@ -1173,7 +1150,7 @@ void QSGTextInputPrivate::init() canPaste = !control->isReadOnly() && QApplication::clipboard()->text().length() != 0; #endif // QT_NO_CLIPBOARD q->connect(control, SIGNAL(updateMicroFocus()), - q, SLOT(updateMicroFocus())); + q, SLOT(updateCursorRectangle())); q->connect(control, SIGNAL(displayTextChanged(QString)), q, SLOT(updateRect())); q->updateSize(); @@ -1189,9 +1166,7 @@ void QSGTextInputPrivate::init() void QSGTextInput::cursorPosChanged() { Q_D(QSGTextInput); - d->updateHorizontalScroll(); - updateRect();//TODO: Only update rect between pos's - updateMicroFocus(); + updateCursorRectangle(); emit cursorPositionChanged(); // XXX todo - not in 4.8? #if 0 @@ -1210,6 +1185,17 @@ void QSGTextInput::cursorPosChanged() } } +void QSGTextInput::updateCursorRectangle() +{ + Q_D(QSGTextInput); + d->updateHorizontalScroll(); + updateRect();//TODO: Only update rect between pos's + updateMicroFocus(); + emit cursorRectangleChanged(); + if (d->cursorItem) + d->cursorItem->setX(d->control->cursorToX() - d->hscroll); +} + void QSGTextInput::selectionChanged() { Q_D(QSGTextInput); diff --git a/src/declarative/items/qsgtextinput_p.h b/src/declarative/items/qsgtextinput_p.h index b3d323b..770afa8 100644 --- a/src/declarative/items/qsgtextinput_p.h +++ b/src/declarative/items/qsgtextinput_p.h @@ -72,7 +72,7 @@ class Q_AUTOTEST_EXPORT QSGTextInput : public QSGImplicitSizePaintedItem Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged) Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) - Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorPositionChanged) + Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged) Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) @@ -218,6 +218,7 @@ public: Q_SIGNALS: void textChanged(); void cursorPositionChanged(); + void cursorRectangleChanged(); void selectionStartChanged(); void selectionEndChanged(); void selectedTextChanged(); @@ -278,8 +279,8 @@ private Q_SLOTS: void q_textChanged(); void selectionChanged(); void createCursor(); - void moveCursor(); void cursorPosChanged(); + void updateCursorRectangle(); void updateRect(const QRect &r = QRect()); void q_canPasteChanged(); diff --git a/tests/auto/declarative/qsgtextinput/data/inputMethodEvent.qml b/tests/auto/declarative/qsgtextinput/data/inputMethodEvent.qml index f8446ab..7aefdf2 100644 --- a/tests/auto/declarative/qsgtextinput/data/inputMethodEvent.qml +++ b/tests/auto/declarative/qsgtextinput/data/inputMethodEvent.qml @@ -2,4 +2,5 @@ import QtQuick 2.0 TextInput { focus: true + autoScroll: false } diff --git a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp index 9d548bb..c6c93c1 100644 --- a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp +++ b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp @@ -2203,6 +2203,9 @@ void tst_qsgtextinput::preeditAutoScroll() QSGTextInput *input = qobject_cast(view.rootObject()); QVERIFY(input); + QSignalSpy cursorRectangleSpy(input, SIGNAL(cursorRectangleChanged())); + int cursorRectangleChanges = 0; + QFontMetricsF fm(input->font()); input->setWidth(fm.width(input->text())); @@ -2210,11 +2213,13 @@ void tst_qsgtextinput::preeditAutoScroll() ic.sendPreeditText(preeditText.mid(0, 3), 1); QVERIFY(input->positionAt(0) != 0); QVERIFY(input->cursorRectangle().left() < input->boundingRect().width()); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); // test the text is scrolled back when the preedit is removed. ic.sendEvent(QInputMethodEvent()); QCOMPARE(input->positionAt(0), 0); QCOMPARE(input->positionAt(input->width()), 5); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); // some tolerance for different fonts. #ifdef Q_OS_LINUX @@ -2230,26 +2235,31 @@ void tst_qsgtextinput::preeditAutoScroll() ic.sendPreeditText(preeditText, i + 1); QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error); QVERIFY(input->positionToRectangle(0).x() < x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); x = input->positionToRectangle(0).x(); } for (int i = 1; i >= 0; --i) { ic.sendPreeditText(preeditText, i + 1); QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error); QVERIFY(input->positionToRectangle(0).x() > x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); x = input->positionToRectangle(0).x(); } // Test incrementing the preedit cursor doesn't cause further // scrolling when right most text is visible. ic.sendPreeditText(preeditText, preeditText.length() - 3); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); x = input->positionToRectangle(0).x(); for (int i = 2; i >= 0; --i) { ic.sendPreeditText(preeditText, preeditText.length() - i); QCOMPARE(input->positionToRectangle(0).x(), x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); } for (int i = 1; i < 3; ++i) { ic.sendPreeditText(preeditText, preeditText.length() - i); QCOMPARE(input->positionToRectangle(0).x(), x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); } // Test disabling auto scroll. -- 2.7.4