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

View File

@ -74,6 +74,7 @@ private slots:
void emptyBlocks(); void emptyBlocks();
void setCharFormat(); void setCharFormat();
void highlightOnInit(); void highlightOnInit();
void highlightOnInitAndAppend();
void stopHighlightingWhenStateDoesNotChange(); void stopHighlightingWhenStateDoesNotChange();
void unindent(); void unindent();
void highlightToEndOfDocument(); void highlightToEndOfDocument();
@ -265,6 +266,19 @@ void tst_QSyntaxHighlighter::highlightOnInit()
QTRY_VERIFY(hl->highlighted); 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 class StateTestHighlighter : public QSyntaxHighlighter
{ {
public: public:
@ -330,6 +344,7 @@ void tst_QSyntaxHighlighter::unindent()
QCOMPARE(doc->toPlainText(), plainText); QCOMPARE(doc->toPlainText(), plainText);
TestHighlighter *hl = new TestHighlighter(doc); TestHighlighter *hl = new TestHighlighter(doc);
QTRY_VERIFY(hl->highlighted);
hl->callCount = 0; hl->callCount = 0;
cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::Start);