source: trunk/doc/src/examples/syntaxhighlighter.qdoc@ 244

Last change on this file since 244 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \example richtext/syntaxhighlighter
44 \title Syntax Highlighter Example
45
46 The Syntax Highlighter example shows how to perform simple syntax
47 highlighting by subclassing the QSyntaxHighlighter class.
48
49 \image syntaxhighlighter-example.png
50
51 The Syntax Highlighter application displays C++ files with custom
52 syntax highlighting.
53
54 The example consists of two classes:
55
56 \list
57 \o The \c Highlighter class defines and applies the
58 highlighting rules.
59 \o The \c MainWindow widget is the application's main window.
60 \endlist
61
62 We will first review the \c Highlighter class to see how you can
63 customize the QSyntaxHighlighter class to fit your preferences,
64 then we will take a look at the relevant parts of the \c
65 MainWindow class to see how you can use your custom highlighter
66 class in an application.
67
68 \section1 Highlighter Class Definition
69
70 \snippet examples/richtext/syntaxhighlighter/highlighter.h 0
71
72 To provide your own syntax highlighting, you must subclass
73 QSyntaxHighlighter, reimplement the \l
74 {QSyntaxHighlighter::highlightBlock()}{highlightBlock()} function,
75 and define your own highlighting rules.
76
77 We have chosen to store our highlighting rules using a private
78 struct: A rule consists of a QRegExp pattern and a QTextCharFormat
79 instance. The various rules are then stored using a QVector.
80
81 The QTextCharFormat class provides formatting information for
82 characters in a QTextDocument specifying the visual properties of
83 the text, as well as information about its role in a hypertext
84 document. In this example, we will only define the font weight and
85 color using the QTextCharFormat::setFontWeight() and
86 QTextCharFormat::setForeground() functions.
87
88 \section1 Highlighter Class Implementation
89
90 When subclassing the QSyntaxHighlighter class you must pass the
91 parent parameter to the base class constructor. The parent is the
92 text document upon which the syntax highligning will be
93 applied. In this example, we have also chosen to define our
94 highlighting rules in the constructor:
95
96 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 0
97 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 1
98
99 First we define a keyword rule which recognizes the most common
100 C++ keywords. We give the \c keywordFormat a bold, dark blue
101 font. For each keyword, we assign the keyword and the specified
102 format to a HighlightingRule object and append the object to our
103 list of rules.
104
105 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 2
106 \codeline
107 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 4
108 \codeline
109 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 5
110
111 Then we create a format that we will apply to Qt class names. The
112 class names will be rendered with a dark magenta color and a bold
113 style. We specify a string pattern that is actually a regular
114 expression capturing all Qt class names. Then we assign the
115 regular expression and the specified format to a HighlightingRule
116 object and append the object to our list of rules.
117
118 We also define highlighting rules for quotations and functions
119 using the same approach: The patterns have the form of regular
120 expressions and are stored in HighlightingRule objects with the
121 associated format.
122
123 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 3
124 \codeline
125 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 6
126
127 The C++ language has two variations of comments: The single line
128 comment (\c //) and the multiline comment (\c{/*...}\starslash). The single
129 line comment can easily be defined through a highlighting rule
130 similar to the previous ones. But the multiline comment needs
131 special care due to the design of the QSyntaxHighlighter class.
132
133 After a QSyntaxHighlighter object is created, its \l
134 {QSyntaxHighlighter::highlightBlock()}{highlightBlock()} function
135 will be called automatically whenever it is necessary by the rich
136 text engine, highlighting the given text block. The problem
137 appears when a comment spans several text blocks. We will take a
138 closer look at how this problem can be solved when reviewing the
139 implementation of the \c Highlighter::highlightBlock()
140 function. At this point we only specify the multiline comment's
141 color.
142
143 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 7
144
145 The highlightBlock() function is called automatically whenever it
146 is necessary by the rich text engine, i.e. when there are text
147 blocks that have changed.
148
149 First we apply the syntax highlighting rules that we stored in the
150 \c highlightingRules vector. For each rule (i.e. for each
151 HighlightingRule object) we search for the pattern in the given
152 textblock using the QString::indexOf() function. When the first
153 occurrence of the pattern is found, we use the
154 QRegExp::matchedLength() function to determine the string that
155 will be formatted. QRegExp::matchedLength() returns the length of
156 the last matched string, or -1 if there was no match.
157
158 To perform the actual formatting the QSyntaxHighlighter class
159 provides the \l {QSyntaxHighlighter::setFormat()}{setFormat()}
160 function. This function operates on the text block that is passed
161 as argument to the \c highlightBlock() function. The specified
162 format is applied to the text from the given start position for
163 the given length. The formatting properties set in the given
164 format are merged at display time with the formatting information
165 stored directly in the document. Note that the document itself
166 remains unmodified by the format set through this function.
167
168 This process is repeated until the last occurrence of the pattern
169 in the current text block is found.
170
171 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 8
172
173 To deal with constructs that can span several text blocks (like
174 the C++ multiline comment), it is necessary to know the end state
175 of the previous text block (e.g. "in comment"). Inside your \c
176 highlightBlock() implementation you can query the end state of the
177 previous text block using the
178 QSyntaxHighlighter::previousBlockState() function. After parsing
179 the block you can save the last state using
180 QSyntaxHighlighter::setCurrentBlockState().
181
182 The \l
183 {QSyntaxHighlighter::previousBlockState()}{previousBlockState()}
184 function return an int value. If no state is set, the returned
185 value is -1. You can designate any other value to identify any
186 given state using the \l
187 {QSyntaxHighlighter::setCurrentBlockState()}{setCurrentBlockState()}
188 function. Once the state is set, the QTextBlock keeps that value
189 until it is set again or until the corresponding paragraph of text
190 is deleted.
191
192 In this example we have chosen to use 0 to represent the "not in
193 comment" state, and 1 for the "in comment" state. When the stored
194 syntax highlighting rules are applied we initialize the current
195 block state to 0.
196
197 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 9
198
199 If the previous block state was "in comment" (\c
200 {previousBlockState() == 1}), we start the search for an end
201 expression at the beginning of the text block. If the
202 previousBlockState() returns 0, we start the search at the
203 location of the first occurrence of a start expression.
204
205 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 10
206 \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 11
207
208 When an end expression is found, we calculate the length of the
209 comment and apply the multiline comment format. Then we search for
210 the next occurrence of the start expression and repeat the
211 process. If no end expression can be found in the current text
212 block we set the current block state to 1, i.e. "in comment".
213
214 This completes the \c Highlighter class implementation; it is now
215 ready for use.
216
217 \section1 MainWindow Class Definition
218
219 Using a QSyntaxHighlighter subclass is simple; just provide your
220 application with an instance of the class and pass it the document
221 upon which you want the highlighting to be applied.
222
223 \snippet examples/richtext/syntaxhighlighter/mainwindow.h 0
224
225 In this example we declare a pointer to a \c Highlighter instance
226 which we later will initialize in the private \c setupEditor()
227 function.
228
229 \section1 MainWindow Class Implementation
230
231 The constructor of the main window is straight forward. We first
232 set up the menus, then we initialize the editor and make it the
233 central widget of the application. Finally we set the main
234 window's title.
235
236 \snippet examples/richtext/syntaxhighlighter/mainwindow.cpp 0
237
238 We initialize and install the \c Highlighter object in the private
239 setupEditor() convenience function:
240
241 \snippet examples/richtext/syntaxhighlighter/mainwindow.cpp 1
242
243 First we create the font we want to use in the editor, then we
244 create the editor itself which is an instance of the QTextEdit
245 class. Before we initialize the editor with the \c MainWindow
246 class definition file, we create a \c Highlighter instance passing
247 the editor's document as argument. This is the document that the
248 highlighting will be applied to. Then we are done.
249
250 A QSyntaxHighlighter object can only be installed on one document
251 at the time, but you can easily reinstall the highlighter on
252 another document using the QSyntaxHighlighter::setDocument()
253 function. The QSyntaxHighlighter class also provides the \l
254 {QSyntaxHighlighter::document()}{document()} function which
255 returns the currently set document.
256*/
Note: See TracBrowser for help on using the repository browser.