Ensure the cursor rectangle is updated when preedit text changes.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Thu, 3 May 2012 03:03:29 +0000 (13:03 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 3 May 2012 05:04:03 +0000 (07:04 +0200)
Updating only when the cursor position changes isn't enough because
changing pre-edit text changes the width of the pre-edit area and
the x offset of all cursor positions within it.

Change-Id: I3c0a5e4ad4714a903ca84c1a25374491f34d95a0
Reviewed-by: Yann Bodson <yann.bodson@nokia.com>
src/quick/items/qquicktextcontrol.cpp
src/quick/items/qquicktextinput.cpp
tests/auto/quick/qquicktextedit/data/inputMethodEvent.qml
tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
tests/auto/quick/qquicktextinput/data/inputMethodEvent.qml
tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp

index 8bc94b9..751706d 100644 (file)
@@ -1479,7 +1479,7 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
     QTextCursorPrivate *cursor_d = QTextCursorPrivate::getPrivate(&cursor);
     if (cursor_d)
         cursor_d->setX();
-    q->updateCursorRectangle(oldPreeditCursor != preeditCursor || forceSelectionChanged);
+    q->updateCursorRectangle(oldPreeditCursor != preeditCursor || forceSelectionChanged || isGettingInput);
     selectionChanged(forceSelectionChanged);
 }
 
index 9cf187e..e219934 100644 (file)
@@ -3217,7 +3217,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
     updateDisplayText(/*force*/ true);
     if (cursorPositionChanged) {
         emitCursorPositionChanged();
-    } else if (m_preeditCursor != oldPreeditCursor) {
+    } else if (m_preeditCursor != oldPreeditCursor || isGettingInput) {
         q->updateCursorRectangle();
     }
 
@@ -3332,7 +3332,7 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo
         emit q->selectionChanged();
     }
 
-    inputMethodAttributesChanged |= (m_cursor == m_lastCursorPos);
+    inputMethodAttributesChanged |= (m_cursor != m_lastCursorPos);
     if (inputMethodAttributesChanged)
         q->updateInputMethod();
     emitUndoRedoChanged();
index ab47368..7df7a55 100644 (file)
@@ -1,6 +1,7 @@
 import QtQuick 2.0
 
 TextEdit {
+    width: 300
     focus: true
 
     cursorDelegate: Item {
index 51b04cf..1b21fcc 100644 (file)
@@ -2858,11 +2858,11 @@ void tst_qquicktextedit::preeditCursorRectangle()
     QCOMPARE(edit->cursorRectangle(), currentRect);
     QCOMPARE(cursor->pos(), currentRect.topLeft());
     QCOMPARE(currentRect, previousRect);
-    QCOMPARE(editSpy.count(), 0); editSpy.clear();
-    QCOMPARE(panelSpy.count(), 0); panelSpy.clear();
 
     // Verify that the micro focus rect moves to the left as the cursor position
     // is incremented.
+    editSpy.clear();
+    panelSpy.clear();
     for (int i = 1; i <= 5; ++i) {
         QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>()
                 << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, preeditText.length(), QVariant()));
@@ -2877,9 +2877,22 @@ void tst_qquicktextedit::preeditCursorRectangle()
         previousRect = currentRect;
     }
 
+    // Verify that if the cursor rectangle is updated if the pre-edit text changes
+    // but the (non-zero) cursor position is the same.
+    editSpy.clear();
+    panelSpy.clear();
+    {   QInputMethodEvent imEvent("wwwww", QList<QInputMethodEvent::Attribute>()
+                << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 5, 1, QVariant()));
+        QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent); }
+    QCoreApplication::sendEvent(qGuiApp->focusObject(), &query);
+    currentRect = query.value(Qt::ImCursorRectangle).toRectF();
+    QCOMPARE(edit->cursorRectangle(), currentRect);
+    QCOMPARE(cursor->pos(), currentRect.topLeft());
+    QCOMPARE(editSpy.count(), 1);
+    QCOMPARE(panelSpy.count(), 1);
+
     // Verify that if there is no preedit cursor then the micro focus rect is the
     // same as it would be if it were positioned at the end of the preedit text.
-    QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent);
     editSpy.clear();
     panelSpy.clear();
     {   QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>());
index 907ea68..9e04620 100644 (file)
@@ -1,6 +1,7 @@
 import QtQuick 2.0
 
 TextInput {
+    width: 300
     focus: true
     autoScroll: false
 
index 2ea2486..e80808b 100644 (file)
@@ -3437,18 +3437,31 @@ void tst_qquicktextinput::preeditCursorRectangle()
         previousRect = currentRect;
     }
 
+    // Verify that if the cursor rectangle is updated if the pre-edit text changes
+    // but the (non-zero) cursor position is the same.
+    inputSpy.clear();
+    panelSpy.clear();
+    sendPreeditText("wwwww", 5);
+    QCoreApplication::sendEvent(qGuiApp->focusObject(), &query);
+    currentRect = query.value(Qt::ImCursorRectangle).toRectF();
+    QCOMPARE(input->cursorRectangle(), currentRect);
+    QCOMPARE(cursor->pos(), currentRect.topLeft());
+    QCOMPARE(inputSpy.count(), 1);
+    QCOMPARE(panelSpy.count(), 1);
+
     // Verify that if there is no preedit cursor then the micro focus rect is the
     // same as it would be if it were positioned at the end of the preedit text.
-    sendPreeditText(preeditText, 0);
-    QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>());
-    QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent);
+    inputSpy.clear();
+    panelSpy.clear();
+    {   QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>());
+        QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent); }
     QCoreApplication::sendEvent(qGuiApp->focusObject(), &query);
     currentRect = query.value(Qt::ImCursorRectangle).toRectF();
     QCOMPARE(currentRect, previousRect);
     QCOMPARE(input->cursorRectangle(), currentRect);
     QCOMPARE(cursor->pos(), currentRect.topLeft());
-    QVERIFY(inputSpy.count() > 0);
-    QVERIFY(panelSpy.count() > 0);
+    QCOMPARE(inputSpy.count(), 1);
+    QCOMPARE(panelSpy.count(), 1);
 }
 
 void tst_qquicktextinput::inputContextMouseHandler()