Add getText(), insert(), and remove() functions to TextEdit.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Thu, 24 Nov 2011 02:53:05 +0000 (12:53 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 25 Nov 2011 05:54:20 +0000 (06:54 +0100)
The getText() function provides access to the plain text content of a
TextEdit, and the insert() and remove() functions allow the text content
to be edited inline instead of having to assign an edited string to the
text property to make any change.

Change-Id: Id4edf0312358e2d2db45e4c649b7bd3d22f02ffa
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/declarative/items/qquicktextedit.cpp
src/declarative/items/qquicktextedit_p.h
tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp

index c5b2f57..1a467c5 100644 (file)
@@ -1975,4 +1975,64 @@ void QQuickTextEdit::q_canPasteChanged()
         emit canPasteChanged();
 }
 
+/*!
+    \qmlmethod string QtQuick2::TextEdit::getText(int start, int end)
+
+    Returns the section of text that is between the \a start and \a end positions.
+
+    The returned text does not include any rich text formatting.
+*/
+
+QString QQuickTextEdit::getText(int start, int end) const
+{
+    Q_D(const QQuickTextEdit);
+    start = qBound(0, start, d->document->characterCount() - 1);
+    end = qBound(0, end, d->document->characterCount() - 1);
+    QTextCursor cursor(d->document);
+    cursor.setPosition(start, QTextCursor::MoveAnchor);
+    cursor.setPosition(end, QTextCursor::KeepAnchor);
+    return cursor.selectedText();
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::insert(int position, string text)
+
+    Inserts \a text into the TextEdit at position.
+*/
+void QQuickTextEdit::insert(int position, const QString &text)
+{
+    Q_D(QQuickTextEdit);
+    if (position < 0 || position >= d->document->characterCount())
+        return;
+    QTextCursor cursor(d->document);
+    cursor.setPosition(position);
+    d->richText = d->richText || (d->format == AutoText && Qt::mightBeRichText(text));
+    if (d->richText) {
+#ifndef QT_NO_TEXTHTMLPARSER
+        cursor.insertHtml(text);
+#else
+        cursor.insertText(text);
+#endif
+    } else {
+        cursor.insertText(text);
+    }
+}
+
+/*!
+    \qmlmethod string QtQuick2::TextEdit::getText(int start, int end)
+
+    Removes the section of text that is between the \a start and \a end positions from the TextEdit.
+*/
+
+void QQuickTextEdit::remove(int start, int end)
+{
+    Q_D(QQuickTextEdit);
+    start = qBound(0, start, d->document->characterCount() - 1);
+    end = qBound(0, end, d->document->characterCount() - 1);
+    QTextCursor cursor(d->document);
+    cursor.setPosition(start, QTextCursor::MoveAnchor);
+    cursor.setPosition(end, QTextCursor::KeepAnchor);
+    cursor.removeSelectedText();
+}
+
 QT_END_NAMESPACE
index e237e2e..f2bec6c 100644 (file)
@@ -217,6 +217,8 @@ public:
 
     bool isInputMethodComposing() const;
 
+    Q_INVOKABLE QString getText(int start, int end) const;
+
 Q_SIGNALS:
     void textChanged(const QString &);
     void paintedSizeChanged();
@@ -258,6 +260,8 @@ public Q_SLOTS:
     void copy();
     void paste();
 #endif
+    void insert(int position, const QString &text);
+    void remove(int start, int end);
 
 private Q_SLOTS:
     void q_textChanged();
index ca585a4..ae1e4b4 100644 (file)
@@ -157,6 +157,13 @@ private slots:
     void inputMethodComposing();
     void cursorRectangleSize();
 
+    void getText_data();
+    void getText();
+    void insert_data();
+    void insert();
+    void remove_data();
+    void remove();
+
     void keySequence_data();
     void keySequence();
 
@@ -195,6 +202,8 @@ Q_DECLARE_METATYPE(IntList)
 typedef QList<Key> KeyList;
 Q_DECLARE_METATYPE(KeyList)
 
+Q_DECLARE_METATYPE(QQuickTextEdit::TextFormat)
+
 void tst_qquicktextedit::simulateKeys(QWindow *window, const QList<Key> &keys)
 {
     for (int i = 0; i < keys.count(); ++i) {
@@ -2357,6 +2366,536 @@ void tst_qquicktextedit::cursorRectangleSize()
     delete canvas;
 }
 
+void tst_qquicktextedit::getText_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<int>("start");
+    QTest::addColumn<int>("end");
+    QTest::addColumn<QString>("expectedText");
+
+    const QString richBoldText = QStringLiteral("This is some <b>bold</b> text");
+    const QString plainBoldText = QStringLiteral("This is some bold text");
+
+    QTest::newRow("all plain text")
+            << standard.at(0)
+            << 0 << standard.at(0).length()
+            << standard.at(0);
+
+    QTest::newRow("plain text sub string")
+            << standard.at(0)
+            << 0 << 12
+            << standard.at(0).mid(0, 12);
+
+    QTest::newRow("plain text sub string reversed")
+            << standard.at(0)
+            << 12 << 0
+            << standard.at(0).mid(0, 12);
+
+    QTest::newRow("plain text cropped beginning")
+            << standard.at(0)
+            << -3 << 4
+            << standard.at(0).mid(0, 4);
+
+    QTest::newRow("plain text cropped end")
+            << standard.at(0)
+            << 23 << standard.at(0).length() + 8
+            << standard.at(0).mid(23);
+
+    QTest::newRow("plain text cropped beginning and end")
+            << standard.at(0)
+            << -9 << standard.at(0).length() + 4
+            << standard.at(0);
+
+    QTest::newRow("all rich text")
+            << richBoldText
+            << 0 << plainBoldText.length()
+            << plainBoldText;
+
+    QTest::newRow("rick text sub string")
+            << richBoldText
+            << 14 << 21
+            << plainBoldText.mid(14, 7);
+}
+
+void tst_qquicktextedit::getText()
+{
+    QFETCH(QString, text);
+    QFETCH(int, start);
+    QFETCH(int, end);
+    QFETCH(QString, expectedText);
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }";
+    QDeclarativeComponent textEditComponent(&engine);
+    textEditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+    QVERIFY(textEdit != 0);
+
+    QCOMPARE(textEdit->getText(start, end), expectedText);
+}
+
+void tst_qquicktextedit::insert_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<QQuickTextEdit::TextFormat>("textFormat");
+    QTest::addColumn<int>("selectionStart");
+    QTest::addColumn<int>("selectionEnd");
+    QTest::addColumn<int>("insertPosition");
+    QTest::addColumn<QString>("insertText");
+    QTest::addColumn<QString>("expectedText");
+    QTest::addColumn<int>("expectedSelectionStart");
+    QTest::addColumn<int>("expectedSelectionEnd");
+    QTest::addColumn<int>("expectedCursorPosition");
+    QTest::addColumn<bool>("selectionChanged");
+    QTest::addColumn<bool>("cursorPositionChanged");
+
+    QTest::newRow("at cursor position (beginning)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0 << 0
+            << QString("Hello")
+            << QString("Hello") + standard.at(0)
+            << 5 << 5 << 5
+            << false << true;
+
+    QTest::newRow("at cursor position (end)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << standard.at(0).length() << standard.at(0).length() << standard.at(0).length()
+            << QString("Hello")
+            << standard.at(0) + QString("Hello")
+            << standard.at(0).length() + 5 << standard.at(0).length() + 5 << standard.at(0).length() + 5
+            << false << true;
+
+    QTest::newRow("at cursor position (middle)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 18 << 18 << 18
+            << QString("Hello")
+            << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18)
+            << 23 << 23 << 23
+            << false << true;
+
+    QTest::newRow("after cursor position (beginning)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0 << 18
+            << QString("Hello")
+            << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18)
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("before cursor position (end)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << standard.at(0).length() << standard.at(0).length() << 18
+            << QString("Hello")
+            << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18)
+            << standard.at(0).length() + 5 << standard.at(0).length() + 5 << standard.at(0).length() + 5
+            << false << true;
+
+    QTest::newRow("before cursor position (middle)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 18 << 18 << 0
+            << QString("Hello")
+            << QString("Hello") + standard.at(0)
+            << 23 << 23 << 23
+            << false << true;
+
+    QTest::newRow("after cursor position (middle)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 18 << 18 << standard.at(0).length()
+            << QString("Hello")
+            << standard.at(0) + QString("Hello")
+            << 18 << 18 << 18
+            << false << false;
+
+    QTest::newRow("before selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 14 << 19 << 0
+            << QString("Hello")
+            << QString("Hello") + standard.at(0)
+            << 19 << 24 << 24
+            << false << true;
+
+    QTest::newRow("before reversed selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 19 << 14 << 0
+            << QString("Hello")
+            << QString("Hello") + standard.at(0)
+            << 19 << 24 << 19
+            << false << true;
+
+    QTest::newRow("after selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 14 << 19 << standard.at(0).length()
+            << QString("Hello")
+            << standard.at(0) + QString("Hello")
+            << 14 << 19 << 19
+            << false << false;
+
+    QTest::newRow("after reversed selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 19 << 14 << standard.at(0).length()
+            << QString("Hello")
+            << standard.at(0) + QString("Hello")
+            << 14 << 19 << 14
+            << false << false;
+
+    QTest::newRow("into selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 14 << 19 << 18
+            << QString("Hello")
+            << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18)
+            << 14 << 24 << 24
+            << true << true;
+
+    QTest::newRow("into reversed selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 19 << 14 << 18
+            << QString("Hello")
+            << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18)
+            << 14 << 24 << 14
+            << true << false;
+
+    QTest::newRow("rich text into plain text")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0 << 0
+            << QString("<b>Hello</b>")
+            << QString("<b>Hello</b>") + standard.at(0)
+            << 12 << 12 << 12
+            << false << true;
+
+    QTest::newRow("rich text into rich text")
+            << standard.at(0) << QQuickTextEdit::RichText
+            << 0 << 0 << 0
+            << QString("<b>Hello</b>")
+            << QString("Hello") + standard.at(0)
+            << 5 << 5 << 5
+            << false << true;
+
+    QTest::newRow("rich text into auto text")
+            << standard.at(0) << QQuickTextEdit::AutoText
+            << 0 << 0 << 0
+            << QString("<b>Hello</b>")
+            << QString("Hello") + standard.at(0)
+            << 5 << 5 << 5
+            << false << true;
+
+    QTest::newRow("before start")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0 << -3
+            << QString("Hello")
+            << standard.at(0)
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("past end")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0 << standard.at(0).length() + 3
+            << QString("Hello")
+            << standard.at(0)
+            << 0 << 0 << 0
+            << false << false;
+}
+
+void tst_qquicktextedit::insert()
+{
+    QFETCH(QString, text);
+    QFETCH(QQuickTextEdit::TextFormat, textFormat);
+    QFETCH(int, selectionStart);
+    QFETCH(int, selectionEnd);
+    QFETCH(int, insertPosition);
+    QFETCH(QString, insertText);
+    QFETCH(QString, expectedText);
+    QFETCH(int, expectedSelectionStart);
+    QFETCH(int, expectedSelectionEnd);
+    QFETCH(int, expectedCursorPosition);
+    QFETCH(bool, selectionChanged);
+    QFETCH(bool, cursorPositionChanged);
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }";
+    QDeclarativeComponent textEditComponent(&engine);
+    textEditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+    QVERIFY(textEdit != 0);
+
+    textEdit->setTextFormat(textFormat);
+    textEdit->select(selectionStart, selectionEnd);
+
+    QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged()));
+    QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged()));
+    QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged()));
+    QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString)));
+    QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged()));
+
+    textEdit->insert(insertPosition, insertText);
+
+    if (textFormat == QQuickTextEdit::RichText || (textFormat == QQuickTextEdit::AutoText && (
+            Qt::mightBeRichText(text) || Qt::mightBeRichText(insertText)))) {
+        QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText);
+    } else {
+        QCOMPARE(textEdit->text(), expectedText);
+    }
+
+    QCOMPARE(textEdit->selectionStart(), expectedSelectionStart);
+    QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd);
+    QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition);
+
+    if (selectionStart > selectionEnd)
+        qSwap(selectionStart, selectionEnd);
+
+    QEXPECT_FAIL("into selection", "selectionChanged signal isn't emitted on edits within selection", Continue);
+    QEXPECT_FAIL("into reversed selection", "selectionChanged signal isn't emitted on edits within selection", Continue);
+    QCOMPARE(selectionSpy.count() > 0, selectionChanged);
+    QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart);
+    QEXPECT_FAIL("into reversed selection", "yeah I don't know", Continue);
+    QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd);
+    QCOMPARE(textSpy.count() > 0, text != expectedText);
+    QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged);
+}
+
+void tst_qquicktextedit::remove_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<QQuickTextEdit::TextFormat>("textFormat");
+    QTest::addColumn<int>("selectionStart");
+    QTest::addColumn<int>("selectionEnd");
+    QTest::addColumn<int>("removeStart");
+    QTest::addColumn<int>("removeEnd");
+    QTest::addColumn<QString>("expectedText");
+    QTest::addColumn<int>("expectedSelectionStart");
+    QTest::addColumn<int>("expectedSelectionEnd");
+    QTest::addColumn<int>("expectedCursorPosition");
+    QTest::addColumn<bool>("selectionChanged");
+    QTest::addColumn<bool>("cursorPositionChanged");
+
+    const QString richBoldText = QStringLiteral("This is some <b>bold</b> text");
+    const QString plainBoldText = QStringLiteral("This is some bold text");
+
+    QTest::newRow("from cursor position (beginning)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0
+            << 0 << 5
+            << standard.at(0).mid(5)
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("to cursor position (beginning)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0
+            << 5 << 0
+            << standard.at(0).mid(5)
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("to cursor position (end)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << standard.at(0).length() << standard.at(0).length()
+            << standard.at(0).length() << standard.at(0).length() - 5
+            << standard.at(0).mid(0, standard.at(0).length() - 5)
+            << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5
+            << false << true;
+
+    QTest::newRow("to cursor position (end)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << standard.at(0).length() << standard.at(0).length()
+            << standard.at(0).length() - 5 << standard.at(0).length()
+            << standard.at(0).mid(0, standard.at(0).length() - 5)
+            << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5
+            << false << true;
+
+    QTest::newRow("from cursor position (middle)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 18 << 18
+            << 18 << 23
+            << standard.at(0).mid(0, 18) + standard.at(0).mid(23)
+            << 18 << 18 << 18
+            << false << false;
+
+    QTest::newRow("to cursor position (middle)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 23 << 23
+            << 18 << 23
+            << standard.at(0).mid(0, 18) + standard.at(0).mid(23)
+            << 18 << 18 << 18
+            << false << true;
+
+    QTest::newRow("after cursor position (beginning)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0
+            << 18 << 23
+            << standard.at(0).mid(0, 18) + standard.at(0).mid(23)
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("before cursor position (end)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << standard.at(0).length() << standard.at(0).length()
+            << 18 << 23
+            << standard.at(0).mid(0, 18) + standard.at(0).mid(23)
+            << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5
+            << false << true;
+
+    QTest::newRow("before cursor position (middle)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 23 << 23
+            << 0 << 5
+            << standard.at(0).mid(5)
+            << 18 << 18 << 18
+            << false << true;
+
+    QTest::newRow("after cursor position (middle)")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 18 << 18
+            << 18 << 23
+            << standard.at(0).mid(0, 18) + standard.at(0).mid(23)
+            << 18 << 18 << 18
+            << false << false;
+
+    QTest::newRow("before selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 14 << 19
+            << 0 << 5
+            << standard.at(0).mid(5)
+            << 9 << 14 << 14
+            << false << true;
+
+    QTest::newRow("before reversed selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 19 << 14
+            << 0 << 5
+            << standard.at(0).mid(5)
+            << 9 << 14 << 9
+            << false << true;
+
+    QTest::newRow("after selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 14 << 19
+            << standard.at(0).length() - 5 << standard.at(0).length()
+            << standard.at(0).mid(0, standard.at(0).length() - 5)
+            << 14 << 19 << 19
+            << false << false;
+
+    QTest::newRow("after reversed selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 19 << 14
+            << standard.at(0).length() - 5 << standard.at(0).length()
+            << standard.at(0).mid(0, standard.at(0).length() - 5)
+            << 14 << 19 << 14
+            << false << false;
+
+    QTest::newRow("from selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 14 << 24
+            << 18 << 23
+            << standard.at(0).mid(0, 18) + standard.at(0).mid(23)
+            << 14 << 19 << 19
+            << true << true;
+
+    QTest::newRow("from reversed selection")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 24 << 14
+            << 18 << 23
+            << standard.at(0).mid(0, 18) + standard.at(0).mid(23)
+            << 14 << 19 << 14
+            << true << false;
+
+    QTest::newRow("plain text cropped beginning")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0
+            << -3 << 4
+            << standard.at(0).mid(4)
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("plain text cropped end")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0
+            << 23 << standard.at(0).length() + 8
+            << standard.at(0).mid(0, 23)
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("plain text cropped beginning and end")
+            << standard.at(0) << QQuickTextEdit::PlainText
+            << 0 << 0
+            << -9 << standard.at(0).length() + 4
+            << QString()
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("all rich text")
+            << richBoldText << QQuickTextEdit::RichText
+            << 0 << 0
+            << 0 << plainBoldText.length()
+            << QString()
+            << 0 << 0 << 0
+            << false << false;
+
+    QTest::newRow("rick text sub string")
+            << richBoldText << QQuickTextEdit::RichText
+            << 0 << 0
+            << 14 << 21
+            << plainBoldText.mid(0, 14) + plainBoldText.mid(21)
+            << 0 << 0 << 0
+            << false << false;
+}
+
+void tst_qquicktextedit::remove()
+{
+    QFETCH(QString, text);
+    QFETCH(QQuickTextEdit::TextFormat, textFormat);
+    QFETCH(int, selectionStart);
+    QFETCH(int, selectionEnd);
+    QFETCH(int, removeStart);
+    QFETCH(int, removeEnd);
+    QFETCH(QString, expectedText);
+    QFETCH(int, expectedSelectionStart);
+    QFETCH(int, expectedSelectionEnd);
+    QFETCH(int, expectedCursorPosition);
+    QFETCH(bool, selectionChanged);
+    QFETCH(bool, cursorPositionChanged);
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }";
+    QDeclarativeComponent textEditComponent(&engine);
+    textEditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+    QVERIFY(textEdit != 0);
+
+    textEdit->setTextFormat(textFormat);
+    textEdit->select(selectionStart, selectionEnd);
+
+    QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged()));
+    QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged()));
+    QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged()));
+    QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString)));
+    QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged()));
+
+    textEdit->remove(removeStart, removeEnd);
+
+    if (textFormat == QQuickTextEdit::RichText
+            || (textFormat == QQuickTextEdit::AutoText && Qt::mightBeRichText(text))) {
+        QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText);
+    } else {
+        QCOMPARE(textEdit->text(), expectedText);
+    }
+
+    if (selectionStart > selectionEnd)  //
+        qSwap(selectionStart, selectionEnd);
+
+    QCOMPARE(textEdit->selectionStart(), expectedSelectionStart);
+    QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd);
+    QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition);
+
+    QEXPECT_FAIL("from selection", "selectionChanged signal isn't emitted on edits within selection", Continue);
+    QEXPECT_FAIL("from reversed selection", "selectionChanged signal isn't emitted on edits within selection", Continue);
+    QCOMPARE(selectionSpy.count() > 0, selectionChanged);
+    QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart);
+    QEXPECT_FAIL("from reversed selection", "selectionEndChanged signal not emitted", Continue);
+    QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd);
+    QCOMPARE(textSpy.count() > 0, text != expectedText);
+
+
+    if (cursorPositionChanged)  //
+        QVERIFY(cursorPositionSpy.count() > 0);
+}
+
+
 void tst_qquicktextedit::keySequence_data()
 {
     QTest::addColumn<QString>("text");