Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/gui/text/qsyntaxhighlighter.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||
2 | - | |||||||||||||
3 | - | |||||||||||||
4 | - | |||||||||||||
5 | - | |||||||||||||
6 | - | |||||||||||||
7 | - | |||||||||||||
8 | class QSyntaxHighlighterPrivate : public QObjectPrivate | - | ||||||||||||
9 | { | - | ||||||||||||
10 | inline QSyntaxHighlighter* q_func() { return static_cast<QSyntaxHighlighter *>(q_ptr); } inline const QSyntaxHighlighter* q_func() const { return static_cast<const QSyntaxHighlighter *>(q_ptr); } friend class QSyntaxHighlighter; | - | ||||||||||||
11 | public: | - | ||||||||||||
12 | inline QSyntaxHighlighterPrivate() | - | ||||||||||||
13 | : rehighlightPending(false), inReformatBlocks(false) | - | ||||||||||||
14 | {} | - | ||||||||||||
15 | - | |||||||||||||
16 | QPointer<QTextDocument> doc; | - | ||||||||||||
17 | - | |||||||||||||
18 | void _q_reformatBlocks(int from, int charsRemoved, int charsAdded); | - | ||||||||||||
19 | void reformatBlocks(int from, int charsRemoved, int charsAdded); | - | ||||||||||||
20 | void reformatBlock(const QTextBlock &block); | - | ||||||||||||
21 | - | |||||||||||||
22 | inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) { | - | ||||||||||||
23 | inReformatBlocks = true; | - | ||||||||||||
24 | cursor.beginEditBlock(); | - | ||||||||||||
25 | int from = cursor.position(); | - | ||||||||||||
26 | cursor.movePosition(operation); | - | ||||||||||||
27 | reformatBlocks(from, 0, cursor.position() - from); | - | ||||||||||||
28 | cursor.endEditBlock(); | - | ||||||||||||
29 | inReformatBlocks = false; | - | ||||||||||||
30 | } | - | ||||||||||||
31 | - | |||||||||||||
32 | inline void _q_delayedRehighlight() { | - | ||||||||||||
33 | if (!rehighlightPending) | - | ||||||||||||
34 | return; | - | ||||||||||||
35 | rehighlightPending = false; | - | ||||||||||||
36 | q_func()->rehighlight(); | - | ||||||||||||
37 | } | - | ||||||||||||
38 | - | |||||||||||||
39 | void applyFormatChanges(); | - | ||||||||||||
40 | QVector<QTextCharFormat> formatChanges; | - | ||||||||||||
41 | QTextBlock currentBlock; | - | ||||||||||||
42 | bool rehighlightPending; | - | ||||||||||||
43 | bool inReformatBlocks; | - | ||||||||||||
44 | }; | - | ||||||||||||
45 | - | |||||||||||||
46 | void QSyntaxHighlighterPrivate::applyFormatChanges() | - | ||||||||||||
47 | { | - | ||||||||||||
48 | bool formatsChanged = false; | - | ||||||||||||
49 | - | |||||||||||||
50 | QTextLayout *layout = currentBlock.layout(); | - | ||||||||||||
51 | - | |||||||||||||
52 | QVector<QTextLayout::FormatRange> ranges = layout->formats(); | - | ||||||||||||
53 | - | |||||||||||||
54 | const int preeditAreaStart = layout->preeditAreaPosition(); | - | ||||||||||||
55 | const int preeditAreaLength = layout->preeditAreaText().length(); | - | ||||||||||||
56 | - | |||||||||||||
57 | if (preeditAreaLength != 0
| 0 | ||||||||||||
58 | QVector<auto isOutsidePreeditArea = [=](const QTextLayout::FormatRange >::Iterator&range) { | - | ||||||||||||
59 | return never executed: range.start < preeditAreaStartreturn range.start < preeditAreaStart || range.start + range.length > preeditAreaStart + preeditAreaLength; never executed: return range.start < preeditAreaStart || range.start + range.length > preeditAreaStart + preeditAreaLength; | 0 | ||||||||||||
60 | || range.start + range.length > preeditAreaStart + preeditAreaLength; never executed: return range.start < preeditAreaStart || range.start + range.length > preeditAreaStart + preeditAreaLength; | 0 | ||||||||||||
61 | }; | - | ||||||||||||
62 | const auto it = std::remove_if(ranges.begin(); | - | ||||||||||||
while(), ranges.end(), | ||||||||||||||
63 | isOutsidePreeditArea); | - | ||||||||||||
64 | if (it != ranges.end()
| 0 | ||||||||||||
if (it->start >= preeditAreaStart | ||||||||||||||
&& it->start + it->length <= preeditAreaStart + preeditAreaLength) { | ||||||||||||||
++it; | ||||||||||||||
} else{ | ||||||||||||||
65 | it =ranges.erase(it);, ranges.end()); | - | ||||||||||||
66 | formatsChanged = true; | - | ||||||||||||
67 | }} never executed: end of block | 0 | ||||||||||||
68 | } never executed: else if (!ranges.isEmpty()end of block
| 0 | ||||||||||||
69 | ranges.clear(); | - | ||||||||||||
70 | formatsChanged = true; | - | ||||||||||||
71 | } never executed: end of block | 0 | ||||||||||||
72 | - | |||||||||||||
73 | int i = 0; | - | ||||||||||||
74 | while (i < formatChanges.count()
| 0 | ||||||||||||
75 | QTextLayout::FormatRange r; | - | ||||||||||||
76 | - | |||||||||||||
77 | while (i < formatChanges.count()
| 0 | ||||||||||||
78 | ++ never executed: i;++i; never executed: ++i; | 0 | ||||||||||||
79 | - | |||||||||||||
80 | if (i == formatChanges.count()
| 0 | ||||||||||||
81 | break; never executed: break; | 0 | ||||||||||||
82 | - | |||||||||||||
83 | r.start = i; | - | ||||||||||||
84 | r.format = formatChanges.at(i); | - | ||||||||||||
85 | - | |||||||||||||
86 | while (i < formatChanges.count()
| 0 | ||||||||||||
87 | ++ never executed: i;++i; never executed: ++i; | 0 | ||||||||||||
88 | - | |||||||||||||
89 | ((!(i <= formatChanges.count())) ? qt_assert("i <= formatChanges.count()",__FILE__,130138) : qt_noop()); | - | ||||||||||||
90 | r.length = i - r.start; | - | ||||||||||||
91 | - | |||||||||||||
92 | if (preeditAreaLength != 0
| 0 | ||||||||||||
93 | if (r.start >= preeditAreaStart
| 0 | ||||||||||||
94 | r.start += preeditAreaLength; never executed: r.start += preeditAreaLength; | 0 | ||||||||||||
95 | else if (r.start + r.length >= preeditAreaStart
| 0 | ||||||||||||
96 | r.length += preeditAreaLength; never executed: r.length += preeditAreaLength; | 0 | ||||||||||||
97 | } never executed: end of block | 0 | ||||||||||||
98 | - | |||||||||||||
99 | ranges << r; | - | ||||||||||||
100 | formatsChanged = true; | - | ||||||||||||
101 | } never executed: end of block | 0 | ||||||||||||
102 | - | |||||||||||||
103 | if (formatsChanged
| 0 | ||||||||||||
104 | layout->setFormats(ranges); | - | ||||||||||||
105 | doc->markContentsDirty(currentBlock.position(), currentBlock.length()); | - | ||||||||||||
106 | } never executed: end of block | 0 | ||||||||||||
107 | } never executed: end of block | 0 | ||||||||||||
108 | - | |||||||||||||
109 | void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded) | - | ||||||||||||
110 | { | - | ||||||||||||
111 | if (!inReformatBlocks) | - | ||||||||||||
112 | reformatBlocks(from, charsRemoved, charsAdded); | - | ||||||||||||
113 | } | - | ||||||||||||
114 | - | |||||||||||||
115 | void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded) | - | ||||||||||||
116 | { | - | ||||||||||||
117 | rehighlightPending = false; | - | ||||||||||||
118 | - | |||||||||||||
119 | QTextBlock block = doc->findBlock(from); | - | ||||||||||||
120 | if (!block.isValid()) | - | ||||||||||||
121 | return; | - | ||||||||||||
122 | - | |||||||||||||
123 | int endPosition; | - | ||||||||||||
124 | QTextBlock lastBlock = doc->findBlock(from + charsAdded + (charsRemoved > 0 ? 1 : 0)); | - | ||||||||||||
125 | if (lastBlock.isValid()) | - | ||||||||||||
126 | endPosition = lastBlock.position() + lastBlock.length(); | - | ||||||||||||
127 | else | - | ||||||||||||
128 | endPosition = doc->docHandle()->length(); | - | ||||||||||||
129 | - | |||||||||||||
130 | bool forceHighlightOfNextBlock = false; | - | ||||||||||||
131 | - | |||||||||||||
132 | while (block.isValid() && (block.position() < endPosition || forceHighlightOfNextBlock)) { | - | ||||||||||||
133 | const int stateBeforeHighlight = block.userState(); | - | ||||||||||||
134 | - | |||||||||||||
135 | reformatBlock(block); | - | ||||||||||||
136 | - | |||||||||||||
137 | forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight); | - | ||||||||||||
138 | - | |||||||||||||
139 | block = block.next(); | - | ||||||||||||
140 | } | - | ||||||||||||
141 | - | |||||||||||||
142 | formatChanges.clear(); | - | ||||||||||||
143 | } | - | ||||||||||||
144 | - | |||||||||||||
145 | void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block) | - | ||||||||||||
146 | { | - | ||||||||||||
147 | QSyntaxHighlighter * const q = q_func(); | - | ||||||||||||
148 | - | |||||||||||||
149 | ((!(!currentBlock.isValid())) ? qt_assert_x("QSyntaxHighlighter::reformatBlock()", "reFormatBlock() called recursively",__FILE__,190198) : qt_noop()); | - | ||||||||||||
150 | - | |||||||||||||
151 | currentBlock = block; | - | ||||||||||||
152 | - | |||||||||||||
153 | formatChanges.fill(QTextCharFormat(), block.length() - 1); | - | ||||||||||||
154 | q->highlightBlock(block.text()); | - | ||||||||||||
155 | applyFormatChanges(); | - | ||||||||||||
156 | - | |||||||||||||
157 | currentBlock = QTextBlock(); | - | ||||||||||||
158 | } | - | ||||||||||||
159 | QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent) | - | ||||||||||||
160 | : QObject(*new QSyntaxHighlighterPrivate, parent) | - | ||||||||||||
161 | { | - | ||||||||||||
162 | if (parent->inherits("QTextEdit")) { | - | ||||||||||||
163 | QTextDocument *doc = parent->property("document").value<QTextDocument *>(); | - | ||||||||||||
164 | if (doc) | - | ||||||||||||
165 | setDocument(doc); | - | ||||||||||||
166 | } | - | ||||||||||||
167 | } | - | ||||||||||||
168 | - | |||||||||||||
169 | - | |||||||||||||
170 | - | |||||||||||||
171 | - | |||||||||||||
172 | - | |||||||||||||
173 | - | |||||||||||||
174 | QSyntaxHighlighter::QSyntaxHighlighter(QTextDocument *parent) | - | ||||||||||||
175 | : QObject(*new QSyntaxHighlighterPrivate, parent) | - | ||||||||||||
176 | { | - | ||||||||||||
177 | setDocument(parent); | - | ||||||||||||
178 | } | - | ||||||||||||
179 | - | |||||||||||||
180 | - | |||||||||||||
181 | - | |||||||||||||
182 | - | |||||||||||||
183 | QSyntaxHighlighter::~QSyntaxHighlighter() | - | ||||||||||||
184 | { | - | ||||||||||||
185 | setDocument(0); | - | ||||||||||||
186 | } | - | ||||||||||||
187 | - | |||||||||||||
188 | - | |||||||||||||
189 | - | |||||||||||||
190 | - | |||||||||||||
191 | - | |||||||||||||
192 | void QSyntaxHighlighter::setDocument(QTextDocument *doc) | - | ||||||||||||
193 | { | - | ||||||||||||
194 | QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
195 | if (d->doc) { | - | ||||||||||||
196 | disconnect(d->doc, qFlagLocation("2""contentsChange(int,int,int)" "\0" __FILE__ ":" "326""334"), | - | ||||||||||||
197 | this, qFlagLocation("1""_q_reformatBlocks(int,int,int)" "\0" __FILE__ ":" "327""335")); | - | ||||||||||||
198 | - | |||||||||||||
199 | QTextCursor cursor(d->doc); | - | ||||||||||||
200 | cursor.beginEditBlock(); | - | ||||||||||||
201 | for (QTextBlock blk = d->doc->begin(); blk.isValid(); blk = blk.next()) | - | ||||||||||||
202 | blk.layout()->clearFormats(); | - | ||||||||||||
203 | cursor.endEditBlock(); | - | ||||||||||||
204 | } | - | ||||||||||||
205 | d->doc = doc; | - | ||||||||||||
206 | if (d->doc) { | - | ||||||||||||
207 | connect(d->doc, qFlagLocation("2""contentsChange(int,int,int)" "\0" __FILE__ ":" "337""345"), | - | ||||||||||||
208 | this, qFlagLocation("1""_q_reformatBlocks(int,int,int)" "\0" __FILE__ ":" "338""346")); | - | ||||||||||||
209 | d->rehighlightPending = true; | - | ||||||||||||
210 | QTimer::singleShot(0, this, qFlagLocation("1""_q_delayedRehighlight()" "\0" __FILE__ ":" "340""348")); | - | ||||||||||||
211 | } | - | ||||||||||||
212 | } | - | ||||||||||||
213 | - | |||||||||||||
214 | - | |||||||||||||
215 | - | |||||||||||||
216 | - | |||||||||||||
217 | - | |||||||||||||
218 | QTextDocument *QSyntaxHighlighter::document() const | - | ||||||||||||
219 | { | - | ||||||||||||
220 | const QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
221 | return d->doc; | - | ||||||||||||
222 | } | - | ||||||||||||
223 | void QSyntaxHighlighter::rehighlight() | - | ||||||||||||
224 | { | - | ||||||||||||
225 | QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
226 | if (!d->doc) | - | ||||||||||||
227 | return; | - | ||||||||||||
228 | - | |||||||||||||
229 | QTextCursor cursor(d->doc); | - | ||||||||||||
230 | d->rehighlight(cursor, QTextCursor::End); | - | ||||||||||||
231 | } | - | ||||||||||||
232 | void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) | - | ||||||||||||
233 | { | - | ||||||||||||
234 | QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
235 | if (!d->doc || !block.isValid() || block.document() != d->doc) | - | ||||||||||||
236 | return; | - | ||||||||||||
237 | - | |||||||||||||
238 | const bool rehighlightPending = d->rehighlightPending; | - | ||||||||||||
239 | - | |||||||||||||
240 | QTextCursor cursor(block); | - | ||||||||||||
241 | d->rehighlight(cursor, QTextCursor::EndOfBlock); | - | ||||||||||||
242 | - | |||||||||||||
243 | if (rehighlightPending) | - | ||||||||||||
244 | d->rehighlightPending = rehighlightPending; | - | ||||||||||||
245 | } | - | ||||||||||||
246 | void QSyntaxHighlighter::setFormat(int start, int count, const QTextCharFormat &format) | - | ||||||||||||
247 | { | - | ||||||||||||
248 | QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
249 | if (start < 0 || start >= d->formatChanges.count()) | - | ||||||||||||
250 | return; | - | ||||||||||||
251 | - | |||||||||||||
252 | const int end = qMin(start + count, d->formatChanges.count()); | - | ||||||||||||
253 | for (int i = start; i < end; ++i) | - | ||||||||||||
254 | d->formatChanges[i] = format; | - | ||||||||||||
255 | } | - | ||||||||||||
256 | void QSyntaxHighlighter::setFormat(int start, int count, const QColor &color) | - | ||||||||||||
257 | { | - | ||||||||||||
258 | QTextCharFormat format; | - | ||||||||||||
259 | format.setForeground(color); | - | ||||||||||||
260 | setFormat(start, count, format); | - | ||||||||||||
261 | } | - | ||||||||||||
262 | void QSyntaxHighlighter::setFormat(int start, int count, const QFont &font) | - | ||||||||||||
263 | { | - | ||||||||||||
264 | QTextCharFormat format; | - | ||||||||||||
265 | format.setFont(font); | - | ||||||||||||
266 | setFormat(start, count, format); | - | ||||||||||||
267 | } | - | ||||||||||||
268 | - | |||||||||||||
269 | - | |||||||||||||
270 | - | |||||||||||||
271 | - | |||||||||||||
272 | - | |||||||||||||
273 | - | |||||||||||||
274 | - | |||||||||||||
275 | QTextCharFormat QSyntaxHighlighter::format(int pos) const | - | ||||||||||||
276 | { | - | ||||||||||||
277 | const QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
278 | if (pos < 0 || pos >= d->formatChanges.count()) | - | ||||||||||||
279 | return QTextCharFormat(); | - | ||||||||||||
280 | return d->formatChanges.at(pos); | - | ||||||||||||
281 | } | - | ||||||||||||
282 | int QSyntaxHighlighter::previousBlockState() const | - | ||||||||||||
283 | { | - | ||||||||||||
284 | const QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
285 | if (!d->currentBlock.isValid()) | - | ||||||||||||
286 | return -1; | - | ||||||||||||
287 | - | |||||||||||||
288 | const QTextBlock previous = d->currentBlock.previous(); | - | ||||||||||||
289 | if (!previous.isValid()) | - | ||||||||||||
290 | return -1; | - | ||||||||||||
291 | - | |||||||||||||
292 | return previous.userState(); | - | ||||||||||||
293 | } | - | ||||||||||||
294 | - | |||||||||||||
295 | - | |||||||||||||
296 | - | |||||||||||||
297 | - | |||||||||||||
298 | - | |||||||||||||
299 | int QSyntaxHighlighter::currentBlockState() const | - | ||||||||||||
300 | { | - | ||||||||||||
301 | const QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
302 | if (!d->currentBlock.isValid()) | - | ||||||||||||
303 | return -1; | - | ||||||||||||
304 | - | |||||||||||||
305 | return d->currentBlock.userState(); | - | ||||||||||||
306 | } | - | ||||||||||||
307 | - | |||||||||||||
308 | - | |||||||||||||
309 | - | |||||||||||||
310 | - | |||||||||||||
311 | - | |||||||||||||
312 | - | |||||||||||||
313 | void QSyntaxHighlighter::setCurrentBlockState(int newState) | - | ||||||||||||
314 | { | - | ||||||||||||
315 | QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
316 | if (!d->currentBlock.isValid()) | - | ||||||||||||
317 | return; | - | ||||||||||||
318 | - | |||||||||||||
319 | d->currentBlock.setUserState(newState); | - | ||||||||||||
320 | } | - | ||||||||||||
321 | void QSyntaxHighlighter::setCurrentBlockUserData(QTextBlockUserData *data) | - | ||||||||||||
322 | { | - | ||||||||||||
323 | QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
324 | if (!d->currentBlock.isValid()) | - | ||||||||||||
325 | return; | - | ||||||||||||
326 | - | |||||||||||||
327 | d->currentBlock.setUserData(data); | - | ||||||||||||
328 | } | - | ||||||||||||
329 | - | |||||||||||||
330 | - | |||||||||||||
331 | - | |||||||||||||
332 | - | |||||||||||||
333 | - | |||||||||||||
334 | - | |||||||||||||
335 | - | |||||||||||||
336 | QTextBlockUserData *QSyntaxHighlighter::currentBlockUserData() const | - | ||||||||||||
337 | { | - | ||||||||||||
338 | const QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
339 | if (!d->currentBlock.isValid()) | - | ||||||||||||
340 | return 0; | - | ||||||||||||
341 | - | |||||||||||||
342 | return d->currentBlock.userData(); | - | ||||||||||||
343 | } | - | ||||||||||||
344 | - | |||||||||||||
345 | - | |||||||||||||
346 | - | |||||||||||||
347 | - | |||||||||||||
348 | - | |||||||||||||
349 | - | |||||||||||||
350 | QTextBlock QSyntaxHighlighter::currentBlock() const | - | ||||||||||||
351 | { | - | ||||||||||||
352 | const QSyntaxHighlighterPrivate * const d = d_func(); | - | ||||||||||||
353 | return d->currentBlock; | - | ||||||||||||
354 | } | - | ||||||||||||
355 | - | |||||||||||||
356 | - | |||||||||||||
357 | - | |||||||||||||
Switch to Source code | Preprocessed file |