Notify when the TextInput cursorRectangle property changes within pre-edit
authorAndrew den Exter <andrew.den-exter@nokia.com>
Mon, 25 Jul 2011 02:55:57 +0000 (12:55 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 25 Jul 2011 04:08:56 +0000 (06:08 +0200)
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
src/declarative/items/qsgtextinput.cpp
src/declarative/items/qsgtextinput_p.h
tests/auto/declarative/qsgtextinput/data/inputMethodEvent.qml
tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp

index ccd0125..a150b7e 100644 (file)
@@ -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);
index b3d323b..770afa8 100644 (file)
@@ -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();
 
index 9d548bb..c6c93c1 100644 (file)
@@ -2203,6 +2203,9 @@ void tst_qsgtextinput::preeditAutoScroll()
     QSGTextInput *input = qobject_cast<QSGTextInput *>(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.