doc/src/examples/syntaxhighlighter.qdoc
branchRCL_3
changeset 7 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 */