QSyntaxHighlighter: Delay all highlights until first rehighlight

When calling setDocument (directly or through the constructor) a delayed
rehighlight is initiated. Previously, if any text was changed before
this rehighlight could run it would cancel the rehighlight, even if the
changed text only caused a new block of text to be highlighted.

Fixes: QTBUG-71307
Change-Id: Ib09b664d90906f5b4427105f0e45469806f3a779
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io>
This commit is contained in:
Mårten Nordheim 2018-11-06 12:08:05 +01:00
parent bdebc90c28
commit dec7961709
2 changed files with 20 additions and 5 deletions

View File

@ -157,14 +157,12 @@ void QSyntaxHighlighterPrivate::applyFormatChanges()
void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded)
{
if (!inReformatBlocks)
if (!inReformatBlocks && !rehighlightPending)
reformatBlocks(from, charsRemoved, charsAdded);
}
void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded)
{
rehighlightPending = false;
QTextBlock block = doc->findBlock(from);
if (!block.isValid())
return;
@ -346,8 +344,10 @@ void QSyntaxHighlighter::setDocument(QTextDocument *doc)
if (d->doc) {
connect(d->doc, SIGNAL(contentsChange(int,int,int)),
this, SLOT(_q_reformatBlocks(int,int,int)));
d->rehighlightPending = true;
QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
if (!d->doc->isEmpty()) {
d->rehighlightPending = true;
QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
}
}
}

View File

@ -74,6 +74,7 @@ private slots:
void emptyBlocks();
void setCharFormat();
void highlightOnInit();
void highlightOnInitAndAppend();
void stopHighlightingWhenStateDoesNotChange();
void unindent();
void highlightToEndOfDocument();
@ -265,6 +266,19 @@ void tst_QSyntaxHighlighter::highlightOnInit()
QTRY_VERIFY(hl->highlighted);
}
void tst_QSyntaxHighlighter::highlightOnInitAndAppend()
{
cursor.insertText("Hello");
cursor.insertBlock();
cursor.insertText("World");
TestHighlighter *hl = new TestHighlighter(doc);
cursor.insertBlock();
cursor.insertText("More text");
QTRY_VERIFY(hl->highlighted);
QVERIFY(hl->highlightedText.endsWith(doc->toPlainText().remove(QLatin1Char('\n'))));
}
class StateTestHighlighter : public QSyntaxHighlighter
{
public:
@ -330,6 +344,7 @@ void tst_QSyntaxHighlighter::unindent()
QCOMPARE(doc->toPlainText(), plainText);
TestHighlighter *hl = new TestHighlighter(doc);
QTRY_VERIFY(hl->highlighted);
hl->callCount = 0;
cursor.movePosition(QTextCursor::Start);