diff options
author | J-P Nurmi <jpnurmi@digia.com> | 2013-06-06 15:16:59 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-06-12 00:18:15 +0200 |
commit | 7f526c40345a360cd0f5fa5b707c66ec4612bbec (patch) | |
tree | e5dda29a6a6e0ebfdbd10e1d368094fdce8e75cf | |
parent | 95aa526987a2ef536c07d2607e8fdfc21c3e9096 (diff) |
Add QQuickTextEdit::append()
This makes it possible to append text more efficiently than
appending to the text -property, and also avoids weird rich
text formatting issues with the latter approach.
Task-number: QTBUG-31575
Change-Id: Id621773588b94e36f8f0b9eb6b22590e9db62811
Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
-rw-r--r-- | src/quick/items/qquicktextedit.cpp | 39 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit_p.h | 1 | ||||
-rw-r--r-- | tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp | 154 |
3 files changed, 194 insertions, 0 deletions
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 6b851903fc..92e81e06cf 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -272,6 +272,12 @@ QString QQuickTextEdit::text() const The text to display. If the text format is AutoText the text edit will automatically determine whether the text should be treated as rich text. This determination is made using Qt::mightBeRichText(). + + The text-property is mostly suitable for setting the initial content and + handling modifications to relatively small text content. The append(), + insert() and remove() methods provide more fine-grained control and + remarkably better performance for modifying especially large rich text + content. */ void QQuickTextEdit::setText(const QString &text) { @@ -2533,4 +2539,37 @@ void QQuickTextEdit::hoverLeaveEvent(QHoverEvent *event) d->control->processEvent(event, QPointF(-d->xoff, -d->yoff)); } +/*! + \qmlmethod void QtQuick2::TextEdit::append(string text) + \since QtQuick 2.2 + + Appends a new paragraph with \a text to the end of the TextEdit. + + In order to append without inserting a new paragraph, + call \c myTextEdit.insert(myTextEdit.length, text) instead. +*/ +void QQuickTextEdit::append(const QString &text) +{ + Q_D(QQuickTextEdit); + QTextCursor cursor(d->document); + cursor.beginEditBlock(); + cursor.movePosition(QTextCursor::End); + + if (!d->document->isEmpty()) + cursor.insertBlock(); + +#ifndef QT_NO_TEXTHTMLPARSER + if (d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text))) { + cursor.insertHtml(text); + } else { + cursor.insertText(text); + } +#else + cursor.insertText(text); +#endif // QT_NO_TEXTHTMLPARSER + + cursor.endEditBlock(); + d->control->updateCursorRectangle(false); +} + QT_END_NAMESPACE diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 1e038640ca..69ffad7e70 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -314,6 +314,7 @@ public Q_SLOTS: void redo(); void insert(int position, const QString &text); void remove(int start, int end); + Q_REVISION(2) void append(const QString &text); private Q_SLOTS: void q_textChanged(); diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 80e8335091..798db9fe23 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -182,6 +182,8 @@ private slots: void getText(); void getFormattedText_data(); void getFormattedText(); + void append_data(); + void append(); void insert_data(); void insert(); void remove_data(); @@ -3827,6 +3829,158 @@ void tst_qquicktextedit::getFormattedText() } } +void tst_qquicktextedit::append_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QQuickTextEdit::TextFormat>("textFormat"); + QTest::addColumn<int>("selectionStart"); + QTest::addColumn<int>("selectionEnd"); + QTest::addColumn<QString>("appendText"); + 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("cursor kept intact (beginning)") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << QString("Hello") + << standard.at(0) + QString("\nHello") + << 0 << 0 << 0 + << false << false; + + QTest::newRow("cursor kept intact (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << 18 + << QString("Hello") + << standard.at(0) + QString("\nHello") + << 18 << 18 << 18 + << false << false; + + QTest::newRow("cursor follows (end)") + << standard.at(0) << QQuickTextEdit::PlainText + << standard.at(0).length() << standard.at(0).length() + << QString("Hello") + << standard.at(0) + QString("\nHello") + << standard.at(0).length() + 6 << standard.at(0).length() + 6 << standard.at(0).length() + 6 + << false << true; + + QTest::newRow("selection kept intact (beginning)") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 18 + << QString("Hello") + << standard.at(0) + QString("\nHello") + << 0 << 18 << 18 + << false << false; + + QTest::newRow("selection kept intact (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 14 << 18 + << QString("Hello") + << standard.at(0) + QString("\nHello") + << 14 << 18 << 18 + << false << false; + + QTest::newRow("selection kept intact, cursor follows (end)") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << standard.at(0).length() + << QString("Hello") + << standard.at(0) + QString("\nHello") + << 18 << standard.at(0).length() + 6 << standard.at(0).length() + 6 + << false << true; + + QTest::newRow("reversed selection kept intact") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << 14 + << QString("Hello") + << standard.at(0) + QString("\nHello") + << 14 << 18 << 14 + << false << false; + + QTest::newRow("rich text into plain text") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << QString("<b>Hello</b>") + << standard.at(0) + QString("\n<b>Hello</b>") + << 0 << 0 << 0 + << false << false; + + QTest::newRow("rich text into rich text") + << standard.at(0) << QQuickTextEdit::RichText + << 0 << 0 + << QString("<b>Hello</b>") + << standard.at(0) + QChar(QChar::ParagraphSeparator) + QString("Hello") + << 0 << 0 << 0 + << false << false; + + QTest::newRow("rich text into auto text") + << standard.at(0) << QQuickTextEdit::AutoText + << 0 << 0 + << QString("<b>Hello</b>") + << standard.at(0) + QString("\nHello") + << 0 << 0 << 0 + << false << false; +} + +void tst_qquicktextedit::append() +{ + QFETCH(QString, text); + QFETCH(QQuickTextEdit::TextFormat, textFormat); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(QString, appendText); + QFETCH(QString, expectedText); + QFETCH(int, expectedSelectionStart); + QFETCH(int, expectedSelectionEnd); + QFETCH(int, expectedCursorPosition); + QFETCH(bool, selectionChanged); + QFETCH(bool, cursorPositionChanged); + + QString componentStr = "import QtQuick 2.2\nTextEdit { text: \"" + text + "\" }"; + QQmlComponent 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(selectedTextChanged())); + QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged())); + QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged())); + QSignalSpy textSpy(textEdit, SIGNAL(textChanged())); + QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged())); + + textEdit->append(appendText); + + if (textFormat == QQuickTextEdit::RichText || (textFormat == QQuickTextEdit::AutoText && ( + Qt::mightBeRichText(text) || Qt::mightBeRichText(appendText)))) { + QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText); + } else { + QCOMPARE(textEdit->text(), expectedText); + + } + QCOMPARE(textEdit->length(), expectedText.length()); + + QCOMPARE(textEdit->selectionStart(), expectedSelectionStart); + QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd); + QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition); + + if (selectionStart > selectionEnd) + qSwap(selectionStart, selectionEnd); + + QEXPECT_FAIL("into selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); + QEXPECT_FAIL("into reversed selection", "selectedTextChanged 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", "selectionEndChanged signal not emitted", Continue); + QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); + QCOMPARE(textSpy.count() > 0, text != expectedText); + QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged); +} + void tst_qquicktextedit::insert_data() { QTest::addColumn<QString>("text"); |