text/qsyntaxhighlighter.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtGui module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qsyntaxhighlighter.h" -
43 -
44#ifndef QT_NO_SYNTAXHIGHLIGHTER -
45#include <private/qobject_p.h> -
46#include <qtextdocument.h> -
47#include <private/qtextdocument_p.h> -
48#include <qtextlayout.h> -
49#include <qpointer.h> -
50#include <qtextobject.h> -
51#include <qtextcursor.h> -
52#include <qdebug.h> -
53#include <qtimer.h> -
54 -
55QT_BEGIN_NAMESPACE -
56 -
57class QSyntaxHighlighterPrivate : public QObjectPrivate -
58{ -
59 Q_DECLARE_PUBLIC(QSyntaxHighlighter) -
60public: -
61 inline QSyntaxHighlighterPrivate() -
62 : rehighlightPending(false), inReformatBlocks(false) -
63 {}
executed: }
Execution Count:17
17
64 -
65 QPointer<QTextDocument> doc; -
66 -
67 void _q_reformatBlocks(int from, int charsRemoved, int charsAdded); -
68 void reformatBlocks(int from, int charsRemoved, int charsAdded); -
69 void reformatBlock(const QTextBlock &block); -
70 -
71 inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) { -
72 inReformatBlocks = true;
executed (the execution status of this line is deduced): inReformatBlocks = true;
-
73 cursor.beginEditBlock();
executed (the execution status of this line is deduced): cursor.beginEditBlock();
-
74 int from = cursor.position();
executed (the execution status of this line is deduced): int from = cursor.position();
-
75 cursor.movePosition(operation);
executed (the execution status of this line is deduced): cursor.movePosition(operation);
-
76 reformatBlocks(from, 0, cursor.position() - from);
executed (the execution status of this line is deduced): reformatBlocks(from, 0, cursor.position() - from);
-
77 cursor.endEditBlock();
executed (the execution status of this line is deduced): cursor.endEditBlock();
-
78 inReformatBlocks = false;
executed (the execution status of this line is deduced): inReformatBlocks = false;
-
79 }
executed: }
Execution Count:5
5
80 -
81 inline void _q_delayedRehighlight() { -
82 if (!rehighlightPending)
evaluated: !rehighlightPending
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:2
1-2
83 return;
executed: return;
Execution Count:1
1
84 rehighlightPending = false;
executed (the execution status of this line is deduced): rehighlightPending = false;
-
85 q_func()->rehighlight();
executed (the execution status of this line is deduced): q_func()->rehighlight();
-
86 }
executed: }
Execution Count:2
2
87 -
88 void applyFormatChanges(); -
89 QVector<QTextCharFormat> formatChanges; -
90 QTextBlock currentBlock; -
91 bool rehighlightPending; -
92 bool inReformatBlocks; -
93}; -
94 -
95void QSyntaxHighlighterPrivate::applyFormatChanges() -
96{ -
97 bool formatsChanged = false;
executed (the execution status of this line is deduced): bool formatsChanged = false;
-
98 -
99 QTextLayout *layout = currentBlock.layout();
executed (the execution status of this line is deduced): QTextLayout *layout = currentBlock.layout();
-
100 -
101 QList<QTextLayout::FormatRange> ranges = layout->additionalFormats();
executed (the execution status of this line is deduced): QList<QTextLayout::FormatRange> ranges = layout->additionalFormats();
-
102 -
103 const int preeditAreaStart = layout->preeditAreaPosition();
executed (the execution status of this line is deduced): const int preeditAreaStart = layout->preeditAreaPosition();
-
104 const int preeditAreaLength = layout->preeditAreaText().length();
executed (the execution status of this line is deduced): const int preeditAreaLength = layout->preeditAreaText().length();
-
105 -
106 if (preeditAreaLength != 0) {
evaluated: preeditAreaLength != 0
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:56
1-56
107 QList<QTextLayout::FormatRange>::Iterator it = ranges.begin();
executed (the execution status of this line is deduced): QList<QTextLayout::FormatRange>::Iterator it = ranges.begin();
-
108 while (it != ranges.end()) {
evaluated: it != ranges.end()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
109 if (it->start >= preeditAreaStart
partially evaluated: it->start >= preeditAreaStart
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
110 && it->start + it->length <= preeditAreaStart + preeditAreaLength) {
partially evaluated: it->start + it->length <= preeditAreaStart + preeditAreaLength
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
111 ++it;
executed (the execution status of this line is deduced): ++it;
-
112 } else {
executed: }
Execution Count:1
1
113 it = ranges.erase(it);
never executed (the execution status of this line is deduced): it = ranges.erase(it);
-
114 formatsChanged = true;
never executed (the execution status of this line is deduced): formatsChanged = true;
-
115 }
never executed: }
0
116 } -
117 } else if (!ranges.isEmpty()) {
executed: }
Execution Count:1
partially evaluated: !ranges.isEmpty()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:56
0-56
118 ranges.clear();
never executed (the execution status of this line is deduced): ranges.clear();
-
119 formatsChanged = true;
never executed (the execution status of this line is deduced): formatsChanged = true;
-
120 }
never executed: }
0
121 -
122 int i = 0;
executed (the execution status of this line is deduced): int i = 0;
-
123 while (i < formatChanges.count()) {
evaluated: i < formatChanges.count()
TRUEFALSE
yes
Evaluation Count:50
yes
Evaluation Count:17
17-50
124 QTextLayout::FormatRange r;
executed (the execution status of this line is deduced): QTextLayout::FormatRange r;
-
125 -
126 while (i < formatChanges.count() && formatChanges.at(i) == r.format)
evaluated: i < formatChanges.count()
TRUEFALSE
yes
Evaluation Count:245
yes
Evaluation Count:40
evaluated: formatChanges.at(i) == r.format
TRUEFALSE
yes
Evaluation Count:235
yes
Evaluation Count:10
10-245
127 ++i;
executed: ++i;
Execution Count:235
235
128 -
129 if (i == formatChanges.count())
evaluated: i == formatChanges.count()
TRUEFALSE
yes
Evaluation Count:40
yes
Evaluation Count:10
10-40
130 break;
executed: break;
Execution Count:40
40
131 -
132 r.start = i;
executed (the execution status of this line is deduced): r.start = i;
-
133 r.format = formatChanges.at(i);
executed (the execution status of this line is deduced): r.format = formatChanges.at(i);
-
134 -
135 while (i < formatChanges.count() && formatChanges.at(i) == r.format)
evaluated: i < formatChanges.count()
TRUEFALSE
yes
Evaluation Count:59
yes
Evaluation Count:2
evaluated: formatChanges.at(i) == r.format
TRUEFALSE
yes
Evaluation Count:51
yes
Evaluation Count:8
2-59
136 ++i;
executed: ++i;
Execution Count:51
51
137 -
138 Q_ASSERT(i <= formatChanges.count());
executed (the execution status of this line is deduced): qt_noop();
-
139 r.length = i - r.start;
executed (the execution status of this line is deduced): r.length = i - r.start;
-
140 -
141 if (preeditAreaLength != 0) {
evaluated: preeditAreaLength != 0
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:8
2-8
142 if (r.start >= preeditAreaStart)
evaluated: r.start >= preeditAreaStart
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
143 r.start += preeditAreaLength;
executed: r.start += preeditAreaLength;
Execution Count:1
1
144 else if (r.start + r.length >= preeditAreaStart)
partially evaluated: r.start + r.length >= preeditAreaStart
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
145 r.length += preeditAreaLength;
executed: r.length += preeditAreaLength;
Execution Count:1
1
146 } -
147 -
148 ranges << r;
executed (the execution status of this line is deduced): ranges << r;
-
149 formatsChanged = true;
executed (the execution status of this line is deduced): formatsChanged = true;
-
150 }
executed: }
Execution Count:10
10
151 -
152 if (formatsChanged) {
evaluated: formatsChanged
TRUEFALSE
yes
Evaluation Count:6
yes
Evaluation Count:51
6-51
153 layout->setAdditionalFormats(ranges);
executed (the execution status of this line is deduced): layout->setAdditionalFormats(ranges);
-
154 doc->markContentsDirty(currentBlock.position(), currentBlock.length());
executed (the execution status of this line is deduced): doc->markContentsDirty(currentBlock.position(), currentBlock.length());
-
155 }
executed: }
Execution Count:6
6
156}
executed: }
Execution Count:57
57
157 -
158void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded) -
159{ -
160 if (!inReformatBlocks)
partially evaluated: !inReformatBlocks
TRUEFALSE
yes
Evaluation Count:29
no
Evaluation Count:0
0-29
161 reformatBlocks(from, charsRemoved, charsAdded);
executed: reformatBlocks(from, charsRemoved, charsAdded);
Execution Count:29
29
162}
executed: }
Execution Count:29
29
163 -
164void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded) -
165{ -
166 rehighlightPending = false;
executed (the execution status of this line is deduced): rehighlightPending = false;
-
167 -
168 QTextBlock block = doc->findBlock(from);
executed (the execution status of this line is deduced): QTextBlock block = doc->findBlock(from);
-
169 if (!block.isValid())
partially evaluated: !block.isValid()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:34
0-34
170 return;
never executed: return;
0
171 -
172 int endPosition;
executed (the execution status of this line is deduced): int endPosition;
-
173 QTextBlock lastBlock = doc->findBlock(from + charsAdded + (charsRemoved > 0 ? 1 : 0));
executed (the execution status of this line is deduced): QTextBlock lastBlock = doc->findBlock(from + charsAdded + (charsRemoved > 0 ? 1 : 0));
-
174 if (lastBlock.isValid())
evaluated: lastBlock.isValid()
TRUEFALSE
yes
Evaluation Count:19
yes
Evaluation Count:15
15-19
175 endPosition = lastBlock.position() + lastBlock.length();
executed: endPosition = lastBlock.position() + lastBlock.length();
Execution Count:19
19
176 else -
177 endPosition = doc->docHandle()->length();
executed: endPosition = doc->docHandle()->length();
Execution Count:15
15
178 -
179 bool forceHighlightOfNextBlock = false;
executed (the execution status of this line is deduced): bool forceHighlightOfNextBlock = false;
-
180 -
181 while (block.isValid() && (block.position() < endPosition || forceHighlightOfNextBlock)) {
evaluated: block.isValid()
TRUEFALSE
yes
Evaluation Count:60
yes
Evaluation Count:31
evaluated: block.position() < endPosition
TRUEFALSE
yes
Evaluation Count:55
yes
Evaluation Count:5
evaluated: forceHighlightOfNextBlock
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:3
2-60
182 const int stateBeforeHighlight = block.userState();
executed (the execution status of this line is deduced): const int stateBeforeHighlight = block.userState();
-
183 -
184 reformatBlock(block);
executed (the execution status of this line is deduced): reformatBlock(block);
-
185 -
186 forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight);
executed (the execution status of this line is deduced): forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight);
-
187 -
188 block = block.next();
executed (the execution status of this line is deduced): block = block.next();
-
189 }
executed: }
Execution Count:57
57
190 -
191 formatChanges.clear();
executed (the execution status of this line is deduced): formatChanges.clear();
-
192}
executed: }
Execution Count:34
34
193 -
194void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block) -
195{ -
196 Q_Q(QSyntaxHighlighter);
executed (the execution status of this line is deduced): QSyntaxHighlighter * const q = q_func();
-
197 -
198 Q_ASSERT_X(!currentBlock.isValid(), "QSyntaxHighlighter::reformatBlock()", "reFormatBlock() called recursively");
executed (the execution status of this line is deduced): qt_noop();
-
199 -
200 currentBlock = block;
executed (the execution status of this line is deduced): currentBlock = block;
-
201 -
202 formatChanges.fill(QTextCharFormat(), block.length() - 1);
executed (the execution status of this line is deduced): formatChanges.fill(QTextCharFormat(), block.length() - 1);
-
203 q->highlightBlock(block.text());
executed (the execution status of this line is deduced): q->highlightBlock(block.text());
-
204 applyFormatChanges();
executed (the execution status of this line is deduced): applyFormatChanges();
-
205 -
206 currentBlock = QTextBlock();
executed (the execution status of this line is deduced): currentBlock = QTextBlock();
-
207}
executed: }
Execution Count:57
57
208 -
209/*! -
210 \class QSyntaxHighlighter -
211 \reentrant -
212 \inmodule QtGui -
213 -
214 \brief The QSyntaxHighlighter class allows you to define syntax -
215 highlighting rules, and in addition you can use the class to query -
216 a document's current formatting or user data. -
217 -
218 \since 4.1 -
219 -
220 \ingroup richtext-processing -
221 -
222 The QSyntaxHighlighter class is a base class for implementing -
223 QTextDocument syntax highlighters. A syntax highligher automatically -
224 highlights parts of the text in a QTextDocument. Syntax highlighters are -
225 often used when the user is entering text in a specific format (for example source code) -
226 and help the user to read the text and identify syntax errors. -
227 -
228 To provide your own syntax highlighting, you must subclass -
229 QSyntaxHighlighter and reimplement highlightBlock(). -
230 -
231 When you create an instance of your QSyntaxHighlighter subclass, -
232 pass it the QTextDocument that you want the syntax -
233 highlighting to be applied to. For example: -
234 -
235 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 0 -
236 -
237 After this your highlightBlock() function will be called -
238 automatically whenever necessary. Use your highlightBlock() -
239 function to apply formatting (e.g. setting the font and color) to -
240 the text that is passed to it. QSyntaxHighlighter provides the -
241 setFormat() function which applies a given QTextCharFormat on -
242 the current text block. For example: -
243 -
244 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 1 -
245 -
246 Some syntaxes can have constructs that span several text -
247 blocks. For example, a C++ syntax highlighter should be able to -
248 cope with \c{/}\c{*...*}\c{/} multiline comments. To deal with -
249 these cases it is necessary to know the end state of the previous -
250 text block (e.g. "in comment"). -
251 -
252 Inside your highlightBlock() implementation you can query the end -
253 state of the previous text block using the previousBlockState() -
254 function. After parsing the block you can save the last state -
255 using setCurrentBlockState(). -
256 -
257 The currentBlockState() and previousBlockState() functions return -
258 an int value. If no state is set, the returned value is -1. You -
259 can designate any other value to identify any given state using -
260 the setCurrentBlockState() function. Once the state is set the -
261 QTextBlock keeps that value until it is set set again or until the -
262 corresponding paragraph of text is deleted. -
263 -
264 For example, if you're writing a simple C++ syntax highlighter, -
265 you might designate 1 to signify "in comment": -
266 -
267 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 2 -
268 -
269 In the example above, we first set the current block state to -
270 0. Then, if the previous block ended within a comment, we higlight -
271 from the beginning of the current block (\c {startIndex = -
272 0}). Otherwise, we search for the given start expression. If the -
273 specified end expression cannot be found in the text block, we -
274 change the current block state by calling setCurrentBlockState(), -
275 and make sure that the rest of the block is higlighted. -
276 -
277 In addition you can query the current formatting and user data -
278 using the format() and currentBlockUserData() functions -
279 respectively. You can also attach user data to the current text -
280 block using the setCurrentBlockUserData() function. -
281 QTextBlockUserData can be used to store custom settings. In the -
282 case of syntax highlighting, it is in particular interesting as -
283 cache storage for information that you may figure out while -
284 parsing the paragraph's text. For an example, see the -
285 setCurrentBlockUserData() documentation. -
286 -
287 \sa QTextDocument, {Syntax Highlighter Example} -
288*/ -
289 -
290/*! -
291 Constructs a QSyntaxHighlighter with the given \a parent. -
292 -
293 If the parent is a QTextEdit, it installs the syntaxhighlighter on the -
294 parents document. The specified QTextEdit also becomes the owner of -
295 the QSyntaxHighlighter. -
296*/ -
297QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent) -
298 : QObject(*new QSyntaxHighlighterPrivate, parent) -
299{ -
300 if (parent->inherits("QTextEdit")) {
partially evaluated: parent->inherits("QTextEdit")
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
301 QTextDocument *doc = parent->property("document").value<QTextDocument *>();
executed (the execution status of this line is deduced): QTextDocument *doc = parent->property("document").value<QTextDocument *>();
-
302 if (doc)
partially evaluated: doc
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
303 setDocument(doc);
executed: setDocument(doc);
Execution Count:1
1
304 }
executed: }
Execution Count:1
1
305}
executed: }
Execution Count:1
1
306 -
307/*! -
308 Constructs a QSyntaxHighlighter and installs it on \a parent. -
309 The specified QTextDocument also becomes the owner of the -
310 QSyntaxHighlighter. -
311*/ -
312QSyntaxHighlighter::QSyntaxHighlighter(QTextDocument *parent) -
313 : QObject(*new QSyntaxHighlighterPrivate, parent) -
314{ -
315 setDocument(parent);
executed (the execution status of this line is deduced): setDocument(parent);
-
316}
executed: }
Execution Count:16
16
317 -
318/*! -
319 Destructor. Uninstalls this syntax highlighter from the text document. -
320*/ -
321QSyntaxHighlighter::~QSyntaxHighlighter() -
322{ -
323 setDocument(0);
executed (the execution status of this line is deduced): setDocument(0);
-
324}
executed: }
Execution Count:17
17
325 -
326/*! -
327 Installs the syntax highlighter on the given QTextDocument \a doc. -
328 A QSyntaxHighlighter can only be used with one document at a time. -
329*/ -
330void QSyntaxHighlighter::setDocument(QTextDocument *doc) -
331{ -
332 Q_D(QSyntaxHighlighter);
executed (the execution status of this line is deduced): QSyntaxHighlighterPrivate * const d = d_func();
-
333 if (d->doc) {
evaluated: d->doc
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:33
1-33
334 disconnect(d->doc, SIGNAL(contentsChange(int,int,int)),
executed (the execution status of this line is deduced): disconnect(d->doc, "2""contentsChange(int,int,int)",
-
335 this, SLOT(_q_reformatBlocks(int,int,int)));
executed (the execution status of this line is deduced): this, "1""_q_reformatBlocks(int,int,int)");
-
336 -
337 QTextCursor cursor(d->doc);
executed (the execution status of this line is deduced): QTextCursor cursor(d->doc);
-
338 cursor.beginEditBlock();
executed (the execution status of this line is deduced): cursor.beginEditBlock();
-
339 for (QTextBlock blk = d->doc->begin(); blk.isValid(); blk = blk.next())
evaluated: blk.isValid()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
340 blk.layout()->clearAdditionalFormats();
executed: blk.layout()->clearAdditionalFormats();
Execution Count:1
1
341 cursor.endEditBlock();
executed (the execution status of this line is deduced): cursor.endEditBlock();
-
342 }
executed: }
Execution Count:1
1
343 d->doc = doc;
executed (the execution status of this line is deduced): d->doc = doc;
-
344 if (d->doc) {
evaluated: d->doc
TRUEFALSE
yes
Evaluation Count:17
yes
Evaluation Count:17
17
345 connect(d->doc, SIGNAL(contentsChange(int,int,int)),
executed (the execution status of this line is deduced): connect(d->doc, "2""contentsChange(int,int,int)",
-
346 this, SLOT(_q_reformatBlocks(int,int,int)));
executed (the execution status of this line is deduced): this, "1""_q_reformatBlocks(int,int,int)");
-
347 d->rehighlightPending = true;
executed (the execution status of this line is deduced): d->rehighlightPending = true;
-
348 QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
executed (the execution status of this line is deduced): QTimer::singleShot(0, this, "1""_q_delayedRehighlight()");
-
349 }
executed: }
Execution Count:17
17
350}
executed: }
Execution Count:34
34
351 -
352/*! -
353 Returns the QTextDocument on which this syntax highlighter is -
354 installed. -
355*/ -
356QTextDocument *QSyntaxHighlighter::document() const -
357{ -
358 Q_D(const QSyntaxHighlighter);
executed (the execution status of this line is deduced): const QSyntaxHighlighterPrivate * const d = d_func();
-
359 return d->doc;
executed: return d->doc;
Execution Count:1
1
360} -
361 -
362/*! -
363 \since 4.2 -
364 -
365 Reapplies the highlighting to the whole document. -
366 -
367 \sa rehighlightBlock() -
368*/ -
369void QSyntaxHighlighter::rehighlight() -
370{ -
371 Q_D(QSyntaxHighlighter);
executed (the execution status of this line is deduced): QSyntaxHighlighterPrivate * const d = d_func();
-
372 if (!d->doc)
partially evaluated: !d->doc
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:3
0-3
373 return;
never executed: return;
0
374 -
375 QTextCursor cursor(d->doc);
executed (the execution status of this line is deduced): QTextCursor cursor(d->doc);
-
376 d->rehighlight(cursor, QTextCursor::End);
executed (the execution status of this line is deduced): d->rehighlight(cursor, QTextCursor::End);
-
377}
executed: }
Execution Count:3
3
378 -
379/*! -
380 \since 4.6 -
381 -
382 Reapplies the highlighting to the given QTextBlock \a block. -
383 -
384 \sa rehighlight() -
385*/ -
386void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) -
387{ -
388 Q_D(QSyntaxHighlighter);
executed (the execution status of this line is deduced): QSyntaxHighlighterPrivate * const d = d_func();
-
389 if (!d->doc || !block.isValid() || block.document() != d->doc)
partially evaluated: !d->doc
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
partially evaluated: !block.isValid()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
partially evaluated: block.document() != d->doc
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
0-2
390 return;
never executed: return;
0
391 -
392 const bool rehighlightPending = d->rehighlightPending;
executed (the execution status of this line is deduced): const bool rehighlightPending = d->rehighlightPending;
-
393 -
394 QTextCursor cursor(block);
executed (the execution status of this line is deduced): QTextCursor cursor(block);
-
395 d->rehighlight(cursor, QTextCursor::EndOfBlock);
executed (the execution status of this line is deduced): d->rehighlight(cursor, QTextCursor::EndOfBlock);
-
396 -
397 if (rehighlightPending)
partially evaluated: rehighlightPending
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
0-2
398 d->rehighlightPending = rehighlightPending;
never executed: d->rehighlightPending = rehighlightPending;
0
399}
executed: }
Execution Count:2
2
400 -
401/*! -
402 \fn void QSyntaxHighlighter::highlightBlock(const QString &text) -
403 -
404 Highlights the given text block. This function is called when -
405 necessary by the rich text engine, i.e. on text blocks which have -
406 changed. -
407 -
408 To provide your own syntax highlighting, you must subclass -
409 QSyntaxHighlighter and reimplement highlightBlock(). In your -
410 reimplementation you should parse the block's \a text and call -
411 setFormat() as often as necessary to apply any font and color -
412 changes that you require. For example: -
413 -
414 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 3 -
415 -
416 Some syntaxes can have constructs that span several text -
417 blocks. For example, a C++ syntax highlighter should be able to -
418 cope with \c{/}\c{*...*}\c{/} multiline comments. To deal with -
419 these cases it is necessary to know the end state of the previous -
420 text block (e.g. "in comment"). -
421 -
422 Inside your highlightBlock() implementation you can query the end -
423 state of the previous text block using the previousBlockState() -
424 function. After parsing the block you can save the last state -
425 using setCurrentBlockState(). -
426 -
427 The currentBlockState() and previousBlockState() functions return -
428 an int value. If no state is set, the returned value is -1. You -
429 can designate any other value to identify any given state using -
430 the setCurrentBlockState() function. Once the state is set the -
431 QTextBlock keeps that value until it is set set again or until the -
432 corresponding paragraph of text gets deleted. -
433 -
434 For example, if you're writing a simple C++ syntax highlighter, -
435 you might designate 1 to signify "in comment". For a text block -
436 that ended in the middle of a comment you'd set 1 using -
437 setCurrentBlockState, and for other paragraphs you'd set 0. -
438 In your parsing code if the return value of previousBlockState() -
439 is 1, you would highlight the text as a C++ comment until you -
440 reached the closing \c{*}\c{/}. -
441 -
442 \sa previousBlockState(), setFormat(), setCurrentBlockState() -
443*/ -
444 -
445/*! -
446 This function is applied to the syntax highlighter's current text -
447 block (i.e. the text that is passed to the highlightBlock() -
448 function). -
449 -
450 The specified \a format is applied to the text from the \a start -
451 position for a length of \a count characters (if \a count is 0, -
452 nothing is done). The formatting properties set in \a format are -
453 merged at display time with the formatting information stored -
454 directly in the document, for example as previously set with -
455 QTextCursor's functions. Note that the document itself remains -
456 unmodified by the format set through this function. -
457 -
458 \sa format(), highlightBlock() -
459*/ -
460void QSyntaxHighlighter::setFormat(int start, int count, const QTextCharFormat &format) -
461{ -
462 Q_D(QSyntaxHighlighter);
executed (the execution status of this line is deduced): QSyntaxHighlighterPrivate * const d = d_func();
-
463 if (start < 0 || start >= d->formatChanges.count())
partially evaluated: start < 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:16
evaluated: start >= d->formatChanges.count()
TRUEFALSE
yes
Evaluation Count:6
yes
Evaluation Count:10
0-16
464 return;
executed: return;
Execution Count:6
6
465 -
466 const int end = qMin(start + count, d->formatChanges.count());
executed (the execution status of this line is deduced): const int end = qMin(start + count, d->formatChanges.count());
-
467 for (int i = start; i < end; ++i)
evaluated: i < end
TRUEFALSE
yes
Evaluation Count:51
yes
Evaluation Count:10
10-51
468 d->formatChanges[i] = format;
executed: d->formatChanges[i] = format;
Execution Count:51
51
469}
executed: }
Execution Count:10
10
470 -
471/*! -
472 \overload -
473 -
474 The specified \a color is applied to the current text block from -
475 the \a start position for a length of \a count characters. -
476 -
477 The other attributes of the current text block, e.g. the font and -
478 background color, are reset to default values. -
479 -
480 \sa format(), highlightBlock() -
481*/ -
482void QSyntaxHighlighter::setFormat(int start, int count, const QColor &color) -
483{ -
484 QTextCharFormat format;
never executed (the execution status of this line is deduced): QTextCharFormat format;
-
485 format.setForeground(color);
never executed (the execution status of this line is deduced): format.setForeground(color);
-
486 setFormat(start, count, format);
never executed (the execution status of this line is deduced): setFormat(start, count, format);
-
487}
never executed: }
0
488 -
489/*! -
490 \overload -
491 -
492 The specified \a font is applied to the current text block from -
493 the \a start position for a length of \a count characters. -
494 -
495 The other attributes of the current text block, e.g. the font and -
496 background color, are reset to default values. -
497 -
498 \sa format(), highlightBlock() -
499*/ -
500void QSyntaxHighlighter::setFormat(int start, int count, const QFont &font) -
501{ -
502 QTextCharFormat format;
never executed (the execution status of this line is deduced): QTextCharFormat format;
-
503 format.setFont(font);
never executed (the execution status of this line is deduced): format.setFont(font);
-
504 setFormat(start, count, format);
never executed (the execution status of this line is deduced): setFormat(start, count, format);
-
505}
never executed: }
0
506 -
507/*! -
508 \fn QTextCharFormat QSyntaxHighlighter::format(int position) const -
509 -
510 Returns the format at \a position inside the syntax highlighter's -
511 current text block. -
512*/ -
513QTextCharFormat QSyntaxHighlighter::format(int pos) const -
514{ -
515 Q_D(const QSyntaxHighlighter);
never executed (the execution status of this line is deduced): const QSyntaxHighlighterPrivate * const d = d_func();
-
516 if (pos < 0 || pos >= d->formatChanges.count())
never evaluated: pos < 0
never evaluated: pos >= d->formatChanges.count()
0
517 return QTextCharFormat();
never executed: return QTextCharFormat();
0
518 return d->formatChanges.at(pos);
never executed: return d->formatChanges.at(pos);
0
519} -
520 -
521/*! -
522 Returns the end state of the text block previous to the -
523 syntax highlighter's current block. If no value was -
524 previously set, the returned value is -1. -
525 -
526 \sa highlightBlock(), setCurrentBlockState() -
527*/ -
528int QSyntaxHighlighter::previousBlockState() const -
529{ -
530 Q_D(const QSyntaxHighlighter);
never executed (the execution status of this line is deduced): const QSyntaxHighlighterPrivate * const d = d_func();
-
531 if (!d->currentBlock.isValid())
never evaluated: !d->currentBlock.isValid()
0
532 return -1;
never executed: return -1;
0
533 -
534 const QTextBlock previous = d->currentBlock.previous();
never executed (the execution status of this line is deduced): const QTextBlock previous = d->currentBlock.previous();
-
535 if (!previous.isValid())
never evaluated: !previous.isValid()
0
536 return -1;
never executed: return -1;
0
537 -
538 return previous.userState();
never executed: return previous.userState();
0
539} -
540 -
541/*! -
542 Returns the state of the current text block. If no value is set, -
543 the returned value is -1. -
544*/ -
545int QSyntaxHighlighter::currentBlockState() const -
546{ -
547 Q_D(const QSyntaxHighlighter);
never executed (the execution status of this line is deduced): const QSyntaxHighlighterPrivate * const d = d_func();
-
548 if (!d->currentBlock.isValid())
never evaluated: !d->currentBlock.isValid()
0
549 return -1;
never executed: return -1;
0
550 -
551 return d->currentBlock.userState();
never executed: return d->currentBlock.userState();
0
552} -
553 -
554/*! -
555 Sets the state of the current text block to \a newState. -
556 -
557 \sa highlightBlock() -
558*/ -
559void QSyntaxHighlighter::setCurrentBlockState(int newState) -
560{ -
561 Q_D(QSyntaxHighlighter);
executed (the execution status of this line is deduced): QSyntaxHighlighterPrivate * const d = d_func();
-
562 if (!d->currentBlock.isValid())
partially evaluated: !d->currentBlock.isValid()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:5
0-5
563 return;
never executed: return;
0
564 -
565 d->currentBlock.setUserState(newState);
executed (the execution status of this line is deduced): d->currentBlock.setUserState(newState);
-
566}
executed: }
Execution Count:5
5
567 -
568/*! -
569 Attaches the given \a data to the current text block. The -
570 ownership is passed to the underlying text document, i.e. the -
571 provided QTextBlockUserData object will be deleted if the -
572 corresponding text block gets deleted. -
573 -
574 QTextBlockUserData can be used to store custom settings. In the -
575 case of syntax highlighting, it is in particular interesting as -
576 cache storage for information that you may figure out while -
577 parsing the paragraph's text. -
578 -
579 For example while parsing the text, you can keep track of -
580 parenthesis characters that you encounter ('{[(' and the like), -
581 and store their relative position and the actual QChar in a simple -
582 class derived from QTextBlockUserData: -
583 -
584 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 4 -
585 -
586 During cursor navigation in the associated editor, you can ask the -
587 current QTextBlock (retrieved using the QTextCursor::block() -
588 function) if it has a user data object set and cast it to your \c -
589 BlockData object. Then you can check if the current cursor -
590 position matches with a previously recorded parenthesis position, -
591 and, depending on the type of parenthesis (opening or closing), -
592 find the next opening or closing parenthesis on the same level. -
593 -
594 In this way you can do a visual parenthesis matching and highlight -
595 from the current cursor position to the matching parenthesis. That -
596 makes it easier to spot a missing parenthesis in your code and to -
597 find where a corresponding opening/closing parenthesis is when -
598 editing parenthesis intensive code. -
599 -
600 \sa QTextBlock::setUserData() -
601*/ -
602void QSyntaxHighlighter::setCurrentBlockUserData(QTextBlockUserData *data) -
603{ -
604 Q_D(QSyntaxHighlighter);
never executed (the execution status of this line is deduced): QSyntaxHighlighterPrivate * const d = d_func();
-
605 if (!d->currentBlock.isValid())
never evaluated: !d->currentBlock.isValid()
0
606 return;
never executed: return;
0
607 -
608 d->currentBlock.setUserData(data);
never executed (the execution status of this line is deduced): d->currentBlock.setUserData(data);
-
609}
never executed: }
0
610 -
611/*! -
612 Returns the QTextBlockUserData object previously attached to the -
613 current text block. -
614 -
615 \sa QTextBlock::userData(), setCurrentBlockUserData() -
616*/ -
617QTextBlockUserData *QSyntaxHighlighter::currentBlockUserData() const -
618{ -
619 Q_D(const QSyntaxHighlighter);
never executed (the execution status of this line is deduced): const QSyntaxHighlighterPrivate * const d = d_func();
-
620 if (!d->currentBlock.isValid())
never evaluated: !d->currentBlock.isValid()
0
621 return 0;
never executed: return 0;
0
622 -
623 return d->currentBlock.userData();
never executed: return d->currentBlock.userData();
0
624} -
625 -
626/*! -
627 \since 4.4 -
628 -
629 Returns the current text block. -
630*/ -
631QTextBlock QSyntaxHighlighter::currentBlock() const -
632{ -
633 Q_D(const QSyntaxHighlighter);
never executed (the execution status of this line is deduced): const QSyntaxHighlighterPrivate * const d = d_func();
-
634 return d->currentBlock;
never executed: return d->currentBlock;
0
635} -
636 -
637QT_END_NAMESPACE -
638 -
639#include "moc_qsyntaxhighlighter.cpp" -
640 -
641#endif // QT_NO_SYNTAXHIGHLIGHTER -
642 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial