|
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 widgets/codeeditor |
|
44 \title Code Editor Example |
|
45 |
|
46 The Code Editor example shows how to create a simple editor that |
|
47 has line numbers and that highlights the current line. |
|
48 |
|
49 \image codeeditor-example.png |
|
50 |
|
51 As can be seen from the image, the editor displays the line |
|
52 numbers in an area to the left of the area for editing. The editor |
|
53 will highlight the line containing the cursor. |
|
54 |
|
55 We implement the editor in \c CodeEditor, which is a widget that |
|
56 inherits QPlainTextEdit. We keep a separate widget in \c |
|
57 CodeEditor (\c LineNumberArea) onto which we draw the line |
|
58 numbers. |
|
59 |
|
60 QPlainTextEdit inherits from QAbstractScrollArea, and editing |
|
61 takes place within its \l{QAbstractScrollArea::}{viewport()}'s |
|
62 margins. We make room for our line number area by setting the left |
|
63 margin of the viewport to the size we need to draw the line |
|
64 numbers. |
|
65 |
|
66 When it comes to editing code, we prefer QPlainTextEdit over |
|
67 QTextEdit because it is optimized for handling plain text. See |
|
68 the QPlainTextEdit class description for details. |
|
69 |
|
70 QPlainTextEdit lets us add selections in addition to the |
|
71 selection the user can make with the mouse or keyboard. We use |
|
72 this functionality to highlight the current line. More on this |
|
73 later. |
|
74 |
|
75 We will now move on to the definitions and implementations of \c |
|
76 CodeEditor and \c LineNumberArea. Let's start with the \c |
|
77 LineNumberArea class. |
|
78 |
|
79 \section1 The LineNumberArea Class |
|
80 |
|
81 We paint the line numbers on this widget, and place it over the \c |
|
82 CodeEditor's \l{QAbstractScrollArea::}{viewport()}'s left margin |
|
83 area. |
|
84 |
|
85 We need to use protected functions in QPlainTextEdit while |
|
86 painting the area. So to keep things simple, we paint the area in |
|
87 the \c CodeEditor class. The area also asks the editor to |
|
88 calculate its size hint. |
|
89 |
|
90 Note that we could simply paint the line numbers directly on the |
|
91 code editor, and drop the LineNumberArea class. However, the |
|
92 QWidget class helps us to \l{QWidget::}{scroll()} its contents. |
|
93 Also, having a separate widget is the right choice if we wish to |
|
94 extend the editor with breakpoints or other code editor features. |
|
95 The widget would then help in the handling of mouse events. |
|
96 |
|
97 \snippet widgets/codeeditor/codeeditor.h extraarea |
|
98 |
|
99 \section1 CodeEditor Class Definition |
|
100 |
|
101 Here is the code editor's class definition: |
|
102 |
|
103 \snippet widgets/codeeditor/codeeditor.h codeeditordefinition |
|
104 |
|
105 In the editor we resize and draw the line numbers on the \c |
|
106 LineNumberArea. We need to do this when the number of lines in the |
|
107 editor changes, and when the editor's viewport() is scrolled. Of |
|
108 course, it is also done when the editor's size changes. We do |
|
109 this in \c updateLineNumberWidth() and \c updateLineNumberArea(). |
|
110 |
|
111 Whenever, the cursor's position changes, we highlight the current |
|
112 line in \c highlightCurrentLine(). |
|
113 |
|
114 \section1 CodeEditor Class Implementation |
|
115 |
|
116 We will now go through the code editors implementation, starting |
|
117 off with the constructor. |
|
118 |
|
119 \snippet widgets/codeeditor/codeeditor.cpp constructor |
|
120 |
|
121 In the constructor we connect our slots to signals in |
|
122 QPlainTextEdit. It is necessary to calculate the line number area |
|
123 width and highlight the first line when the editor is created. |
|
124 |
|
125 \snippet widgets/codeeditor/codeeditor.cpp extraAreaWidth |
|
126 |
|
127 The \c lineNumberAreaWidth() function calculates the width of the |
|
128 \c LineNumberArea widget. We take the number of digits in the last |
|
129 line of the editor and multiply that with the maximum width of a |
|
130 digit. |
|
131 |
|
132 \snippet widgets/codeeditor/codeeditor.cpp slotUpdateExtraAreaWidth |
|
133 |
|
134 When we update the width of the line number area, we simply call |
|
135 QAbstractScrollArea::setViewportMargins(). |
|
136 |
|
137 \snippet widgets/codeeditor/codeeditor.cpp slotUpdateRequest |
|
138 |
|
139 This slot is invoked when the editors viewport has been scrolled. |
|
140 The QRect given as argument is the part of the editing area that |
|
141 is do be updated (redrawn). \c dy holds the number of pixels the |
|
142 view has been scrolled vertically. |
|
143 |
|
144 \snippet widgets/codeeditor/codeeditor.cpp resizeEvent |
|
145 |
|
146 When the size of the editor changes, we also need to resize the |
|
147 line number area. |
|
148 |
|
149 \snippet widgets/codeeditor/codeeditor.cpp cursorPositionChanged |
|
150 |
|
151 When the cursor position changes, we highlight the current line, |
|
152 i.e., the line containing the cursor. |
|
153 |
|
154 QPlainTextEdit gives the possibility to have more than one |
|
155 selection at the same time. we can set the character format |
|
156 (QTextCharFormat) of these selections. We clear the cursors |
|
157 selection before setting the new new |
|
158 QPlainTextEdit::ExtraSelection, else several lines would get |
|
159 highlighted when the user selects multiple lines with the mouse. |
|
160 \omit ask someone how this works \endomit |
|
161 |
|
162 One sets the selection with a text cursor. When using the |
|
163 FullWidthSelection property, the current cursor text block (line) |
|
164 will be selected. If you want to select just a portion of the text |
|
165 block, the cursor should be moved with QTextCursor::movePosition() |
|
166 from a position set with \l{QTextCursor::}{setPosition()}. |
|
167 |
|
168 \snippet widgets/codeeditor/codeeditor.cpp extraAreaPaintEvent_0 |
|
169 |
|
170 The \c lineNumberAreaPaintEvent() is called from \c LineNumberArea |
|
171 whenever it receives a paint event. We start off by painting the |
|
172 widget's background. |
|
173 |
|
174 \snippet widgets/codeeditor/codeeditor.cpp extraAreaPaintEvent_1 |
|
175 |
|
176 We will now loop through all visible lines and paint the line |
|
177 numbers in the extra area for each line. Notice that in a plain |
|
178 text edit each line will consist of one QTextBlock; though, if |
|
179 line wrapping is enabled, a line may span several rows in the text |
|
180 edit's viewport. |
|
181 |
|
182 We get the top and bottom y-coordinate of the first text block, |
|
183 and adjust these values by the height of the current text block in |
|
184 each iteration in the loop. |
|
185 |
|
186 \snippet widgets/codeeditor/codeeditor.cpp extraAreaPaintEvent_2 |
|
187 |
|
188 Notice that we check if the block is visible in addition to check |
|
189 if it is in the areas viewport - a block can, for example, be |
|
190 hidden by a window placed over the text edit. |
|
191 |
|
192 \section1 Suggestions for Extending the Code Editor |
|
193 |
|
194 No self-respecting code editor is without a syntax |
|
195 highligther; the \l{Syntax Highlighter Example} shows how to |
|
196 create one. |
|
197 |
|
198 In addition to line numbers, you can add more to the extra area, |
|
199 for instance, break points. |
|
200 |
|
201 QSyntaxHighlighter gives the possibility to add user data to each |
|
202 text block with |
|
203 \l{QSyntaxHighlighter::}{setCurrentBlockUserData()}. This can be |
|
204 used to implement parenthesis matching. In the \c |
|
205 highlightCurrentLine(), the data of the currentBlock() can be |
|
206 fetched with QTextBlock::userData(). Matching parentheses can be |
|
207 highlighted with an extra selection. |
|
208 |
|
209 */ |