TextEdit: fix cursor rectangle positioning
authorJ-P Nurmi <jpnurmi@digia.com>
Mon, 12 May 2014 16:09:08 +0000 (18:09 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 16 May 2014 12:40:21 +0000 (14:40 +0200)
QQuickTextControl::cursorRectangleChanged() wasn't emitted as
appropriate when dragging mouse => The cursor delegate was stuck
in wrong position under certain circumstances, especially when
selecting multiple lines.

Task-number: QTBUG-38947
Change-Id: Ib5b0d2f6ea2a1b3712fbaba4a7ad1865d2b0a74e
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
src/quick/items/qquicktextcontrol.cpp
tests/auto/quick/qquicktextedit/data/qtbug-38947.qml [new file with mode: 0644]
tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp

index 53d736f..3087835 100644 (file)
@@ -423,7 +423,6 @@ void QQuickTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /
 #endif
         emit q->selectionChanged();
     }
-    q->updateCursorRectangle(true);
 }
 
 void QQuickTextControlPrivate::_q_updateCurrentCharFormatAndSelection()
@@ -1152,8 +1151,10 @@ void QQuickTextControlPrivate::mouseMoveEvent(QMouseEvent *e, const QPointF &mou
 #endif
 
         if (interactionFlags & Qt::TextEditable) {
-            if (cursor.position() != oldCursorPos)
+            if (cursor.position() != oldCursorPos) {
                 emit q->cursorPositionChanged();
+                q->updateCursorRectangle(true);
+            }
             _q_updateCurrentCharFormatAndSelection();
 #ifndef QT_NO_IM
             if (qGuiApp)
@@ -1161,6 +1162,7 @@ void QQuickTextControlPrivate::mouseMoveEvent(QMouseEvent *e, const QPointF &mou
 #endif
         } else if (cursor.position() != oldCursorPos) {
             emit q->cursorPositionChanged();
+            q->updateCursorRectangle(true);
         }
         selectionChanged(true);
         repaintOldAndNewSelection(oldSelection);
@@ -1255,6 +1257,7 @@ void QQuickTextControlPrivate::mouseDoubleClickEvent(QMouseEvent *e, const QPoin
             setClipboardSelection();
 #endif
             emit q->cursorPositionChanged();
+            q->updateCursorRectangle(true);
         }
     } else if (!sendMouseEventToInputContext(e, pos)) {
         e->ignore();
diff --git a/tests/auto/quick/qquicktextedit/data/qtbug-38947.qml b/tests/auto/quick/qquicktextedit/data/qtbug-38947.qml
new file mode 100644 (file)
index 0000000..3c8254f
--- /dev/null
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+TextEdit {
+    text: "Hello\nWorld!"
+    selectByMouse: true
+    cursorDelegate: Rectangle {
+        width: 10
+        color: "transparent"
+        border.color: "red"
+    }
+}
index 45d23ab..32e4a99 100644 (file)
@@ -207,6 +207,7 @@ private slots:
     void embeddedImages_data();
 
     void emptytags_QTBUG_22058();
+    void cursorRectangle_QTBUG_38947();
 
 private:
     void simulateKeys(QWindow *window, const QList<Key> &keys);
@@ -5259,6 +5260,33 @@ void tst_qquicktextedit::emptytags_QTBUG_22058()
     QCOMPARE(input->text(), QString("<b>Bold<>"));
 }
 
+void tst_qquicktextedit::cursorRectangle_QTBUG_38947()
+{
+    QQuickView window(testFileUrl("qtbug-38947.qml"));
+
+    window.show();
+    window.requestActivate();
+    QTest::qWaitForWindowExposed(&window);
+    QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(window.rootObject());
+    QVERIFY(edit);
+
+    QPoint from = edit->positionToRectangle(0).center().toPoint();
+    QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, from);
+
+    QSignalSpy spy(edit, SIGNAL(cursorRectangleChanged()));
+    QVERIFY(spy.isValid());
+
+    for (int i = i; i < edit->length() - 1; ++i) {
+        QRectF rect = edit->positionToRectangle(i);
+        QTest::mouseMove(&window, rect.center().toPoint());
+        QCOMPARE(edit->cursorRectangle(), rect);
+        QCOMPARE(spy.count(), i);
+    }
+
+    QPoint to = edit->positionToRectangle(edit->length() - 1).center().toPoint();
+    QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, to);
+}
+
 QTEST_MAIN(tst_qquicktextedit)
 
 #include "tst_qquicktextedit.moc"