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 Pick-to: 6.2 5.15 Change-Id: I99ee2cfef4944fcac8aca492741fd0f3b0de4920 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
parent
a892a7b2ca
commit
8fbedf2196
@ -382,8 +382,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) {
|
||||
|
@ -198,6 +198,9 @@ private slots:
|
||||
|
||||
void resourceProvider();
|
||||
|
||||
void contentsChangeIndices_data();
|
||||
void contentsChangeIndices();
|
||||
|
||||
private:
|
||||
void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
|
||||
void buildRegExpData();
|
||||
@ -3820,5 +3823,62 @@ void tst_QTextDocument::resourceProvider()
|
||||
QCOMPARE(providerCalled, 2);
|
||||
}
|
||||
|
||||
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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user