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

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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