8167137abed65f5f231ea7e76510fae82e859f35
[profile/ivi/qtbase.git] / examples / widgets / doc / src / syntaxhighlighter.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
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 Free Documentation License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Free
19 ** Documentation License version 1.3 as published by the Free Software
20 ** Foundation and appearing in the file included in the packaging of
21 ** this file.  Please review the following information to ensure
22 ** the GNU Free Documentation License version 1.3 requirements
23 ** will be met: http://www.gnu.org/copyleft/fdl.html.
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \example richtext/syntaxhighlighter
30     \title Syntax Highlighter Example
31
32     \brief 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         \li The \c Highlighter class defines and applies the
44            highlighting rules.
45         \li 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 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 richtext/syntaxhighlighter/highlighter.cpp 0
83     \snippet 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 richtext/syntaxhighlighter/highlighter.cpp 2
92     \codeline
93     \snippet richtext/syntaxhighlighter/highlighter.cpp 4
94     \codeline
95     \snippet 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 richtext/syntaxhighlighter/highlighter.cpp 3
110     \codeline
111     \snippet 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{/*...*}\c{/}). 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 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 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 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 richtext/syntaxhighlighter/highlighter.cpp 10
192     \snippet 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 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 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 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
243     \section1 Other Code Editor Features
244
245     It is possible to implement parenthesis matching with
246     QSyntaxHighlighter. The "Matching Parentheses with
247     QSyntaxHighlighter" article in Qt Quarterly 31
248     (\l{http://doc.qt.nokia.com/qq/}) implements this. We also have
249     the \l{Code Editor Example}, which shows how to implement line
250     numbers and how to highlight the current line.
251
252 */