diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2020-04-21 09:55:05 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-11-29 23:33:20 +0100 |
commit | ea59faf5a5be398d77d03117b2c5704a55c87d75 (patch) | |
tree | c7f117437887334ff356cec4dc36fcbb658a1d1b | |
parent | 135ff4f78b179a69f36e548dab787dfbafa317f8 (diff) |
QTextDocument: fix an off-by-one in the changed signal for lists
When blocks are added or removed in block groups, i.e. items added or
removed from text lists, the whole group is marked as changed, but the
calculation of the before/after group length would be one off. That
was reflected in the contentsChange signal.
Add unit test. Since the whole group changes when list items are
added, text is removed and the change-begin is not where the cursor
was when the change was made.
Fixes: QTBUG-82455
Change-Id: I99ee2cfef4944fcac8aca492741fd0f3b0de4920
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit 8fbedf2196a292fe2affcf83ddc846b9c852772a)
-rw-r--r-- | src/gui/text/qtextdocument_p.cpp | 5 | ||||
-rw-r--r-- | tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp | 60 |
2 files changed, 64 insertions, 1 deletions
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 5857f44e66..d92d88e26f 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -381,8 +381,11 @@ int QTextDocumentPrivate::insert_block(int pos, uint strPos, int format, int blo Q_ASSERT(blocks.length() == fragments.length()); QTextBlockGroup *group = qobject_cast<QTextBlockGroup *>(objectForFormat(blockFormat)); - if (group) + if (group) { group->blockInserted(QTextBlock(this, b)); + docChangeOldLength--; + docChangeLength--; + } QTextFrame *frame = qobject_cast<QTextFrame *>(objectForFormat(formats.format(format))); if (frame) { diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 7bc9fe47c5..a61824b51c 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -197,6 +197,9 @@ private slots: void clearUndoRedoStacks(); void mergeFontFamilies(); + void contentsChangeIndices_data(); + void contentsChangeIndices(); + private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); void buildRegExpData(); @@ -3716,5 +3719,62 @@ void tst_QTextDocument::clearUndoRedoStacks() } +void tst_QTextDocument::contentsChangeIndices_data() +{ + QTest::addColumn<QString>("html"); + // adding list entries change the entire block, so change position is + // not the same as the cursor position if this value is >= 0 + QTest::addColumn<int>("expectedBegin"); + + QTest::addRow("text") << "Test" << -1; + QTest::addRow("unnumbered list") << "<ul><li>Test</li></ul>" << 0; + QTest::addRow("numbered list") << "<ol><li>Test</li></ol>" << 0; + QTest::addRow("table") << "<table><tr><td>Test</td></tr></table>" << -1; +} + +void tst_QTextDocument::contentsChangeIndices() +{ + QFETCH(QString, html); + QFETCH(int, expectedBegin); + + QTextDocument doc; + QTestDocumentLayout *layout = new QTestDocumentLayout(&doc); + doc.setDocumentLayout(layout); + doc.setHtml(QString("<html><body>%1</body></html>").arg(html)); + + int documentLength = 0; + int cursorLength = 0; + int changeBegin = 0; + int changeRemoved = 0; + int changeAdded = 0; + connect(&doc, &QTextDocument::contentsChange, this, [&](int pos, int removed, int added){ + documentLength = doc.characterCount(); + + QTextCursor cursor(&doc); + cursor.movePosition(QTextCursor::End); + // includes end-of-paragraph character + cursorLength = cursor.position() + 1; + + changeBegin = pos; + changeRemoved = removed; + changeAdded = added; + }); + + QTextCursor cursor(&doc); + cursor.movePosition(QTextCursor::End); + if (expectedBegin < 0) + expectedBegin = cursor.position(); + cursor.insertBlock(); + + const int changeEnd = changeBegin + changeAdded; + + QVERIFY(documentLength > 0); + QCOMPARE(documentLength, cursorLength); + QVERIFY(documentLength >= changeEnd); + QCOMPARE(changeBegin, expectedBegin); + QCOMPARE(changeAdded - changeRemoved, 1); +} + + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" |