1 | /****************************************************************************
|
2 | **
|
3 | ** Copyright (C) 2016 The Qt Company Ltd.
|
4 | ** Contact: https://www.qt.io/licensing/
|
5 | **
|
6 | ** Copyright (C) 2020 Francesc Martinez
|
7 | ** LinkedIn: www.linkedin.com/in/cescmm/
|
8 | ** Web: www.francescmm.com
|
9 | **
|
10 | ** This file is part of the examples of the Qt Toolkit.
|
11 | **
|
12 | ** $QT_BEGIN_LICENSE:BSD$
|
13 | ** Commercial License Usage
|
14 | ** Licensees holding valid commercial Qt licenses may use this file in
|
15 | ** accordance with the commercial license agreement provided with the
|
16 | ** Software or, alternatively, in accordance with the terms contained in
|
17 | ** a written agreement between you and The Qt Company. For licensing terms
|
18 | ** and conditions see https://www.qt.io/terms-conditions. For further
|
19 | ** information use the contact form at https://www.qt.io/contact-us.
|
20 | **
|
21 | ** BSD License Usage
|
22 | ** Alternatively, you may use this file under the terms of the BSD license
|
23 | ** as follows:
|
24 | **
|
25 | ** "Redistribution and use in source and binary forms, with or without
|
26 | ** modification, are permitted provided that the following conditions are
|
27 | ** met:
|
28 | ** * Redistributions of source code must retain the above copyright
|
29 | ** notice, this list of conditions and the following disclaimer.
|
30 | ** * Redistributions in binary form must reproduce the above copyright
|
31 | ** notice, this list of conditions and the following disclaimer in
|
32 | ** the documentation and/or other materials provided with the
|
33 | ** distribution.
|
34 | ** * Neither the name of The Qt Company Ltd nor the names of its
|
35 | ** contributors may be used to endorse or promote products derived
|
36 | ** from this software without specific prior written permission.
|
37 | **
|
38 | **
|
39 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
40 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
41 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
42 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
43 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
44 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
45 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
46 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
47 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
48 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
49 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
50 | **
|
51 | ** $QT_END_LICENSE$
|
52 | **
|
53 | ****************************************************************************/
|
54 |
|
55 | #include "Highlighter.h"
|
56 |
|
57 | namespace
|
58 | {
|
59 |
|
60 | void createHighlightningRules(QVector<Highlighter::HighlightingRule> &highlightingRules)
|
61 | {
|
62 | if (highlightingRules.empty())
|
63 | {
|
64 | Highlighter::HighlightingRule rule;
|
65 |
|
66 | QTextCharFormat format;
|
67 | format.setForeground(QColor(255, 184, 108));
|
68 | rule.pattern = QRegularExpression(QStringLiteral("::[A-Za-z0-9_]+" ));
|
69 | rule.format = format;
|
70 | highlightingRules.append(rule);
|
71 |
|
72 | format.setForeground(QColor(219, 219, 168));
|
73 | rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Za-z0-9_]+(?=\\()" ));
|
74 | rule.format = format;
|
75 | highlightingRules.append(rule);
|
76 |
|
77 | format.setForeground(QColor(80, 200, 175));
|
78 | rule.pattern = QRegularExpression(QStringLiteral("new \\b[A-Za-z0-9_]+(?=\\()" ));
|
79 | rule.format = format;
|
80 | highlightingRules.append(rule);
|
81 |
|
82 | format.setForeground(QColor(87, 155, 213));
|
83 | const QString keywordPatterns[]
|
84 | = { QStringLiteral("\\bchar\\b" ), QStringLiteral("\\bclass\\b" ), QStringLiteral("\\bconst\\b" ),
|
85 | QStringLiteral("\\bdouble\\b" ), QStringLiteral("\\benum\\b" ), QStringLiteral("\\bexplicit\\b" ),
|
86 | QStringLiteral("\\bfriend\\b" ), QStringLiteral("\\binline\\b" ), QStringLiteral("\\bint\\b" ),
|
87 | QStringLiteral("\\blong\\b" ), QStringLiteral("\\bnamespace\\b" ), QStringLiteral("\\boperator\\b" ),
|
88 | QStringLiteral("\\bprivate\\b" ), QStringLiteral("\\bprotected\\b" ), QStringLiteral("\\bpublic\\b" ),
|
89 | QStringLiteral("\\bshort\\b" ), QStringLiteral("\\bsignals\\b" ), QStringLiteral("\\bsigned\\b" ),
|
90 | QStringLiteral("\\bslots\\b" ), QStringLiteral("\\bstatic\\b" ), QStringLiteral("\\bstruct\\b" ),
|
91 | QStringLiteral("\\btemplate\\b" ), QStringLiteral("\\btypedef\\b" ), QStringLiteral("\\btypename\\b" ),
|
92 | QStringLiteral("\\bunion\\b" ), QStringLiteral("\\bunsigned\\b" ), QStringLiteral("\\bvirtual\\b" ),
|
93 | QStringLiteral("\\bauto\\b" ), QStringLiteral("\\bexplicit\\b" ), QStringLiteral("\\bfinal\\b" ),
|
94 | QStringLiteral("\\bnullptr\\b" ), QStringLiteral("\\boverride\\b" ), QStringLiteral("\\busing\\b" ),
|
95 | QStringLiteral("\\bvoid\\b" ), QStringLiteral("\\bvolatile\\b" ), QStringLiteral("\\bbool\\b" ),
|
96 | QStringLiteral("\\btrue\\b" ), QStringLiteral("\\bfalse\\b" ), QStringLiteral("\\bdelete\\b" ),
|
97 | QStringLiteral("\\bnew\\b" ), QStringLiteral("\\bthis\\b" ) };
|
98 |
|
99 | for (const QString &pattern : keywordPatterns)
|
100 | {
|
101 | rule.pattern = QRegularExpression(pattern);
|
102 | rule.format = format;
|
103 | highlightingRules.append(rule);
|
104 | }
|
105 |
|
106 | format.setForeground(QColor(80, 200, 175));
|
107 | rule.pattern = QRegularExpression(QStringLiteral("\\bQ[A-Za-z]+\\b" ));
|
108 | rule.format = format;
|
109 | highlightingRules.append(rule);
|
110 |
|
111 | format.setForeground(QColor(98, 114, 164));
|
112 | rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*" ));
|
113 | rule.format = format;
|
114 | highlightingRules.append(rule);
|
115 |
|
116 | format.setForeground(QColor(205, 144, 119));
|
117 | rule.pattern = QRegularExpression(QStringLiteral("\".*\"" ));
|
118 | rule.format = format;
|
119 | highlightingRules.append(rule);
|
120 |
|
121 | format.setForeground(QColor(219, 219, 168));
|
122 | rule.pattern = QRegularExpression(QStringLiteral("\\&[A-Za-z0-9_]+::[A-Za-z0-9_]+" ));
|
123 | rule.format = format;
|
124 | highlightingRules.append(rule);
|
125 |
|
126 | format.setForeground(QColor(80, 200, 175));
|
127 | rule.pattern = QRegularExpression(QStringLiteral("\\&?\\b[A-Za-z0-9_]+::" ));
|
128 | rule.format = format;
|
129 | highlightingRules.append(rule);
|
130 |
|
131 | format.setForeground(QColor(205, 144, 119));
|
132 | rule.pattern = QRegularExpression(QStringLiteral("<[A-Za-z0-9_\\.]+>" ));
|
133 | rule.format = format;
|
134 | highlightingRules.append(rule);
|
135 |
|
136 | format.setForeground(QColor(80, 200, 175));
|
137 | rule.pattern = QRegularExpression(QStringLiteral("[A-Za-z0-9_\\.]+<[A-Za-z0-9_\\.]+>" ));
|
138 | rule.format = format;
|
139 | highlightingRules.append(rule);
|
140 |
|
141 | format.setForeground(QColor(195, 133, 191));
|
142 | rule.pattern = QRegularExpression(QStringLiteral("#include" ));
|
143 | rule.format = format;
|
144 | highlightingRules.append(rule);
|
145 |
|
146 | format.setForeground(Qt::white);
|
147 | rule.pattern = QRegularExpression(QStringLiteral("::" ));
|
148 | rule.format = format;
|
149 | highlightingRules.append(rule);
|
150 | }
|
151 | }
|
152 |
|
153 | }
|
154 |
|
155 | QVector<Highlighter::HighlightingRule> Highlighter::highlightingRules;
|
156 |
|
157 | Highlighter::Highlighter(QTextDocument *parent)
|
158 | : QSyntaxHighlighter(parent)
|
159 | {
|
160 | createHighlightningRules(highlightingRules);
|
161 | multiLineCommentFormat.setForeground(QColor(98, 114, 164));
|
162 | commentStartExpression = QRegularExpression(QStringLiteral("/\\*" ));
|
163 | commentEndExpression = QRegularExpression(QStringLiteral("\\*/" ));
|
164 | }
|
165 |
|
166 | void Highlighter::highlightBlock(const QString &text)
|
167 | {
|
168 | for (const HighlightingRule &rule : qAsConst(highlightingRules))
|
169 | {
|
170 | QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
171 | while (matchIterator.hasNext())
|
172 | {
|
173 | QRegularExpressionMatch match = matchIterator.next();
|
174 | setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
175 | }
|
176 | }
|
177 | setCurrentBlockState(0);
|
178 |
|
179 | int startIndex = 0;
|
180 | if (previousBlockState() != 1)
|
181 | startIndex = text.indexOf(commentStartExpression);
|
182 |
|
183 | while (startIndex >= 0)
|
184 | {
|
185 | QRegularExpressionMatch match = commentEndExpression.match(text, startIndex);
|
186 | int endIndex = match.capturedStart();
|
187 | int = 0;
|
188 |
|
189 | if (endIndex == -1)
|
190 | {
|
191 | setCurrentBlockState(1);
|
192 | commentLength = text.length() - startIndex;
|
193 | }
|
194 | else
|
195 | {
|
196 | commentLength = endIndex - startIndex + match.capturedLength();
|
197 | }
|
198 | setFormat(startIndex, commentLength, multiLineCommentFormat);
|
199 | startIndex = text.indexOf(commentStartExpression, startIndex + commentLength);
|
200 | }
|
201 | }
|
202 | |