summaryrefslogtreecommitdiff
authorar <ar>2004-06-10 22:34:29 (UTC)
committer ar <ar>2004-06-10 22:34:29 (UTC)
commit82f7b1969f5a5c050d21d9087856c59829495083 (patch) (unidiff)
treeafa525f8540f948973013989b420f64fea199a79
parent292e3738ddaa03a75cb1e515b52597e06cc0ace2 (diff)
downloadopie-82f7b1969f5a5c050d21d9087856c59829495083.zip
opie-82f7b1969f5a5c050d21d9087856c59829495083.tar.gz
opie-82f7b1969f5a5c050d21d9087856c59829495083.tar.bz2
- Fix: 0001167 - not the best solution, but it works.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-write/qtextedit.cpp2469
1 files changed, 1235 insertions, 1234 deletions
diff --git a/noncore/apps/opie-write/qtextedit.cpp b/noncore/apps/opie-write/qtextedit.cpp
index 73b7b7b..bba8a65 100644
--- a/noncore/apps/opie-write/qtextedit.cpp
+++ b/noncore/apps/opie-write/qtextedit.cpp
@@ -1,4575 +1,4576 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of the QTextEdit class 4** Implementation of the QTextEdit class
5** 5**
6** Created : 990101 6** Created : 990101
7** 7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the widgets module of the Qt GUI Toolkit. 10** This file is part of the widgets module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition 21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License 22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software. 23** Agreement provided with the Software.
24** 24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27** 27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements. 29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information. 30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information. 31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32** 32**
33** Contact info@trolltech.com if any conditions of this licensing are 33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37 37
38#include "qtextedit.h" 38#include "qtextedit.h"
39 39
40#include "qrichtext_p.h" 40#include "qrichtext_p.h"
41#include "qlistbox.h" 41#include "qlistbox.h"
42#include "qclipboard.h" 42#include "qclipboard.h"
43#include "qpopupmenu.h" 43#include "qpopupmenu.h"
44 44
45#define ACCEL_KEY(k) "\t" + QString("Ctrl+" #k) 45#define ACCEL_KEY(k) "\t" + QString("Ctrl+" #k)
46 46
47using namespace Qt3; 47using namespace Qt3;
48 48
49static bool qt_enable_richtext_copy = FALSE; 49static bool qt_enable_richtext_copy = FALSE;
50 50
51struct QUndoRedoInfoPrivate 51struct QUndoRedoInfoPrivate
52{ 52{
53 QTextString text; 53 QTextString text;
54}; 54};
55 55
56namespace Qt3 { 56namespace Qt3 {
57 57
58class QTextEditPrivate 58class QTextEditPrivate
59{ 59{
60public: 60public:
61 QTextEditPrivate() 61 QTextEditPrivate()
62 :preeditStart(-1),preeditLength(-1),ensureCursorVisibleInShowEvent(FALSE) 62 :preeditStart(-1),preeditLength(-1),ensureCursorVisibleInShowEvent(FALSE)
63 { 63 {
64 for ( int i=0; i<7; i++ ) 64 for ( int i=0; i<7; i++ )
65 id[i] = 0; 65 id[i] = 0;
66 } 66 }
67 int id[ 7 ]; 67 int id[ 7 ];
68 int preeditStart; 68 int preeditStart;
69 int preeditLength; 69 int preeditLength;
70 bool ensureCursorVisibleInShowEvent; 70 bool ensureCursorVisibleInShowEvent;
71 QString scrollToAnchor; // used to deferr scrollToAnchor() until the show event when we are resized 71 QString scrollToAnchor; // used to deferr scrollToAnchor() until the show event when we are resized
72}; 72};
73 73
74} 74}
75 75
76static bool block_set_alignment = FALSE; 76static bool block_set_alignment = FALSE;
77 77
78/*! 78/*!
79 \class QTextEdit qtextedit.h 79 \class QTextEdit qtextedit.h
80 \brief The QTextEdit widget provides a powerful single-page rich text editor. 80 \brief The QTextEdit widget provides a powerful single-page rich text editor.
81 81
82 \ingroup basic 82 \ingroup basic
83 \ingroup text 83 \ingroup text
84 \mainclass 84 \mainclass
85 85
86 \tableofcontents 86 \tableofcontents
87 87
88 \section1 Introduction and Concepts 88 \section1 Introduction and Concepts
89 89
90 QTextEdit is an advanced WYSIWYG viewer/editor supporting rich 90 QTextEdit is an advanced WYSIWYG viewer/editor supporting rich
91 text formatting using HTML-style tags. It is optimized to handle 91 text formatting using HTML-style tags. It is optimized to handle
92 large documents and to respond quickly to user input. 92 large documents and to respond quickly to user input.
93 93
94 QTextEdit has three modes of operation: 94 QTextEdit has three modes of operation:
95 \table 95 \table
96 \header \i Mode \i Command \i Notes 96 \header \i Mode \i Command \i Notes
97 \row \i Plain Text Editor \i setTextFormat(PlainText) 97 \row \i Plain Text Editor \i setTextFormat(PlainText)
98 \i Set text with setText(); text() returns plain text. Text 98 \i Set text with setText(); text() returns plain text. Text
99 attributes (e.g. colors) can be set, but plain text is always 99 attributes (e.g. colors) can be set, but plain text is always
100 returned.<sup>1.</sup> 100 returned.<sup>1.</sup>
101 \row \i Rich Text Editor \i setTextFormat(RichText) 101 \row \i Rich Text Editor \i setTextFormat(RichText)
102 \i Set text with setText(); text() returns rich text. Rich 102 \i Set text with setText(); text() returns rich text. Rich
103 text editing is fairly limited. You can't set margins or 103 text editing is fairly limited. You can't set margins or
104 insert images for example (although you can read and 104 insert images for example (although you can read and
105 correctly display files that have margins set and that 105 correctly display files that have margins set and that
106 include images). This mode is mostly useful for editing small 106 include images). This mode is mostly useful for editing small
107 amounts of rich text. <sup>2.</sup> 107 amounts of rich text. <sup>2.</sup>
108 \row \i Text Viewer<sup>3.</sup> \i setReadOnly(TRUE) 108 \row \i Text Viewer<sup>3.</sup> \i setReadOnly(TRUE)
109 \i Set text with setText() or append() (which has no undo 109 \i Set text with setText() or append() (which has no undo
110 history so is faster and uses less memory); text() returns 110 history so is faster and uses less memory); text() returns
111 plain or rich text depending on the textFormat(). This mode 111 plain or rich text depending on the textFormat(). This mode
112 can correctly display a large subset of HTML tags. 112 can correctly display a large subset of HTML tags.
113 \endtable 113 \endtable
114 114
115 <sup>1.</sup><small>We do \e not recommend using QTextEdit to 115 <sup>1.</sup><small>We do \e not recommend using QTextEdit to
116 create syntax highlighting editors because the current API is 116 create syntax highlighting editors because the current API is
117 insufficient for this purpose. We hope to release a more complete 117 insufficient for this purpose. We hope to release a more complete
118 API that will support syntax highlighting in a later 118 API that will support syntax highlighting in a later
119 release.</small> 119 release.</small>
120 120
121 <sup>2.</sup><small>A more complete API that supports setting 121 <sup>2.</sup><small>A more complete API that supports setting
122 margins, images, etc., is planned for a later Qt release.</small> 122 margins, images, etc., is planned for a later Qt release.</small>
123 123
124 <sup>3.</sup><small>Qt 3.1 will provide a Log Viewer mode which is 124 <sup>3.</sup><small>Qt 3.1 will provide a Log Viewer mode which is
125 optimised for the fast and memory efficient display of large 125 optimised for the fast and memory efficient display of large
126 amounts of read only text.</small> 126 amounts of read only text.</small>
127 127
128 We recommend that you always call setTextFormat() to set the mode 128 We recommend that you always call setTextFormat() to set the mode
129 you want to use. If you use \c AutoText then setText() and 129 you want to use. If you use \c AutoText then setText() and
130 append() will try to determine whether the text they are given is 130 append() will try to determine whether the text they are given is
131 plain text or rich text. If you use \c RichText then setText() and 131 plain text or rich text. If you use \c RichText then setText() and
132 append() will assume that the text they are given is rich text. 132 append() will assume that the text they are given is rich text.
133 insert() simply inserts the text it is given. 133 insert() simply inserts the text it is given.
134 134
135 QTextEdit works on paragraphs and characters. A paragraph is a 135 QTextEdit works on paragraphs and characters. A paragraph is a
136 formatted string which is word-wrapped to fit into the width of 136 formatted string which is word-wrapped to fit into the width of
137 the widget. By default when reading plain text, two newlines 137 the widget. By default when reading plain text, two newlines
138 signify a paragraph. A document consists of zero or more 138 signify a paragraph. A document consists of zero or more
139 paragraphs, indexed from 0. Characters are indexed on a 139 paragraphs, indexed from 0. Characters are indexed on a
140 per-paragraph basis, also indexed from 0. The words in the 140 per-paragraph basis, also indexed from 0. The words in the
141 paragraph are aligned in accordance with the paragraph's 141 paragraph are aligned in accordance with the paragraph's
142 alignment(). Paragraphs are separated by hard line breaks. Each 142 alignment(). Paragraphs are separated by hard line breaks. Each
143 character within a paragraph has its own attributes, for example, 143 character within a paragraph has its own attributes, for example,
144 font and color. 144 font and color.
145 145
146 The text edit documentation uses the following concepts: 146 The text edit documentation uses the following concepts:
147 \list 147 \list
148 \i \e{current format} -- 148 \i \e{current format} --
149 this is the format at the current cursor position, \e and it 149 this is the format at the current cursor position, \e and it
150 is the format of the selected text if any. 150 is the format of the selected text if any.
151 \i \e{current paragraph} -- the paragraph which contains the 151 \i \e{current paragraph} -- the paragraph which contains the
152 cursor. 152 cursor.
153 \endlist 153 \endlist
154 154
155 QTextEdit can display images (using QMimeSourceFactory), lists and 155 QTextEdit can display images (using QMimeSourceFactory), lists and
156 tables. If the text is too large to view within the text edit's 156 tables. If the text is too large to view within the text edit's
157 viewport, scrollbars will appear. The text edit can load both 157 viewport, scrollbars will appear. The text edit can load both
158 plain text and HTML files (a subset of HTML 3.2 and 4). The 158 plain text and HTML files (a subset of HTML 3.2 and 4). The
159 rendering style and the set of valid tags are defined by a 159 rendering style and the set of valid tags are defined by a
160 styleSheet(). Custom tags can be created and placed in a custom 160 styleSheet(). Custom tags can be created and placed in a custom
161 style sheet. Change the style sheet with \l{setStyleSheet()}; see 161 style sheet. Change the style sheet with \l{setStyleSheet()}; see
162 QStyleSheet for details. The images identified by image tags are 162 QStyleSheet for details. The images identified by image tags are
163 displayed if they can be interpreted using the text edit's 163 displayed if they can be interpreted using the text edit's
164 \l{QMimeSourceFactory}; see setMimeSourceFactory(). 164 \l{QMimeSourceFactory}; see setMimeSourceFactory().
165 165
166 If you want a text browser with more navigation use QTextBrowser. 166 If you want a text browser with more navigation use QTextBrowser.
167 If you just need to display a small piece of rich text use QLabel 167 If you just need to display a small piece of rich text use QLabel
168 or QSimpleRichText. 168 or QSimpleRichText.
169 169
170 If you create a new QTextEdit, and want to allow the user to edit 170 If you create a new QTextEdit, and want to allow the user to edit
171 rich text, call setTextFormat(Qt::RichText) to ensure that the 171 rich text, call setTextFormat(Qt::RichText) to ensure that the
172 text is treated as rich text. (Rich text uses HTML tags to set 172 text is treated as rich text. (Rich text uses HTML tags to set
173 text formatting attributes. See QStyleSheet for information on the 173 text formatting attributes. See QStyleSheet for information on the
174 HTML tags that are supported.). If you don't call setTextFormat() 174 HTML tags that are supported.). If you don't call setTextFormat()
175 explicitly the text edit will guess from the text itself whether 175 explicitly the text edit will guess from the text itself whether
176 it is rich text or plain text. This means that if the text looks 176 it is rich text or plain text. This means that if the text looks
177 like HTML or XML it will probably be interpreted as rich text, so 177 like HTML or XML it will probably be interpreted as rich text, so
178 you should call setTextFormat(Qt::PlainText) to preserve such 178 you should call setTextFormat(Qt::PlainText) to preserve such
179 text. 179 text.
180 180
181 Note that we do not intend to add a full-featured web browser 181 Note that we do not intend to add a full-featured web browser
182 widget to Qt (because that would easily double Qt's size and only 182 widget to Qt (because that would easily double Qt's size and only
183 a few applications would benefit from it). The rich 183 a few applications would benefit from it). The rich
184 text support in Qt is designed to provide a fast, portable and 184 text support in Qt is designed to provide a fast, portable and
185 efficient way to add reasonable online help facilities to 185 efficient way to add reasonable online help facilities to
186 applications, and to provide a basis for rich text editors. 186 applications, and to provide a basis for rich text editors.
187 \section1 Using QTextEdit as a Display Widget 187 \section1 Using QTextEdit as a Display Widget
188 188
189 QTextEdit can display a large HTML subset, including tables and 189 QTextEdit can display a large HTML subset, including tables and
190 images. 190 images.
191 191
192 The text is set or replaced using setText() which deletes any 192 The text is set or replaced using setText() which deletes any
193 existing text and replaces it with the text passed in the 193 existing text and replaces it with the text passed in the
194 setText() call. If you call setText() with legacy HTML (with 194 setText() call. If you call setText() with legacy HTML (with
195 setTextFormat(RichText) in force), and then call text(), the text 195 setTextFormat(RichText) in force), and then call text(), the text
196 that is returned may have different markup, but will render the 196 that is returned may have different markup, but will render the
197 same. Text can be inserted with insert(), paste(), pasteSubType() 197 same. Text can be inserted with insert(), paste(), pasteSubType()
198 and append(). Text that is appended does not go into the undo 198 and append(). Text that is appended does not go into the undo
199 history; this makes append() faster and consumes less memory. Text 199 history; this makes append() faster and consumes less memory. Text
200 can also be cut(). The entire text is deleted with clear() and the 200 can also be cut(). The entire text is deleted with clear() and the
201 selected text is deleted with removeSelectedText(). Selected 201 selected text is deleted with removeSelectedText(). Selected
202 (marked) text can also be deleted with del() (which will delete 202 (marked) text can also be deleted with del() (which will delete
203 the character to the right of the cursor if no text is selected). 203 the character to the right of the cursor if no text is selected).
204 204
205 Loading and saving text is achieved using setText() and text(), 205 Loading and saving text is achieved using setText() and text(),
206 for example: 206 for example:
207 \code 207 \code
208 QFile file( fileName ); // Read the text from a file 208 QFile file( fileName ); // Read the text from a file
209 if ( file.open( IO_ReadOnly ) ) { 209 if ( file.open( IO_ReadOnly ) ) {
210 QTextStream ts( &file ); 210 QTextStream ts( &file );
211 textEdit->setText( ts.read() ); 211 textEdit->setText( ts.read() );
212 } 212 }
213 \endcode 213 \endcode
214 \code 214 \code
215 QFile file( fileName ); // Write the text to a file 215 QFile file( fileName ); // Write the text to a file
216 if ( file.open( IO_WriteOnly ) ) { 216 if ( file.open( IO_WriteOnly ) ) {
217 QTextStream ts( &file ); 217 QTextStream ts( &file );
218 ts << textEdit->text(); 218 ts << textEdit->text();
219 textEdit->setModified( FALSE ); 219 textEdit->setModified( FALSE );
220 } 220 }
221 \endcode 221 \endcode
222 222
223 By default the text edit wraps words at whitespace to fit within 223 By default the text edit wraps words at whitespace to fit within
224 the text edit widget. The setWordWrap() function is used to 224 the text edit widget. The setWordWrap() function is used to
225 specify the kind of word wrap you want, or \c NoWrap if you don't 225 specify the kind of word wrap you want, or \c NoWrap if you don't
226 want any wrapping. Call setWordWrap() to set a fixed pixel width 226 want any wrapping. Call setWordWrap() to set a fixed pixel width
227 \c FixedPixelWidth, or character column (e.g. 80 column) \c 227 \c FixedPixelWidth, or character column (e.g. 80 column) \c
228 FixedColumnWidth with the pixels or columns specified with 228 FixedColumnWidth with the pixels or columns specified with
229 setWrapColumnOrWidth(). If you use word wrap to the widget's width 229 setWrapColumnOrWidth(). If you use word wrap to the widget's width
230 \c WidgetWidth, you can specify whether to break on whitespace or 230 \c WidgetWidth, you can specify whether to break on whitespace or
231 anywhere with setWrapPolicy(). 231 anywhere with setWrapPolicy().
232 232
233 The background color is set differently than other widgets, using 233 The background color is set differently than other widgets, using
234 setPaper(). You specify a brush style which could be a plain color 234 setPaper(). You specify a brush style which could be a plain color
235 or a complex pixmap. 235 or a complex pixmap.
236 236
237 Hypertext links are automatically underlined; this can be changed 237 Hypertext links are automatically underlined; this can be changed
238 with setLinkUnderline(). The tab stop width is set with 238 with setLinkUnderline(). The tab stop width is set with
239 setTabStopWidth(). 239 setTabStopWidth().
240 240
241 The zoomIn() and zoomOut() functions can be used to resize the 241 The zoomIn() and zoomOut() functions can be used to resize the
242 text by increasing (decreasing for zoomOut()) the point size used. 242 text by increasing (decreasing for zoomOut()) the point size used.
243 Images are not affected by the zoom functions. 243 Images are not affected by the zoom functions.
244 244
245 The lines() function returns the number of lines in the text and 245 The lines() function returns the number of lines in the text and
246 paragraphs() returns the number of paragraphs. The number of lines 246 paragraphs() returns the number of paragraphs. The number of lines
247 within a particular paragraph is returned by linesOfParagraph(). 247 within a particular paragraph is returned by linesOfParagraph().
248 The length of the entire text in characters is returned by 248 The length of the entire text in characters is returned by
249 length(). 249 length().
250 250
251 You can scroll to an anchor in the text, e.g. \c{<a 251 You can scroll to an anchor in the text, e.g. \c{<a
252 name="anchor">} with scrollToAnchor(). The find() function can be 252 name="anchor">} with scrollToAnchor(). The find() function can be
253 used to find and select a given string within the text. 253 used to find and select a given string within the text.
254 254
255 A read-only QTextEdit provides the same functionality as the 255 A read-only QTextEdit provides the same functionality as the
256 (obsolete) QTextView. (QTextView is still supplied for 256 (obsolete) QTextView. (QTextView is still supplied for
257 compatibility with old code.) 257 compatibility with old code.)
258 258
259 \section2 Read-only key bindings 259 \section2 Read-only key bindings
260 260
261 When QTextEdit is used read-only the key-bindings are limited to 261 When QTextEdit is used read-only the key-bindings are limited to
262 navigation, and text may only be selected with the mouse: 262 navigation, and text may only be selected with the mouse:
263 \table 263 \table
264 \header \i Keypresses \i Action 264 \header \i Keypresses \i Action
265 \row \i \e{UpArrow} \i Move one line up 265 \row \i \e{UpArrow} \i Move one line up
266 \row \i \e{DownArrow} \i Move one line down 266 \row \i \e{DownArrow} \i Move one line down
267 \row \i \e{LeftArrow} \i Move one character left 267 \row \i \e{LeftArrow} \i Move one character left
268 \row \i \e{RightArrow} \i Move one character right 268 \row \i \e{RightArrow} \i Move one character right
269 \row \i \e{PageUp} \i Move one (viewport) page up 269 \row \i \e{PageUp} \i Move one (viewport) page up
270 \row \i \e{PageDown} \i Move one (viewport) page down 270 \row \i \e{PageDown} \i Move one (viewport) page down
271 \row \i \e{Home} \i Move to the beginning of the text 271 \row \i \e{Home} \i Move to the beginning of the text
272 \row \i \e{End} \i Move to the end of the text 272 \row \i \e{End} \i Move to the end of the text
273 \row \i \e{Shift+Wheel} \i Scroll the page horizontally (the Wheel is the mouse wheel) 273 \row \i \e{Shift+Wheel} \i Scroll the page horizontally (the Wheel is the mouse wheel)
274 \row \i \e{Ctrl+Wheel} \i Zoom the text 274 \row \i \e{Ctrl+Wheel} \i Zoom the text
275 \endtable 275 \endtable
276 276
277 The text edit may be able to provide some meta-information. For 277 The text edit may be able to provide some meta-information. For
278 example, the documentTitle() function will return the text from 278 example, the documentTitle() function will return the text from
279 within HTML \c{<title>} tags. 279 within HTML \c{<title>} tags.
280 280
281 The text displayed in a text edit has a \e context. The context is 281 The text displayed in a text edit has a \e context. The context is
282 a path which the text edit's QMimeSourceFactory uses to resolve 282 a path which the text edit's QMimeSourceFactory uses to resolve
283 the locations of files and images. It is passed to the 283 the locations of files and images. It is passed to the
284 mimeSourceFactory() when quering data. (See QTextEdit() and 284 mimeSourceFactory() when quering data. (See QTextEdit() and
285 \l{context()}.) 285 \l{context()}.)
286 286
287 \section1 Using QTextEdit as an Editor 287 \section1 Using QTextEdit as an Editor
288 288
289 All the information about using QTextEdit as a display widget also 289 All the information about using QTextEdit as a display widget also
290 applies here. 290 applies here.
291 291
292 The current format's attributes are set with setItalic(), 292 The current format's attributes are set with setItalic(),
293 setBold(), setUnderline(), setFamily() (font family), 293 setBold(), setUnderline(), setFamily() (font family),
294 setPointSize(), setColor() and setCurrentFont(). The current 294 setPointSize(), setColor() and setCurrentFont(). The current
295 paragraph's alignment is set with setAlignment(). 295 paragraph's alignment is set with setAlignment().
296 296
297 Use setSelection() to select text. The setSelectionAttributes() 297 Use setSelection() to select text. The setSelectionAttributes()
298 function is used to indicate how selected text should be 298 function is used to indicate how selected text should be
299 displayed. Use hasSelectedText() to find out if any text is 299 displayed. Use hasSelectedText() to find out if any text is
300 selected. The currently selected text's position is available 300 selected. The currently selected text's position is available
301 using getSelection() and the selected text itself is returned by 301 using getSelection() and the selected text itself is returned by
302 selectedText(). The selection can be copied to the clipboard with 302 selectedText(). The selection can be copied to the clipboard with
303 copy(), or cut to the clipboard with cut(). It can be deleted with 303 copy(), or cut to the clipboard with cut(). It can be deleted with
304 removeSelectedText(). The entire text can be selected (or 304 removeSelectedText(). The entire text can be selected (or
305 unselected) using selectAll(). QTextEdit supports multiple 305 unselected) using selectAll(). QTextEdit supports multiple
306 selections. Most of the selection functions operate on the default 306 selections. Most of the selection functions operate on the default
307 selection, selection 0. If the user presses a non-selecting key, 307 selection, selection 0. If the user presses a non-selecting key,
308 e.g. a cursor key without also holding down Shift, all selections 308 e.g. a cursor key without also holding down Shift, all selections
309 are cleared. 309 are cleared.
310 310
311 Set and get the position of the cursor with setCursorPosition() 311 Set and get the position of the cursor with setCursorPosition()
312 and getCursorPosition() respectively. When the cursor is moved, 312 and getCursorPosition() respectively. When the cursor is moved,
313 the signals currentFontChanged(), currentColorChanged() and 313 the signals currentFontChanged(), currentColorChanged() and
314 currentAlignmentChanged() are emitted to reflect the font, color 314 currentAlignmentChanged() are emitted to reflect the font, color
315 and alignment at the new cursor position. 315 and alignment at the new cursor position.
316 316
317 If the text changes, the textChanged() signal is emitted, and if 317 If the text changes, the textChanged() signal is emitted, and if
318 the user inserts a new line by pressing Return or Enter, 318 the user inserts a new line by pressing Return or Enter,
319 returnPressed() is emitted. The isModified() function will return 319 returnPressed() is emitted. The isModified() function will return
320 TRUE if the text has been modified. 320 TRUE if the text has been modified.
321 321
322 QTextEdit provides command-based undo and redo. To set the depth 322 QTextEdit provides command-based undo and redo. To set the depth
323 of the command history use setUndoDepth() which defaults to 100 323 of the command history use setUndoDepth() which defaults to 100
324 steps. To undo or redo the last operation call undo() or redo(). 324 steps. To undo or redo the last operation call undo() or redo().
325 The signals undoAvailable() and redoAvailable() indicate whether 325 The signals undoAvailable() and redoAvailable() indicate whether
326 the undo and redo operations can be executed. 326 the undo and redo operations can be executed.
327 327
328 The indent() function is used to reindent a paragraph. It is 328 The indent() function is used to reindent a paragraph. It is
329 useful for code editors, for example in <em>Qt Designer</em>'s 329 useful for code editors, for example in <em>Qt Designer</em>'s
330 code editor \e{Ctrl+I} invokes the indent() function. 330 code editor \e{Ctrl+I} invokes the indent() function.
331 331
332 \section2 Editing key bindings 332 \section2 Editing key bindings
333 333
334 The list of key-bindings which are implemented for editing: 334 The list of key-bindings which are implemented for editing:
335 \table 335 \table
336 \header \i Keypresses \i Action 336 \header \i Keypresses \i Action
337 \row \i \e{Backspace} \i Delete the character to the left of the cursor 337 \row \i \e{Backspace} \i Delete the character to the left of the cursor
338 \row \i \e{Delete} \i Delete the character to the right of the cursor 338 \row \i \e{Delete} \i Delete the character to the right of the cursor
339 \row \i \e{Ctrl+A} \i Move the cursor to the beginning of the line 339 \row \i \e{Ctrl+A} \i Move the cursor to the beginning of the line
340 \row \i \e{Ctrl+B} \i Move the cursor one character left 340 \row \i \e{Ctrl+B} \i Move the cursor one character left
341 \row \i \e{Ctrl+C} \i Copy the marked text to the clipboard (also 341 \row \i \e{Ctrl+C} \i Copy the marked text to the clipboard (also
342 \e{Ctrl+Insert} under Windows) 342 \e{Ctrl+Insert} under Windows)
343 \row \i \e{Ctrl+D} \i Delete the character to the right of the cursor 343 \row \i \e{Ctrl+D} \i Delete the character to the right of the cursor
344 \row \i \e{Ctrl+E} \i Move the cursor to the end of the line 344 \row \i \e{Ctrl+E} \i Move the cursor to the end of the line
345 \row \i \e{Ctrl+F} \i Move the cursor one character right 345 \row \i \e{Ctrl+F} \i Move the cursor one character right
346 \row \i \e{Ctrl+H} \i Delete the character to the left of the cursor 346 \row \i \e{Ctrl+H} \i Delete the character to the left of the cursor
347 \row \i \e{Ctrl+K} \i Delete to end of line 347 \row \i \e{Ctrl+K} \i Delete to end of line
348 \row \i \e{Ctrl+N} \i Move the cursor one line down 348 \row \i \e{Ctrl+N} \i Move the cursor one line down
349 \row \i \e{Ctrl+P} \i Move the cursor one line up 349 \row \i \e{Ctrl+P} \i Move the cursor one line up
350 \row \i \e{Ctrl+V} \i Paste the clipboard text into line edit 350 \row \i \e{Ctrl+V} \i Paste the clipboard text into line edit
351 (also \e{Shift+Insert} under Windows) 351 (also \e{Shift+Insert} under Windows)
352 \row \i \e{Ctrl+X} \i Cut the marked text, copy to clipboard 352 \row \i \e{Ctrl+X} \i Cut the marked text, copy to clipboard
353 (also \e{Shift+Delete} under Windows) 353 (also \e{Shift+Delete} under Windows)
354 \row \i \e{Ctrl+Z} \i Undo the last operation 354 \row \i \e{Ctrl+Z} \i Undo the last operation
355 \row \i \e{Ctrl+Y} \i Redo the last operation 355 \row \i \e{Ctrl+Y} \i Redo the last operation
356 \row \i \e{LeftArrow} \i Move the cursor one character left 356 \row \i \e{LeftArrow} \i Move the cursor one character left
357 \row \i \e{Ctrl+LeftArrow} \i Move the cursor one word left 357 \row \i \e{Ctrl+LeftArrow} \i Move the cursor one word left
358 \row \i \e{RightArrow} \i Move the cursor one character right 358 \row \i \e{RightArrow} \i Move the cursor one character right
359 \row \i \e{Ctrl+RightArrow} \i Move the cursor one word right 359 \row \i \e{Ctrl+RightArrow} \i Move the cursor one word right
360 \row \i \e{UpArrow} \i Move the cursor one line up 360 \row \i \e{UpArrow} \i Move the cursor one line up
361 \row \i \e{Ctrl+UpArrow} \i Move the cursor one word up 361 \row \i \e{Ctrl+UpArrow} \i Move the cursor one word up
362 \row \i \e{DownArrow} \i Move the cursor one line down 362 \row \i \e{DownArrow} \i Move the cursor one line down
363 \row \i \e{Ctrl+Down Arrow} \i Move the cursor one word down 363 \row \i \e{Ctrl+Down Arrow} \i Move the cursor one word down
364 \row \i \e{PageUp} \i Move the cursor one page up 364 \row \i \e{PageUp} \i Move the cursor one page up
365 \row \i \e{PageDown} \i Move the cursor one page down 365 \row \i \e{PageDown} \i Move the cursor one page down
366 \row \i \e{Home} \i Move the cursor to the beginning of the line 366 \row \i \e{Home} \i Move the cursor to the beginning of the line
367 \row \i \e{Ctrl+Home} \i Move the cursor to the beginning of the text 367 \row \i \e{Ctrl+Home} \i Move the cursor to the beginning of the text
368 \row \i \e{End} \i Move the cursor to the end of the line 368 \row \i \e{End} \i Move the cursor to the end of the line
369 \row \i \e{Ctrl+End} \i Move the cursor to the end of the text 369 \row \i \e{Ctrl+End} \i Move the cursor to the end of the text
370 \row \i \e{Shift+Wheel} \i Scroll the page horizontally 370 \row \i \e{Shift+Wheel} \i Scroll the page horizontally
371 (the Wheel is the mouse wheel) 371 (the Wheel is the mouse wheel)
372 \row \i \e{Ctrl+Wheel} \i Zoom the text 372 \row \i \e{Ctrl+Wheel} \i Zoom the text
373 \endtable 373 \endtable
374 374
375 To select (mark) text hold down the Shift key whilst pressing one 375 To select (mark) text hold down the Shift key whilst pressing one
376 of the movement keystrokes, for example, <i>Shift+Right Arrow</i> 376 of the movement keystrokes, for example, <i>Shift+Right Arrow</i>
377 will select the character to the right, and <i>Shift+Ctrl+Right 377 will select the character to the right, and <i>Shift+Ctrl+Right
378 Arrow</i> will select the word to the right, etc. 378 Arrow</i> will select the word to the right, etc.
379 379
380 By default the text edit widget operates in insert mode so all 380 By default the text edit widget operates in insert mode so all
381 text that the user enters is inserted into the text edit and any 381 text that the user enters is inserted into the text edit and any
382 text to the right of the cursor is moved out of the way. The mode 382 text to the right of the cursor is moved out of the way. The mode
383 can be changed to overwrite, where new text overwrites any text to 383 can be changed to overwrite, where new text overwrites any text to
384 the right of the cursor, using setOverwriteMode(). 384 the right of the cursor, using setOverwriteMode().
385 385
386*/ 386*/
387 387
388/*! \enum QTextEdit::KeyboardAction 388/*! \enum QTextEdit::KeyboardAction
389 389
390 This enum is used by doKeyboardAction() to specify which action 390 This enum is used by doKeyboardAction() to specify which action
391 should be executed: 391 should be executed:
392 392
393 \value ActionBackspace Delete the character to the left of the 393 \value ActionBackspace Delete the character to the left of the
394 cursor. 394 cursor.
395 395
396 \value ActionDelete Delete the character to the right of the cursor. 396 \value ActionDelete Delete the character to the right of the cursor.
397 397
398 \value ActionReturn Split the paragraph at the cursor position. 398 \value ActionReturn Split the paragraph at the cursor position.
399 399
400 \value ActionKill If the cursor is not at the end of the paragraph, 400 \value ActionKill If the cursor is not at the end of the paragraph,
401 delete the text from the cursor position until the end of the 401 delete the text from the cursor position until the end of the
402 paragraph. If the cursor is at the end of the paragraph, delete the 402 paragraph. If the cursor is at the end of the paragraph, delete the
403 hard line break at the end of the paragraph - this will cause this 403 hard line break at the end of the paragraph - this will cause this
404 paragraph to be joined with the following paragraph. 404 paragraph to be joined with the following paragraph.
405*/ 405*/
406 406
407/*! \enum QTextEdit::VerticalAlignment 407/*! \enum QTextEdit::VerticalAlignment
408 408
409 This enum is used to set the vertical alignment of the text. 409 This enum is used to set the vertical alignment of the text.
410 410
411 \value AlignNormal Normal alignment 411 \value AlignNormal Normal alignment
412 \value AlignSuperScript Superscript 412 \value AlignSuperScript Superscript
413 \value AlignSubScript Subscript 413 \value AlignSubScript Subscript
414*/ 414*/
415 415
416/*! \fn void QTextEdit::copyAvailable (bool yes) 416/*! \fn void QTextEdit::copyAvailable (bool yes)
417 417
418 This signal is emitted when text is selected or de-selected in the text 418 This signal is emitted when text is selected or de-selected in the text
419 edit. 419 edit.
420 420
421 When text is selected this signal will be emitted with \a yes set to 421 When text is selected this signal will be emitted with \a yes set to
422 TRUE. If no text has been selected or if the selected text is 422 TRUE. If no text has been selected or if the selected text is
423 de-selected this signal is emitted with \a yes set to FALSE. 423 de-selected this signal is emitted with \a yes set to FALSE.
424 424
425 If \a yes is TRUE then copy() can be used to copy the selection to the 425 If \a yes is TRUE then copy() can be used to copy the selection to the
426 clipboard. If \a yes is FALSE then copy() does nothing. 426 clipboard. If \a yes is FALSE then copy() does nothing.
427 427
428 \sa selectionChanged() 428 \sa selectionChanged()
429*/ 429*/
430 430
431 431
432/*! \fn void QTextEdit::textChanged() 432/*! \fn void QTextEdit::textChanged()
433 433
434 This signal is emitted whenever the text in the text edit changes. 434 This signal is emitted whenever the text in the text edit changes.
435 435
436 \sa setText() append() 436 \sa setText() append()
437 */ 437 */
438 438
439/*! \fn void QTextEdit::selectionChanged() 439/*! \fn void QTextEdit::selectionChanged()
440 440
441 This signal is emitted whenever the selection changes. 441 This signal is emitted whenever the selection changes.
442 442
443 \sa setSelection() copyAvailable() 443 \sa setSelection() copyAvailable()
444*/ 444*/
445 445
446/*! \fn QTextDocument *QTextEdit::document() const 446/*! \fn QTextDocument *QTextEdit::document() const
447 447
448 \internal 448 \internal
449 449
450 This function returns the QTextDocument which is used by the text 450 This function returns the QTextDocument which is used by the text
451 edit. 451 edit.
452*/ 452*/
453 453
454/*! \fn void QTextEdit::setDocument( QTextDocument *doc ) 454/*! \fn void QTextEdit::setDocument( QTextDocument *doc )
455 455
456 \internal 456 \internal
457 457
458 This function sets the QTextDocument which should be used by the text 458 This function sets the QTextDocument which should be used by the text
459 edit to \a doc. This can be used, for example, if you want to 459 edit to \a doc. This can be used, for example, if you want to
460 display a document using multiple views. You would create a 460 display a document using multiple views. You would create a
461 QTextDocument and set it to the text edits which should display it. 461 QTextDocument and set it to the text edits which should display it.
462 You would need to connect to the textChanged() and 462 You would need to connect to the textChanged() and
463 selectionChanged() signals of all the text edits and update them all 463 selectionChanged() signals of all the text edits and update them all
464 accordingly (preferably with a slight delay for efficiency reasons). 464 accordingly (preferably with a slight delay for efficiency reasons).
465*/ 465*/
466 466
467/*! \enum QTextEdit::CursorAction 467/*! \enum QTextEdit::CursorAction
468 468
469 This enum is used by moveCursor() to specify in which direction 469 This enum is used by moveCursor() to specify in which direction
470 the cursor should be moved: 470 the cursor should be moved:
471 471
472 \value MoveBackward Moves the cursor one character backward 472 \value MoveBackward Moves the cursor one character backward
473 473
474 \value MoveWordBackward Moves the cursor one word backward 474 \value MoveWordBackward Moves the cursor one word backward
475 475
476 \value MoveForward Moves the cursor one character forward 476 \value MoveForward Moves the cursor one character forward
477 477
478 \value MoveWordForward Moves the cursor one word forward 478 \value MoveWordForward Moves the cursor one word forward
479 479
480 \value MoveUp Moves the cursor up one line 480 \value MoveUp Moves the cursor up one line
481 481
482 \value MoveDown Moves the cursor down one line 482 \value MoveDown Moves the cursor down one line
483 483
484 \value MoveLineStart Moves the cursor to the beginning of the line 484 \value MoveLineStart Moves the cursor to the beginning of the line
485 485
486 \value MoveLineEnd Moves the cursor to the end of the line 486 \value MoveLineEnd Moves the cursor to the end of the line
487 487
488 \value MoveHome Moves the cursor to the beginning of the document 488 \value MoveHome Moves the cursor to the beginning of the document
489 489
490 \value MoveEnd Moves the cursor to the end of the document 490 \value MoveEnd Moves the cursor to the end of the document
491 491
492 \value MovePgUp Moves the cursor one page up 492 \value MovePgUp Moves the cursor one page up
493 493
494 \value MovePgDown Moves the cursor one page down 494 \value MovePgDown Moves the cursor one page down
495*/ 495*/
496 496
497 497
498/*! 498/*!
499 \property QTextEdit::overwriteMode 499 \property QTextEdit::overwriteMode
500 \brief the text edit's overwrite mode 500 \brief the text edit's overwrite mode
501 501
502 If FALSE (the default) characters entered by the user are inserted 502 If FALSE (the default) characters entered by the user are inserted
503 with any characters to the right being moved out of the way. 503 with any characters to the right being moved out of the way.
504 If TRUE, the editor is in overwrite mode, i.e. characters entered by 504 If TRUE, the editor is in overwrite mode, i.e. characters entered by
505 the user overwrite any characters to the right of the cursor position. 505 the user overwrite any characters to the right of the cursor position.
506*/ 506*/
507 507
508/*! \fn void QTextEdit::setCurrentFont( const QFont &f ) 508/*! \fn void QTextEdit::setCurrentFont( const QFont &f )
509 509
510 Sets the font of the current format to \a f. 510 Sets the font of the current format to \a f.
511 511
512 \sa font() setPointSize() setFamily() 512 \sa font() setPointSize() setFamily()
513*/ 513*/
514 514
515/*! 515/*!
516 \property QTextEdit::undoDepth 516 \property QTextEdit::undoDepth
517 \brief the depth of the undo history 517 \brief the depth of the undo history
518 518
519 The maximum number of steps in the undo/redo history. 519 The maximum number of steps in the undo/redo history.
520 The default is 100. 520 The default is 100.
521 521
522 \sa undo() redo() 522 \sa undo() redo()
523*/ 523*/
524 524
525/*! \fn void QTextEdit::undoAvailable( bool yes ) 525/*! \fn void QTextEdit::undoAvailable( bool yes )
526 526
527 This signal is emitted when the availability of undo changes. If \a 527 This signal is emitted when the availability of undo changes. If \a
528 yes is TRUE, then undo() will work until undoAvailable( FALSE ) is 528 yes is TRUE, then undo() will work until undoAvailable( FALSE ) is
529 next emitted. 529 next emitted.
530 530
531 \sa undo() undoDepth() 531 \sa undo() undoDepth()
532*/ 532*/
533 533
534/*! \fn void QTextEdit::modificationChanged( bool m ) 534/*! \fn void QTextEdit::modificationChanged( bool m )
535 535
536 This signal is emitted when the modification of the document 536 This signal is emitted when the modification of the document
537 changed. If \a m is TRUE, the document was modified, otherwise the 537 changed. If \a m is TRUE, the document was modified, otherwise the
538 modification state has been reset to unmodified. 538 modification state has been reset to unmodified.
539 539
540 \sa modified 540 \sa modified
541*/ 541*/
542 542
543/*! \fn void QTextEdit::redoAvailable( bool yes ) 543/*! \fn void QTextEdit::redoAvailable( bool yes )
544 544
545 This signal is emitted when the availability of redo changes. If \a 545 This signal is emitted when the availability of redo changes. If \a
546 yes is TRUE, then redo() will work until redoAvailable( FALSE ) is 546 yes is TRUE, then redo() will work until redoAvailable( FALSE ) is
547 next emitted. 547 next emitted.
548 548
549 \sa redo() undoDepth() 549 \sa redo() undoDepth()
550*/ 550*/
551 551
552/*! \fn void QTextEdit::currentFontChanged( const QFont &f ) 552/*! \fn void QTextEdit::currentFontChanged( const QFont &f )
553 553
554 This signal is emitted if the font of the current format has changed. 554 This signal is emitted if the font of the current format has changed.
555 555
556 The new font is \a f. 556 The new font is \a f.
557 557
558 \sa setCurrentFont() 558 \sa setCurrentFont()
559*/ 559*/
560 560
561/*! \fn void QTextEdit::currentColorChanged( const QColor &c ) 561/*! \fn void QTextEdit::currentColorChanged( const QColor &c )
562 562
563 This signal is emitted if the color of the current format has changed. 563 This signal is emitted if the color of the current format has changed.
564 564
565 The new color is \a c. 565 The new color is \a c.
566 566
567 \sa setColor() 567 \sa setColor()
568*/ 568*/
569 569
570/*! \fn void QTextEdit::currentVerticalAlignmentChanged( VerticalAlignment a ) 570/*! \fn void QTextEdit::currentVerticalAlignmentChanged( VerticalAlignment a )
571 571
572 This signal is emitted if the vertical alignment of the current 572 This signal is emitted if the vertical alignment of the current
573 format has changed. 573 format has changed.
574 574
575 The new vertical alignment is \a a. 575 The new vertical alignment is \a a.
576 576
577 \sa setVerticalAlignment() 577 \sa setVerticalAlignment()
578*/ 578*/
579 579
580/*! \fn void QTextEdit::currentAlignmentChanged( int a ) 580/*! \fn void QTextEdit::currentAlignmentChanged( int a )
581 581
582 This signal is emitted if the alignment of the current paragraph 582 This signal is emitted if the alignment of the current paragraph
583 has changed. 583 has changed.
584 584
585 The new alignment is \a a. 585 The new alignment is \a a.
586 586
587 \sa setAlignment() 587 \sa setAlignment()
588*/ 588*/
589 589
590/*! \fn void QTextEdit::cursorPositionChanged( QTextCursor *c ) 590/*! \fn void QTextEdit::cursorPositionChanged( QTextCursor *c )
591 591
592 This signal is emitted if the position of the cursor changed. \a c 592 This signal is emitted if the position of the cursor changed. \a c
593 points to the text cursor object. 593 points to the text cursor object.
594 594
595 \sa setCursorPosition() 595 \sa setCursorPosition()
596*/ 596*/
597 597
598/*! \overload void QTextEdit::cursorPositionChanged( int para, int pos ) 598/*! \overload void QTextEdit::cursorPositionChanged( int para, int pos )
599 599
600 This signal is emitted if the position of the cursor changed. \a 600 This signal is emitted if the position of the cursor changed. \a
601 para contains the paragraph index and \a pos contains the character 601 para contains the paragraph index and \a pos contains the character
602 position within the paragraph. 602 position within the paragraph.
603 603
604 \sa setCursorPosition() 604 \sa setCursorPosition()
605*/ 605*/
606 606
607/*! \fn void QTextEdit::returnPressed() 607/*! \fn void QTextEdit::returnPressed()
608 608
609 This signal is emitted if the user pressed the Return or the Enter key. 609 This signal is emitted if the user pressed the Return or the Enter key.
610*/ 610*/
611 611
612/*! 612/*!
613 \fn QTextCursor *QTextEdit::textCursor() const 613 \fn QTextCursor *QTextEdit::textCursor() const
614 614
615 Returns the text edit's text cursor. 615 Returns the text edit's text cursor.
616 616
617 \warning QTextCursor is not in the public API, but in special 617 \warning QTextCursor is not in the public API, but in special
618 circumstances you might wish to use it. 618 circumstances you might wish to use it.
619*/ 619*/
620 620
621/*! Constructs an empty QTextEdit with parent \a parent and name \a 621/*! Constructs an empty QTextEdit with parent \a parent and name \a
622 name. 622 name.
623*/ 623*/
624 624
625QTextEdit::QTextEdit( QWidget *parent, const char *name ) 625QTextEdit::QTextEdit( QWidget *parent, const char *name )
626 : QScrollView( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase ), 626 : QScrollView( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase ),
627 doc( new QTextDocument( 0 ) ), undoRedoInfo( doc ) 627 doc( new QTextDocument( 0 ) ), undoRedoInfo( doc )
628{ 628{
629 init(); 629 init();
630} 630}
631 631
632/*! 632/*!
633 Constructs a QTextEdit with parent \a parent and name \a name. The 633 Constructs a QTextEdit with parent \a parent and name \a name. The
634 text edit will display the text \a text using context \a context. 634 text edit will display the text \a text using context \a context.
635 635
636 The \a context is a path which the text edit's QMimeSourceFactory 636 The \a context is a path which the text edit's QMimeSourceFactory
637 uses to resolve the locations of files and images. It is passed to 637 uses to resolve the locations of files and images. It is passed to
638 the mimeSourceFactory() when quering data. 638 the mimeSourceFactory() when quering data.
639 639
640 For example if the text contains an image tag, 640 For example if the text contains an image tag,
641 \c{<img src="image.png">}, and the context is "path/to/look/in", the 641 \c{<img src="image.png">}, and the context is "path/to/look/in", the
642 QMimeSourceFactory will try to load the image from 642 QMimeSourceFactory will try to load the image from
643 "path/to/look/in/image.png". If the tag was 643 "path/to/look/in/image.png". If the tag was
644 \c{<img src="/image.png">}, the context will not be used (because 644 \c{<img src="/image.png">}, the context will not be used (because
645 QMimeSourceFactory recognizes that we have used an absolute path) 645 QMimeSourceFactory recognizes that we have used an absolute path)
646 and will try to load "/image.png". The context is applied in exactly 646 and will try to load "/image.png". The context is applied in exactly
647 the same way to \e hrefs, for example, 647 the same way to \e hrefs, for example,
648 \c{<a href="target.html">Target</a>}, would resolve to 648 \c{<a href="target.html">Target</a>}, would resolve to
649 "path/to/look/in/target.html". 649 "path/to/look/in/target.html".
650 650
651*/ 651*/
652 652
653QTextEdit::QTextEdit( const QString& text, const QString& context, 653QTextEdit::QTextEdit( const QString& text, const QString& context,
654 QWidget *parent, const char *name) 654 QWidget *parent, const char *name)
655 : QScrollView( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase ), 655 : QScrollView( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase ),
656 doc( new QTextDocument( 0 ) ), undoRedoInfo( doc ) 656 doc( new QTextDocument( 0 ) ), undoRedoInfo( doc )
657{ 657{
658 init(); 658 init();
659 setText( text, context ); 659 setText( text, context );
660} 660}
661 661
662/*! \reimp */ 662/*! \reimp */
663 663
664QTextEdit::~QTextEdit() 664QTextEdit::~QTextEdit()
665{ 665{
666 delete undoRedoInfo.d; 666 delete undoRedoInfo.d;
667 undoRedoInfo.d = 0; 667 undoRedoInfo.d = 0;
668 delete cursor; 668 delete cursor;
669 delete doc; 669 delete doc;
670 delete d; 670 delete d;
671} 671}
672 672
673void QTextEdit::init() 673void QTextEdit::init()
674{ 674{
675 setFrameStyle( Sunken ); 675 setFrameStyle( Sunken );
676 setVScrollBarMode( AlwaysOn );
676 undoEnabled = TRUE; 677 undoEnabled = TRUE;
677 readonly = TRUE; 678 readonly = TRUE;
678 setReadOnly( FALSE ); 679 setReadOnly( FALSE );
679 d = new QTextEditPrivate; 680 d = new QTextEditPrivate;
680 connect( doc, SIGNAL( minimumWidthChanged(int) ), 681 connect( doc, SIGNAL( minimumWidthChanged(int) ),
681 this, SLOT( documentWidthChanged(int) ) ); 682 this, SLOT( documentWidthChanged(int) ) );
682 683
683 mousePressed = FALSE; 684 mousePressed = FALSE;
684 inDoubleClick = FALSE; 685 inDoubleClick = FALSE;
685 modified = FALSE; 686 modified = FALSE;
686 onLink = QString::null; 687 onLink = QString::null;
687 overWrite = FALSE; 688 overWrite = FALSE;
688 wrapMode = WidgetWidth; 689 wrapMode = WidgetWidth;
689 wrapWidth = -1; 690 wrapWidth = -1;
690 wPolicy = AtWhiteSpace; 691 wPolicy = AtWhiteSpace;
691 inDnD = FALSE; 692 inDnD = FALSE;
692 693
693 doc->setFormatter( new QTextFormatterBreakWords ); 694 doc->setFormatter( new QTextFormatterBreakWords );
694 doc->formatCollection()->defaultFormat()->setFont( QScrollView::font() ); 695 doc->formatCollection()->defaultFormat()->setFont( QScrollView::font() );
695 doc->formatCollection()->defaultFormat()->setColor( colorGroup().color( QColorGroup::Text ) ); 696 doc->formatCollection()->defaultFormat()->setColor( colorGroup().color( QColorGroup::Text ) );
696 currentFormat = doc->formatCollection()->defaultFormat(); 697 currentFormat = doc->formatCollection()->defaultFormat();
697 currentAlignment = Qt3::AlignAuto; 698 currentAlignment = Qt3::AlignAuto;
698 699
699 viewport()->setBackgroundMode( PaletteBase ); 700 viewport()->setBackgroundMode( PaletteBase );
700 viewport()->setAcceptDrops( TRUE ); 701 viewport()->setAcceptDrops( TRUE );
701 resizeContents( 0, doc->lastParagraph() ? 702 resizeContents( 0, doc->lastParagraph() ?
702 ( doc->lastParagraph()->paragId() + 1 ) * doc->formatCollection()->defaultFormat()->height() : 0 ); 703 ( doc->lastParagraph()->paragId() + 1 ) * doc->formatCollection()->defaultFormat()->height() : 0 );
703 704
704 setKeyCompression( TRUE ); 705 setKeyCompression( TRUE );
705 viewport()->setMouseTracking( TRUE ); 706 viewport()->setMouseTracking( TRUE );
706#ifndef QT_NO_CURSOR 707#ifndef QT_NO_CURSOR
707 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 708 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
708#endif 709#endif
709 cursor = new QTextCursor( doc ); 710 cursor = new QTextCursor( doc );
710 711
711 formatTimer = new QTimer( this ); 712 formatTimer = new QTimer( this );
712 connect( formatTimer, SIGNAL( timeout() ), 713 connect( formatTimer, SIGNAL( timeout() ),
713 this, SLOT( formatMore() ) ); 714 this, SLOT( formatMore() ) );
714 lastFormatted = doc->firstParagraph(); 715 lastFormatted = doc->firstParagraph();
715 716
716 scrollTimer = new QTimer( this ); 717 scrollTimer = new QTimer( this );
717 connect( scrollTimer, SIGNAL( timeout() ), 718 connect( scrollTimer, SIGNAL( timeout() ),
718 this, SLOT( autoScrollTimerDone() ) ); 719 this, SLOT( autoScrollTimerDone() ) );
719 720
720 interval = 0; 721 interval = 0;
721 changeIntervalTimer = new QTimer( this ); 722 changeIntervalTimer = new QTimer( this );
722 connect( changeIntervalTimer, SIGNAL( timeout() ), 723 connect( changeIntervalTimer, SIGNAL( timeout() ),
723 this, SLOT( doChangeInterval() ) ); 724 this, SLOT( doChangeInterval() ) );
724 725
725 cursorVisible = TRUE; 726 cursorVisible = TRUE;
726 blinkTimer = new QTimer( this ); 727 blinkTimer = new QTimer( this );
727 connect( blinkTimer, SIGNAL( timeout() ), 728 connect( blinkTimer, SIGNAL( timeout() ),
728 this, SLOT( blinkCursor() ) ); 729 this, SLOT( blinkCursor() ) );
729 730
730#ifndef QT_NO_DRAGANDDROP 731#ifndef QT_NO_DRAGANDDROP
731 dragStartTimer = new QTimer( this ); 732 dragStartTimer = new QTimer( this );
732 connect( dragStartTimer, SIGNAL( timeout() ), 733 connect( dragStartTimer, SIGNAL( timeout() ),
733 this, SLOT( startDrag() ) ); 734 this, SLOT( startDrag() ) );
734#endif 735#endif
735 736
736 737
737 formatMore(); 738 formatMore();
738 739
739 blinkCursorVisible = FALSE; 740 blinkCursorVisible = FALSE;
740 741
741 viewport()->setFocusProxy( this ); 742 viewport()->setFocusProxy( this );
742 viewport()->setFocusPolicy( WheelFocus ); 743 viewport()->setFocusPolicy( WheelFocus );
743 viewport()->installEventFilter( this ); 744 viewport()->installEventFilter( this );
744 installEventFilter( this ); 745 installEventFilter( this );
745} 746}
746 747
747void QTextEdit::paintDocument( bool drawAll, QPainter *p, int cx, int cy, int cw, int ch ) 748void QTextEdit::paintDocument( bool drawAll, QPainter *p, int cx, int cy, int cw, int ch )
748{ 749{
749 bool drawCur = hasFocus() || viewport()->hasFocus(); 750 bool drawCur = hasFocus() || viewport()->hasFocus();
750 if ( hasSelectedText() || isReadOnly() || !cursorVisible ) 751 if ( hasSelectedText() || isReadOnly() || !cursorVisible )
751 drawCur = FALSE; 752 drawCur = FALSE;
752 QColorGroup g = colorGroup(); 753 QColorGroup g = colorGroup();
753 if ( doc->paper() ) 754 if ( doc->paper() )
754 g.setBrush( QColorGroup::Base, *doc->paper() ); 755 g.setBrush( QColorGroup::Base, *doc->paper() );
755 756
756 if ( contentsY() < doc->y() ) { 757 if ( contentsY() < doc->y() ) {
757 p->fillRect( contentsX(), contentsY(), visibleWidth(), doc->y(), 758 p->fillRect( contentsX(), contentsY(), visibleWidth(), doc->y(),
758 g.brush( QColorGroup::Base ) ); 759 g.brush( QColorGroup::Base ) );
759 } 760 }
760 if ( drawAll && doc->width() - contentsX() < cx + cw ) { 761 if ( drawAll && doc->width() - contentsX() < cx + cw ) {
761 p->fillRect( doc->width() - contentsX(), cy, cx + cw - doc->width() + contentsX(), ch, 762 p->fillRect( doc->width() - contentsX(), cy, cx + cw - doc->width() + contentsX(), ch,
762 g.brush( QColorGroup::Base ) ); 763 g.brush( QColorGroup::Base ) );
763 } 764 }
764 765
765 p->setBrushOrigin( -contentsX(), -contentsY() ); 766 p->setBrushOrigin( -contentsX(), -contentsY() );
766 767
767 lastFormatted = doc->draw( p, cx, cy, cw, ch, g, !drawAll, drawCur, cursor ); 768 lastFormatted = doc->draw( p, cx, cy, cw, ch, g, !drawAll, drawCur, cursor );
768 769
769 if ( lastFormatted == doc->lastParagraph() ) 770 if ( lastFormatted == doc->lastParagraph() )
770 resizeContents( contentsWidth(), doc->height() ); 771 resizeContents( contentsWidth(), doc->height() );
771 772
772 if ( contentsHeight() < visibleHeight() && ( !doc->lastParagraph() || doc->lastParagraph()->isValid() ) && drawAll ) 773 if ( contentsHeight() < visibleHeight() && ( !doc->lastParagraph() || doc->lastParagraph()->isValid() ) && drawAll )
773 p->fillRect( 0, contentsHeight(), visibleWidth(), 774 p->fillRect( 0, contentsHeight(), visibleWidth(),
774 visibleHeight() - contentsHeight(), g.brush( QColorGroup::Base ) ); 775 visibleHeight() - contentsHeight(), g.brush( QColorGroup::Base ) );
775} 776}
776 777
777/*! \reimp */ 778/*! \reimp */
778 779
779void QTextEdit::drawContents( QPainter *p, int cx, int cy, int cw, int ch ) 780void QTextEdit::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
780{ 781{
781 paintDocument( TRUE, p, cx, cy, cw, ch ); 782 paintDocument( TRUE, p, cx, cy, cw, ch );
782 int v; 783 int v;
783 p->setPen( foregroundColor() ); 784 p->setPen( foregroundColor() );
784 if ( document()->isPageBreakEnabled() && ( v = document()->flow()->pageSize() ) > 0 ) { 785 if ( document()->isPageBreakEnabled() && ( v = document()->flow()->pageSize() ) > 0 ) {
785 int l = int(cy / v) * v; 786 int l = int(cy / v) * v;
786 while ( l < cy + ch ) { 787 while ( l < cy + ch ) {
787 p->drawLine( cx, l, cx + cw - 1, l ); 788 p->drawLine( cx, l, cx + cw - 1, l );
788 l += v; 789 l += v;
789 } 790 }
790 } 791 }
791 792
792} 793}
793 794
794/*! \reimp */ 795/*! \reimp */
795 796
796void QTextEdit::drawContents( QPainter * ) 797void QTextEdit::drawContents( QPainter * )
797{ 798{
798} 799}
799 800
800/*! \reimp */ 801/*! \reimp */
801 802
802bool QTextEdit::event( QEvent *e ) 803bool QTextEdit::event( QEvent *e )
803{ 804{
804 if ( e->type() == QEvent::AccelOverride && !isReadOnly() ) { 805 if ( e->type() == QEvent::AccelOverride && !isReadOnly() ) {
805 QKeyEvent* ke = (QKeyEvent*) e; 806 QKeyEvent* ke = (QKeyEvent*) e;
806 if ( ke->state() == NoButton || ke->state() == Keypad ) { 807 if ( ke->state() == NoButton || ke->state() == Keypad ) {
807 if ( ke->key() < Key_Escape ) { 808 if ( ke->key() < Key_Escape ) {
808 ke->accept(); 809 ke->accept();
809 } else { 810 } else {
810 switch ( ke->key() ) { 811 switch ( ke->key() ) {
811 case Key_Return: 812 case Key_Return:
812 case Key_Enter: 813 case Key_Enter:
813 case Key_Delete: 814 case Key_Delete:
814 case Key_Home: 815 case Key_Home:
815 case Key_End: 816 case Key_End:
816 case Key_Backspace: 817 case Key_Backspace:
817 ke->accept(); 818 ke->accept();
818 default: 819 default:
819 break; 820 break;
820 } 821 }
821 } 822 }
822 } else if ( ke->state() & ControlButton ) { 823 } else if ( ke->state() & ControlButton ) {
823 switch ( ke->key() ) { 824 switch ( ke->key() ) {
824// Those are too frequently used for application functionality 825// Those are too frequently used for application functionality
825 /* case Key_A: 826/* case Key_A:
826 case Key_B: 827 case Key_B:
827 case Key_D: 828 case Key_D:
828 case Key_E: 829 case Key_E:
829 case Key_F: 830 case Key_F:
830 case Key_H: 831 case Key_H:
831 case Key_I: 832 case Key_I:
832 case Key_K: 833 case Key_K:
833 case Key_N: 834 case Key_N:
834 case Key_P: 835 case Key_P:
835 case Key_T: 836 case Key_T:
836*/ 837*/
837 case Key_C: 838 case Key_C:
838 case Key_V: 839 case Key_V:
839 case Key_X: 840 case Key_X:
840 case Key_Y: 841 case Key_Y:
841 case Key_Z: 842 case Key_Z:
842 case Key_Left: 843 case Key_Left:
843 case Key_Right: 844 case Key_Right:
844 case Key_Up: 845 case Key_Up:
845 case Key_Down: 846 case Key_Down:
846 case Key_Home: 847 case Key_Home:
847 case Key_End: 848 case Key_End:
848 case Key_Tab: 849 case Key_Tab:
849#if defined (Q_WS_WIN) 850#if defined (Q_WS_WIN)
850 case Key_Insert: 851 case Key_Insert:
851 case Key_Delete: 852 case Key_Delete:
852#endif 853#endif
853 ke->accept(); 854 ke->accept();
854 default: 855 default:
855 break; 856 break;
856 } 857 }
857 } else { 858 } else {
858 switch ( ke->key() ) { 859 switch ( ke->key() ) {
859#if defined (Q_WS_WIN) 860#if defined (Q_WS_WIN)
860 case Key_Insert: 861 case Key_Insert:
861 ke->accept(); 862 ke->accept();
862#endif 863#endif
863 default: 864 default:
864 break; 865 break;
865 } 866 }
866 } 867 }
867 } 868 }
868 869
869 if ( e->type() == QEvent::Show ) { 870 if ( e->type() == QEvent::Show ) {
870 if ( d->ensureCursorVisibleInShowEvent ) { 871 if ( d->ensureCursorVisibleInShowEvent ) {
871 sync(); 872 sync();
872 ensureCursorVisible(); 873 ensureCursorVisible();
873 d->ensureCursorVisibleInShowEvent = FALSE; 874 d->ensureCursorVisibleInShowEvent = FALSE;
874 } 875 }
875 if ( !d->scrollToAnchor.isEmpty() ) { 876 if ( !d->scrollToAnchor.isEmpty() ) {
876 scrollToAnchor( d->scrollToAnchor ); 877 scrollToAnchor( d->scrollToAnchor );
877 d->scrollToAnchor = QString::null; 878 d->scrollToAnchor = QString::null;
878 } 879 }
879 } 880 }
880 return QWidget::event( e ); 881 return QWidget::event( e );
881} 882}
882 883
883/*! 884/*!
884 Processes the key event, \a e. 885 Processes the key event, \a e.
885 By default key events are used to provide keyboard navigation and 886 By default key events are used to provide keyboard navigation and
886 text editing. 887 text editing.
887*/ 888*/
888 889
889void QTextEdit::keyPressEvent( QKeyEvent *e ) 890void QTextEdit::keyPressEvent( QKeyEvent *e )
890{ 891{
891 changeIntervalTimer->stop(); 892 changeIntervalTimer->stop();
892 interval = 10; 893 interval = 10;
893 bool unknown = FALSE; 894 bool unknown = FALSE;
894 if ( isReadOnly() ) { 895 if ( isReadOnly() ) {
895 if ( !handleReadOnlyKeyEvent( e ) ) 896 if ( !handleReadOnlyKeyEvent( e ) )
896 QScrollView::keyPressEvent( e ); 897 QScrollView::keyPressEvent( e );
897 changeIntervalTimer->start( 100, TRUE ); 898 changeIntervalTimer->start( 100, TRUE );
898 return; 899 return;
899 } 900 }
900 901
901 902
902 bool selChanged = FALSE; 903 bool selChanged = FALSE;
903 for ( int i = 1; i < doc->numSelections(); ++i ) // start with 1 as we don't want to remove the Standard-Selection 904 for ( int i = 1; i < doc->numSelections(); ++i ) // start with 1 as we don't want to remove the Standard-Selection
904 selChanged = doc->removeSelection( i ) || selChanged; 905 selChanged = doc->removeSelection( i ) || selChanged;
905 906
906 if ( selChanged ) { 907 if ( selChanged ) {
907 cursor->paragraph()->document()->nextDoubleBuffered = TRUE; 908 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
908 repaintChanged(); 909 repaintChanged();
909 } 910 }
910 911
911 bool clearUndoRedoInfo = TRUE; 912 bool clearUndoRedoInfo = TRUE;
912 913
913 914
914 switch ( e->key() ) { 915 switch ( e->key() ) {
915 case Key_Left: 916 case Key_Left:
916 case Key_Right: { 917 case Key_Right: {
917 // a bit hacky, but can't change this without introducing new enum values for move and keeping the 918 // a bit hacky, but can't change this without introducing new enum values for move and keeping the
918 // correct semantics and movement for BiDi and non BiDi text. 919 // correct semantics and movement for BiDi and non BiDi text.
919 CursorAction a; 920 CursorAction a;
920 if ( cursor->paragraph()->string()->isRightToLeft() == (e->key() == Key_Right) ) 921 if ( cursor->paragraph()->string()->isRightToLeft() == (e->key() == Key_Right) )
921 a = e->state() & ControlButton ? MoveWordBackward : MoveBackward; 922 a = e->state() & ControlButton ? MoveWordBackward : MoveBackward;
922 else 923 else
923 a = e->state() & ControlButton ? MoveWordForward : MoveForward; 924 a = e->state() & ControlButton ? MoveWordForward : MoveForward;
924 moveCursor( a, e->state() & ShiftButton ); 925 moveCursor( a, e->state() & ShiftButton );
925 break; 926 break;
926 } 927 }
927 case Key_Up: 928 case Key_Up:
928 moveCursor( e->state() & ControlButton ? MovePgUp : MoveUp, e->state() & ShiftButton ); 929 moveCursor( e->state() & ControlButton ? MovePgUp : MoveUp, e->state() & ShiftButton );
929 break; 930 break;
930 case Key_Down: 931 case Key_Down:
931 moveCursor( e->state() & ControlButton ? MovePgDown : MoveDown, e->state() & ShiftButton ); 932 moveCursor( e->state() & ControlButton ? MovePgDown : MoveDown, e->state() & ShiftButton );
932 break; 933 break;
933 case Key_Home: 934 case Key_Home:
934 moveCursor( e->state() & ControlButton ? MoveHome : MoveLineStart, e->state() & ShiftButton ); 935 moveCursor( e->state() & ControlButton ? MoveHome : MoveLineStart, e->state() & ShiftButton );
935 break; 936 break;
936 case Key_End: 937 case Key_End:
937 moveCursor( e->state() & ControlButton ? MoveEnd : MoveLineEnd, e->state() & ShiftButton ); 938 moveCursor( e->state() & ControlButton ? MoveEnd : MoveLineEnd, e->state() & ShiftButton );
938 break; 939 break;
939 case Key_Prior: 940 case Key_Prior:
940 moveCursor( MovePgUp, e->state() & ShiftButton ); 941 moveCursor( MovePgUp, e->state() & ShiftButton );
941 break; 942 break;
942 case Key_Next: 943 case Key_Next:
943 moveCursor( MovePgDown, e->state() & ShiftButton ); 944 moveCursor( MovePgDown, e->state() & ShiftButton );
944 break; 945 break;
945 case Key_Return: case Key_Enter: 946 case Key_Return: case Key_Enter:
946 if ( doc->hasSelection( QTextDocument::Standard, FALSE ) ) 947 if ( doc->hasSelection( QTextDocument::Standard, FALSE ) )
947 removeSelectedText(); 948 removeSelectedText();
948 if ( textFormat() == Qt::RichText && ( e->state() & ControlButton ) ) { 949 if ( textFormat() == Qt::RichText && ( e->state() & ControlButton ) ) {
949 // Ctrl-Enter inserts a line break in rich text mode 950 // Ctrl-Enter inserts a line break in rich text mode
950 insert( QString( QChar( 0x2028) ), TRUE, FALSE, TRUE ); 951 insert( QString( QChar( 0x2028) ), TRUE, FALSE, TRUE );
951 } else { 952 } else {
952#ifndef QT_NO_CURSOR 953#ifndef QT_NO_CURSOR
953 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 954 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
954#endif 955#endif
955 clearUndoRedoInfo = FALSE; 956 clearUndoRedoInfo = FALSE;
956 doKeyboardAction( ActionReturn ); 957 doKeyboardAction( ActionReturn );
957 emit returnPressed(); 958 emit returnPressed();
958 } 959 }
959 break; 960 break;
960 case Key_Delete: 961 case Key_Delete:
961#if defined (Q_WS_WIN) 962#if defined (Q_WS_WIN)
962 if ( e->state() & ShiftButton ) { 963 if ( e->state() & ShiftButton ) {
963 cut(); 964 cut();
964 break; 965 break;
965 } else 966 } else
966#endif 967#endif
967 if ( doc->hasSelection( QTextDocument::Standard, TRUE ) ) { 968 if ( doc->hasSelection( QTextDocument::Standard, TRUE ) ) {
968 removeSelectedText(); 969 removeSelectedText();
969 break; 970 break;
970 } 971 }
971 doKeyboardAction( ActionDelete ); 972 doKeyboardAction( ActionDelete );
972 clearUndoRedoInfo = FALSE; 973 clearUndoRedoInfo = FALSE;
973 974
974 break; 975 break;
975 case Key_Insert: 976 case Key_Insert:
976 if ( e->state() & ShiftButton ) 977 if ( e->state() & ShiftButton )
977 paste(); 978 paste();
978#if defined (Q_WS_WIN) 979#if defined (Q_WS_WIN)
979 else if ( e->state() & ControlButton ) 980 else if ( e->state() & ControlButton )
980 copy(); 981 copy();
981#endif 982#endif
982 break; 983 break;
983 case Key_Backspace: 984 case Key_Backspace:
984 if ( doc->hasSelection( QTextDocument::Standard, TRUE ) ) { 985 if ( doc->hasSelection( QTextDocument::Standard, TRUE ) ) {
985 removeSelectedText(); 986 removeSelectedText();
986 break; 987 break;
987 } 988 }
988 989
989 doKeyboardAction( ActionBackspace ); 990 doKeyboardAction( ActionBackspace );
990 clearUndoRedoInfo = FALSE; 991 clearUndoRedoInfo = FALSE;
991 992
992 break; 993 break;
993 case Key_F16: // Copy key on Sun keyboards 994 case Key_F16: // Copy key on Sun keyboards
994 copy(); 995 copy();
995 break; 996 break;
996 case Key_F18: // Paste key on Sun keyboards 997 case Key_F18: // Paste key on Sun keyboards
997 paste(); 998 paste();
998 break; 999 break;
999 case Key_F20: // Cut key on Sun keyboards 1000 case Key_F20: // Cut key on Sun keyboards
1000 cut(); 1001 cut();
1001 break; 1002 break;
1002 default: { 1003 default: {
1003 if ( e->text().length() && 1004 if ( e->text().length() &&
1004 ( !( e->state() & ControlButton ) && 1005 ( !( e->state() & ControlButton ) &&
1005 !( e->state() & AltButton ) || 1006 !( e->state() & AltButton ) ||
1006 ( ( e->state() & ControlButton | AltButton ) == (ControlButton|AltButton) ) ) && 1007 ( ( e->state() & ControlButton | AltButton ) == (ControlButton|AltButton) ) ) &&
1007 ( !e->ascii() || e->ascii() >= 32 || e->text() == "\t" ) ) { 1008 ( !e->ascii() || e->ascii() >= 32 || e->text() == "\t" ) ) {
1008 clearUndoRedoInfo = FALSE; 1009 clearUndoRedoInfo = FALSE;
1009 if ( e->key() == Key_Tab ) { 1010 if ( e->key() == Key_Tab ) {
1010 if ( textFormat() == Qt::RichText && cursor->paragraph()->isListItem() ) { 1011 if ( textFormat() == Qt::RichText && cursor->paragraph()->isListItem() ) {
1011 clearUndoRedo(); 1012 clearUndoRedo();
1012 undoRedoInfo.type = UndoRedoInfo::Style; 1013 undoRedoInfo.type = UndoRedoInfo::Style;
1013 undoRedoInfo.id = cursor->paragraph()->paragId(); 1014 undoRedoInfo.id = cursor->paragraph()->paragId();
1014 undoRedoInfo.eid = undoRedoInfo.id; 1015 undoRedoInfo.eid = undoRedoInfo.id;
1015 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid ); 1016 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
1016 cursor->paragraph()->setListDepth( cursor->paragraph()->listDepth() +1 ); 1017 cursor->paragraph()->setListDepth( cursor->paragraph()->listDepth() +1 );
1017 clearUndoRedo(); 1018 clearUndoRedo();
1018 drawCursor( FALSE ); 1019 drawCursor( FALSE );
1019 repaintChanged(); 1020 repaintChanged();
1020 drawCursor( TRUE ); 1021 drawCursor( TRUE );
1021 break; 1022 break;
1022 } 1023 }
1023 } 1024 }
1024 1025
1025 if ( textFormat() == Qt::RichText && !cursor->paragraph()->isListItem() ) { 1026 if ( textFormat() == Qt::RichText && !cursor->paragraph()->isListItem() ) {
1026 if ( cursor->index() == 0 && ( e->text()[0] == '-' || e->text()[0] == '*' ) ) { 1027 if ( cursor->index() == 0 && ( e->text()[0] == '-' || e->text()[0] == '*' ) ) {
1027 clearUndoRedo(); 1028 clearUndoRedo();
1028 undoRedoInfo.type = UndoRedoInfo::Style; 1029 undoRedoInfo.type = UndoRedoInfo::Style;
1029 undoRedoInfo.id = cursor->paragraph()->paragId(); 1030 undoRedoInfo.id = cursor->paragraph()->paragId();
1030 undoRedoInfo.eid = undoRedoInfo.id; 1031 undoRedoInfo.eid = undoRedoInfo.id;
1031 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid ); 1032 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
1032 setParagType( QStyleSheetItem::DisplayListItem, QStyleSheetItem::ListDisc ); 1033 setParagType( QStyleSheetItem::DisplayListItem, QStyleSheetItem::ListDisc );
1033 clearUndoRedo(); 1034 clearUndoRedo();
1034 drawCursor( FALSE ); 1035 drawCursor( FALSE );
1035 repaintChanged(); 1036 repaintChanged();
1036 drawCursor( TRUE ); 1037 drawCursor( TRUE );
1037 break; 1038 break;
1038 } 1039 }
1039 } 1040 }
1040 if ( overWrite && !cursor->atParagEnd() ) 1041 if ( overWrite && !cursor->atParagEnd() )
1041 cursor->remove(); 1042 cursor->remove();
1042 QString t = e->text(); 1043 QString t = e->text();
1043 QTextParagraph *p = cursor->paragraph(); 1044 QTextParagraph *p = cursor->paragraph();
1044 if ( p && p->string() && p->string()->isRightToLeft() ) { 1045 if ( p && p->string() && p->string()->isRightToLeft() ) {
1045 QChar *c = (QChar *)t.unicode(); 1046 QChar *c = (QChar *)t.unicode();
1046 int l = t.length(); 1047 int l = t.length();
1047 while( l-- ) { 1048 while( l-- ) {
1048 if ( c->mirrored() ) 1049 if ( c->mirrored() )
1049 *c = c->mirroredChar(); 1050 *c = c->mirroredChar();
1050 c++; 1051 c++;
1051 } 1052 }
1052 } 1053 }
1053 insert( t, TRUE, FALSE, TRUE ); 1054 insert( t, TRUE, FALSE, TRUE );
1054 break; 1055 break;
1055 } else if ( e->state() & ControlButton ) { 1056 } else if ( e->state() & ControlButton ) {
1056 switch ( e->key() ) { 1057 switch ( e->key() ) {
1057 case Key_C: case Key_F16: // Copy key on Sun keyboards 1058 case Key_C: case Key_F16: // Copy key on Sun keyboards
1058 copy(); 1059 copy();
1059 break; 1060 break;
1060 case Key_V: 1061 case Key_V:
1061 paste(); 1062 paste();
1062 break; 1063 break;
1063 case Key_X: 1064 case Key_X:
1064 cut(); 1065 cut();
1065 break; 1066 break;
1066 case Key_I: case Key_T: case Key_Tab: 1067 case Key_I: case Key_T: case Key_Tab:
1067 indent(); 1068 indent();
1068 break; 1069 break;
1069 case Key_A: 1070 case Key_A:
1070#if defined(Q_WS_X11) 1071#if defined(Q_WS_X11)
1071 moveCursor( MoveLineStart, e->state() & ShiftButton ); 1072 moveCursor( MoveLineStart, e->state() & ShiftButton );
1072#else 1073#else
1073 selectAll( TRUE ); 1074 selectAll( TRUE );
1074#endif 1075#endif
1075 break; 1076 break;
1076 case Key_B: 1077 case Key_B:
1077 moveCursor( MoveBackward, e->state() & ShiftButton ); 1078 moveCursor( MoveBackward, e->state() & ShiftButton );
1078 break; 1079 break;
1079 case Key_F: 1080 case Key_F:
1080 moveCursor( MoveForward, e->state() & ShiftButton ); 1081 moveCursor( MoveForward, e->state() & ShiftButton );
1081 break; 1082 break;
1082 case Key_D: 1083 case Key_D:
1083 if ( doc->hasSelection( QTextDocument::Standard ) ) { 1084 if ( doc->hasSelection( QTextDocument::Standard ) ) {
1084 removeSelectedText(); 1085 removeSelectedText();
1085 break; 1086 break;
1086 } 1087 }
1087 doKeyboardAction( ActionDelete ); 1088 doKeyboardAction( ActionDelete );
1088 clearUndoRedoInfo = FALSE; 1089 clearUndoRedoInfo = FALSE;
1089 break; 1090 break;
1090 case Key_H: 1091 case Key_H:
1091 if ( doc->hasSelection( QTextDocument::Standard ) ) { 1092 if ( doc->hasSelection( QTextDocument::Standard ) ) {
1092 removeSelectedText(); 1093 removeSelectedText();
1093 break; 1094 break;
1094 } 1095 }
1095 if ( !cursor->paragraph()->prev() && 1096 if ( !cursor->paragraph()->prev() &&
1096 cursor->atParagStart() ) 1097 cursor->atParagStart() )
1097 break; 1098 break;
1098 1099
1099 doKeyboardAction( ActionBackspace ); 1100 doKeyboardAction( ActionBackspace );
1100 clearUndoRedoInfo = FALSE; 1101 clearUndoRedoInfo = FALSE;
1101 break; 1102 break;
1102 case Key_E: 1103 case Key_E:
1103 moveCursor( MoveLineEnd, e->state() & ShiftButton ); 1104 moveCursor( MoveLineEnd, e->state() & ShiftButton );
1104 break; 1105 break;
1105 case Key_N: 1106 case Key_N:
1106 moveCursor( MoveDown, e->state() & ShiftButton ); 1107 moveCursor( MoveDown, e->state() & ShiftButton );
1107 break; 1108 break;
1108 case Key_P: 1109 case Key_P:
1109 moveCursor( MoveUp, e->state() & ShiftButton ); 1110 moveCursor( MoveUp, e->state() & ShiftButton );
1110 break; 1111 break;
1111 case Key_Z: 1112 case Key_Z:
1112 if(e->state() & ShiftButton) 1113 if(e->state() & ShiftButton)
1113 redo(); 1114 redo();
1114 else 1115 else
1115 undo(); 1116 undo();
1116 break; 1117 break;
1117 case Key_Y: 1118 case Key_Y:
1118 redo(); 1119 redo();
1119 break; 1120 break;
1120 case Key_K: 1121 case Key_K:
1121 doKeyboardAction( ActionKill ); 1122 doKeyboardAction( ActionKill );
1122 break; 1123 break;
1123#if defined(Q_WS_WIN) 1124#if defined(Q_WS_WIN)
1124 case Key_Insert: 1125 case Key_Insert:
1125 copy(); 1126 copy();
1126 break; 1127 break;
1127 case Key_Delete: 1128 case Key_Delete:
1128 del(); 1129 del();
1129 break; 1130 break;
1130#endif 1131#endif
1131 default: 1132 default:
1132 unknown = FALSE; 1133 unknown = FALSE;
1133 break; 1134 break;
1134 } 1135 }
1135 } else { 1136 } else {
1136 unknown = TRUE; 1137 unknown = TRUE;
1137 } 1138 }
1138 } 1139 }
1139 } 1140 }
1140 1141
1141 emit cursorPositionChanged( cursor ); 1142 emit cursorPositionChanged( cursor );
1142 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() ); 1143 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
1143 if ( clearUndoRedoInfo ) 1144 if ( clearUndoRedoInfo )
1144 clearUndoRedo(); 1145 clearUndoRedo();
1145 changeIntervalTimer->start( 100, TRUE ); 1146 changeIntervalTimer->start( 100, TRUE );
1146 if ( unknown ) 1147 if ( unknown )
1147 e->ignore(); 1148 e->ignore();
1148} 1149}
1149 1150
1150/*! 1151/*!
1151 Executes keyboard action \a action. This is normally called by 1152 Executes keyboard action \a action. This is normally called by
1152 a key event handler. 1153 a key event handler.
1153*/ 1154*/
1154 1155
1155void QTextEdit::doKeyboardAction( KeyboardAction action ) 1156void QTextEdit::doKeyboardAction( KeyboardAction action )
1156{ 1157{
1157 if ( isReadOnly() ) 1158 if ( isReadOnly() )
1158 return; 1159 return;
1159 1160
1160 if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough 1161 if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough
1161 return; 1162 return;
1162 1163
1163 lastFormatted = cursor->paragraph(); 1164 lastFormatted = cursor->paragraph();
1164 drawCursor( FALSE ); 1165 drawCursor( FALSE );
1165 bool doUpdateCurrentFormat = TRUE; 1166 bool doUpdateCurrentFormat = TRUE;
1166 1167
1167 switch ( action ) { 1168 switch ( action ) {
1168 case ActionDelete: 1169 case ActionDelete:
1169 if ( !cursor->atParagEnd() ) { 1170 if ( !cursor->atParagEnd() ) {
1170 checkUndoRedoInfo( UndoRedoInfo::Delete ); 1171 checkUndoRedoInfo( UndoRedoInfo::Delete );
1171 if ( !undoRedoInfo.valid() ) { 1172 if ( !undoRedoInfo.valid() ) {
1172 undoRedoInfo.id = cursor->paragraph()->paragId(); 1173 undoRedoInfo.id = cursor->paragraph()->paragId();
1173 undoRedoInfo.index = cursor->index(); 1174 undoRedoInfo.index = cursor->index();
1174 undoRedoInfo.d->text = QString::null; 1175 undoRedoInfo.d->text = QString::null;
1175 } 1176 }
1176 undoRedoInfo.d->text.insert( undoRedoInfo.d->text.length(), cursor->paragraph()->at( cursor->index() ), TRUE ); 1177 undoRedoInfo.d->text.insert( undoRedoInfo.d->text.length(), cursor->paragraph()->at( cursor->index() ), TRUE );
1177 cursor->remove(); 1178 cursor->remove();
1178 } else { 1179 } else {
1179 clearUndoRedo(); 1180 clearUndoRedo();
1180 doc->setSelectionStart( QTextDocument::Temp, *cursor ); 1181 doc->setSelectionStart( QTextDocument::Temp, *cursor );
1181 cursor->gotoNextLetter(); 1182 cursor->gotoNextLetter();
1182 doc->setSelectionEnd( QTextDocument::Temp, *cursor ); 1183 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
1183 removeSelectedText( QTextDocument::Temp ); 1184 removeSelectedText( QTextDocument::Temp );
1184 } 1185 }
1185 break; 1186 break;
1186 case ActionBackspace: 1187 case ActionBackspace:
1187 if ( textFormat() == Qt::RichText && cursor->paragraph()->isListItem() && cursor->index() == 0 ) { 1188 if ( textFormat() == Qt::RichText && cursor->paragraph()->isListItem() && cursor->index() == 0 ) {
1188 clearUndoRedo(); 1189 clearUndoRedo();
1189 undoRedoInfo.type = UndoRedoInfo::Style; 1190 undoRedoInfo.type = UndoRedoInfo::Style;
1190 undoRedoInfo.id = cursor->paragraph()->paragId(); 1191 undoRedoInfo.id = cursor->paragraph()->paragId();
1191 undoRedoInfo.eid = undoRedoInfo.id; 1192 undoRedoInfo.eid = undoRedoInfo.id;
1192 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid ); 1193 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
1193 int ldepth = cursor->paragraph()->listDepth(); 1194 int ldepth = cursor->paragraph()->listDepth();
1194 ldepth = QMAX( ldepth-1, 0 ); 1195 ldepth = QMAX( ldepth-1, 0 );
1195 cursor->paragraph()->setListDepth( ldepth ); 1196 cursor->paragraph()->setListDepth( ldepth );
1196 if ( ldepth == 0 ) 1197 if ( ldepth == 0 )
1197 cursor->paragraph()->setListItem( FALSE ); 1198 cursor->paragraph()->setListItem( FALSE );
1198 clearUndoRedo(); 1199 clearUndoRedo();
1199 lastFormatted = cursor->paragraph(); 1200 lastFormatted = cursor->paragraph();
1200 repaintChanged(); 1201 repaintChanged();
1201 drawCursor( TRUE ); 1202 drawCursor( TRUE );
1202 return; 1203 return;
1203 } 1204 }
1204 if ( !cursor->atParagStart() ) { 1205 if ( !cursor->atParagStart() ) {
1205 checkUndoRedoInfo( UndoRedoInfo::Delete ); 1206 checkUndoRedoInfo( UndoRedoInfo::Delete );
1206 if ( !undoRedoInfo.valid() ) { 1207 if ( !undoRedoInfo.valid() ) {
1207 undoRedoInfo.id = cursor->paragraph()->paragId(); 1208 undoRedoInfo.id = cursor->paragraph()->paragId();
1208 undoRedoInfo.index = cursor->index(); 1209 undoRedoInfo.index = cursor->index();
1209 undoRedoInfo.d->text = QString::null; 1210 undoRedoInfo.d->text = QString::null;
1210 } 1211 }
1211 cursor->gotoPreviousLetter(); 1212 cursor->gotoPreviousLetter();
1212 undoRedoInfo.d->text.insert( 0, cursor->paragraph()->at( cursor->index() ), TRUE ); 1213 undoRedoInfo.d->text.insert( 0, cursor->paragraph()->at( cursor->index() ), TRUE );
1213 undoRedoInfo.index = cursor->index(); 1214 undoRedoInfo.index = cursor->index();
1214 cursor->remove(); 1215 cursor->remove();
1215 lastFormatted = cursor->paragraph(); 1216 lastFormatted = cursor->paragraph();
1216 } else if ( cursor->paragraph()->prev() ){ 1217 } else if ( cursor->paragraph()->prev() ){
1217 clearUndoRedo(); 1218 clearUndoRedo();
1218 doc->setSelectionStart( QTextDocument::Temp, *cursor ); 1219 doc->setSelectionStart( QTextDocument::Temp, *cursor );
1219 cursor->gotoPreviousLetter(); 1220 cursor->gotoPreviousLetter();
1220 doc->setSelectionEnd( QTextDocument::Temp, *cursor ); 1221 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
1221 removeSelectedText( QTextDocument::Temp ); 1222 removeSelectedText( QTextDocument::Temp );
1222 } 1223 }
1223 break; 1224 break;
1224 case ActionReturn: 1225 case ActionReturn:
1225 checkUndoRedoInfo( UndoRedoInfo::Return ); 1226 checkUndoRedoInfo( UndoRedoInfo::Return );
1226 if ( !undoRedoInfo.valid() ) { 1227 if ( !undoRedoInfo.valid() ) {
1227 undoRedoInfo.id = cursor->paragraph()->paragId(); 1228 undoRedoInfo.id = cursor->paragraph()->paragId();
1228 undoRedoInfo.index = cursor->index(); 1229 undoRedoInfo.index = cursor->index();
1229 undoRedoInfo.d->text = QString::null; 1230 undoRedoInfo.d->text = QString::null;
1230 } 1231 }
1231 undoRedoInfo.d->text += "\n"; 1232 undoRedoInfo.d->text += "\n";
1232 cursor->splitAndInsertEmptyParagraph(); 1233 cursor->splitAndInsertEmptyParagraph();
1233 if ( cursor->paragraph()->prev() ) { 1234 if ( cursor->paragraph()->prev() ) {
1234 lastFormatted = cursor->paragraph()->prev(); 1235 lastFormatted = cursor->paragraph()->prev();
1235 lastFormatted->invalidate( 0 ); 1236 lastFormatted->invalidate( 0 );
1236 } 1237 }
1237 doUpdateCurrentFormat = FALSE; 1238 doUpdateCurrentFormat = FALSE;
1238 break; 1239 break;
1239 case ActionKill: 1240 case ActionKill:
1240 clearUndoRedo(); 1241 clearUndoRedo();
1241 doc->setSelectionStart( QTextDocument::Temp, *cursor ); 1242 doc->setSelectionStart( QTextDocument::Temp, *cursor );
1242 if ( cursor->atParagEnd() ) 1243 if ( cursor->atParagEnd() )
1243 cursor->gotoNextLetter(); 1244 cursor->gotoNextLetter();
1244 else 1245 else
1245 cursor->setIndex( cursor->paragraph()->length() - 1 ); 1246 cursor->setIndex( cursor->paragraph()->length() - 1 );
1246 doc->setSelectionEnd( QTextDocument::Temp, *cursor ); 1247 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
1247 removeSelectedText( QTextDocument::Temp ); 1248 removeSelectedText( QTextDocument::Temp );
1248 break; 1249 break;
1249 } 1250 }
1250 1251
1251 formatMore(); 1252 formatMore();
1252 repaintChanged(); 1253 repaintChanged();
1253 ensureCursorVisible(); 1254 ensureCursorVisible();
1254 drawCursor( TRUE ); 1255 drawCursor( TRUE );
1255 updateMicroFocusHint(); 1256 updateMicroFocusHint();
1256 if ( doUpdateCurrentFormat ) 1257 if ( doUpdateCurrentFormat )
1257 updateCurrentFormat(); 1258 updateCurrentFormat();
1258 setModified(); 1259 setModified();
1259 emit textChanged(); 1260 emit textChanged();
1260} 1261}
1261 1262
1262void QTextEdit::readFormats( QTextCursor &c1, QTextCursor &c2, QTextString &text, bool fillStyles ) 1263void QTextEdit::readFormats( QTextCursor &c1, QTextCursor &c2, QTextString &text, bool fillStyles )
1263{ 1264{
1264 QDataStream styleStream( undoRedoInfo.styleInformation, IO_WriteOnly ); 1265 QDataStream styleStream( undoRedoInfo.styleInformation, IO_WriteOnly );
1265 c2.restoreState(); 1266 c2.restoreState();
1266 c1.restoreState(); 1267 c1.restoreState();
1267 int lastIndex = text.length(); 1268 int lastIndex = text.length();
1268 if ( c1.paragraph() == c2.paragraph() ) { 1269 if ( c1.paragraph() == c2.paragraph() ) {
1269 for ( int i = c1.index(); i < c2.index(); ++i ) 1270 for ( int i = c1.index(); i < c2.index(); ++i )
1270 text.insert( lastIndex + i - c1.index(), c1.paragraph()->at( i ), TRUE ); 1271 text.insert( lastIndex + i - c1.index(), c1.paragraph()->at( i ), TRUE );
1271 if ( fillStyles ) { 1272 if ( fillStyles ) {
1272 styleStream << (int) 1; 1273 styleStream << (int) 1;
1273 c1.paragraph()->writeStyleInformation( styleStream ); 1274 c1.paragraph()->writeStyleInformation( styleStream );
1274 } 1275 }
1275 } else { 1276 } else {
1276 int i; 1277 int i;
1277 for ( i = c1.index(); i < c1.paragraph()->length()-1; ++i ) 1278 for ( i = c1.index(); i < c1.paragraph()->length()-1; ++i )
1278 text.insert( lastIndex++, c1.paragraph()->at( i ), TRUE ); 1279 text.insert( lastIndex++, c1.paragraph()->at( i ), TRUE );
1279 int num = 2; // start and end, being different 1280 int num = 2; // start and end, being different
1280 text += "\n"; lastIndex++; 1281 text += "\n"; lastIndex++;
1281 QTextParagraph *p = c1.paragraph()->next(); 1282 QTextParagraph *p = c1.paragraph()->next();
1282 while ( p && p != c2.paragraph() ) { 1283 while ( p && p != c2.paragraph() ) {
1283 for ( i = 0; i < p->length()-1; ++i ) 1284 for ( i = 0; i < p->length()-1; ++i )
1284 text.insert( lastIndex++ , p->at( i ), TRUE ); 1285 text.insert( lastIndex++ , p->at( i ), TRUE );
1285 text += "\n"; num++; lastIndex++; 1286 text += "\n"; num++; lastIndex++;
1286 p = p->next(); 1287 p = p->next();
1287 } 1288 }
1288 for ( i = 0; i < c2.index(); ++i ) 1289 for ( i = 0; i < c2.index(); ++i )
1289 text.insert( i + lastIndex, c2.paragraph()->at( i ), TRUE ); 1290 text.insert( i + lastIndex, c2.paragraph()->at( i ), TRUE );
1290 if ( fillStyles ) { 1291 if ( fillStyles ) {
1291 styleStream << num; 1292 styleStream << num;
1292 for ( QTextParagraph *p = c1.paragraph(); --num >= 0; p = p->next() ) 1293 for ( QTextParagraph *p = c1.paragraph(); --num >= 0; p = p->next() )
1293 p->writeStyleInformation( styleStream ); 1294 p->writeStyleInformation( styleStream );
1294 } 1295 }
1295 } 1296 }
1296} 1297}
1297 1298
1298/*! Removes the selection \a selNum (by default 0). This does not 1299/*! Removes the selection \a selNum (by default 0). This does not
1299 remove the selected text. 1300 remove the selected text.
1300 1301
1301 \sa removeSelectedText() 1302 \sa removeSelectedText()
1302*/ 1303*/
1303 1304
1304void QTextEdit::removeSelection( int selNum ) 1305void QTextEdit::removeSelection( int selNum )
1305{ 1306{
1306 doc->removeSelection( selNum ); 1307 doc->removeSelection( selNum );
1307 repaintChanged(); 1308 repaintChanged();
1308} 1309}
1309 1310
1310/*! Deletes the selected text (i.e. the default selection's text) of 1311/*! Deletes the selected text (i.e. the default selection's text) of
1311 the selection \a selNum (by default, 0). If there is no selected text 1312 the selection \a selNum (by default, 0). If there is no selected text
1312 nothing happens. 1313 nothing happens.
1313 1314
1314 \sa selectedText removeSelection() 1315 \sa selectedText removeSelection()
1315*/ 1316*/
1316 1317
1317void QTextEdit::removeSelectedText( int selNum ) 1318void QTextEdit::removeSelectedText( int selNum )
1318{ 1319{
1319 if ( isReadOnly() ) 1320 if ( isReadOnly() )
1320 return; 1321 return;
1321 1322
1322 QTextCursor c1 = doc->selectionStartCursor( selNum ); 1323 QTextCursor c1 = doc->selectionStartCursor( selNum );
1323 c1.restoreState(); 1324 c1.restoreState();
1324 QTextCursor c2 = doc->selectionEndCursor( selNum ); 1325 QTextCursor c2 = doc->selectionEndCursor( selNum );
1325 c2.restoreState(); 1326 c2.restoreState();
1326 1327
1327 // ### no support for editing tables yet, plus security for broken selections 1328 // ### no support for editing tables yet, plus security for broken selections
1328 if ( c1.nestedDepth() || c2.nestedDepth() ) 1329 if ( c1.nestedDepth() || c2.nestedDepth() )
1329 return; 1330 return;
1330 1331
1331 for ( int i = 0; i < (int)doc->numSelections(); ++i ) { 1332 for ( int i = 0; i < (int)doc->numSelections(); ++i ) {
1332 if ( i == selNum ) 1333 if ( i == selNum )
1333 continue; 1334 continue;
1334 doc->removeSelection( i ); 1335 doc->removeSelection( i );
1335 } 1336 }
1336 1337
1337 drawCursor( FALSE ); 1338 drawCursor( FALSE );
1338 checkUndoRedoInfo( UndoRedoInfo::RemoveSelected ); 1339 checkUndoRedoInfo( UndoRedoInfo::RemoveSelected );
1339 if ( !undoRedoInfo.valid() ) { 1340 if ( !undoRedoInfo.valid() ) {
1340 doc->selectionStart( selNum, undoRedoInfo.id, undoRedoInfo.index ); 1341 doc->selectionStart( selNum, undoRedoInfo.id, undoRedoInfo.index );
1341 undoRedoInfo.d->text = QString::null; 1342 undoRedoInfo.d->text = QString::null;
1342 } 1343 }
1343 readFormats( c1, c2, undoRedoInfo.d->text, TRUE ); 1344 readFormats( c1, c2, undoRedoInfo.d->text, TRUE );
1344 1345
1345 1346
1346 doc->removeSelectedText( selNum, cursor ); 1347 doc->removeSelectedText( selNum, cursor );
1347 if ( cursor->isValid() ) { 1348 if ( cursor->isValid() ) {
1348 ensureCursorVisible(); 1349 ensureCursorVisible();
1349 lastFormatted = cursor->paragraph(); 1350 lastFormatted = cursor->paragraph();
1350 formatMore(); 1351 formatMore();
1351 repaintChanged(); 1352 repaintChanged();
1352 ensureCursorVisible(); 1353 ensureCursorVisible();
1353 drawCursor( TRUE ); 1354 drawCursor( TRUE );
1354 clearUndoRedo(); 1355 clearUndoRedo();
1355#if defined(Q_WS_WIN) 1356#if defined(Q_WS_WIN)
1356 // there seems to be a problem with repainting or erasing the area 1357 // there seems to be a problem with repainting or erasing the area
1357 // of the scrollview which is not the contents on windows 1358 // of the scrollview which is not the contents on windows
1358 if ( contentsHeight() < visibleHeight() ) 1359 if ( contentsHeight() < visibleHeight() )
1359 viewport()->repaint( 0, contentsHeight(), visibleWidth(), visibleHeight() - contentsHeight(), TRUE ); 1360 viewport()->repaint( 0, contentsHeight(), visibleWidth(), visibleHeight() - contentsHeight(), TRUE );
1360#endif 1361#endif
1361#ifndef QT_NO_CURSOR 1362#ifndef QT_NO_CURSOR
1362 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 1363 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
1363#endif 1364#endif
1364 updateMicroFocusHint(); 1365 updateMicroFocusHint();
1365 } else { 1366 } else {
1366 delete cursor; 1367 delete cursor;
1367 cursor = new QTextCursor( doc ); 1368 cursor = new QTextCursor( doc );
1368 drawCursor( TRUE ); 1369 drawCursor( TRUE );
1369 viewport()->repaint( TRUE ); 1370 viewport()->repaint( TRUE );
1370 } 1371 }
1371 setModified(); 1372 setModified();
1372 emit textChanged(); 1373 emit textChanged();
1373 emit selectionChanged(); 1374 emit selectionChanged();
1374} 1375}
1375 1376
1376/*! Moves the text cursor according to \a action. This is normally 1377/*! Moves the text cursor according to \a action. This is normally
1377 used by some key event handler. \a select specifies whether the text 1378 used by some key event handler. \a select specifies whether the text
1378 between the current cursor position and the new position should be 1379 between the current cursor position and the new position should be
1379 selected. 1380 selected.
1380*/ 1381*/
1381 1382
1382void QTextEdit::moveCursor( CursorAction action, bool select ) 1383void QTextEdit::moveCursor( CursorAction action, bool select )
1383{ 1384{
1384 drawCursor( FALSE ); 1385 drawCursor( FALSE );
1385 if ( select ) { 1386 if ( select ) {
1386 if ( !doc->hasSelection( QTextDocument::Standard ) ) 1387 if ( !doc->hasSelection( QTextDocument::Standard ) )
1387 doc->setSelectionStart( QTextDocument::Standard, *cursor ); 1388 doc->setSelectionStart( QTextDocument::Standard, *cursor );
1388 moveCursor( action ); 1389 moveCursor( action );
1389 if ( doc->setSelectionEnd( QTextDocument::Standard, *cursor ) ) { 1390 if ( doc->setSelectionEnd( QTextDocument::Standard, *cursor ) ) {
1390 cursor->paragraph()->document()->nextDoubleBuffered = TRUE; 1391 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
1391 repaintChanged(); 1392 repaintChanged();
1392 } else {
1393 drawCursor( TRUE );
1394 }
1395 ensureCursorVisible();
1396 emit selectionChanged();
1397 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) );
1398 } else { 1393 } else {
1399 bool redraw = doc->removeSelection( QTextDocument::Standard ); 1394 drawCursor( TRUE );
1400 moveCursor( action ); 1395 }
1401 if ( !redraw ) { 1396 ensureCursorVisible();
1402 ensureCursorVisible(); 1397 emit selectionChanged();
1403 drawCursor( TRUE ); 1398 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) );
1404 } else { 1399 } else {
1405 cursor->paragraph()->document()->nextDoubleBuffered = TRUE; 1400 bool redraw = doc->removeSelection( QTextDocument::Standard );
1406 repaintChanged(); 1401 moveCursor( action );
1407 ensureCursorVisible(); 1402 if ( !redraw ) {
1408 drawCursor( TRUE ); 1403 ensureCursorVisible();
1404 drawCursor( TRUE );
1405 } else {
1406 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
1407 repaintChanged();
1408 ensureCursorVisible();
1409 drawCursor( TRUE );
1409#ifndef QT_NO_CURSOR 1410#ifndef QT_NO_CURSOR
1410 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 1411 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
1411#endif 1412#endif
1412 } 1413 }
1413 if ( redraw ) { 1414 if ( redraw ) {
1414 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) ); 1415 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) );
1415 emit selectionChanged(); 1416 emit selectionChanged();
1416 } 1417 }
1417 } 1418 }
1418 1419
1419 drawCursor( TRUE ); 1420 drawCursor( TRUE );
1420 updateCurrentFormat(); 1421 updateCurrentFormat();
1421 updateMicroFocusHint(); 1422 updateMicroFocusHint();
1422} 1423}
1423 1424
1424/*! \overload 1425/*! \overload
1425*/ 1426*/
1426 1427
1427void QTextEdit::moveCursor( CursorAction action ) 1428void QTextEdit::moveCursor( CursorAction action )
1428{ 1429{
1429 switch ( action ) { 1430 switch ( action ) {
1430 case MoveBackward: 1431 case MoveBackward:
1431 cursor->gotoPreviousLetter(); 1432 cursor->gotoPreviousLetter();
1432 break; 1433 break;
1433 case MoveWordBackward: 1434 case MoveWordBackward:
1434 cursor->gotoPreviousWord(); 1435 cursor->gotoPreviousWord();
1435 break; 1436 break;
1436 case MoveForward: 1437 case MoveForward:
1437 cursor->gotoNextLetter(); 1438 cursor->gotoNextLetter();
1438 break; 1439 break;
1439 case MoveWordForward: 1440 case MoveWordForward:
1440 cursor->gotoNextWord(); 1441 cursor->gotoNextWord();
1441 break; 1442 break;
1442 case MoveUp: 1443 case MoveUp:
1443 cursor->gotoUp(); 1444 cursor->gotoUp();
1444 break; 1445 break;
1445 case MovePgUp: 1446 case MovePgUp:
1446 cursor->gotoPageUp( visibleHeight() ); 1447 cursor->gotoPageUp( visibleHeight() );
1447 break; 1448 break;
1448 case MoveDown: 1449 case MoveDown:
1449 cursor->gotoDown(); 1450 cursor->gotoDown();
1450 break; 1451 break;
1451 case MovePgDown: 1452 case MovePgDown:
1452 cursor->gotoPageDown( visibleHeight() ); 1453 cursor->gotoPageDown( visibleHeight() );
1453 break; 1454 break;
1454 case MoveLineStart: 1455 case MoveLineStart:
1455 cursor->gotoLineStart(); 1456 cursor->gotoLineStart();
1456 break; 1457 break;
1457 case MoveHome: 1458 case MoveHome:
1458 cursor->gotoHome(); 1459 cursor->gotoHome();
1459 break; 1460 break;
1460 case MoveLineEnd: 1461 case MoveLineEnd:
1461 cursor->gotoLineEnd(); 1462 cursor->gotoLineEnd();
1462 break; 1463 break;
1463 case MoveEnd: 1464 case MoveEnd:
1464 ensureFormatted( doc->lastParagraph() ); 1465 ensureFormatted( doc->lastParagraph() );
1465 cursor->gotoEnd(); 1466 cursor->gotoEnd();
1466 break; 1467 break;
1467 } 1468 }
1468 updateMicroFocusHint(); 1469 updateMicroFocusHint();
1469 updateCurrentFormat(); 1470 updateCurrentFormat();
1470} 1471}
1471 1472
1472/*! \reimp */ 1473/*! \reimp */
1473 1474
1474void QTextEdit::resizeEvent( QResizeEvent *e ) 1475void QTextEdit::resizeEvent( QResizeEvent *e )
1475{ 1476{
1476 QScrollView::resizeEvent( e ); 1477 QScrollView::resizeEvent( e );
1477 if ( doc->visibleWidth() == 0 ) 1478 if ( doc->visibleWidth() == 0 )
1478 doResize(); 1479 doResize();
1479} 1480}
1480 1481
1481/*! \reimp */ 1482/*! \reimp */
1482 1483
1483void QTextEdit::viewportResizeEvent( QResizeEvent *e ) 1484void QTextEdit::viewportResizeEvent( QResizeEvent *e )
1484{ 1485{
1485 QScrollView::viewportResizeEvent( e ); 1486 QScrollView::viewportResizeEvent( e );
1486 if ( e->oldSize().width() != e->size().width() ) { 1487 if ( e->oldSize().width() != e->size().width() ) {
1487 bool stayAtBottom = e->oldSize().height() != e->size().height() && 1488 bool stayAtBottom = e->oldSize().height() != e->size().height() &&
1488 contentsY() > 0 && contentsY() >= doc->height() - e->oldSize().height(); 1489 contentsY() > 0 && contentsY() >= doc->height() - e->oldSize().height();
1489 doResize(); 1490 doResize();
1490 if ( stayAtBottom ) 1491 if ( stayAtBottom )
1491 scrollToBottom(); 1492 scrollToBottom();
1492 } 1493 }
1493} 1494}
1494 1495
1495/*! 1496/*!
1496 Ensures that the cursor is visible by scrolling the text edit if 1497 Ensures that the cursor is visible by scrolling the text edit if
1497 necessary. 1498 necessary.
1498 1499
1499 \sa setCursorPosition() 1500 \sa setCursorPosition()
1500*/ 1501*/
1501 1502
1502void QTextEdit::ensureCursorVisible() 1503void QTextEdit::ensureCursorVisible()
1503{ 1504{
1504 if ( !isVisible() ) { 1505 if ( !isVisible() ) {
1505 d->ensureCursorVisibleInShowEvent = TRUE; 1506 d->ensureCursorVisibleInShowEvent = TRUE;
1506 return; 1507 return;
1507 } 1508 }
1508 lastFormatted = cursor->paragraph(); 1509 lastFormatted = cursor->paragraph();
1509 formatMore(); 1510 formatMore();
1510 QTextStringChar *chr = cursor->paragraph()->at( cursor->index() ); 1511 QTextStringChar *chr = cursor->paragraph()->at( cursor->index() );
1511 int h = cursor->paragraph()->lineHeightOfChar( cursor->index() ); 1512 int h = cursor->paragraph()->lineHeightOfChar( cursor->index() );
1512 int x = cursor->paragraph()->rect().x() + chr->x + cursor->offsetX(); 1513 int x = cursor->paragraph()->rect().x() + chr->x + cursor->offsetX();
1513 int y = 0; int dummy; 1514 int y = 0; int dummy;
1514 cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y ); 1515 cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y );
1515 y += cursor->paragraph()->rect().y() + cursor->offsetY(); 1516 y += cursor->paragraph()->rect().y() + cursor->offsetY();
1516 int w = 1; 1517 int w = 1;
1517 ensureVisible( x, y + h / 2, w, h / 2 + 2 ); 1518 ensureVisible( x, y + h / 2, w, h / 2 + 2 );
1518} 1519}
1519 1520
1520/*! 1521/*!
1521 \internal 1522 \internal
1522*/ 1523*/
1523void QTextEdit::drawCursor( bool visible ) 1524void QTextEdit::drawCursor( bool visible )
1524{ 1525{
1525 if ( !isUpdatesEnabled() || 1526 if ( !isUpdatesEnabled() ||
1526 !viewport()->isUpdatesEnabled() || 1527 !viewport()->isUpdatesEnabled() ||
1527 !cursor->paragraph() || 1528 !cursor->paragraph() ||
1528 !cursor->paragraph()->isValid() || 1529 !cursor->paragraph()->isValid() ||
1529 !selectedText().isEmpty() || 1530 !selectedText().isEmpty() ||
1530 ( visible && !hasFocus() && !viewport()->hasFocus() && !inDnD ) || 1531 ( visible && !hasFocus() && !viewport()->hasFocus() && !inDnD ) ||
1531 isReadOnly() ) 1532 isReadOnly() )
1532 return; 1533 return;
1533 1534
1534 QPainter p( viewport() ); 1535 QPainter p( viewport() );
1535 QRect r( cursor->topParagraph()->rect() ); 1536 QRect r( cursor->topParagraph()->rect() );
1536 cursor->paragraph()->setChanged( TRUE ); 1537 cursor->paragraph()->setChanged( TRUE );
1537 p.translate( -contentsX() + cursor->totalOffsetX(), -contentsY() + cursor->totalOffsetY() ); 1538 p.translate( -contentsX() + cursor->totalOffsetX(), -contentsY() + cursor->totalOffsetY() );
1538 QPixmap *pix = 0; 1539 QPixmap *pix = 0;
1539 QColorGroup cg( colorGroup() ); 1540 QColorGroup cg( colorGroup() );
1540 if ( cursor->paragraph()->background() ) 1541 if ( cursor->paragraph()->background() )
1541 cg.setBrush( QColorGroup::Base, *cursor->paragraph()->background() ); 1542 cg.setBrush( QColorGroup::Base, *cursor->paragraph()->background() );
1542 else if ( doc->paper() ) 1543 else if ( doc->paper() )
1543 cg.setBrush( QColorGroup::Base, *doc->paper() ); 1544 cg.setBrush( QColorGroup::Base, *doc->paper() );
1544 p.setBrushOrigin( -contentsX(), -contentsY() ); 1545 p.setBrushOrigin( -contentsX(), -contentsY() );
1545 cursor->paragraph()->document()->nextDoubleBuffered = TRUE; 1546 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
1546 if ( !cursor->nestedDepth() ) { 1547 if ( !cursor->nestedDepth() ) {
1547 int h = cursor->paragraph()->lineHeightOfChar( cursor->index() ); 1548 int h = cursor->paragraph()->lineHeightOfChar( cursor->index() );
1548 int dist = 5; 1549 int dist = 5;
1549 if ( ( cursor->paragraph()->alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify ) 1550 if ( ( cursor->paragraph()->alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify )
1550 dist = 50; 1551 dist = 50;
1551 int x = r.x() - cursor->totalOffsetX() + cursor->x() - dist; 1552 int x = r.x() - cursor->totalOffsetX() + cursor->x() - dist;
1552 x = QMAX( x, 0 ); 1553 x = QMAX( x, 0 );
1553 p.setClipRect( QRect( x - contentsX(), 1554 p.setClipRect( QRect( x - contentsX(),
1554 r.y() - cursor->totalOffsetY() + cursor->y() - contentsY(), 2 * dist, h ) ); 1555 r.y() - cursor->totalOffsetY() + cursor->y() - contentsY(), 2 * dist, h ) );
1555 doc->drawParagraph( &p, cursor->paragraph(), x, 1556 doc->drawParagraph( &p, cursor->paragraph(), x,
1556 r.y() - cursor->totalOffsetY() + cursor->y(), 2 * dist, h, pix, cg, visible, cursor ); 1557 r.y() - cursor->totalOffsetY() + cursor->y(), 2 * dist, h, pix, cg, visible, cursor );
1557 } else { 1558 } else {
1558 doc->drawParagraph( &p, cursor->paragraph(), r.x() - cursor->totalOffsetX(), 1559 doc->drawParagraph( &p, cursor->paragraph(), r.x() - cursor->totalOffsetX(),
1559 r.y() - cursor->totalOffsetY(), r.width(), r.height(), 1560 r.y() - cursor->totalOffsetY(), r.width(), r.height(),
1560 pix, cg, visible, cursor ); 1561 pix, cg, visible, cursor );
1561 } 1562 }
1562 cursorVisible = visible; 1563 cursorVisible = visible;
1563} 1564}
1564 1565
1565enum { 1566enum {
1566 IdUndo = 0, 1567 IdUndo = 0,
1567 IdRedo = 1, 1568 IdRedo = 1,
1568 IdCut = 2, 1569 IdCut = 2,
1569 IdCopy = 3, 1570 IdCopy = 3,
1570 IdPaste = 4, 1571 IdPaste = 4,
1571 IdClear = 5, 1572 IdClear = 5,
1572 IdSelectAll = 6 1573 IdSelectAll = 6
1573}; 1574};
1574 1575
1575/*! \reimp */ 1576/*! \reimp */
1576#ifndef QT_NO_WHEELEVENT 1577#ifndef QT_NO_WHEELEVENT
1577void QTextEdit::contentsWheelEvent( QWheelEvent *e ) 1578void QTextEdit::contentsWheelEvent( QWheelEvent *e )
1578{ 1579{
1579 if ( isReadOnly() ) { 1580 if ( isReadOnly() ) {
1580 if ( e->state() & ControlButton ) { 1581 if ( e->state() & ControlButton ) {
1581 if ( e->delta() > 0 ) 1582 if ( e->delta() > 0 )
1582 zoomOut(); 1583 zoomOut();
1583 else if ( e->delta() < 0 ) 1584 else if ( e->delta() < 0 )
1584 zoomIn(); 1585 zoomIn();
1585 return; 1586 return;
1586 } 1587 }
1587 } 1588 }
1588 QScrollView::contentsWheelEvent( e ); 1589 QScrollView::contentsWheelEvent( e );
1589} 1590}
1590#endif 1591#endif
1591 1592
1592/*! \reimp */ 1593/*! \reimp */
1593 1594
1594void QTextEdit::contentsMousePressEvent( QMouseEvent *e ) 1595void QTextEdit::contentsMousePressEvent( QMouseEvent *e )
1595{ 1596{
1596 clearUndoRedo(); 1597 clearUndoRedo();
1597 QTextCursor oldCursor = *cursor; 1598 QTextCursor oldCursor = *cursor;
1598 QTextCursor c = *cursor; 1599 QTextCursor c = *cursor;
1599 mousePos = e->pos(); 1600 mousePos = e->pos();
1600 mightStartDrag = FALSE; 1601 mightStartDrag = FALSE;
1601 pressedLink = QString::null; 1602 pressedLink = QString::null;
1602 1603
1603 if ( e->button() == LeftButton ) { 1604 if ( e->button() == LeftButton ) {
1604 mousePressed = TRUE; 1605 mousePressed = TRUE;
1605 drawCursor( FALSE ); 1606 drawCursor( FALSE );
1606 placeCursor( e->pos() ); 1607 placeCursor( e->pos() );
1607 ensureCursorVisible(); 1608 ensureCursorVisible();
1608 1609
1609 if ( isReadOnly() && linksEnabled() ) { 1610 if ( isReadOnly() && linksEnabled() ) {
1610 QTextCursor c = *cursor; 1611 QTextCursor c = *cursor;
1611 placeCursor( e->pos(), &c, TRUE ); 1612 placeCursor( e->pos(), &c, TRUE );
1612 if ( c.paragraph() && c.paragraph()->at( c.index() ) && 1613 if ( c.paragraph() && c.paragraph()->at( c.index() ) &&
1613 c.paragraph()->at( c.index() )->isAnchor() ) { 1614 c.paragraph()->at( c.index() )->isAnchor() ) {
1614 pressedLink = c.paragraph()->at( c.index() )->anchorHref(); 1615 pressedLink = c.paragraph()->at( c.index() )->anchorHref();
1615 } 1616 }
1616 } 1617 }
1617 1618
1618#ifndef QT_NO_DRAGANDDROP 1619#ifndef QT_NO_DRAGANDDROP
1619 if ( doc->inSelection( QTextDocument::Standard, e->pos() ) ) { 1620 if ( doc->inSelection( QTextDocument::Standard, e->pos() ) ) {
1620 mightStartDrag = TRUE; 1621 mightStartDrag = TRUE;
1621 drawCursor( TRUE ); 1622 drawCursor( TRUE );
1622 dragStartTimer->start( QApplication::startDragTime(), TRUE ); 1623 dragStartTimer->start( QApplication::startDragTime(), TRUE );
1623 dragStartPos = e->pos(); 1624 dragStartPos = e->pos();
1624 return; 1625 return;
1625 } 1626 }
1626#endif 1627#endif
1627 1628
1628 bool redraw = FALSE; 1629 bool redraw = FALSE;
1629 if ( doc->hasSelection( QTextDocument::Standard ) ) { 1630 if ( doc->hasSelection( QTextDocument::Standard ) ) {
1630 if ( !( e->state() & ShiftButton ) ) { 1631 if ( !( e->state() & ShiftButton ) ) {
1631 redraw = doc->removeSelection( QTextDocument::Standard ); 1632 redraw = doc->removeSelection( QTextDocument::Standard );
1632 doc->setSelectionStart( QTextDocument::Standard, *cursor ); 1633 doc->setSelectionStart( QTextDocument::Standard, *cursor );
1633 } else { 1634 } else {
1634 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw; 1635 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw;
1635 } 1636 }
1636 } else { 1637 } else {
1637 if ( isReadOnly() || !( e->state() & ShiftButton ) ) { 1638 if ( isReadOnly() || !( e->state() & ShiftButton ) ) {
1638 doc->setSelectionStart( QTextDocument::Standard, *cursor ); 1639 doc->setSelectionStart( QTextDocument::Standard, *cursor );
1639 } else { 1640 } else {
1640 doc->setSelectionStart( QTextDocument::Standard, c ); 1641 doc->setSelectionStart( QTextDocument::Standard, c );
1641 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw; 1642 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw;
1642 } 1643 }
1643 } 1644 }
1644 1645
1645 for ( int i = 1; i < doc->numSelections(); ++i ) // start with 1 as we don't want to remove the Standard-Selection 1646 for ( int i = 1; i < doc->numSelections(); ++i ) // start with 1 as we don't want to remove the Standard-Selection
1646 redraw = doc->removeSelection( i ) || redraw; 1647 redraw = doc->removeSelection( i ) || redraw;
1647 1648
1648 if ( !redraw ) { 1649 if ( !redraw ) {
1649 drawCursor( TRUE ); 1650 drawCursor( TRUE );
1650 } else { 1651 } else {
1651 repaintChanged(); 1652 repaintChanged();
1652#ifndef QT_NO_CURSOR 1653#ifndef QT_NO_CURSOR
1653 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 1654 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
1654#endif 1655#endif
1655 } 1656 }
1656 } else if ( e->button() == MidButton ) { 1657 } else if ( e->button() == MidButton ) {
1657 bool redraw = doc->removeSelection( QTextDocument::Standard ); 1658 bool redraw = doc->removeSelection( QTextDocument::Standard );
1658 if ( !redraw ) { 1659 if ( !redraw ) {
1659 drawCursor( TRUE ); 1660 drawCursor( TRUE );
1660 } else { 1661 } else {
1661 repaintChanged(); 1662 repaintChanged();
1662#ifndef QT_NO_CURSOR 1663#ifndef QT_NO_CURSOR
1663 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 1664 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
1664#endif 1665#endif
1665 } 1666 }
1666 } 1667 }
1667 1668
1668 if ( *cursor != oldCursor ) 1669 if ( *cursor != oldCursor )
1669 updateCurrentFormat(); 1670 updateCurrentFormat();
1670} 1671}
1671 1672
1672/*! \reimp */ 1673/*! \reimp */
1673 1674
1674void QTextEdit::contentsMouseMoveEvent( QMouseEvent *e ) 1675void QTextEdit::contentsMouseMoveEvent( QMouseEvent *e )
1675{ 1676{
1676 if ( mousePressed ) { 1677 if ( mousePressed ) {
1677#ifndef QT_NO_DRAGANDDROP 1678#ifndef QT_NO_DRAGANDDROP
1678 if ( mightStartDrag ) { 1679 if ( mightStartDrag ) {
1679 dragStartTimer->stop(); 1680 dragStartTimer->stop();
1680 if ( ( e->pos() - dragStartPos ).manhattanLength() > QApplication::startDragDistance() ) 1681 if ( ( e->pos() - dragStartPos ).manhattanLength() > QApplication::startDragDistance() )
1681 startDrag(); 1682 startDrag();
1682#ifndef QT_NO_CURSOR 1683#ifndef QT_NO_CURSOR
1683 if ( !isReadOnly() ) 1684 if ( !isReadOnly() )
1684 viewport()->setCursor( ibeamCursor ); 1685 viewport()->setCursor( ibeamCursor );
1685#endif 1686#endif
1686 return; 1687 return;
1687 } 1688 }
1688#endif 1689#endif
1689 mousePos = e->pos(); 1690 mousePos = e->pos();
1690 handleMouseMove( mousePos ); 1691 handleMouseMove( mousePos );
1691 oldMousePos = mousePos; 1692 oldMousePos = mousePos;
1692 } 1693 }
1693 1694
1694#ifndef QT_NO_CURSOR 1695#ifndef QT_NO_CURSOR
1695 if ( !isReadOnly() && !mousePressed ) { 1696 if ( !isReadOnly() && !mousePressed ) {
1696 if ( doc->hasSelection( QTextDocument::Standard ) && doc->inSelection( QTextDocument::Standard, e->pos() ) ) 1697 if ( doc->hasSelection( QTextDocument::Standard ) && doc->inSelection( QTextDocument::Standard, e->pos() ) )
1697 viewport()->setCursor( arrowCursor ); 1698 viewport()->setCursor( arrowCursor );
1698 else 1699 else
1699 viewport()->setCursor( ibeamCursor ); 1700 viewport()->setCursor( ibeamCursor );
1700 } 1701 }
1701#endif 1702#endif
1702 updateCursor( e->pos() ); 1703 updateCursor( e->pos() );
1703} 1704}
1704 1705
1705/*! \reimp */ 1706/*! \reimp */
1706 1707
1707void QTextEdit::contentsMouseReleaseEvent( QMouseEvent * e ) 1708void QTextEdit::contentsMouseReleaseEvent( QMouseEvent * e )
1708{ 1709{
1709 QTextCursor oldCursor = *cursor; 1710 QTextCursor oldCursor = *cursor;
1710 if ( scrollTimer->isActive() ) 1711 if ( scrollTimer->isActive() )
1711 scrollTimer->stop(); 1712 scrollTimer->stop();
1712#ifndef QT_NO_DRAGANDDROP 1713#ifndef QT_NO_DRAGANDDROP
1713 if ( dragStartTimer->isActive() ) 1714 if ( dragStartTimer->isActive() )
1714 dragStartTimer->stop(); 1715 dragStartTimer->stop();
1715 if ( mightStartDrag ) { 1716 if ( mightStartDrag ) {
1716 selectAll( FALSE ); 1717 selectAll( FALSE );
1717 mousePressed = FALSE; 1718 mousePressed = FALSE;
1718 } 1719 }
1719#endif 1720#endif
1720 if ( mousePressed ) { 1721 if ( mousePressed ) {
1721 mousePressed = FALSE; 1722 mousePressed = FALSE;
1722 } 1723 }
1723 emit cursorPositionChanged( cursor ); 1724 emit cursorPositionChanged( cursor );
1724 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() ); 1725 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
1725 if ( oldCursor != *cursor ) 1726 if ( oldCursor != *cursor )
1726 updateCurrentFormat(); 1727 updateCurrentFormat();
1727 inDoubleClick = FALSE; 1728 inDoubleClick = FALSE;
1728 1729
1729#ifndef QT_NO_NETWORKPROTOCOL 1730#ifndef QT_NO_NETWORKPROTOCOL
1730 if ( !onLink.isEmpty() && onLink == pressedLink && linksEnabled() ) { 1731 if ( !onLink.isEmpty() && onLink == pressedLink && linksEnabled() ) {
1731 QUrl u( doc->context(), onLink, TRUE ); 1732 QUrl u( doc->context(), onLink, TRUE );
1732 emitLinkClicked( u.toString( FALSE, FALSE ) ); 1733 emitLinkClicked( u.toString( FALSE, FALSE ) );
1733 1734
1734 // emitting linkClicked() may result in that the cursor winds 1735 // emitting linkClicked() may result in that the cursor winds
1735 // up hovering over a different valid link - check this and 1736 // up hovering over a different valid link - check this and
1736 // set the appropriate cursor shape 1737 // set the appropriate cursor shape
1737 updateCursor( e->pos() ); 1738 updateCursor( e->pos() );
1738 } 1739 }
1739#endif 1740#endif
1740 drawCursor( TRUE ); 1741 drawCursor( TRUE );
1741 if ( !doc->hasSelection( QTextDocument::Standard, TRUE ) ) 1742 if ( !doc->hasSelection( QTextDocument::Standard, TRUE ) )
1742 doc->removeSelection( QTextDocument::Standard ); 1743 doc->removeSelection( QTextDocument::Standard );
1743 1744
1744 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) ); 1745 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) );
1745 emit selectionChanged(); 1746 emit selectionChanged();
1746} 1747}
1747 1748
1748/*! \reimp */ 1749/*! \reimp */
1749 1750
1750void QTextEdit::contentsMouseDoubleClickEvent( QMouseEvent * ) 1751void QTextEdit::contentsMouseDoubleClickEvent( QMouseEvent * )
1751{ 1752{
1752 QTextCursor c1 = *cursor; 1753 QTextCursor c1 = *cursor;
1753 QTextCursor c2 = *cursor; 1754 QTextCursor c2 = *cursor;
1754 if ( cursor->index() > 0 && !cursor->paragraph()->at( cursor->index()-1 )->c.isSpace() ) 1755 if ( cursor->index() > 0 && !cursor->paragraph()->at( cursor->index()-1 )->c.isSpace() )
1755 c1.gotoPreviousWord(); 1756 c1.gotoPreviousWord();
1756 if ( !cursor->paragraph()->at( cursor->index() )->c.isSpace() && !cursor->atParagEnd() ) 1757 if ( !cursor->paragraph()->at( cursor->index() )->c.isSpace() && !cursor->atParagEnd() )
1757 c2.gotoNextWord(); 1758 c2.gotoNextWord();
1758 1759
1759 doc->setSelectionStart( QTextDocument::Standard, c1 ); 1760 doc->setSelectionStart( QTextDocument::Standard, c1 );
1760 doc->setSelectionEnd( QTextDocument::Standard, c2 ); 1761 doc->setSelectionEnd( QTextDocument::Standard, c2 );
1761 1762
1762 *cursor = c2; 1763 *cursor = c2;
1763 1764
1764 repaintChanged(); 1765 repaintChanged();
1765 1766
1766 inDoubleClick = TRUE; 1767 inDoubleClick = TRUE;
1767 mousePressed = TRUE; 1768 mousePressed = TRUE;
1768} 1769}
1769 1770
1770#ifndef QT_NO_DRAGANDDROP 1771#ifndef QT_NO_DRAGANDDROP
1771 1772
1772/*! \reimp */ 1773/*! \reimp */
1773 1774
1774void QTextEdit::contentsDragEnterEvent( QDragEnterEvent *e ) 1775void QTextEdit::contentsDragEnterEvent( QDragEnterEvent *e )
1775{ 1776{
1776 if ( isReadOnly() || !QTextDrag::canDecode( e ) ) { 1777 if ( isReadOnly() || !QTextDrag::canDecode( e ) ) {
1777 e->ignore(); 1778 e->ignore();
1778 return; 1779 return;
1779 } 1780 }
1780 e->acceptAction(); 1781 e->acceptAction();
1781 inDnD = TRUE; 1782 inDnD = TRUE;
1782} 1783}
1783 1784
1784/*! \reimp */ 1785/*! \reimp */
1785 1786
1786void QTextEdit::contentsDragMoveEvent( QDragMoveEvent *e ) 1787void QTextEdit::contentsDragMoveEvent( QDragMoveEvent *e )
1787{ 1788{
1788 if ( isReadOnly() || !QTextDrag::canDecode( e ) ) { 1789 if ( isReadOnly() || !QTextDrag::canDecode( e ) ) {
1789 e->ignore(); 1790 e->ignore();
1790 return; 1791 return;
1791 } 1792 }
1792 drawCursor( FALSE ); 1793 drawCursor( FALSE );
1793 placeCursor( e->pos(), cursor ); 1794 placeCursor( e->pos(), cursor );
1794 drawCursor( TRUE ); 1795 drawCursor( TRUE );
1795 e->acceptAction(); 1796 e->acceptAction();
1796} 1797}
1797 1798
1798/*! \reimp */ 1799/*! \reimp */
1799 1800
1800void QTextEdit::contentsDragLeaveEvent( QDragLeaveEvent * ) 1801void QTextEdit::contentsDragLeaveEvent( QDragLeaveEvent * )
1801{ 1802{
1802 inDnD = FALSE; 1803 inDnD = FALSE;
1803} 1804}
1804 1805
1805/*! \reimp */ 1806/*! \reimp */
1806 1807
1807void QTextEdit::contentsDropEvent( QDropEvent *e ) 1808void QTextEdit::contentsDropEvent( QDropEvent *e )
1808{ 1809{
1809 if ( isReadOnly() ) 1810 if ( isReadOnly() )
1810 return; 1811 return;
1811 inDnD = FALSE; 1812 inDnD = FALSE;
1812 e->acceptAction(); 1813 e->acceptAction();
1813 QString text; 1814 QString text;
1814 bool intern = FALSE; 1815 bool intern = FALSE;
1815 if ( QTextDrag::decode( e, text ) ) { 1816 if ( QTextDrag::decode( e, text ) ) {
1816 bool hasSel = doc->hasSelection( QTextDocument::Standard ); 1817 bool hasSel = doc->hasSelection( QTextDocument::Standard );
1817 bool internalDrag = e->source() == this || e->source() == viewport(); 1818 bool internalDrag = e->source() == this || e->source() == viewport();
1818 int dropId, dropIndex; 1819 int dropId, dropIndex;
1819 QTextCursor insertCursor = *cursor; 1820 QTextCursor insertCursor = *cursor;
1820 dropId = cursor->paragraph()->paragId(); 1821 dropId = cursor->paragraph()->paragId();
1821 dropIndex = cursor->index(); 1822 dropIndex = cursor->index();
1822 if ( hasSel && internalDrag ) { 1823 if ( hasSel && internalDrag ) {
1823 QTextCursor c1, c2; 1824 QTextCursor c1, c2;
1824 int selStartId, selStartIndex; 1825 int selStartId, selStartIndex;
1825 int selEndId, selEndIndex; 1826 int selEndId, selEndIndex;
1826 c1 = doc->selectionStartCursor( QTextDocument::Standard ); 1827 c1 = doc->selectionStartCursor( QTextDocument::Standard );
1827 c1.restoreState(); 1828 c1.restoreState();
1828 c2 = doc->selectionEndCursor( QTextDocument::Standard ); 1829 c2 = doc->selectionEndCursor( QTextDocument::Standard );
1829 c2.restoreState(); 1830 c2.restoreState();
1830 selStartId = c1.paragraph()->paragId(); 1831 selStartId = c1.paragraph()->paragId();
1831 selStartIndex = c1.index(); 1832 selStartIndex = c1.index();
1832 selEndId = c2.paragraph()->paragId(); 1833 selEndId = c2.paragraph()->paragId();
1833 selEndIndex = c2.index(); 1834 selEndIndex = c2.index();
1834 if ( ( ( dropId > selStartId ) || 1835 if ( ( ( dropId > selStartId ) ||
1835 ( dropId == selStartId && dropIndex > selStartIndex ) ) && 1836 ( dropId == selStartId && dropIndex > selStartIndex ) ) &&
1836 ( ( dropId < selEndId ) || 1837 ( ( dropId < selEndId ) ||
1837 ( dropId == selEndId && dropIndex <= selEndIndex ) ) ) 1838 ( dropId == selEndId && dropIndex <= selEndIndex ) ) )
1838 insertCursor = c1; 1839 insertCursor = c1;
1839 if ( dropId == selEndId && dropIndex > selEndIndex ) { 1840 if ( dropId == selEndId && dropIndex > selEndIndex ) {
1840 insertCursor = c1; 1841 insertCursor = c1;
1841 if ( selStartId == selEndId ) { 1842 if ( selStartId == selEndId ) {
1842 insertCursor.setIndex( dropIndex - 1843 insertCursor.setIndex( dropIndex -
1843 ( selEndIndex - selStartIndex ) ); 1844 ( selEndIndex - selStartIndex ) );
1844 } else { 1845 } else {
1845 insertCursor.setIndex( dropIndex - selEndIndex + 1846 insertCursor.setIndex( dropIndex - selEndIndex +
1846 selStartIndex ); 1847 selStartIndex );
1847 } 1848 }
1848 } 1849 }
1849 } 1850 }
1850 1851
1851 if ( internalDrag && e->action() == QDropEvent::Move ) { 1852 if ( internalDrag && e->action() == QDropEvent::Move ) {
1852 removeSelectedText(); 1853 removeSelectedText();
1853 intern = TRUE; 1854 intern = TRUE;
1854 } else { 1855 } else {
1855 doc->removeSelection( QTextDocument::Standard ); 1856 doc->removeSelection( QTextDocument::Standard );
1856#ifndef QT_NO_CURSOR 1857#ifndef QT_NO_CURSOR
1857 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 1858 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
1858#endif 1859#endif
1859 } 1860 }
1860 drawCursor( FALSE ); 1861 drawCursor( FALSE );
1861 cursor->setParagraph( insertCursor.paragraph() ); 1862 cursor->setParagraph( insertCursor.paragraph() );
1862 cursor->setIndex( insertCursor.index() ); 1863 cursor->setIndex( insertCursor.index() );
1863 drawCursor( TRUE ); 1864 drawCursor( TRUE );
1864 if ( !cursor->nestedDepth() ) { 1865 if ( !cursor->nestedDepth() ) {
1865 insert( text, FALSE, TRUE, FALSE ); 1866 insert( text, FALSE, TRUE, FALSE );
1866 } else { 1867 } else {
1867 if ( intern ) 1868 if ( intern )
1868 undo(); 1869 undo();
1869 e->ignore(); 1870 e->ignore();
1870 } 1871 }
1871 } 1872 }
1872} 1873}
1873 1874
1874#endif 1875#endif
1875 1876
1876void QTextEdit::autoScrollTimerDone() 1877void QTextEdit::autoScrollTimerDone()
1877{ 1878{
1878 if ( mousePressed ) 1879 if ( mousePressed )
1879 handleMouseMove( viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) ) ); 1880 handleMouseMove( viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) ) );
1880} 1881}
1881 1882
1882void QTextEdit::handleMouseMove( const QPoint& pos ) 1883void QTextEdit::handleMouseMove( const QPoint& pos )
1883{ 1884{
1884 if ( !mousePressed ) 1885 if ( !mousePressed )
1885 return; 1886 return;
1886 1887
1887 if ( !scrollTimer->isActive() && pos.y() < contentsY() || pos.y() > contentsY() + visibleHeight() ) 1888 if ( !scrollTimer->isActive() && pos.y() < contentsY() || pos.y() > contentsY() + visibleHeight() )
1888 scrollTimer->start( 100, FALSE ); 1889 scrollTimer->start( 100, FALSE );
1889 else if ( scrollTimer->isActive() && pos.y() >= contentsY() && pos.y() <= contentsY() + visibleHeight() ) 1890 else if ( scrollTimer->isActive() && pos.y() >= contentsY() && pos.y() <= contentsY() + visibleHeight() )
1890 scrollTimer->stop(); 1891 scrollTimer->stop();
1891 1892
1892 drawCursor( FALSE ); 1893 drawCursor( FALSE );
1893 QTextCursor oldCursor = *cursor; 1894 QTextCursor oldCursor = *cursor;
1894 1895
1895 placeCursor( pos ); 1896 placeCursor( pos );
1896 1897
1897 if ( inDoubleClick ) { 1898 if ( inDoubleClick ) {
1898 QTextCursor cl = *cursor; 1899 QTextCursor cl = *cursor;
1899 cl.gotoPreviousWord(); 1900 cl.gotoPreviousWord();
1900 QTextCursor cr = *cursor; 1901 QTextCursor cr = *cursor;
1901 cr.gotoNextWord(); 1902 cr.gotoNextWord();
1902 1903
1903 int diff = QABS( oldCursor.paragraph()->at( oldCursor.index() )->x - mousePos.x() ); 1904 int diff = QABS( oldCursor.paragraph()->at( oldCursor.index() )->x - mousePos.x() );
1904 int ldiff = QABS( cl.paragraph()->at( cl.index() )->x - mousePos.x() ); 1905 int ldiff = QABS( cl.paragraph()->at( cl.index() )->x - mousePos.x() );
1905 int rdiff = QABS( cr.paragraph()->at( cr.index() )->x - mousePos.x() ); 1906 int rdiff = QABS( cr.paragraph()->at( cr.index() )->x - mousePos.x() );
1906 1907
1907 1908
1908 if ( cursor->paragraph()->lineStartOfChar( cursor->index() ) != 1909 if ( cursor->paragraph()->lineStartOfChar( cursor->index() ) !=
1909 oldCursor.paragraph()->lineStartOfChar( oldCursor.index() ) ) 1910 oldCursor.paragraph()->lineStartOfChar( oldCursor.index() ) )
1910 diff = 0xFFFFFF; 1911 diff = 0xFFFFFF;
1911 1912
1912 if ( rdiff < diff && rdiff < ldiff ) 1913 if ( rdiff < diff && rdiff < ldiff )
1913 *cursor = cr; 1914 *cursor = cr;
1914 else if ( ldiff < diff && ldiff < rdiff ) 1915 else if ( ldiff < diff && ldiff < rdiff )
1915 *cursor = cl; 1916 *cursor = cl;
1916 else 1917 else
1917 *cursor = oldCursor; 1918 *cursor = oldCursor;
1918 1919
1919 } 1920 }
1920 ensureCursorVisible(); 1921 ensureCursorVisible();
1921 1922
1922 bool redraw = FALSE; 1923 bool redraw = FALSE;
1923 if ( doc->hasSelection( QTextDocument::Standard ) ) { 1924 if ( doc->hasSelection( QTextDocument::Standard ) ) {
1924 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw; 1925 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw;
1925 } 1926 }
1926 1927
1927 if ( !redraw ) { 1928 if ( !redraw ) {
1928 drawCursor( TRUE ); 1929 drawCursor( TRUE );
1929 } else { 1930 } else {
1930 repaintChanged(); 1931 repaintChanged();
1931 drawCursor( TRUE ); 1932 drawCursor( TRUE );
1932 } 1933 }
1933 1934
1934 if ( currentFormat && currentFormat->key() != cursor->paragraph()->at( cursor->index() )->format()->key() ) { 1935 if ( currentFormat && currentFormat->key() != cursor->paragraph()->at( cursor->index() )->format()->key() ) {
1935 currentFormat->removeRef(); 1936 currentFormat->removeRef();
1936 currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( cursor->index() )->format() ); 1937 currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( cursor->index() )->format() );
1937 if ( currentFormat->isMisspelled() ) { 1938 if ( currentFormat->isMisspelled() ) {
1938 currentFormat->removeRef(); 1939 currentFormat->removeRef();
1939 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() ); 1940 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() );
1940 } 1941 }
1941 emit currentFontChanged( currentFormat->font() ); 1942 emit currentFontChanged( currentFormat->font() );
1942 emit currentColorChanged( currentFormat->color() ); 1943 emit currentColorChanged( currentFormat->color() );
1943 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() ); 1944 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
1944 } 1945 }
1945 1946
1946 if ( currentAlignment != cursor->paragraph()->alignment() ) { 1947 if ( currentAlignment != cursor->paragraph()->alignment() ) {
1947 currentAlignment = cursor->paragraph()->alignment(); 1948 currentAlignment = cursor->paragraph()->alignment();
1948 block_set_alignment = TRUE; 1949 block_set_alignment = TRUE;
1949 emit currentAlignmentChanged( currentAlignment ); 1950 emit currentAlignmentChanged( currentAlignment );
1950 block_set_alignment = FALSE; 1951 block_set_alignment = FALSE;
1951 } 1952 }
1952} 1953}
1953 1954
1954/*! 1955/*!
1955 \fn void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c ) 1956 \fn void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c )
1956 Places the cursor \a c at the character which is closest to position 1957 Places the cursor \a c at the character which is closest to position
1957 \a pos (in contents coordinates). If \a c is 0, the default text 1958 \a pos (in contents coordinates). If \a c is 0, the default text
1958 cursor is used. 1959 cursor is used.
1959 1960
1960 \sa setCursorPosition() 1961 \sa setCursorPosition()
1961*/ 1962*/
1962 1963
1963void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c, bool link ) 1964void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c, bool link )
1964{ 1965{
1965 if ( !c ) 1966 if ( !c )
1966 c = cursor; 1967 c = cursor;
1967 1968
1968 c->restoreState(); 1969 c->restoreState();
1969 QTextParagraph *s = doc->firstParagraph(); 1970 QTextParagraph *s = doc->firstParagraph();
1970 c->place( pos, s, link ); 1971 c->place( pos, s, link );
1971 updateMicroFocusHint(); 1972 updateMicroFocusHint();
1972} 1973}
1973 1974
1974 1975
1975void QTextEdit::updateMicroFocusHint() 1976void QTextEdit::updateMicroFocusHint()
1976{ 1977{
1977 QTextCursor c( *cursor ); 1978 QTextCursor c( *cursor );
1978 if ( d->preeditStart != -1 ) 1979 if ( d->preeditStart != -1 )
1979 c.setIndex( d->preeditStart ); 1980 c.setIndex( d->preeditStart );
1980 1981
1981 if ( hasFocus() || viewport()->hasFocus() ) { 1982 if ( hasFocus() || viewport()->hasFocus() ) {
1982 int h = c.paragraph()->lineHeightOfChar( cursor->index() ); 1983 int h = c.paragraph()->lineHeightOfChar( cursor->index() );
1983 if ( !readonly ) { 1984 if ( !readonly ) {
1984 QFont f = c.paragraph()->at( c.index() )->format()->font(); 1985 QFont f = c.paragraph()->at( c.index() )->format()->font();
1985 setMicroFocusHint( c.x() - contentsX() + frameWidth(), 1986 setMicroFocusHint( c.x() - contentsX() + frameWidth(),
1986 c.y() + cursor->paragraph()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE ); 1987 c.y() + cursor->paragraph()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
1987 } 1988 }
1988 } 1989 }
1989} 1990}
1990 1991
1991 1992
1992 1993
1993void QTextEdit::formatMore() 1994void QTextEdit::formatMore()
1994{ 1995{
1995 if ( !lastFormatted ) 1996 if ( !lastFormatted )
1996 return; 1997 return;
1997 1998
1998 int bottom = contentsHeight(); 1999 int bottom = contentsHeight();
1999 int lastBottom = -1; 2000 int lastBottom = -1;
2000 int to = 20; 2001 int to = 20;
2001 bool firstVisible = FALSE; 2002 bool firstVisible = FALSE;
2002 QRect cr( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 2003 QRect cr( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
2003 for ( int i = 0; ( i < to || firstVisible ) && lastFormatted; ++i ) { 2004 for ( int i = 0; ( i < to || firstVisible ) && lastFormatted; ++i ) {
2004 lastFormatted->format(); 2005 lastFormatted->format();
2005 if ( i == 0 ) 2006 if ( i == 0 )
2006 firstVisible = lastFormatted->rect().intersects( cr ); 2007 firstVisible = lastFormatted->rect().intersects( cr );
2007 else if ( firstVisible ) 2008 else if ( firstVisible )
2008 firstVisible = lastFormatted->rect().intersects( cr ); 2009 firstVisible = lastFormatted->rect().intersects( cr );
2009 bottom = QMAX( bottom, lastFormatted->rect().top() + 2010 bottom = QMAX( bottom, lastFormatted->rect().top() +
2010 lastFormatted->rect().height() ); 2011 lastFormatted->rect().height() );
2011 lastBottom = lastFormatted->rect().top() + lastFormatted->rect().height(); 2012 lastBottom = lastFormatted->rect().top() + lastFormatted->rect().height();
2012 lastFormatted = lastFormatted->next(); 2013 lastFormatted = lastFormatted->next();
2013 if ( lastFormatted ) 2014 if ( lastFormatted )
2014 lastBottom = -1; 2015 lastBottom = -1;
2015 } 2016 }
2016 2017
2017 if ( bottom > contentsHeight() ) { 2018 if ( bottom > contentsHeight() ) {
2018 resizeContents( contentsWidth(), QMAX( doc->height(), bottom ) ); 2019 resizeContents( contentsWidth(), QMAX( doc->height(), bottom ) );
2019 } else if ( lastBottom != -1 && lastBottom < contentsHeight() ) { 2020 } else if ( lastBottom != -1 && lastBottom < contentsHeight() ) {
2020 resizeContents( contentsWidth(), QMAX( doc->height(), lastBottom ) ); 2021 resizeContents( contentsWidth(), QMAX( doc->height(), lastBottom ) );
2021 if ( contentsHeight() < visibleHeight() ) 2022 if ( contentsHeight() < visibleHeight() )
2022 updateContents( 0, contentsHeight(), visibleWidth(), 2023 updateContents( 0, contentsHeight(), visibleWidth(),
2023 visibleHeight() - contentsHeight() ); 2024 visibleHeight() - contentsHeight() );
2024 } 2025 }
2025 2026
2026 if ( lastFormatted ) 2027 if ( lastFormatted )
2027 formatTimer->start( interval, TRUE ); 2028 formatTimer->start( interval, TRUE );
2028 else 2029 else
2029 interval = QMAX( 0, interval ); 2030 interval = QMAX( 0, interval );
2030} 2031}
2031 2032
2032void QTextEdit::doResize() 2033void QTextEdit::doResize()
2033{ 2034{
2034 if ( wrapMode == FixedPixelWidth ) 2035 if ( wrapMode == FixedPixelWidth )
2035 return; 2036 return;
2036 doc->setMinimumWidth( -1 ); 2037 doc->setMinimumWidth( -1 );
2037 resizeContents( 0, 0 ); 2038 resizeContents( 0, 0 );
2038 doc->setWidth( visibleWidth() ); 2039 doc->setWidth( visibleWidth() );
2039 doc->invalidate(); 2040 doc->invalidate();
2040 lastFormatted = doc->firstParagraph(); 2041 lastFormatted = doc->firstParagraph();
2041 interval = 0; 2042 interval = 0;
2042 formatMore(); 2043 formatMore();
2043 repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), FALSE ); 2044 repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), FALSE );
2044} 2045}
2045 2046
2046/*! \internal */ 2047/*! \internal */
2047 2048
2048void QTextEdit::doChangeInterval() 2049void QTextEdit::doChangeInterval()
2049{ 2050{
2050 interval = 0; 2051 interval = 0;
2051} 2052}
2052 2053
2053/*! \reimp */ 2054/*! \reimp */
2054 2055
2055bool QTextEdit::eventFilter( QObject *o, QEvent *e ) 2056bool QTextEdit::eventFilter( QObject *o, QEvent *e )
2056{ 2057{
2057 if ( o == this || o == viewport() ) { 2058 if ( o == this || o == viewport() ) {
2058 if ( e->type() == QEvent::FocusIn ) { 2059 if ( e->type() == QEvent::FocusIn ) {
2059 blinkTimer->start( QApplication::cursorFlashTime() / 2 ); 2060 blinkTimer->start( QApplication::cursorFlashTime() / 2 );
2060 drawCursor( TRUE ); 2061 drawCursor( TRUE );
2061 updateMicroFocusHint(); 2062 updateMicroFocusHint();
2062 } else if ( e->type() == QEvent::FocusOut ) { 2063 } else if ( e->type() == QEvent::FocusOut ) {
2063 blinkTimer->stop(); 2064 blinkTimer->stop();
2064 drawCursor( FALSE ); 2065 drawCursor( FALSE );
2065 } 2066 }
2066 } 2067 }
2067 2068
2068 return QScrollView::eventFilter( o, e ); 2069 return QScrollView::eventFilter( o, e );
2069} 2070}
2070 2071
2071/*! Inserts \a text at the current cursor position. If \a indent is 2072/*! Inserts \a text at the current cursor position. If \a indent is
2072 TRUE, the paragraph is re-indented. If \a checkNewLine is TRUE, 2073 TRUE, the paragraph is re-indented. If \a checkNewLine is TRUE,
2073 newline characters in \a text result in hard line breaks (i.e. new 2074 newline characters in \a text result in hard line breaks (i.e. new
2074 paragraphs). If \a checkNewLine is FALSE and there are newlines in 2075 paragraphs). If \a checkNewLine is FALSE and there are newlines in
2075 \a text, the behavior is undefined. If \a checkNewLine is FALSE the 2076 \a text, the behavior is undefined. If \a checkNewLine is FALSE the
2076 behaviour of the editor is undefined if the \a text contains 2077 behaviour of the editor is undefined if the \a text contains
2077 newlines. If \a removeSelected is TRUE, any selected text (in 2078 newlines. If \a removeSelected is TRUE, any selected text (in
2078 selection 0) is removed before the text is inserted. 2079 selection 0) is removed before the text is inserted.
2079 2080
2080 \sa paste() pasteSubType() 2081 \sa paste() pasteSubType()
2081*/ 2082*/
2082 2083
2083void QTextEdit::insert( const QString &text, bool indent, bool checkNewLine, bool removeSelected ) 2084void QTextEdit::insert( const QString &text, bool indent, bool checkNewLine, bool removeSelected )
2084{ 2085{
2085 if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough 2086 if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough
2086 return; 2087 return;
2087 QString txt( text ); 2088 QString txt( text );
2088 drawCursor( FALSE ); 2089 drawCursor( FALSE );
2089 if ( !isReadOnly() && doc->hasSelection( QTextDocument::Standard ) && removeSelected ) 2090 if ( !isReadOnly() && doc->hasSelection( QTextDocument::Standard ) && removeSelected )
2090 removeSelectedText(); 2091 removeSelectedText();
2091 QTextCursor c2 = *cursor; 2092 QTextCursor c2 = *cursor;
2092 int oldLen = 0; 2093 int oldLen = 0;
2093 2094
2094 if ( undoEnabled && !isReadOnly() ) { 2095 if ( undoEnabled && !isReadOnly() ) {
2095 checkUndoRedoInfo( UndoRedoInfo::Insert ); 2096 checkUndoRedoInfo( UndoRedoInfo::Insert );
2096 if ( !undoRedoInfo.valid() ) { 2097 if ( !undoRedoInfo.valid() ) {
2097 undoRedoInfo.id = cursor->paragraph()->paragId(); 2098 undoRedoInfo.id = cursor->paragraph()->paragId();
2098 undoRedoInfo.index = cursor->index(); 2099 undoRedoInfo.index = cursor->index();
2099 undoRedoInfo.d->text = QString::null; 2100 undoRedoInfo.d->text = QString::null;
2100 } 2101 }
2101 oldLen = undoRedoInfo.d->text.length(); 2102 oldLen = undoRedoInfo.d->text.length();
2102 } 2103 }
2103 2104
2104 lastFormatted = checkNewLine && cursor->paragraph()->prev() ? 2105 lastFormatted = checkNewLine && cursor->paragraph()->prev() ?
2105 cursor->paragraph()->prev() : cursor->paragraph(); 2106 cursor->paragraph()->prev() : cursor->paragraph();
2106 QTextCursor oldCursor = *cursor; 2107 QTextCursor oldCursor = *cursor;
2107 cursor->insert( txt, checkNewLine ); 2108 cursor->insert( txt, checkNewLine );
2108 if ( doc->useFormatCollection() ) { 2109 if ( doc->useFormatCollection() ) {
2109 doc->setSelectionStart( QTextDocument::Temp, oldCursor ); 2110 doc->setSelectionStart( QTextDocument::Temp, oldCursor );
2110 doc->setSelectionEnd( QTextDocument::Temp, *cursor ); 2111 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
2111 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format ); 2112 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format );
2112 doc->removeSelection( QTextDocument::Temp ); 2113 doc->removeSelection( QTextDocument::Temp );
2113 } 2114 }
2114 2115
2115 if ( indent && ( txt == "{" || txt == "}" || txt == ":" || txt == "#" ) ) 2116 if ( indent && ( txt == "{" || txt == "}" || txt == ":" || txt == "#" ) )
2116 cursor->indent(); 2117 cursor->indent();
2117 formatMore(); 2118 formatMore();
2118 repaintChanged(); 2119 repaintChanged();
2119 ensureCursorVisible(); 2120 ensureCursorVisible();
2120 drawCursor( TRUE ); 2121 drawCursor( TRUE );
2121 2122
2122 if ( undoEnabled && !isReadOnly() ) { 2123 if ( undoEnabled && !isReadOnly() ) {
2123 undoRedoInfo.d->text += txt; 2124 undoRedoInfo.d->text += txt;
2124 if ( !doc->preProcessor() ) { 2125 if ( !doc->preProcessor() ) {
2125 for ( int i = 0; i < (int)txt.length(); ++i ) { 2126 for ( int i = 0; i < (int)txt.length(); ++i ) {
2126 if ( txt[ i ] != '\n' && c2.paragraph()->at( c2.index() )->format() ) { 2127 if ( txt[ i ] != '\n' && c2.paragraph()->at( c2.index() )->format() ) {
2127 c2.paragraph()->at( c2.index() )->format()->addRef(); 2128 c2.paragraph()->at( c2.index() )->format()->addRef();
2128 undoRedoInfo.d->text.setFormat( oldLen + i, c2.paragraph()->at( c2.index() )->format(), TRUE ); 2129 undoRedoInfo.d->text.setFormat( oldLen + i, c2.paragraph()->at( c2.index() )->format(), TRUE );
2129 } 2130 }
2130 c2.gotoNextLetter(); 2131 c2.gotoNextLetter();
2131 } 2132 }
2132 } 2133 }
2133 } 2134 }
2134 2135
2135 if ( !removeSelected ) { 2136 if ( !removeSelected ) {
2136 doc->setSelectionStart( QTextDocument::Standard, oldCursor ); 2137 doc->setSelectionStart( QTextDocument::Standard, oldCursor );
2137 doc->setSelectionEnd( QTextDocument::Standard, *cursor ); 2138 doc->setSelectionEnd( QTextDocument::Standard, *cursor );
2138 repaintChanged(); 2139 repaintChanged();
2139 } 2140 }
2140 updateMicroFocusHint(); 2141 updateMicroFocusHint();
2141 setModified(); 2142 setModified();
2142 emit textChanged(); 2143 emit textChanged();
2143} 2144}
2144 2145
2145/*! Inserts \a text in the paragraph \a para and position \a index */ 2146/*! Inserts \a text in the paragraph \a para and position \a index */
2146 2147
2147void QTextEdit::insertAt( const QString &text, int para, int index ) 2148void QTextEdit::insertAt( const QString &text, int para, int index )
2148{ 2149{
2149 removeSelection( QTextDocument::Standard ); 2150 removeSelection( QTextDocument::Standard );
2150 QTextParagraph *p = doc->paragAt( para ); 2151 QTextParagraph *p = doc->paragAt( para );
2151 if ( !p ) 2152 if ( !p )
2152 return; 2153 return;
2153 QTextCursor tmp = *cursor; 2154 QTextCursor tmp = *cursor;
2154 cursor->setParagraph( p ); 2155 cursor->setParagraph( p );
2155 cursor->setIndex( index ); 2156 cursor->setIndex( index );
2156 insert( text, FALSE, TRUE, FALSE ); 2157 insert( text, FALSE, TRUE, FALSE );
2157 *cursor = tmp; 2158 *cursor = tmp;
2158 removeSelection( QTextDocument::Standard ); 2159 removeSelection( QTextDocument::Standard );
2159} 2160}
2160 2161
2161/*! Inserts \a text as the paragraph at position \a para. If \a para 2162/*! Inserts \a text as the paragraph at position \a para. If \a para
2162 is -1, the text is appended. 2163 is -1, the text is appended.
2163*/ 2164*/
2164 2165
2165void QTextEdit::insertParagraph( const QString &text, int para ) 2166void QTextEdit::insertParagraph( const QString &text, int para )
2166{ 2167{
2167 QTextParagraph *p = doc->paragAt( para ); 2168 QTextParagraph *p = doc->paragAt( para );
2168 if ( p ) { 2169 if ( p ) {
2169 QTextCursor tmp( doc ); 2170 QTextCursor tmp( doc );
2170 tmp.setParagraph( p ); 2171 tmp.setParagraph( p );
2171 tmp.setIndex( 0 ); 2172 tmp.setIndex( 0 );
2172 tmp.insert( text, TRUE ); 2173 tmp.insert( text, TRUE );
2173 tmp.splitAndInsertEmptyParagraph(); 2174 tmp.splitAndInsertEmptyParagraph();
2174 repaintChanged(); 2175 repaintChanged();
2175 } else { 2176 } else {
2176 append( text ); 2177 append( text );
2177 } 2178 }
2178} 2179}
2179 2180
2180/*! Removes the paragraph \a para */ 2181/*! Removes the paragraph \a para */
2181 2182
2182void QTextEdit::removeParagraph( int para ) 2183void QTextEdit::removeParagraph( int para )
2183{ 2184{
2184 QTextParagraph *p = doc->paragAt( para ); 2185 QTextParagraph *p = doc->paragAt( para );
2185 if ( !p ) 2186 if ( !p )
2186 return; 2187 return;
2187 for ( int i = 0; i < doc->numSelections(); ++i ) 2188 for ( int i = 0; i < doc->numSelections(); ++i )
2188 doc->removeSelection( i ); 2189 doc->removeSelection( i );
2189 2190
2190 if ( p == doc->firstParagraph() && p == doc->lastParagraph() ) { 2191 if ( p == doc->firstParagraph() && p == doc->lastParagraph() ) {
2191 p->remove( 0, p->length() - 1 ); 2192 p->remove( 0, p->length() - 1 );
2192 repaintChanged(); 2193 repaintChanged();
2193 return; 2194 return;
2194 } 2195 }
2195 drawCursor( FALSE ); 2196 drawCursor( FALSE );
2196 bool resetCursor = cursor->paragraph() == p; 2197 bool resetCursor = cursor->paragraph() == p;
2197 if ( p->prev() ) 2198 if ( p->prev() )
2198 p->prev()->setNext( p->next() ); 2199 p->prev()->setNext( p->next() );
2199 else 2200 else
2200 doc->setFirstParagraph( p->next() ); 2201 doc->setFirstParagraph( p->next() );
2201 if ( p->next() ) 2202 if ( p->next() )
2202 p->next()->setPrev( p->prev() ); 2203 p->next()->setPrev( p->prev() );
2203 else 2204 else
2204 doc->setLastParagraph( p->prev() ); 2205 doc->setLastParagraph( p->prev() );
2205 QTextParagraph *start = p->next(); 2206 QTextParagraph *start = p->next();
2206 int h = p->rect().height(); 2207 int h = p->rect().height();
2207 delete p; 2208 delete p;
2208 p = start; 2209 p = start;
2209 int dy = -h; 2210 int dy = -h;
2210 while ( p ) { 2211 while ( p ) {
2211 p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 ); 2212 p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 );
2212 p->move( dy ); 2213 p->move( dy );
2213 p->invalidate( 0 ); 2214 p->invalidate( 0 );
2214 p->setEndState( -1 ); 2215 p->setEndState( -1 );
2215 p = p->next(); 2216 p = p->next();
2216 } 2217 }
2217 2218
2218 if ( resetCursor ) { 2219 if ( resetCursor ) {
2219 cursor->setParagraph( doc->firstParagraph() ); 2220 cursor->setParagraph( doc->firstParagraph() );
2220 cursor->setIndex( 0 ); 2221 cursor->setIndex( 0 );
2221 } 2222 }
2222 repaintChanged(); 2223 repaintChanged();
2223 drawCursor( TRUE ); 2224 drawCursor( TRUE );
2224} 2225}
2225 2226
2226/*! 2227/*!
2227 Undoes the last operation. 2228 Undoes the last operation.
2228 2229
2229 If there is no operation to undo, e.g. there is no undo step in the 2230 If there is no operation to undo, e.g. there is no undo step in the
2230 undo/redo history, nothing happens. 2231 undo/redo history, nothing happens.
2231 2232
2232 \sa undoAvailable() redo() undoDepth() 2233 \sa undoAvailable() redo() undoDepth()
2233*/ 2234*/
2234 2235
2235void QTextEdit::undo() 2236void QTextEdit::undo()
2236{ 2237{
2237 // XXX FIXME The next line is here because there may be a command 2238 // XXX FIXME The next line is here because there may be a command
2238 // that needs to be 'flushed'. The FIXME is because I am not 2239 // that needs to be 'flushed'. The FIXME is because I am not
2239 // 100% certain this is the right call to do this. 2240 // 100% certain this is the right call to do this.
2240 clearUndoRedo(); 2241 clearUndoRedo();
2241 if ( isReadOnly() || !doc->commands()->isUndoAvailable() || !undoEnabled ) 2242 if ( isReadOnly() || !doc->commands()->isUndoAvailable() || !undoEnabled )
2242 return; 2243 return;
2243 2244
2244 for ( int i = 0; i < (int)doc->numSelections(); ++i ) 2245 for ( int i = 0; i < (int)doc->numSelections(); ++i )
2245 doc->removeSelection( i ); 2246 doc->removeSelection( i );
2246 2247
2247#ifndef QT_NO_CURSOR 2248#ifndef QT_NO_CURSOR
2248 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 2249 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
2249#endif 2250#endif
2250 2251
2251 clearUndoRedo(); 2252 clearUndoRedo();
2252 drawCursor( FALSE ); 2253 drawCursor( FALSE );
2253 QTextCursor *c = doc->undo( cursor ); 2254 QTextCursor *c = doc->undo( cursor );
2254 if ( !c ) { 2255 if ( !c ) {
2255 drawCursor( TRUE ); 2256 drawCursor( TRUE );
2256 return; 2257 return;
2257 } 2258 }
2258 lastFormatted = 0; 2259 lastFormatted = 0;
2259 ensureCursorVisible(); 2260 ensureCursorVisible();
2260 repaintChanged(); 2261 repaintChanged();
2261 drawCursor( TRUE ); 2262 drawCursor( TRUE );
2262 updateMicroFocusHint(); 2263 updateMicroFocusHint();
2263 setModified(); 2264 setModified();
2264 emit textChanged(); 2265 emit textChanged();
2265} 2266}
2266 2267
2267/*! 2268/*!
2268 Redoes the last operation. 2269 Redoes the last operation.
2269 2270
2270 If there is no operation to redo, e.g. there is no redo step in the 2271 If there is no operation to redo, e.g. there is no redo step in the
2271 undo/redo history, nothing happens. 2272 undo/redo history, nothing happens.
2272 2273
2273 \sa redoAvailable() undo() undoDepth() 2274 \sa redoAvailable() undo() undoDepth()
2274*/ 2275*/
2275 2276
2276void QTextEdit::redo() 2277void QTextEdit::redo()
2277{ 2278{
2278 if ( isReadOnly() || !doc->commands()->isRedoAvailable() || !undoEnabled ) 2279 if ( isReadOnly() || !doc->commands()->isRedoAvailable() || !undoEnabled )
2279 return; 2280 return;
2280 2281
2281 for ( int i = 0; i < (int)doc->numSelections(); ++i ) 2282 for ( int i = 0; i < (int)doc->numSelections(); ++i )
2282 doc->removeSelection( i ); 2283 doc->removeSelection( i );
2283 2284
2284#ifndef QT_NO_CURSOR 2285#ifndef QT_NO_CURSOR
2285 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 2286 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
2286#endif 2287#endif
2287 2288
2288 clearUndoRedo(); 2289 clearUndoRedo();
2289 drawCursor( FALSE ); 2290 drawCursor( FALSE );
2290 QTextCursor *c = doc->redo( cursor ); 2291 QTextCursor *c = doc->redo( cursor );
2291 if ( !c ) { 2292 if ( !c ) {
2292 drawCursor( TRUE ); 2293 drawCursor( TRUE );
2293 return; 2294 return;
2294 } 2295 }
2295 lastFormatted = 0; 2296 lastFormatted = 0;
2296 ensureCursorVisible(); 2297 ensureCursorVisible();
2297 repaintChanged(); 2298 repaintChanged();
2298 ensureCursorVisible(); 2299 ensureCursorVisible();
2299 drawCursor( TRUE ); 2300 drawCursor( TRUE );
2300 updateMicroFocusHint(); 2301 updateMicroFocusHint();
2301 setModified(); 2302 setModified();
2302 emit textChanged(); 2303 emit textChanged();
2303} 2304}
2304 2305
2305/*! 2306/*!
2306 Pastes the text from the clipboard into the text edit at the current 2307 Pastes the text from the clipboard into the text edit at the current
2307 cursor position. Only plain text is pasted. 2308 cursor position. Only plain text is pasted.
2308 2309
2309 If there is no text in the clipboard nothing happens. 2310 If there is no text in the clipboard nothing happens.
2310 2311
2311 \sa pasteSubType() cut() QTextEdit::copy() 2312 \sa pasteSubType() cut() QTextEdit::copy()
2312*/ 2313*/
2313 2314
2314void QTextEdit::paste() 2315void QTextEdit::paste()
2315{ 2316{
2316#ifndef QT_NO_CLIPBOARD 2317#ifndef QT_NO_CLIPBOARD
2317 if ( isReadOnly() ) 2318 if ( isReadOnly() )
2318 return; 2319 return;
2319 pasteSubType( "plain" ); 2320 pasteSubType( "plain" );
2320 updateMicroFocusHint(); 2321 updateMicroFocusHint();
2321#endif 2322#endif
2322} 2323}
2323 2324
2324void QTextEdit::checkUndoRedoInfo( UndoRedoInfo::Type t ) 2325void QTextEdit::checkUndoRedoInfo( UndoRedoInfo::Type t )
2325{ 2326{
2326 if ( undoRedoInfo.valid() && t != undoRedoInfo.type ) { 2327 if ( undoRedoInfo.valid() && t != undoRedoInfo.type ) {
2327 clearUndoRedo(); 2328 clearUndoRedo();
2328 } 2329 }
2329 undoRedoInfo.type = t; 2330 undoRedoInfo.type = t;
2330} 2331}
2331 2332
2332/*! Repaints any paragraphs that have changed. 2333/*! Repaints any paragraphs that have changed.
2333 2334
2334 Although used extensively internally you shouldn't need to call this 2335 Although used extensively internally you shouldn't need to call this
2335 yourself. 2336 yourself.
2336*/ 2337*/
2337 2338
2338void QTextEdit::repaintChanged() 2339void QTextEdit::repaintChanged()
2339{ 2340{
2340 if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() ) 2341 if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() )
2341 return; 2342 return;
2342 QPainter p( viewport() ); 2343 QPainter p( viewport() );
2343 p.translate( -contentsX(), -contentsY() ); 2344 p.translate( -contentsX(), -contentsY() );
2344 paintDocument( FALSE, &p, contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 2345 paintDocument( FALSE, &p, contentsX(), contentsY(), visibleWidth(), visibleHeight() );
2345} 2346}
2346 2347
2347/*! 2348/*!
2348 Copies the selected text (from selection 0) to the clipboard and 2349 Copies the selected text (from selection 0) to the clipboard and
2349 deletes it from the text edit. 2350 deletes it from the text edit.
2350 2351
2351 If there is no selected text (in selection 0) nothing happens. 2352 If there is no selected text (in selection 0) nothing happens.
2352 2353
2353 \sa QTextEdit::copy() paste() pasteSubType() 2354 \sa QTextEdit::copy() paste() pasteSubType()
2354*/ 2355*/
2355 2356
2356void QTextEdit::cut() 2357void QTextEdit::cut()
2357{ 2358{
2358 if ( isReadOnly() ) 2359 if ( isReadOnly() )
2359 return; 2360 return;
2360 2361
2361 QString t; 2362 QString t;
2362 if ( doc->hasSelection( QTextDocument::Standard ) && 2363 if ( doc->hasSelection( QTextDocument::Standard ) &&
2363 !( t = doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy ) ).isEmpty() ) { 2364 !( t = doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy ) ).isEmpty() ) {
2364 QApplication::clipboard()->setText( t ); 2365 QApplication::clipboard()->setText( t );
2365 removeSelectedText(); 2366 removeSelectedText();
2366 } 2367 }
2367 updateMicroFocusHint(); 2368 updateMicroFocusHint();
2368} 2369}
2369 2370
2370/*! Copies any selected text (from selection 0) to the clipboard. 2371/*! Copies any selected text (from selection 0) to the clipboard.
2371 2372
2372 \sa hasSelectedText() copyAvailable() 2373 \sa hasSelectedText() copyAvailable()
2373 */ 2374 */
2374 2375
2375void QTextEdit::copy() 2376void QTextEdit::copy()
2376{ 2377{
2377 QString t = doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy ); 2378 QString t = doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy );
2378 if ( doc->hasSelection( QTextDocument::Standard ) && 2379 if ( doc->hasSelection( QTextDocument::Standard ) &&
2379 !t.isEmpty() && t.simplifyWhiteSpace() != "<selstart/>" ) 2380 !t.isEmpty() && t.simplifyWhiteSpace() != "<selstart/>" )
2380 QApplication::clipboard()->setText( t ); 2381 QApplication::clipboard()->setText( t );
2381} 2382}
2382 2383
2383/*! 2384/*!
2384 Re-indents the current paragraph. 2385 Re-indents the current paragraph.
2385*/ 2386*/
2386 2387
2387void QTextEdit::indent() 2388void QTextEdit::indent()
2388{ 2389{
2389 if ( isReadOnly() ) 2390 if ( isReadOnly() )
2390 return; 2391 return;
2391 2392
2392 drawCursor( FALSE ); 2393 drawCursor( FALSE );
2393 if ( !doc->hasSelection( QTextDocument::Standard ) ) 2394 if ( !doc->hasSelection( QTextDocument::Standard ) )
2394 cursor->indent(); 2395 cursor->indent();
2395 else 2396 else
2396 doc->indentSelection( QTextDocument::Standard ); 2397 doc->indentSelection( QTextDocument::Standard );
2397 repaintChanged(); 2398 repaintChanged();
2398 drawCursor( TRUE ); 2399 drawCursor( TRUE );
2399 setModified(); 2400 setModified();
2400 emit textChanged(); 2401 emit textChanged();
2401} 2402}
2402 2403
2403/*! Reimplemented to allow tabbing through links. 2404/*! Reimplemented to allow tabbing through links.
2404 If \a n is TRUE the tab moves the focus to the next child; if \a n 2405 If \a n is TRUE the tab moves the focus to the next child; if \a n
2405 is FALSE the tab moves the focus to the previous child. 2406 is FALSE the tab moves the focus to the previous child.
2406 Returns TRUE if the focus was moved; otherwise returns FALSE. 2407 Returns TRUE if the focus was moved; otherwise returns FALSE.
2407 */ 2408 */
2408 2409
2409bool QTextEdit::focusNextPrevChild( bool n ) 2410bool QTextEdit::focusNextPrevChild( bool n )
2410{ 2411{
2411 if ( !isReadOnly() || !linksEnabled() ) 2412 if ( !isReadOnly() || !linksEnabled() )
2412 return FALSE; 2413 return FALSE;
2413 bool b = doc->focusNextPrevChild( n ); 2414 bool b = doc->focusNextPrevChild( n );
2414 repaintChanged(); 2415 repaintChanged();
2415 if ( b ) 2416 if ( b )
2416 //##### this does not work with tables. The focusIndicator 2417 //##### this does not work with tables. The focusIndicator
2417 //should really be a QTextCursor. Fix 3.1 2418 //should really be a QTextCursor. Fix 3.1
2418 makeParagVisible( doc->focusIndicator.parag ); 2419 makeParagVisible( doc->focusIndicator.parag );
2419 return b; 2420 return b;
2420} 2421}
2421 2422
2422/*! 2423/*!
2423 \internal 2424 \internal
2424 2425
2425 This functions sets the current format to \a f. Only the fields of \a 2426 This functions sets the current format to \a f. Only the fields of \a
2426 f which are specified by the \a flags are used. 2427 f which are specified by the \a flags are used.
2427*/ 2428*/
2428 2429
2429void QTextEdit::setFormat( QTextFormat *f, int flags ) 2430void QTextEdit::setFormat( QTextFormat *f, int flags )
2430{ 2431{
2431 if ( doc->hasSelection( QTextDocument::Standard ) ) { 2432 if ( doc->hasSelection( QTextDocument::Standard ) ) {
2432 drawCursor( FALSE ); 2433 drawCursor( FALSE );
2433 QTextCursor c1 = doc->selectionStartCursor( QTextDocument::Standard ); 2434 QTextCursor c1 = doc->selectionStartCursor( QTextDocument::Standard );
2434 c1.restoreState(); 2435 c1.restoreState();
2435 QTextCursor c2 = doc->selectionEndCursor( QTextDocument::Standard ); 2436 QTextCursor c2 = doc->selectionEndCursor( QTextDocument::Standard );
2436 c2.restoreState(); 2437 c2.restoreState();
2437 clearUndoRedo(); 2438 clearUndoRedo();
2438 undoRedoInfo.type = UndoRedoInfo::Format; 2439 undoRedoInfo.type = UndoRedoInfo::Format;
2439 undoRedoInfo.id = c1.paragraph()->paragId(); 2440 undoRedoInfo.id = c1.paragraph()->paragId();
2440 undoRedoInfo.index = c1.index(); 2441 undoRedoInfo.index = c1.index();
2441 undoRedoInfo.eid = c2.paragraph()->paragId(); 2442 undoRedoInfo.eid = c2.paragraph()->paragId();
2442 undoRedoInfo.eindex = c2.index(); 2443 undoRedoInfo.eindex = c2.index();
2443 readFormats( c1, c2, undoRedoInfo.d->text ); 2444 readFormats( c1, c2, undoRedoInfo.d->text );
2444 undoRedoInfo.format = f; 2445 undoRedoInfo.format = f;
2445 undoRedoInfo.flags = flags; 2446 undoRedoInfo.flags = flags;
2446 clearUndoRedo(); 2447 clearUndoRedo();
2447 doc->setFormat( QTextDocument::Standard, f, flags ); 2448 doc->setFormat( QTextDocument::Standard, f, flags );
2448 repaintChanged(); 2449 repaintChanged();
2449 formatMore(); 2450 formatMore();
2450 drawCursor( TRUE ); 2451 drawCursor( TRUE );
2451 setModified(); 2452 setModified();
2452 emit textChanged(); 2453 emit textChanged();
2453 } 2454 }
2454 if ( currentFormat && currentFormat->key() != f->key() ) { 2455 if ( currentFormat && currentFormat->key() != f->key() ) {
2455 currentFormat->removeRef(); 2456 currentFormat->removeRef();
2456 currentFormat = doc->formatCollection()->format( f ); 2457 currentFormat = doc->formatCollection()->format( f );
2457 if ( currentFormat->isMisspelled() ) { 2458 if ( currentFormat->isMisspelled() ) {
2458 currentFormat->removeRef(); 2459 currentFormat->removeRef();
2459 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() ); 2460 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() );
2460 } 2461 }
2461 emit currentFontChanged( currentFormat->font() ); 2462 emit currentFontChanged( currentFormat->font() );
2462 emit currentColorChanged( currentFormat->color() ); 2463 emit currentColorChanged( currentFormat->color() );
2463 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() ); 2464 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
2464 if ( cursor->index() == cursor->paragraph()->length() - 1 ) { 2465 if ( cursor->index() == cursor->paragraph()->length() - 1 ) {
2465 currentFormat->addRef(); 2466 currentFormat->addRef();
2466 cursor->paragraph()->string()->setFormat( cursor->index(), currentFormat, TRUE ); 2467 cursor->paragraph()->string()->setFormat( cursor->index(), currentFormat, TRUE );
2467 if ( cursor->paragraph()->length() == 1 ) { 2468 if ( cursor->paragraph()->length() == 1 ) {
2468 cursor->paragraph()->invalidate( 0 ); 2469 cursor->paragraph()->invalidate( 0 );
2469 cursor->paragraph()->format(); 2470 cursor->paragraph()->format();
2470 repaintChanged(); 2471 repaintChanged();
2471 } 2472 }
2472 } 2473 }
2473 } 2474 }
2474} 2475}
2475 2476
2476/*! \reimp */ 2477/*! \reimp */
2477 2478
2478void QTextEdit::setPalette( const QPalette &p ) 2479void QTextEdit::setPalette( const QPalette &p )
2479{ 2480{
2480 QScrollView::setPalette( p ); 2481 QScrollView::setPalette( p );
2481 if ( textFormat() == PlainText ) { 2482 if ( textFormat() == PlainText ) {
2482 QTextFormat *f = doc->formatCollection()->defaultFormat(); 2483 QTextFormat *f = doc->formatCollection()->defaultFormat();
2483 f->setColor( colorGroup().text() ); 2484 f->setColor( colorGroup().text() );
2484 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 2485 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
2485 } 2486 }
2486} 2487}
2487 2488
2488/*! \internal 2489/*! \internal
2489 2490
2490 \warning In Qt 3.1 we will provide a cleaer API for the 2491 \warning In Qt 3.1 we will provide a cleaer API for the
2491 functionality which is provided by this function and in Qt 4.0 this 2492 functionality which is provided by this function and in Qt 4.0 this
2492 function will go away. 2493 function will go away.
2493 2494
2494 Sets the paragraph style of the current paragraph 2495 Sets the paragraph style of the current paragraph
2495 to \a dm. If \a dm is QStyleSheetItem::DisplayListItem, the 2496 to \a dm. If \a dm is QStyleSheetItem::DisplayListItem, the
2496 type of the list item is set to \a listStyle. 2497 type of the list item is set to \a listStyle.
2497 2498
2498 \sa setAlignment() 2499 \sa setAlignment()
2499*/ 2500*/
2500 2501
2501void QTextEdit::setParagType( QStyleSheetItem::DisplayMode dm, QStyleSheetItem::ListStyle listStyle ) 2502void QTextEdit::setParagType( QStyleSheetItem::DisplayMode dm, QStyleSheetItem::ListStyle listStyle )
2502{ 2503{
2503 if ( isReadOnly() ) 2504 if ( isReadOnly() )
2504 return; 2505 return;
2505 2506
2506 drawCursor( FALSE ); 2507 drawCursor( FALSE );
2507 QTextParagraph *start = cursor->paragraph(); 2508 QTextParagraph *start = cursor->paragraph();
2508 QTextParagraph *end = start; 2509 QTextParagraph *end = start;
2509 if ( doc->hasSelection( QTextDocument::Standard ) ) { 2510 if ( doc->hasSelection( QTextDocument::Standard ) ) {
2510 start = doc->selectionStartCursor( QTextDocument::Standard ).topParagraph(); 2511 start = doc->selectionStartCursor( QTextDocument::Standard ).topParagraph();
2511 end = doc->selectionEndCursor( QTextDocument::Standard ).topParagraph(); 2512 end = doc->selectionEndCursor( QTextDocument::Standard ).topParagraph();
2512 if ( end->paragId() < start->paragId() ) 2513 if ( end->paragId() < start->paragId() )
2513 return; // do not trust our selections 2514 return; // do not trust our selections
2514 } 2515 }
2515 2516
2516 clearUndoRedo(); 2517 clearUndoRedo();
2517 undoRedoInfo.type = UndoRedoInfo::Style; 2518 undoRedoInfo.type = UndoRedoInfo::Style;
2518 undoRedoInfo.id = start->paragId(); 2519 undoRedoInfo.id = start->paragId();
2519 undoRedoInfo.eid = end->paragId(); 2520 undoRedoInfo.eid = end->paragId();
2520 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid ); 2521 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
2521 2522
2522 while ( start != end->next() ) { 2523 while ( start != end->next() ) {
2523 start->setListStyle( listStyle ); 2524 start->setListStyle( listStyle );
2524 if ( dm == QStyleSheetItem::DisplayListItem ) { 2525 if ( dm == QStyleSheetItem::DisplayListItem ) {
2525 start->setListItem( TRUE ); 2526 start->setListItem( TRUE );
2526 if( start->listDepth() == 0 ) 2527 if( start->listDepth() == 0 )
2527 start->setListDepth( 1 ); 2528 start->setListDepth( 1 );
2528 } else if ( start->isListItem() ) { 2529 } else if ( start->isListItem() ) {
2529 start->setListItem( FALSE ); 2530 start->setListItem( FALSE );
2530 start->setListDepth( QMAX( start->listDepth()-1, 0 ) ); 2531 start->setListDepth( QMAX( start->listDepth()-1, 0 ) );
2531 } 2532 }
2532 start = start->next(); 2533 start = start->next();
2533 } 2534 }
2534 2535
2535 clearUndoRedo(); 2536 clearUndoRedo();
2536 repaintChanged(); 2537 repaintChanged();
2537 formatMore(); 2538 formatMore();
2538 drawCursor( TRUE ); 2539 drawCursor( TRUE );
2539 setModified(); 2540 setModified();
2540 emit textChanged(); 2541 emit textChanged();
2541} 2542}
2542 2543
2543/*! 2544/*!
2544 Sets the alignment of the current paragraph to \a a. Valid alignments 2545 Sets the alignment of the current paragraph to \a a. Valid alignments
2545 are \c Qt::AlignLeft, \c Qt::AlignRight, Qt::AlignJustify and 2546 are \c Qt::AlignLeft, \c Qt::AlignRight, Qt::AlignJustify and
2546 Qt::AlignCenter (which centers horizontally). 2547 Qt::AlignCenter (which centers horizontally).
2547 2548
2548*/ 2549*/
2549 2550
2550void QTextEdit::setAlignment( int a ) 2551void QTextEdit::setAlignment( int a )
2551{ 2552{
2552 if ( isReadOnly() || block_set_alignment ) 2553 if ( isReadOnly() || block_set_alignment )
2553 return; 2554 return;
2554 2555
2555 drawCursor( FALSE ); 2556 drawCursor( FALSE );
2556 QTextParagraph *start = cursor->paragraph(); 2557 QTextParagraph *start = cursor->paragraph();
2557 QTextParagraph *end = start; 2558 QTextParagraph *end = start;
2558 if ( doc->hasSelection( QTextDocument::Standard ) ) { 2559 if ( doc->hasSelection( QTextDocument::Standard ) ) {
2559 start = doc->selectionStartCursor( QTextDocument::Standard ).topParagraph(); 2560 start = doc->selectionStartCursor( QTextDocument::Standard ).topParagraph();
2560 end = doc->selectionEndCursor( QTextDocument::Standard ).topParagraph(); 2561 end = doc->selectionEndCursor( QTextDocument::Standard ).topParagraph();
2561 if ( end->paragId() < start->paragId() ) 2562 if ( end->paragId() < start->paragId() )
2562 return; // do not trust our selections 2563 return; // do not trust our selections
2563 } 2564 }
2564 2565
2565 clearUndoRedo(); 2566 clearUndoRedo();
2566 undoRedoInfo.type = UndoRedoInfo::Style; 2567 undoRedoInfo.type = UndoRedoInfo::Style;
2567 undoRedoInfo.id = start->paragId(); 2568 undoRedoInfo.id = start->paragId();
2568 undoRedoInfo.eid = end->paragId(); 2569 undoRedoInfo.eid = end->paragId();
2569 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid ); 2570 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
2570 2571
2571 while ( start != end->next() ) { 2572 while ( start != end->next() ) {
2572 start->setAlignment( a ); 2573 start->setAlignment( a );
2573 start = start->next(); 2574 start = start->next();
2574 } 2575 }
2575 2576
2576 clearUndoRedo(); 2577 clearUndoRedo();
2577 repaintChanged(); 2578 repaintChanged();
2578 formatMore(); 2579 formatMore();
2579 drawCursor( TRUE ); 2580 drawCursor( TRUE );
2580 if ( currentAlignment != a ) { 2581 if ( currentAlignment != a ) {
2581 currentAlignment = a; 2582 currentAlignment = a;
2582 emit currentAlignmentChanged( currentAlignment ); 2583 emit currentAlignmentChanged( currentAlignment );
2583 } 2584 }
2584 setModified(); 2585 setModified();
2585 emit textChanged(); 2586 emit textChanged();
2586} 2587}
2587 2588
2588void QTextEdit::updateCurrentFormat() 2589void QTextEdit::updateCurrentFormat()
2589{ 2590{
2590 int i = cursor->index(); 2591 int i = cursor->index();
2591 if ( i > 0 ) 2592 if ( i > 0 )
2592 --i; 2593 --i;
2593 if ( doc->useFormatCollection() && 2594 if ( doc->useFormatCollection() &&
2594 ( !currentFormat || currentFormat->key() != cursor->paragraph()->at( i )->format()->key() ) ) { 2595 ( !currentFormat || currentFormat->key() != cursor->paragraph()->at( i )->format()->key() ) ) {
2595 if ( currentFormat ) 2596 if ( currentFormat )
2596 currentFormat->removeRef(); 2597 currentFormat->removeRef();
2597 currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( i )->format() ); 2598 currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( i )->format() );
2598 if ( currentFormat->isMisspelled() ) { 2599 if ( currentFormat->isMisspelled() ) {
2599 currentFormat->removeRef(); 2600 currentFormat->removeRef();
2600 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() ); 2601 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() );
2601 } 2602 }
2602 emit currentFontChanged( currentFormat->font() ); 2603 emit currentFontChanged( currentFormat->font() );
2603 emit currentColorChanged( currentFormat->color() ); 2604 emit currentColorChanged( currentFormat->color() );
2604 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() ); 2605 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
2605 } 2606 }
2606 2607
2607 if ( currentAlignment != cursor->paragraph()->alignment() ) { 2608 if ( currentAlignment != cursor->paragraph()->alignment() ) {
2608 currentAlignment = cursor->paragraph()->alignment(); 2609 currentAlignment = cursor->paragraph()->alignment();
2609 block_set_alignment = TRUE; 2610 block_set_alignment = TRUE;
2610 emit currentAlignmentChanged( currentAlignment ); 2611 emit currentAlignmentChanged( currentAlignment );
2611 block_set_alignment = FALSE; 2612 block_set_alignment = FALSE;
2612 } 2613 }
2613} 2614}
2614 2615
2615/*! 2616/*!
2616 If \a b is TRUE sets the current format to italic; otherwise sets 2617 If \a b is TRUE sets the current format to italic; otherwise sets
2617 the current format to non-italic. 2618 the current format to non-italic.
2618 2619
2619 \sa italic() 2620 \sa italic()
2620*/ 2621*/
2621 2622
2622void QTextEdit::setItalic( bool b ) 2623void QTextEdit::setItalic( bool b )
2623{ 2624{
2624 QTextFormat f( *currentFormat ); 2625 QTextFormat f( *currentFormat );
2625 f.setItalic( b ); 2626 f.setItalic( b );
2626 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2627 QTextFormat *f2 = doc->formatCollection()->format( &f );
2627 setFormat( f2, QTextFormat::Italic ); 2628 setFormat( f2, QTextFormat::Italic );
2628} 2629}
2629 2630
2630/*! 2631/*!
2631 If \a b is TRUE sets the current format to bold; otherwise sets the 2632 If \a b is TRUE sets the current format to bold; otherwise sets the
2632 current format to non-bold. 2633 current format to non-bold.
2633 2634
2634 \sa bold() 2635 \sa bold()
2635*/ 2636*/
2636 2637
2637void QTextEdit::setBold( bool b ) 2638void QTextEdit::setBold( bool b )
2638{ 2639{
2639 QTextFormat f( *currentFormat ); 2640 QTextFormat f( *currentFormat );
2640 f.setBold( b ); 2641 f.setBold( b );
2641 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2642 QTextFormat *f2 = doc->formatCollection()->format( &f );
2642 setFormat( f2, QTextFormat::Bold ); 2643 setFormat( f2, QTextFormat::Bold );
2643} 2644}
2644 2645
2645/*! 2646/*!
2646 If \a b is TRUE sets the current format to underline; otherwise sets 2647 If \a b is TRUE sets the current format to underline; otherwise sets
2647 the current format to non-underline. 2648 the current format to non-underline.
2648 2649
2649 \sa underline() 2650 \sa underline()
2650*/ 2651*/
2651 2652
2652void QTextEdit::setUnderline( bool b ) 2653void QTextEdit::setUnderline( bool b )
2653{ 2654{
2654 QTextFormat f( *currentFormat ); 2655 QTextFormat f( *currentFormat );
2655 f.setUnderline( b ); 2656 f.setUnderline( b );
2656 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2657 QTextFormat *f2 = doc->formatCollection()->format( &f );
2657 setFormat( f2, QTextFormat::Underline ); 2658 setFormat( f2, QTextFormat::Underline );
2658} 2659}
2659 2660
2660/*! 2661/*!
2661 Sets the font family of the current format to \a fontFamily. 2662 Sets the font family of the current format to \a fontFamily.
2662 2663
2663 \sa family() setCurrentFont() 2664 \sa family() setCurrentFont()
2664*/ 2665*/
2665 2666
2666void QTextEdit::setFamily( const QString &fontFamily ) 2667void QTextEdit::setFamily( const QString &fontFamily )
2667{ 2668{
2668 QTextFormat f( *currentFormat ); 2669 QTextFormat f( *currentFormat );
2669 f.setFamily( fontFamily ); 2670 f.setFamily( fontFamily );
2670 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2671 QTextFormat *f2 = doc->formatCollection()->format( &f );
2671 setFormat( f2, QTextFormat::Family ); 2672 setFormat( f2, QTextFormat::Family );
2672} 2673}
2673 2674
2674/*! 2675/*!
2675 Sets the point size of the current format to \a s. 2676 Sets the point size of the current format to \a s.
2676 2677
2677 Note that if \a s is zero or negative, the behaviour of this 2678 Note that if \a s is zero or negative, the behaviour of this
2678 function is not defined. 2679 function is not defined.
2679 2680
2680 \sa pointSize() setCurrentFont() setFamily() 2681 \sa pointSize() setCurrentFont() setFamily()
2681*/ 2682*/
2682 2683
2683void QTextEdit::setPointSize( int s ) 2684void QTextEdit::setPointSize( int s )
2684{ 2685{
2685 QTextFormat f( *currentFormat ); 2686 QTextFormat f( *currentFormat );
2686 f.setPointSize( s ); 2687 f.setPointSize( s );
2687 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2688 QTextFormat *f2 = doc->formatCollection()->format( &f );
2688 setFormat( f2, QTextFormat::Size ); 2689 setFormat( f2, QTextFormat::Size );
2689} 2690}
2690 2691
2691/*! 2692/*!
2692 Sets the color of the current format, i.e. of the text, to \a c. 2693 Sets the color of the current format, i.e. of the text, to \a c.
2693 2694
2694 \sa color() setPaper() 2695 \sa color() setPaper()
2695*/ 2696*/
2696 2697
2697void QTextEdit::setColor( const QColor &c ) 2698void QTextEdit::setColor( const QColor &c )
2698{ 2699{
2699 QTextFormat f( *currentFormat ); 2700 QTextFormat f( *currentFormat );
2700 f.setColor( c ); 2701 f.setColor( c );
2701 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2702 QTextFormat *f2 = doc->formatCollection()->format( &f );
2702 setFormat( f2, QTextFormat::Color ); 2703 setFormat( f2, QTextFormat::Color );
2703} 2704}
2704 2705
2705/*! 2706/*!
2706 Sets the vertical alignment of the current format, i.e. of the text, to \a a. 2707 Sets the vertical alignment of the current format, i.e. of the text, to \a a.
2707 2708
2708 \sa color() setPaper() 2709 \sa color() setPaper()
2709*/ 2710*/
2710 2711
2711void QTextEdit::setVerticalAlignment( VerticalAlignment a ) 2712void QTextEdit::setVerticalAlignment( VerticalAlignment a )
2712{ 2713{
2713 QTextFormat f( *currentFormat ); 2714 QTextFormat f( *currentFormat );
2714 f.setVAlign( (QTextFormat::VerticalAlignment)a ); 2715 f.setVAlign( (QTextFormat::VerticalAlignment)a );
2715 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2716 QTextFormat *f2 = doc->formatCollection()->format( &f );
2716 setFormat( f2, QTextFormat::VAlign ); 2717 setFormat( f2, QTextFormat::VAlign );
2717} 2718}
2718 2719
2719void QTextEdit::setFontInternal( const QFont &f_ ) 2720void QTextEdit::setFontInternal( const QFont &f_ )
2720{ 2721{
2721 QTextFormat f( *currentFormat ); 2722 QTextFormat f( *currentFormat );
2722 f.setFont( f_ ); 2723 f.setFont( f_ );
2723 QTextFormat *f2 = doc->formatCollection()->format( &f ); 2724 QTextFormat *f2 = doc->formatCollection()->format( &f );
2724 setFormat( f2, QTextFormat::Font ); 2725 setFormat( f2, QTextFormat::Font );
2725} 2726}
2726 2727
2727 2728
2728QString QTextEdit::text() const 2729QString QTextEdit::text() const
2729{ 2730{
2730 if ( isReadOnly() ) 2731 if ( isReadOnly() )
2731 return doc->originalText(); 2732 return doc->originalText();
2732 return doc->text(); 2733 return doc->text();
2733} 2734}
2734 2735
2735/*! 2736/*!
2736 \overload 2737 \overload
2737 Returns the text of paragraph \a para. 2738 Returns the text of paragraph \a para.
2738 2739
2739 If textFormat() is \c RichText the text will contain HTML 2740 If textFormat() is \c RichText the text will contain HTML
2740 formatting tags. 2741 formatting tags.
2741*/ 2742*/
2742 2743
2743QString QTextEdit::text( int para ) const 2744QString QTextEdit::text( int para ) const
2744{ 2745{
2745 return doc->text( para ); 2746 return doc->text( para );
2746} 2747}
2747 2748
2748/*! 2749/*!
2749 \overload 2750 \overload
2750 2751
2751 Changes the text of the text edit to the string \a text and the 2752 Changes the text of the text edit to the string \a text and the
2752 context to \a context. Any previous text is removed. 2753 context to \a context. Any previous text is removed.
2753 2754
2754 \a text may be interpreted either as plain text or as rich text, 2755 \a text may be interpreted either as plain text or as rich text,
2755 depending on the textFormat(). The default setting is \c AutoText, 2756 depending on the textFormat(). The default setting is \c AutoText,
2756 i.e. the text edit autodetects the format from \a text. 2757 i.e. the text edit autodetects the format from \a text.
2757 2758
2758 The optional \a context is a path which the text edit's 2759 The optional \a context is a path which the text edit's
2759 QMimeSourceFactory uses to resolve the locations of files and images. 2760 QMimeSourceFactory uses to resolve the locations of files and images.
2760 (See \l{QTextEdit::QTextEdit()}.) It is passed to the text edit's 2761 (See \l{QTextEdit::QTextEdit()}.) It is passed to the text edit's
2761 QMimeSourceFactory when quering data. 2762 QMimeSourceFactory when quering data.
2762 2763
2763 Note that the undo/redo history is cleared by this function. 2764 Note that the undo/redo history is cleared by this function.
2764 2765
2765 \sa text(), setTextFormat() 2766 \sa text(), setTextFormat()
2766*/ 2767*/
2767 2768
2768void QTextEdit::setText( const QString &text, const QString &context ) 2769void QTextEdit::setText( const QString &text, const QString &context )
2769{ 2770{
2770 if ( !isModified() && isReadOnly() && 2771 if ( !isModified() && isReadOnly() &&
2771 this->context() == context && this->text() == text ) 2772 this->context() == context && this->text() == text )
2772 return; 2773 return;
2773 2774
2774 emit undoAvailable( FALSE ); 2775 emit undoAvailable( FALSE );
2775 emit redoAvailable( FALSE ); 2776 emit redoAvailable( FALSE );
2776 undoRedoInfo.clear(); 2777 undoRedoInfo.clear();
2777 doc->commands()->clear(); 2778 doc->commands()->clear();
2778 2779
2779 lastFormatted = 0; 2780 lastFormatted = 0;
2780 cursor->restoreState(); 2781 cursor->restoreState();
2781 doc->setText( text, context ); 2782 doc->setText( text, context );
2782 2783
2783 if ( wrapMode == FixedPixelWidth ) { 2784 if ( wrapMode == FixedPixelWidth ) {
2784 resizeContents( wrapWidth, 0 ); 2785 resizeContents( wrapWidth, 0 );
2785 doc->setWidth( wrapWidth ); 2786 doc->setWidth( wrapWidth );
2786 doc->setMinimumWidth( wrapWidth ); 2787 doc->setMinimumWidth( wrapWidth );
2787 } else { 2788 } else {
2788 doc->setMinimumWidth( -1 ); 2789 doc->setMinimumWidth( -1 );
2789 resizeContents( 0, 0 ); 2790 resizeContents( 0, 0 );
2790 } 2791 }
2791 2792
2792 lastFormatted = doc->firstParagraph(); 2793 lastFormatted = doc->firstParagraph();
2793 delete cursor; 2794 delete cursor;
2794 cursor = new QTextCursor( doc ); 2795 cursor = new QTextCursor( doc );
2795 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 2796 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
2796 2797
2797 if ( isModified() ) 2798 if ( isModified() )
2798 setModified( FALSE ); 2799 setModified( FALSE );
2799 emit textChanged(); 2800 emit textChanged();
2800 formatMore(); 2801 formatMore();
2801 updateCurrentFormat(); 2802 updateCurrentFormat();
2802 d->scrollToAnchor = QString::null; 2803 d->scrollToAnchor = QString::null;
2803} 2804}
2804 2805
2805/*! 2806/*!
2806 \property QTextEdit::text 2807 \property QTextEdit::text
2807 \brief the text edit's text 2808 \brief the text edit's text
2808 2809
2809 There is no default text. 2810 There is no default text.
2810 2811
2811 On setting, any previous text is deleted. 2812 On setting, any previous text is deleted.
2812 2813
2813 The text may be interpreted either as plain text or as rich text, 2814 The text may be interpreted either as plain text or as rich text,
2814 depending on the textFormat(). The default setting is \c AutoText, 2815 depending on the textFormat(). The default setting is \c AutoText,
2815 i.e. the text edit autodetects the format of the text. 2816 i.e. the text edit autodetects the format of the text.
2816 2817
2817 For richtext, calling text() on an editable QTextEdit will cause the text 2818 For richtext, calling text() on an editable QTextEdit will cause the text
2818 to be regenerated from the textedit. This may mean that the QString returned 2819 to be regenerated from the textedit. This may mean that the QString returned
2819 may not be exactly the same as the one that was set. 2820 may not be exactly the same as the one that was set.
2820 2821
2821 \sa textFormat 2822 \sa textFormat
2822*/ 2823*/
2823 2824
2824 2825
2825/*! 2826/*!
2826 \property QTextEdit::readOnly 2827 \property QTextEdit::readOnly
2827 \brief whether the text edit is read-only 2828 \brief whether the text edit is read-only
2828 2829
2829 In a read-only text edit the user can only navigate through the text 2830 In a read-only text edit the user can only navigate through the text
2830 and select text; modifying the text is not possible. 2831 and select text; modifying the text is not possible.
2831 2832
2832 This property's default is FALSE. 2833 This property's default is FALSE.
2833*/ 2834*/
2834 2835
2835/*! 2836/*!
2836 Finds the next occurrence of the string, \a expr. Returns TRUE if 2837 Finds the next occurrence of the string, \a expr. Returns TRUE if
2837 \a expr is found; otherwise returns FALSE. 2838 \a expr is found; otherwise returns FALSE.
2838 2839
2839 If \a para and \a index are both null the search begins from the 2840 If \a para and \a index are both null the search begins from the
2840 current cursor position. If \a para and \a index are both not 2841 current cursor position. If \a para and \a index are both not
2841 null, the search begins from the \e *\a index character position 2842 null, the search begins from the \e *\a index character position
2842 in the \e *\a para paragraph. 2843 in the \e *\a para paragraph.
2843 2844
2844 If \a cs is TRUE the search is case sensitive, otherwise it is 2845 If \a cs is TRUE the search is case sensitive, otherwise it is
2845 case insensitive. If \a wo is TRUE the search looks for whole word 2846 case insensitive. If \a wo is TRUE the search looks for whole word
2846 matches only; otherwise it searches for any matching text. If \a 2847 matches only; otherwise it searches for any matching text. If \a
2847 forward is TRUE (the default) the search works forward from the 2848 forward is TRUE (the default) the search works forward from the
2848 starting position to the end of the text, otherwise it works 2849 starting position to the end of the text, otherwise it works
2849 backwards to the beginning of the text. 2850 backwards to the beginning of the text.
2850 2851
2851 If \a expr is found the function returns TRUE. If \a index and \a 2852 If \a expr is found the function returns TRUE. If \a index and \a
2852 para are not null, the number of the paragraph in which the first 2853 para are not null, the number of the paragraph in which the first
2853 character of the match was found is put into \e *\a para, and the 2854 character of the match was found is put into \e *\a para, and the
2854 index position of that character within the paragraph is put into 2855 index position of that character within the paragraph is put into
2855 \e *\a index. 2856 \e *\a index.
2856 2857
2857 If \a expr is not found the function returns FALSE. If \a index 2858 If \a expr is not found the function returns FALSE. If \a index
2858 and \a para are not null and \a expr is not found, \e *\a index 2859 and \a para are not null and \a expr is not found, \e *\a index
2859 and \e *\a para are undefined. 2860 and \e *\a para are undefined.
2860*/ 2861*/
2861 2862
2862bool QTextEdit::find( const QString &expr, bool cs, bool wo, bool forward, 2863bool QTextEdit::find( const QString &expr, bool cs, bool wo, bool forward,
2863 int *para, int *index ) 2864 int *para, int *index )
2864{ 2865{
2865 drawCursor( FALSE ); 2866 drawCursor( FALSE );
2866#ifndef QT_NO_CURSOR 2867#ifndef QT_NO_CURSOR
2867 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 2868 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
2868#endif 2869#endif
2869 QTextCursor findcur = *cursor; 2870 QTextCursor findcur = *cursor;
2870 if ( para && index ) { 2871 if ( para && index ) {
2871 if ( doc->paragAt( *para ) ) 2872 if ( doc->paragAt( *para ) )
2872 findcur.gotoPosition( doc->paragAt(*para), *index ); 2873 findcur.gotoPosition( doc->paragAt(*para), *index );
2873 else 2874 else
2874 findcur.gotoEnd(); 2875 findcur.gotoEnd();
2875 } else if ( doc->hasSelection( QTextDocument::Standard ) ){ 2876 } else if ( doc->hasSelection( QTextDocument::Standard ) ){
2876 // maks sure we do not find the same selection again 2877 // maks sure we do not find the same selection again
2877 if ( forward ) 2878 if ( forward )
2878 findcur.gotoNextLetter(); 2879 findcur.gotoNextLetter();
2879 else 2880 else
2880 findcur.gotoPreviousLetter(); 2881 findcur.gotoPreviousLetter();
2881 } 2882 }
2882 removeSelection( QTextDocument::Standard ); 2883 removeSelection( QTextDocument::Standard );
2883 bool found = doc->find( findcur, expr, cs, wo, forward ); 2884 bool found = doc->find( findcur, expr, cs, wo, forward );
2884 if ( found ) { 2885 if ( found ) {
2885 if ( para ) 2886 if ( para )
2886 *para = findcur.paragraph()->paragId(); 2887 *para = findcur.paragraph()->paragId();
2887 if ( index ) 2888 if ( index )
2888 *index = findcur.index(); 2889 *index = findcur.index();
2889 *cursor = findcur; 2890 *cursor = findcur;
2890 repaintChanged(); 2891 repaintChanged();
2891 ensureCursorVisible(); 2892 ensureCursorVisible();
2892 } 2893 }
2893 drawCursor( TRUE ); 2894 drawCursor( TRUE );
2894 return found; 2895 return found;
2895} 2896}
2896 2897
2897void QTextEdit::blinkCursor() 2898void QTextEdit::blinkCursor()
2898{ 2899{
2899 if ( !cursorVisible ) 2900 if ( !cursorVisible )
2900 return; 2901 return;
2901 bool cv = cursorVisible; 2902 bool cv = cursorVisible;
2902 blinkCursorVisible = !blinkCursorVisible; 2903 blinkCursorVisible = !blinkCursorVisible;
2903 drawCursor( blinkCursorVisible ); 2904 drawCursor( blinkCursorVisible );
2904 cursorVisible = cv; 2905 cursorVisible = cv;
2905} 2906}
2906 2907
2907/*! 2908/*!
2908 Sets the cursor to position \a index in paragraph \a para. 2909 Sets the cursor to position \a index in paragraph \a para.
2909 2910
2910 \sa getCursorPosition() 2911 \sa getCursorPosition()
2911*/ 2912*/
2912 2913
2913void QTextEdit::setCursorPosition( int para, int index ) 2914void QTextEdit::setCursorPosition( int para, int index )
2914{ 2915{
2915 QTextParagraph *p = doc->paragAt( para ); 2916 QTextParagraph *p = doc->paragAt( para );
2916 if ( !p ) 2917 if ( !p )
2917 return; 2918 return;
2918 2919
2919 if ( index > p->length() - 1 ) 2920 if ( index > p->length() - 1 )
2920 index = p->length() - 1; 2921 index = p->length() - 1;
2921 2922
2922 drawCursor( FALSE ); 2923 drawCursor( FALSE );
2923 cursor->setParagraph( p ); 2924 cursor->setParagraph( p );
2924 cursor->setIndex( index ); 2925 cursor->setIndex( index );
2925 ensureCursorVisible(); 2926 ensureCursorVisible();
2926 drawCursor( TRUE ); 2927 drawCursor( TRUE );
2927 updateCurrentFormat(); 2928 updateCurrentFormat();
2928 emit cursorPositionChanged( cursor ); 2929 emit cursorPositionChanged( cursor );
2929 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() ); 2930 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
2930} 2931}
2931 2932
2932/*! 2933/*!
2933 This function sets the \e *\a para and \e *\a index parameters to the 2934 This function sets the \e *\a para and \e *\a index parameters to the
2934 current cursor position. \a para and \a index must be non-null int 2935 current cursor position. \a para and \a index must be non-null int
2935 pointers. 2936 pointers.
2936 2937
2937 \sa setCursorPosition() 2938 \sa setCursorPosition()
2938 */ 2939 */
2939 2940
2940void QTextEdit::getCursorPosition( int *para, int *index ) const 2941void QTextEdit::getCursorPosition( int *para, int *index ) const
2941{ 2942{
2942 if ( !para || !index ) 2943 if ( !para || !index )
2943 return; 2944 return;
2944 *para = cursor->paragraph()->paragId(); 2945 *para = cursor->paragraph()->paragId();
2945 *index = cursor->index(); 2946 *index = cursor->index();
2946} 2947}
2947 2948
2948/*! Sets a selection which starts at position \a indexFrom in 2949/*! Sets a selection which starts at position \a indexFrom in
2949 paragraph \a paraFrom and ends at position \a indexTo in paragraph 2950 paragraph \a paraFrom and ends at position \a indexTo in paragraph
2950 \a paraTo. Existing selections which have a different id (selNum) 2951 \a paraTo. Existing selections which have a different id (selNum)
2951 are not removed, existing selections which have the same id as \a 2952 are not removed, existing selections which have the same id as \a
2952 selNum are removed. 2953 selNum are removed.
2953 2954
2954 Uses the selection settings of selection \a selNum. If \a selNum is 0, 2955 Uses the selection settings of selection \a selNum. If \a selNum is 0,
2955 this is the default selection. 2956 this is the default selection.
2956 2957
2957 The cursor is moved to the end of the selection if \a selNum is 0, 2958 The cursor is moved to the end of the selection if \a selNum is 0,
2958 otherwise the cursor position remains unchanged. 2959 otherwise the cursor position remains unchanged.
2959 2960
2960 \sa getSelection() selectedText 2961 \sa getSelection() selectedText
2961*/ 2962*/
2962 2963
2963void QTextEdit::setSelection( int paraFrom, int indexFrom, 2964void QTextEdit::setSelection( int paraFrom, int indexFrom,
2964 int paraTo, int indexTo, int selNum ) 2965 int paraTo, int indexTo, int selNum )
2965{ 2966{
2966 if ( doc->hasSelection( selNum ) ) { 2967 if ( doc->hasSelection( selNum ) ) {
2967 doc->removeSelection( selNum ); 2968 doc->removeSelection( selNum );
2968 repaintChanged(); 2969 repaintChanged();
2969 } 2970 }
2970 if ( selNum > doc->numSelections() - 1 ) 2971 if ( selNum > doc->numSelections() - 1 )
2971 doc->addSelection( selNum ); 2972 doc->addSelection( selNum );
2972 QTextParagraph *p1 = doc->paragAt( paraFrom ); 2973 QTextParagraph *p1 = doc->paragAt( paraFrom );
2973 if ( !p1 ) 2974 if ( !p1 )
2974 return; 2975 return;
2975 QTextParagraph *p2 = doc->paragAt( paraTo ); 2976 QTextParagraph *p2 = doc->paragAt( paraTo );
2976 if ( !p2 ) 2977 if ( !p2 )
2977 return; 2978 return;
2978 2979
2979 if ( indexFrom > p1->length() - 1 ) 2980 if ( indexFrom > p1->length() - 1 )
2980 indexFrom = p1->length() - 1; 2981 indexFrom = p1->length() - 1;
2981 if ( indexTo > p2->length() - 1 ) 2982 if ( indexTo > p2->length() - 1 )
2982 indexTo = p2->length() - 1; 2983 indexTo = p2->length() - 1;
2983 2984
2984 drawCursor( FALSE ); 2985 drawCursor( FALSE );
2985 QTextCursor c = *cursor; 2986 QTextCursor c = *cursor;
2986 QTextCursor oldCursor = *cursor; 2987 QTextCursor oldCursor = *cursor;
2987 c.setParagraph( p1 ); 2988 c.setParagraph( p1 );
2988 c.setIndex( indexFrom ); 2989 c.setIndex( indexFrom );
2989 cursor->setParagraph( p2 ); 2990 cursor->setParagraph( p2 );
2990 cursor->setIndex( indexTo ); 2991 cursor->setIndex( indexTo );
2991 doc->setSelectionStart( selNum, c ); 2992 doc->setSelectionStart( selNum, c );
2992 doc->setSelectionEnd( selNum, *cursor ); 2993 doc->setSelectionEnd( selNum, *cursor );
2993 repaintChanged(); 2994 repaintChanged();
2994 ensureCursorVisible(); 2995 ensureCursorVisible();
2995 if ( selNum != QTextDocument::Standard ) 2996 if ( selNum != QTextDocument::Standard )
2996 *cursor = oldCursor; 2997 *cursor = oldCursor;
2997 drawCursor( TRUE ); 2998 drawCursor( TRUE );
2998} 2999}
2999 3000
3000/*! 3001/*!
3001 If there is a selection, \e *\a paraFrom is set to the number of the 3002 If there is a selection, \e *\a paraFrom is set to the number of the
3002 paragraph in which the selection begins and \e *\a paraTo is set to 3003 paragraph in which the selection begins and \e *\a paraTo is set to
3003 the number of the paragraph in which the selection ends. (They could 3004 the number of the paragraph in which the selection ends. (They could
3004 be the same.) \e *\a indexFrom is set to the index at which the 3005 be the same.) \e *\a indexFrom is set to the index at which the
3005 selection begins within \e *\a paraFrom, and \e *\a indexTo is set to 3006 selection begins within \e *\a paraFrom, and \e *\a indexTo is set to
3006 the index at which the selection ends within \e *\a paraTo. 3007 the index at which the selection ends within \e *\a paraTo.
3007 3008
3008 If there is no selection, \e *\a paraFrom, \e *\a indexFrom, \e *\a 3009 If there is no selection, \e *\a paraFrom, \e *\a indexFrom, \e *\a
3009 paraTo and \e *\a indexTo are all set to -1. 3010 paraTo and \e *\a indexTo are all set to -1.
3010 3011
3011 \a paraFrom, \a indexFrom, \a paraTo and \a indexTo must be non-null 3012 \a paraFrom, \a indexFrom, \a paraTo and \a indexTo must be non-null
3012 int pointers. 3013 int pointers.
3013 3014
3014 The \a selNum is the number of the selection (multiple selections 3015 The \a selNum is the number of the selection (multiple selections
3015 are supported). It defaults to 0 (the default selection). 3016 are supported). It defaults to 0 (the default selection).
3016 3017
3017 \sa setSelection() selectedText 3018 \sa setSelection() selectedText
3018*/ 3019*/
3019 3020
3020void QTextEdit::getSelection( int *paraFrom, int *indexFrom, 3021void QTextEdit::getSelection( int *paraFrom, int *indexFrom,
3021 int *paraTo, int *indexTo, int selNum ) const 3022 int *paraTo, int *indexTo, int selNum ) const
3022{ 3023{
3023 if ( !paraFrom || !paraTo || !indexFrom || !indexTo ) 3024 if ( !paraFrom || !paraTo || !indexFrom || !indexTo )
3024 return; 3025 return;
3025 if ( !doc->hasSelection( selNum ) ) { 3026 if ( !doc->hasSelection( selNum ) ) {
3026 *paraFrom = -1; 3027 *paraFrom = -1;
3027 *indexFrom = -1; 3028 *indexFrom = -1;
3028 *paraTo = -1; 3029 *paraTo = -1;
3029 *indexTo = -1; 3030 *indexTo = -1;
3030 return; 3031 return;
3031 } 3032 }
3032 3033
3033 doc->selectionStart( selNum, *paraFrom, *indexFrom ); 3034 doc->selectionStart( selNum, *paraFrom, *indexFrom );
3034 doc->selectionEnd( selNum, *paraTo, *indexTo ); 3035 doc->selectionEnd( selNum, *paraTo, *indexTo );
3035} 3036}
3036 3037
3037/*! 3038/*!
3038 \property QTextEdit::textFormat 3039 \property QTextEdit::textFormat
3039 \brief the text format: rich text, plain text or auto text 3040 \brief the text format: rich text, plain text or auto text
3040 3041
3041 The text format is one of the following: 3042 The text format is one of the following:
3042 \list 3043 \list
3043 \i PlainText - all characters, except newlines, are displayed 3044 \i PlainText - all characters, except newlines, are displayed
3044 verbatim, including spaces. Whenever a newline appears in the text the 3045 verbatim, including spaces. Whenever a newline appears in the text the
3045 text edit inserts a hard line break and begins a new paragraph. 3046 text edit inserts a hard line break and begins a new paragraph.
3046 \i RichText - rich text rendering. The available styles are 3047 \i RichText - rich text rendering. The available styles are
3047 defined in the default stylesheet QStyleSheet::defaultSheet(). 3048 defined in the default stylesheet QStyleSheet::defaultSheet().
3048 \i AutoText - this is the default. The text edit autodetects 3049 \i AutoText - this is the default. The text edit autodetects
3049 which rendering style is best, \c PlainText or \c RichText. This is 3050 which rendering style is best, \c PlainText or \c RichText. This is
3050 done by using the QStyleSheet::mightBeRichText() function. 3051 done by using the QStyleSheet::mightBeRichText() function.
3051 \endlist 3052 \endlist
3052*/ 3053*/
3053 3054
3054void QTextEdit::setTextFormat( TextFormat format ) 3055void QTextEdit::setTextFormat( TextFormat format )
3055{ 3056{
3056 doc->setTextFormat( format ); 3057 doc->setTextFormat( format );
3057} 3058}
3058 3059
3059Qt::TextFormat QTextEdit::textFormat() const 3060Qt::TextFormat QTextEdit::textFormat() const
3060{ 3061{
3061 return doc->textFormat(); 3062 return doc->textFormat();
3062} 3063}
3063 3064
3064/*! 3065/*!
3065 Returns the number of paragraphs in the text; this could be 0. 3066 Returns the number of paragraphs in the text; this could be 0.
3066*/ 3067*/
3067 3068
3068int QTextEdit::paragraphs() const 3069int QTextEdit::paragraphs() const
3069{ 3070{
3070 return doc->lastParagraph()->paragId() + 1; 3071 return doc->lastParagraph()->paragId() + 1;
3071} 3072}
3072 3073
3073/*! 3074/*!
3074 Returns the number of lines in paragraph \a para, or -1 if there 3075 Returns the number of lines in paragraph \a para, or -1 if there
3075 is no paragraph with index \a para. 3076 is no paragraph with index \a para.
3076*/ 3077*/
3077 3078
3078int QTextEdit::linesOfParagraph( int para ) const 3079int QTextEdit::linesOfParagraph( int para ) const
3079{ 3080{
3080 QTextParagraph *p = doc->paragAt( para ); 3081 QTextParagraph *p = doc->paragAt( para );
3081 if ( !p ) 3082 if ( !p )
3082 return -1; 3083 return -1;
3083 return p->lines(); 3084 return p->lines();
3084} 3085}
3085 3086
3086/*! 3087/*!
3087 Returns the length of the paragraph \a para (number of 3088 Returns the length of the paragraph \a para (number of
3088 characters), or -1 if there is no paragraph with index \a para 3089 characters), or -1 if there is no paragraph with index \a para
3089*/ 3090*/
3090 3091
3091int QTextEdit::paragraphLength( int para ) const 3092int QTextEdit::paragraphLength( int para ) const
3092{ 3093{
3093 QTextParagraph *p = doc->paragAt( para ); 3094 QTextParagraph *p = doc->paragAt( para );
3094 if ( !p ) 3095 if ( !p )
3095 return -1; 3096 return -1;
3096 return p->length() - 1; 3097 return p->length() - 1;
3097} 3098}
3098 3099
3099/*! 3100/*!
3100 Returns the number of lines in the text edit; this could be 0. 3101 Returns the number of lines in the text edit; this could be 0.
3101 3102
3102 \warning This function may be slow. Lines change all the time 3103 \warning This function may be slow. Lines change all the time
3103 during word wrapping, so this function has to iterate over all the 3104 during word wrapping, so this function has to iterate over all the
3104 paragraphs and get the number of lines from each one individually. 3105 paragraphs and get the number of lines from each one individually.
3105*/ 3106*/
3106 3107
3107int QTextEdit::lines() const 3108int QTextEdit::lines() const
3108{ 3109{
3109 QTextParagraph *p = doc->firstParagraph(); 3110 QTextParagraph *p = doc->firstParagraph();
3110 int l = 0; 3111 int l = 0;
3111 while ( p ) { 3112 while ( p ) {
3112 l += p->lines(); 3113 l += p->lines();
3113 p = p->next(); 3114 p = p->next();
3114 } 3115 }
3115 3116
3116 return l; 3117 return l;
3117} 3118}
3118 3119
3119/*! 3120/*!
3120 Returns the line number of the line in paragraph \a para in which 3121 Returns the line number of the line in paragraph \a para in which
3121 the character at position \a index appears. The \a index position is 3122 the character at position \a index appears. The \a index position is
3122 relative to the beginning of the paragraph. If there is no such 3123 relative to the beginning of the paragraph. If there is no such
3123 paragraph or no such character at the \a index position (e.g. the 3124 paragraph or no such character at the \a index position (e.g. the
3124 index is out of range) -1 is returned. 3125 index is out of range) -1 is returned.
3125*/ 3126*/
3126 3127
3127int QTextEdit::lineOfChar( int para, int index ) 3128int QTextEdit::lineOfChar( int para, int index )
3128{ 3129{
3129 QTextParagraph *p = doc->paragAt( para ); 3130 QTextParagraph *p = doc->paragAt( para );
3130 if ( !p ) 3131 if ( !p )
3131 return -1; 3132 return -1;
3132 3133
3133 int idx, line; 3134 int idx, line;
3134 QTextStringChar *c = p->lineStartOfChar( index, &idx, &line ); 3135 QTextStringChar *c = p->lineStartOfChar( index, &idx, &line );
3135 if ( !c ) 3136 if ( !c )
3136 return -1; 3137 return -1;
3137 3138
3138 return line; 3139 return line;
3139} 3140}
3140 3141
3141void QTextEdit::setModified( bool m ) 3142void QTextEdit::setModified( bool m )
3142{ 3143{
3143 bool oldModified = modified; 3144 bool oldModified = modified;
3144 modified = m; 3145 modified = m;
3145 if ( modified && doc->oTextValid ) 3146 if ( modified && doc->oTextValid )
3146 doc->invalidateOriginalText(); 3147 doc->invalidateOriginalText();
3147 if ( oldModified != modified ) 3148 if ( oldModified != modified )
3148 emit modificationChanged( modified ); 3149 emit modificationChanged( modified );
3149} 3150}
3150 3151
3151/*! \property QTextEdit::modified 3152/*! \property QTextEdit::modified
3152 \brief whether the document has been modified by the user 3153 \brief whether the document has been modified by the user
3153*/ 3154*/
3154 3155
3155bool QTextEdit::isModified() const 3156bool QTextEdit::isModified() const
3156{ 3157{
3157 return modified; 3158 return modified;
3158} 3159}
3159 3160
3160void QTextEdit::setModified() 3161void QTextEdit::setModified()
3161{ 3162{
3162 if ( !isModified() ) 3163 if ( !isModified() )
3163 setModified( TRUE ); 3164 setModified( TRUE );
3164} 3165}
3165 3166
3166/*! 3167/*!
3167 Returns TRUE if the current format is italic; otherwise returns FALSE. 3168 Returns TRUE if the current format is italic; otherwise returns FALSE.
3168 3169
3169 \sa setItalic() 3170 \sa setItalic()
3170*/ 3171*/
3171 3172
3172bool QTextEdit::italic() const 3173bool QTextEdit::italic() const
3173{ 3174{
3174 return currentFormat->font().italic(); 3175 return currentFormat->font().italic();
3175} 3176}
3176 3177
3177/*! 3178/*!
3178 Returns TRUE if the current format is bold; otherwise returns FALSE. 3179 Returns TRUE if the current format is bold; otherwise returns FALSE.
3179 3180
3180 \sa setBold() 3181 \sa setBold()
3181*/ 3182*/
3182 3183
3183bool QTextEdit::bold() const 3184bool QTextEdit::bold() const
3184{ 3185{
3185 return currentFormat->font().bold(); 3186 return currentFormat->font().bold();
3186} 3187}
3187 3188
3188/*! 3189/*!
3189 Returns TRUE if the current format is underlined; otherwise returns 3190 Returns TRUE if the current format is underlined; otherwise returns
3190 FALSE. 3191 FALSE.
3191 3192
3192 \sa setUnderline() 3193 \sa setUnderline()
3193*/ 3194*/
3194 3195
3195bool QTextEdit::underline() const 3196bool QTextEdit::underline() const
3196{ 3197{
3197 return currentFormat->font().underline(); 3198 return currentFormat->font().underline();
3198} 3199}
3199 3200
3200/*! 3201/*!
3201 Returns the font family of the current format. 3202 Returns the font family of the current format.
3202 3203
3203 \sa setFamily() setCurrentFont() setPointSize() 3204 \sa setFamily() setCurrentFont() setPointSize()
3204*/ 3205*/
3205 3206
3206QString QTextEdit::family() const 3207QString QTextEdit::family() const
3207{ 3208{
3208 return currentFormat->font().family(); 3209 return currentFormat->font().family();
3209} 3210}
3210 3211
3211/*! 3212/*!
3212 Returns the point size of the font of the current format. 3213 Returns the point size of the font of the current format.
3213 3214
3214 \sa setFamily() setCurrentFont() setPointSize() 3215 \sa setFamily() setCurrentFont() setPointSize()
3215 3216
3216*/ 3217*/
3217 3218
3218int QTextEdit::pointSize() const 3219int QTextEdit::pointSize() const
3219{ 3220{
3220 return currentFormat->font().pointSize(); 3221 return currentFormat->font().pointSize();
3221} 3222}
3222 3223
3223/*! 3224/*!
3224 Returns the color of the current format. 3225 Returns the color of the current format.
3225 3226
3226 \sa setColor() setPaper() 3227 \sa setColor() setPaper()
3227*/ 3228*/
3228 3229
3229QColor QTextEdit::color() const 3230QColor QTextEdit::color() const
3230{ 3231{
3231 return currentFormat->color(); 3232 return currentFormat->color();
3232} 3233}
3233 3234
3234/*! 3235/*!
3235 Returns the font of the current format. 3236 Returns the font of the current format.
3236 3237
3237 \sa setCurrentFont() setFamily() setPointSize() 3238 \sa setCurrentFont() setFamily() setPointSize()
3238 3239
3239*/ 3240*/
3240 3241
3241QFont QTextEdit::font() const 3242QFont QTextEdit::font() const
3242{ 3243{
3243 return currentFormat->font(); 3244 return currentFormat->font();
3244} 3245}
3245 3246
3246/*! 3247/*!
3247 Returns the alignment of the current paragraph. 3248 Returns the alignment of the current paragraph.
3248 3249
3249 \sa setAlignment() 3250 \sa setAlignment()
3250*/ 3251*/
3251 3252
3252int QTextEdit::alignment() const 3253int QTextEdit::alignment() const
3253{ 3254{
3254 return currentAlignment; 3255 return currentAlignment;
3255} 3256}
3256 3257
3257void QTextEdit::startDrag() 3258void QTextEdit::startDrag()
3258{ 3259{
3259#ifndef QT_NO_DRAGANDDROP 3260#ifndef QT_NO_DRAGANDDROP
3260 mousePressed = FALSE; 3261 mousePressed = FALSE;
3261 inDoubleClick = FALSE; 3262 inDoubleClick = FALSE;
3262 QDragObject *drag = new QTextDrag( doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy ), viewport() ); 3263 QDragObject *drag = new QTextDrag( doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy ), viewport() );
3263 if ( isReadOnly() ) { 3264 if ( isReadOnly() ) {
3264 drag->dragCopy(); 3265 drag->dragCopy();
3265 } else { 3266 } else {
3266 if ( drag->drag() && QDragObject::target() != this && QDragObject::target() != viewport() ) 3267 if ( drag->drag() && QDragObject::target() != this && QDragObject::target() != viewport() )
3267 removeSelectedText(); 3268 removeSelectedText();
3268 } 3269 }
3269#endif 3270#endif
3270} 3271}
3271 3272
3272/*! 3273/*!
3273 If \a select is TRUE (the default), all the text is selected as 3274 If \a select is TRUE (the default), all the text is selected as
3274 selection 0. 3275 selection 0.
3275 If \a select is FALSE any selected text is unselected, i.e., the 3276 If \a select is FALSE any selected text is unselected, i.e., the
3276 default selection (selection 0) is cleared. 3277 default selection (selection 0) is cleared.
3277 3278
3278 \sa selectedText 3279 \sa selectedText
3279*/ 3280*/
3280 3281
3281void QTextEdit::selectAll( bool select ) 3282void QTextEdit::selectAll( bool select )
3282{ 3283{
3283 if ( !select ) 3284 if ( !select )
3284 doc->removeSelection( QTextDocument::Standard ); 3285 doc->removeSelection( QTextDocument::Standard );
3285 else 3286 else
3286 doc->selectAll( QTextDocument::Standard ); 3287 doc->selectAll( QTextDocument::Standard );
3287 repaintChanged(); 3288 repaintChanged();
3288 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) ); 3289 emit copyAvailable( doc->hasSelection( QTextDocument::Standard ) );
3289 emit selectionChanged(); 3290 emit selectionChanged();
3290#ifndef QT_NO_CURSOR 3291#ifndef QT_NO_CURSOR
3291 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 3292 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
3292#endif 3293#endif
3293} 3294}
3294 3295
3295void QTextEdit::UndoRedoInfo::clear() 3296void QTextEdit::UndoRedoInfo::clear()
3296{ 3297{
3297 if ( valid() ) { 3298 if ( valid() ) {
3298 if ( type == Insert || type == Return ) 3299 if ( type == Insert || type == Return )
3299 doc->addCommand( new QTextInsertCommand( doc, id, index, d->text.rawData(), styleInformation ) ); 3300 doc->addCommand( new QTextInsertCommand( doc, id, index, d->text.rawData(), styleInformation ) );
3300 else if ( type == Format ) 3301 else if ( type == Format )
3301 doc->addCommand( new QTextFormatCommand( doc, id, index, eid, eindex, d->text.rawData(), format, flags ) ); 3302 doc->addCommand( new QTextFormatCommand( doc, id, index, eid, eindex, d->text.rawData(), format, flags ) );
3302 else if ( type == Style ) 3303 else if ( type == Style )
3303 doc->addCommand( new QTextStyleCommand( doc, id, eid, styleInformation ) ); 3304 doc->addCommand( new QTextStyleCommand( doc, id, eid, styleInformation ) );
3304 else if ( type != Invalid ) { 3305 else if ( type != Invalid ) {
3305 doc->addCommand( new QTextDeleteCommand( doc, id, index, d->text.rawData(), styleInformation ) ); 3306 doc->addCommand( new QTextDeleteCommand( doc, id, index, d->text.rawData(), styleInformation ) );
3306 } 3307 }
3307 } 3308 }
3308 type = Invalid; 3309 type = Invalid;
3309 d->text = QString::null; 3310 d->text = QString::null;
3310 id = -1; 3311 id = -1;
3311 index = -1; 3312 index = -1;
3312 styleInformation = QByteArray(); 3313 styleInformation = QByteArray();
3313} 3314}
3314 3315
3315 3316
3316/*! 3317/*!
3317 If there is some selected text (in selection 0) it is deleted. If 3318 If there is some selected text (in selection 0) it is deleted. If
3318 there is no selected text (in selection 0) the character to the 3319 there is no selected text (in selection 0) the character to the
3319 right of the text cursor is deleted. 3320 right of the text cursor is deleted.
3320 3321
3321 \sa removeSelectedText() cut() 3322 \sa removeSelectedText() cut()
3322 3323
3323*/ 3324*/
3324 3325
3325void QTextEdit::del() 3326void QTextEdit::del()
3326{ 3327{
3327 if ( doc->hasSelection( QTextDocument::Standard ) ) { 3328 if ( doc->hasSelection( QTextDocument::Standard ) ) {
3328 removeSelectedText(); 3329 removeSelectedText();
3329 return; 3330 return;
3330 } 3331 }
3331 3332
3332 doKeyboardAction( ActionDelete ); 3333 doKeyboardAction( ActionDelete );
3333} 3334}
3334 3335
3335 3336
3336QTextEdit::UndoRedoInfo::UndoRedoInfo( QTextDocument *dc ) 3337QTextEdit::UndoRedoInfo::UndoRedoInfo( QTextDocument *dc )
3337 : type( Invalid ), doc( dc ) 3338 : type( Invalid ), doc( dc )
3338{ 3339{
3339 d = new QUndoRedoInfoPrivate; 3340 d = new QUndoRedoInfoPrivate;
3340 d->text = QString::null; 3341 d->text = QString::null;
3341 id = -1; 3342 id = -1;
3342 index = -1; 3343 index = -1;
3343} 3344}
3344 3345
3345QTextEdit::UndoRedoInfo::~UndoRedoInfo() 3346QTextEdit::UndoRedoInfo::~UndoRedoInfo()
3346{ 3347{
3347 delete d; 3348 delete d;
3348} 3349}
3349 3350
3350bool QTextEdit::UndoRedoInfo::valid() const 3351bool QTextEdit::UndoRedoInfo::valid() const
3351{ 3352{
3352 return id >= 0 && type != Invalid; 3353 return id >= 0 && type != Invalid;
3353} 3354}
3354 3355
3355/*! 3356/*!
3356 \internal 3357 \internal
3357 3358
3358 Resets the current format to the default format. 3359 Resets the current format to the default format.
3359*/ 3360*/
3360 3361
3361void QTextEdit::resetFormat() 3362void QTextEdit::resetFormat()
3362{ 3363{
3363 setAlignment( Qt3::AlignAuto ); 3364 setAlignment( Qt3::AlignAuto );
3364 setParagType( QStyleSheetItem::DisplayBlock, QStyleSheetItem::ListDisc ); 3365 setParagType( QStyleSheetItem::DisplayBlock, QStyleSheetItem::ListDisc );
3365 setFormat( doc->formatCollection()->defaultFormat(), QTextFormat::Format ); 3366 setFormat( doc->formatCollection()->defaultFormat(), QTextFormat::Format );
3366} 3367}
3367 3368
3368/*! Returns the QStyleSheet which is currently used in this text edit. 3369/*! Returns the QStyleSheet which is currently used in this text edit.
3369 3370
3370 \sa setStyleSheet() 3371 \sa setStyleSheet()
3371 */ 3372 */
3372 3373
3373QStyleSheet* QTextEdit::styleSheet() const 3374QStyleSheet* QTextEdit::styleSheet() const
3374{ 3375{
3375 return doc->styleSheet(); 3376 return doc->styleSheet();
3376} 3377}
3377 3378
3378/*! Sets the stylesheet to use with this text edit to \a styleSheet. Changes 3379/*! Sets the stylesheet to use with this text edit to \a styleSheet. Changes
3379 will only take effect for new text added with setText() or append(). 3380 will only take effect for new text added with setText() or append().
3380 3381
3381 \sa styleSheet() 3382 \sa styleSheet()
3382 */ 3383 */
3383 3384
3384void QTextEdit::setStyleSheet( QStyleSheet* styleSheet ) 3385void QTextEdit::setStyleSheet( QStyleSheet* styleSheet )
3385{ 3386{
3386 doc->setStyleSheet( styleSheet ); 3387 doc->setStyleSheet( styleSheet );
3387} 3388}
3388 3389
3389/*! 3390/*!
3390 \property QTextEdit::paper 3391 \property QTextEdit::paper
3391 \brief the background (paper) brush. 3392 \brief the background (paper) brush.
3392 3393
3393 The brush that is currently used to draw the background of the 3394 The brush that is currently used to draw the background of the
3394 text edit. The initial setting is an empty brush. 3395 text edit. The initial setting is an empty brush.
3395 */ 3396 */
3396 3397
3397void QTextEdit::setPaper( const QBrush& pap ) 3398void QTextEdit::setPaper( const QBrush& pap )
3398{ 3399{
3399 doc->setPaper( new QBrush( pap ) ); 3400 doc->setPaper( new QBrush( pap ) );
3400 viewport()->setBackgroundColor( pap.color() ); 3401 viewport()->setBackgroundColor( pap.color() );
3401 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 3402 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3402} 3403}
3403 3404
3404QBrush QTextEdit::paper() const 3405QBrush QTextEdit::paper() const
3405{ 3406{
3406 if ( doc->paper() ) 3407 if ( doc->paper() )
3407 return *doc->paper(); 3408 return *doc->paper();
3408 return QBrush(); 3409 return QBrush();
3409} 3410}
3410 3411
3411/*! 3412/*!
3412 \property QTextEdit::linkUnderline 3413 \property QTextEdit::linkUnderline
3413 \brief whether hypertext links will be underlined 3414 \brief whether hypertext links will be underlined
3414 3415
3415 If TRUE (the default) hypertext links will be displayed underlined. 3416 If TRUE (the default) hypertext links will be displayed underlined.
3416 If FALSE links will not be displayed underlined. 3417 If FALSE links will not be displayed underlined.
3417*/ 3418*/
3418 3419
3419void QTextEdit::setLinkUnderline( bool b ) 3420void QTextEdit::setLinkUnderline( bool b )
3420{ 3421{
3421 doc->setUnderlineLinks( b ); 3422 doc->setUnderlineLinks( b );
3422} 3423}
3423 3424
3424bool QTextEdit::linkUnderline() const 3425bool QTextEdit::linkUnderline() const
3425{ 3426{
3426 return doc->underlineLinks(); 3427 return doc->underlineLinks();
3427} 3428}
3428 3429
3429/*! Sets the text edit's mimesource factory to \a factory. See 3430/*! Sets the text edit's mimesource factory to \a factory. See
3430 QMimeSourceFactory for further details. 3431 QMimeSourceFactory for further details.
3431 3432
3432 \sa mimeSourceFactory() 3433 \sa mimeSourceFactory()
3433 */ 3434 */
3434 3435
3435void QTextEdit::setMimeSourceFactory( QMimeSourceFactory* factory ) 3436void QTextEdit::setMimeSourceFactory( QMimeSourceFactory* factory )
3436{ 3437{
3437 doc->setMimeSourceFactory( factory ); 3438 doc->setMimeSourceFactory( factory );
3438} 3439}
3439 3440
3440/*! Returns the QMimeSourceFactory which is currently used by this 3441/*! Returns the QMimeSourceFactory which is currently used by this
3441 text edit. 3442 text edit.
3442 3443
3443 \sa setMimeSourceFactory() 3444 \sa setMimeSourceFactory()
3444*/ 3445*/
3445 3446
3446QMimeSourceFactory* QTextEdit::mimeSourceFactory() const 3447QMimeSourceFactory* QTextEdit::mimeSourceFactory() const
3447{ 3448{
3448 return doc->mimeSourceFactory(); 3449 return doc->mimeSourceFactory();
3449} 3450}
3450 3451
3451/*! 3452/*!
3452 Returns how many pixels high the text edit needs to be to display 3453 Returns how many pixels high the text edit needs to be to display
3453 all the text if the text edit is \a w pixels wide. 3454 all the text if the text edit is \a w pixels wide.
3454*/ 3455*/
3455 3456
3456int QTextEdit::heightForWidth( int w ) const 3457int QTextEdit::heightForWidth( int w ) const
3457{ 3458{
3458 int oldw = doc->width(); 3459 int oldw = doc->width();
3459 doc->doLayout( 0, w ); 3460 doc->doLayout( 0, w );
3460 int h = doc->height(); 3461 int h = doc->height();
3461 doc->setWidth( oldw ); 3462 doc->setWidth( oldw );
3462 doc->invalidate(); 3463 doc->invalidate();
3463 ( (QTextEdit*)this )->formatMore(); 3464 ( (QTextEdit*)this )->formatMore();
3464 return h; 3465 return h;
3465} 3466}
3466 3467
3467/*! Appends the text \a text to the end of the text edit. 3468/*! Appends the text \a text to the end of the text edit.
3468 Note that the undo/redo history is cleared by this function. 3469 Note that the undo/redo history is cleared by this function.
3469 */ 3470 */
3470 3471
3471void QTextEdit::append( const QString &text ) 3472void QTextEdit::append( const QString &text )
3472{ 3473{
3473 // flush and clear the undo/redo stack if necessary 3474 // flush and clear the undo/redo stack if necessary
3474 undoRedoInfo.clear(); 3475 undoRedoInfo.clear();
3475 doc->commands()->clear(); 3476 doc->commands()->clear();
3476 3477
3477 doc->removeSelection( QTextDocument::Standard ); 3478 doc->removeSelection( QTextDocument::Standard );
3478 TextFormat f = doc->textFormat(); 3479 TextFormat f = doc->textFormat();
3479 if ( f == AutoText ) { 3480 if ( f == AutoText ) {
3480 if ( QStyleSheet::mightBeRichText( text ) ) 3481 if ( QStyleSheet::mightBeRichText( text ) )
3481 f = RichText; 3482 f = RichText;
3482 else 3483 else
3483 f = PlainText; 3484 f = PlainText;
3484 } 3485 }
3485 3486
3486 drawCursor( FALSE ); 3487 drawCursor( FALSE );
3487 QTextCursor oldc( *cursor ); 3488 QTextCursor oldc( *cursor );
3488 ensureFormatted( doc->lastParagraph() ); 3489 ensureFormatted( doc->lastParagraph() );
3489 bool atBottom = contentsY() >= contentsHeight() - visibleHeight(); 3490 bool atBottom = contentsY() >= contentsHeight() - visibleHeight();
3490 cursor->gotoEnd(); 3491 cursor->gotoEnd();
3491 if ( cursor->index() > 0 ) 3492 if ( cursor->index() > 0 )
3492 cursor->splitAndInsertEmptyParagraph(); 3493 cursor->splitAndInsertEmptyParagraph();
3493 QTextCursor oldCursor2 = *cursor; 3494 QTextCursor oldCursor2 = *cursor;
3494 3495
3495 if ( f == Qt::PlainText ) { 3496 if ( f == Qt::PlainText ) {
3496 cursor->insert( text, TRUE ); 3497 cursor->insert( text, TRUE );
3497 if ( doc->useFormatCollection() && 3498 if ( doc->useFormatCollection() &&
3498 currentFormat != cursor->paragraph()->at( cursor->index() )->format() ) { 3499 currentFormat != cursor->paragraph()->at( cursor->index() )->format() ) {
3499 doc->setSelectionStart( QTextDocument::Temp, oldCursor2 ); 3500 doc->setSelectionStart( QTextDocument::Temp, oldCursor2 );
3500 doc->setSelectionEnd( QTextDocument::Temp, *cursor ); 3501 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
3501 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format ); 3502 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format );
3502 doc->removeSelection( QTextDocument::Temp ); 3503 doc->removeSelection( QTextDocument::Temp );
3503 } 3504 }
3504 } else { 3505 } else {
3505 if ( cursor->paragraph()->prev() ) 3506 if ( cursor->paragraph()->prev() )
3506 cursor->paragraph()->prev()->invalidate(0); // vertical margins might have to change 3507 cursor->paragraph()->prev()->invalidate(0); // vertical margins might have to change
3507 doc->setRichTextInternal( text ); 3508 doc->setRichTextInternal( text );
3508 } 3509 }
3509 formatMore(); 3510 formatMore();
3510 repaintChanged(); 3511 repaintChanged();
3511 if ( atBottom ) 3512 if ( atBottom )
3512 scrollToBottom(); 3513 scrollToBottom();
3513 *cursor = oldc; 3514 *cursor = oldc;
3514 if ( !isReadOnly() ) 3515 if ( !isReadOnly() )
3515 cursorVisible = TRUE; 3516 cursorVisible = TRUE;
3516 setModified(); 3517 setModified();
3517 emit textChanged(); 3518 emit textChanged();
3518} 3519}
3519 3520
3520/*! \property QTextEdit::hasSelectedText 3521/*! \property QTextEdit::hasSelectedText
3521 \brief whether some text is selected in selection 0 3522 \brief whether some text is selected in selection 0
3522 */ 3523 */
3523 3524
3524bool QTextEdit::hasSelectedText() const 3525bool QTextEdit::hasSelectedText() const
3525{ 3526{
3526 return doc->hasSelection( QTextDocument::Standard ); 3527 return doc->hasSelection( QTextDocument::Standard );
3527} 3528}
3528 3529
3529/*!\property QTextEdit::selectedText 3530/*!\property QTextEdit::selectedText
3530 \brief The selected text (from selection 0) or an empty string if 3531 \brief The selected text (from selection 0) or an empty string if
3531 there is no currently selected text (in selection 0). 3532 there is no currently selected text (in selection 0).
3532 3533
3533 The text is always returned as \c PlainText regardless of the text 3534 The text is always returned as \c PlainText regardless of the text
3534 format. In a future version of Qt an HTML subset \e may be returned 3535 format. In a future version of Qt an HTML subset \e may be returned
3535 depending on the text format. 3536 depending on the text format.
3536 3537
3537 \sa hasSelectedText 3538 \sa hasSelectedText
3538 */ 3539 */
3539 3540
3540QString QTextEdit::selectedText() const 3541QString QTextEdit::selectedText() const
3541{ 3542{
3542 return doc->selectedText( QTextDocument::Standard ); 3543 return doc->selectedText( QTextDocument::Standard );
3543} 3544}
3544 3545
3545bool QTextEdit::handleReadOnlyKeyEvent( QKeyEvent *e ) 3546bool QTextEdit::handleReadOnlyKeyEvent( QKeyEvent *e )
3546{ 3547{
3547 switch( e->key() ) { 3548 switch( e->key() ) {
3548 case Key_Down: 3549 case Key_Down:
3549 setContentsPos( contentsX(), contentsY() + 10 ); 3550 setContentsPos( contentsX(), contentsY() + 10 );
3550 break; 3551 break;
3551 case Key_Up: 3552 case Key_Up:
3552 setContentsPos( contentsX(), contentsY() - 10 ); 3553 setContentsPos( contentsX(), contentsY() - 10 );
3553 break; 3554 break;
3554 case Key_Left: 3555 case Key_Left:
3555 setContentsPos( contentsX() - 10, contentsY() ); 3556 setContentsPos( contentsX() - 10, contentsY() );
3556 break; 3557 break;
3557 case Key_Right: 3558 case Key_Right:
3558 setContentsPos( contentsX() + 10, contentsY() ); 3559 setContentsPos( contentsX() + 10, contentsY() );
3559 break; 3560 break;
3560 case Key_PageUp: 3561 case Key_PageUp:
3561 setContentsPos( contentsX(), contentsY() - visibleHeight() ); 3562 setContentsPos( contentsX(), contentsY() - visibleHeight() );
3562 break; 3563 break;
3563 case Key_PageDown: 3564 case Key_PageDown:
3564 setContentsPos( contentsX(), contentsY() + visibleHeight() ); 3565 setContentsPos( contentsX(), contentsY() + visibleHeight() );
3565 break; 3566 break;
3566 case Key_Home: 3567 case Key_Home:
3567 setContentsPos( contentsX(), 0 ); 3568 setContentsPos( contentsX(), 0 );
3568 break; 3569 break;
3569 case Key_End: 3570 case Key_End:
3570 setContentsPos( contentsX(), contentsHeight() - visibleHeight() ); 3571 setContentsPos( contentsX(), contentsHeight() - visibleHeight() );
3571 break; 3572 break;
3572 case Key_F16: // Copy key on Sun keyboards 3573 case Key_F16: // Copy key on Sun keyboards
3573 copy(); 3574 copy();
3574 break; 3575 break;
3575#ifndef QT_NO_NETWORKPROTOCOL 3576#ifndef QT_NO_NETWORKPROTOCOL
3576 case Key_Return: 3577 case Key_Return:
3577 case Key_Enter: 3578 case Key_Enter:
3578 case Key_Space: { 3579 case Key_Space: {
3579 if ( !doc->focusIndicator.href.isEmpty() ) { 3580 if ( !doc->focusIndicator.href.isEmpty() ) {
3580 QUrl u( doc->context(), doc->focusIndicator.href, TRUE ); 3581 QUrl u( doc->context(), doc->focusIndicator.href, TRUE );
3581 emitLinkClicked( u.toString( FALSE, FALSE ) ); 3582 emitLinkClicked( u.toString( FALSE, FALSE ) );
3582#ifndef QT_NO_CURSOR 3583#ifndef QT_NO_CURSOR
3583 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 3584 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
3584#endif 3585#endif
3585 } 3586 }
3586 } break; 3587 } break;
3587#endif 3588#endif
3588 default: 3589 default:
3589 if ( e->state() & ControlButton ) { 3590 if ( e->state() & ControlButton ) {
3590 switch ( e->key() ) { 3591 switch ( e->key() ) {
3591 case Key_C: case Key_F16: // Copy key on Sun keyboards 3592 case Key_C: case Key_F16: // Copy key on Sun keyboards
3592 copy(); 3593 copy();
3593 break; 3594 break;
3594 } 3595 }
3595 } 3596 }
3596 return FALSE; 3597 return FALSE;
3597 } 3598 }
3598 return TRUE; 3599 return TRUE;
3599} 3600}
3600 3601
3601/*! Returns the context of the edit. 3602/*! Returns the context of the edit.
3602 The context is a path which the text edit's QMimeSourceFactory 3603 The context is a path which the text edit's QMimeSourceFactory
3603 uses to resolve the locations of files and images. 3604 uses to resolve the locations of files and images.
3604 3605
3605 \sa text 3606 \sa text
3606*/ 3607*/
3607 3608
3608QString QTextEdit::context() const 3609QString QTextEdit::context() const
3609{ 3610{
3610 return doc->context(); 3611 return doc->context();
3611} 3612}
3612 3613
3613/*! 3614/*!
3614 \property QTextEdit::documentTitle 3615 \property QTextEdit::documentTitle
3615 \brief the title of the document parsed from the text. 3616 \brief the title of the document parsed from the text.
3616 3617
3617 For \c PlainText the title will be an empty string. For \c RichText 3618 For \c PlainText the title will be an empty string. For \c RichText
3618 the title will be the text between the \c{<title>} tags, if present, 3619 the title will be the text between the \c{<title>} tags, if present,
3619 otherwise an empty string. 3620 otherwise an empty string.
3620*/ 3621*/
3621 3622
3622QString QTextEdit::documentTitle() const 3623QString QTextEdit::documentTitle() const
3623{ 3624{
3624 return doc->attributes()[ "title" ]; 3625 return doc->attributes()[ "title" ];
3625} 3626}
3626 3627
3627void QTextEdit::makeParagVisible( QTextParagraph *p ) 3628void QTextEdit::makeParagVisible( QTextParagraph *p )
3628{ 3629{
3629 setContentsPos( contentsX(), QMIN( p->rect().y(), contentsHeight() - visibleHeight() ) ); 3630 setContentsPos( contentsX(), QMIN( p->rect().y(), contentsHeight() - visibleHeight() ) );
3630} 3631}
3631 3632
3632/*! Scrolls the text edit to make the text at the anchor called \a name 3633/*! Scrolls the text edit to make the text at the anchor called \a name
3633 visible, if it can be found in the document. If the anchor isn't found 3634 visible, if it can be found in the document. If the anchor isn't found
3634 no scrolling will occur. An anchor is defined using the HTML anchor 3635 no scrolling will occur. An anchor is defined using the HTML anchor
3635 tag, e.g. \c{<a name="target">}. 3636 tag, e.g. \c{<a name="target">}.
3636*/ 3637*/
3637 3638
3638void QTextEdit::scrollToAnchor( const QString& name ) 3639void QTextEdit::scrollToAnchor( const QString& name )
3639{ 3640{
3640 if ( !isVisible() ) { 3641 if ( !isVisible() ) {
3641 d->scrollToAnchor = name; 3642 d->scrollToAnchor = name;
3642 return; 3643 return;
3643 } 3644 }
3644 if ( name.isEmpty() ) 3645 if ( name.isEmpty() )
3645 return; 3646 return;
3646 sync(); 3647 sync();
3647 QTextCursor cursor( doc ); 3648 QTextCursor cursor( doc );
3648 QTextParagraph* last = doc->lastParagraph(); 3649 QTextParagraph* last = doc->lastParagraph();
3649 for (;;) { 3650 for (;;) {
3650 QTextStringChar* c = cursor.paragraph()->at( cursor.index() ); 3651 QTextStringChar* c = cursor.paragraph()->at( cursor.index() );
3651 if( c->isAnchor() ) { 3652 if( c->isAnchor() ) {
3652 QString a = c->anchorName(); 3653 QString a = c->anchorName();
3653 if ( a == name || 3654 if ( a == name ||
3654 (a.contains( '#' ) && QStringList::split( '#', a ).contains( name ) ) ) { 3655 (a.contains( '#' ) && QStringList::split( '#', a ).contains( name ) ) ) {
3655 setContentsPos( contentsX(), QMIN( cursor.paragraph()->rect().top() + cursor.totalOffsetY(), contentsHeight() - visibleHeight() ) ); 3656 setContentsPos( contentsX(), QMIN( cursor.paragraph()->rect().top() + cursor.totalOffsetY(), contentsHeight() - visibleHeight() ) );
3656 break; 3657 break;
3657 } 3658 }
3658 } 3659 }
3659 if ( cursor.paragraph() == last && cursor.atParagEnd() ) 3660 if ( cursor.paragraph() == last && cursor.atParagEnd() )
3660 break; 3661 break;
3661 cursor.gotoNextLetter(); 3662 cursor.gotoNextLetter();
3662 } 3663 }
3663} 3664}
3664 3665
3665/*! If there is an anchor at position \a pos (in contents 3666/*! If there is an anchor at position \a pos (in contents
3666 coordinates), its name is returned, otherwise an empty string is 3667 coordinates), its name is returned, otherwise an empty string is
3667 returned. 3668 returned.
3668*/ 3669*/
3669 3670
3670QString QTextEdit::anchorAt( const QPoint& pos ) 3671QString QTextEdit::anchorAt( const QPoint& pos )
3671{ 3672{
3672 QTextCursor c( doc ); 3673 QTextCursor c( doc );
3673 placeCursor( pos, &c ); 3674 placeCursor( pos, &c );
3674 return c.paragraph()->at( c.index() )->anchorHref(); 3675 return c.paragraph()->at( c.index() )->anchorHref();
3675} 3676}
3676 3677
3677void QTextEdit::documentWidthChanged( int w ) 3678void QTextEdit::documentWidthChanged( int w )
3678{ 3679{
3679 resizeContents( QMAX( visibleWidth(), w), contentsHeight() ); 3680 resizeContents( QMAX( visibleWidth(), w), contentsHeight() );
3680} 3681}
3681 3682
3682/*! \internal 3683/*! \internal
3683 3684
3684 This function does nothing 3685 This function does nothing
3685*/ 3686*/
3686 3687
3687void QTextEdit::updateStyles() 3688void QTextEdit::updateStyles()
3688{ 3689{
3689} 3690}
3690 3691
3691void QTextEdit::setDocument( QTextDocument *dc ) 3692void QTextEdit::setDocument( QTextDocument *dc )
3692{ 3693{
3693 if ( dc == doc ) 3694 if ( dc == doc )
3694 return; 3695 return;
3695 doc = dc; 3696 doc = dc;
3696 delete cursor; 3697 delete cursor;
3697 cursor = new QTextCursor( doc ); 3698 cursor = new QTextCursor( doc );
3698 clearUndoRedo(); 3699 clearUndoRedo();
3699 undoRedoInfo.doc = doc; 3700 undoRedoInfo.doc = doc;
3700 lastFormatted = 0; 3701 lastFormatted = 0;
3701} 3702}
3702 3703
3703#ifndef QT_NO_CLIPBOARD 3704#ifndef QT_NO_CLIPBOARD
3704 3705
3705/*! 3706/*!
3706 Pastes the text with format \a subtype from the clipboard into the 3707 Pastes the text with format \a subtype from the clipboard into the
3707 text edit at the current cursor position. The \a subtype can be 3708 text edit at the current cursor position. The \a subtype can be
3708 "plain" or "html". 3709 "plain" or "html".
3709 3710
3710 If there is no text with format \a subtype in the clipboard nothing 3711 If there is no text with format \a subtype in the clipboard nothing
3711 happens. 3712 happens.
3712 3713
3713 \sa paste() cut() QTextEdit::copy() 3714 \sa paste() cut() QTextEdit::copy()
3714*/ 3715*/
3715void QTextEdit::pasteSubType( const QCString& subtype ) 3716void QTextEdit::pasteSubType( const QCString& subtype )
3716{ 3717{
3717 QCString st = subtype; 3718 QCString st = subtype;
3718 QString t = QApplication::clipboard()->text(st); 3719 QString t = QApplication::clipboard()->text(st);
3719 if ( doc->hasSelection( QTextDocument::Standard ) ) 3720 if ( doc->hasSelection( QTextDocument::Standard ) )
3720 removeSelectedText(); 3721 removeSelectedText();
3721 if ( !t.isEmpty() ) { 3722 if ( !t.isEmpty() ) {
3722 if ( t.startsWith( "<selstart/>" ) ) { 3723 if ( t.startsWith( "<selstart/>" ) ) {
3723 t.remove( 0, 11 ); 3724 t.remove( 0, 11 );
3724 QTextCursor oldC = *cursor; 3725 QTextCursor oldC = *cursor;
3725 lastFormatted = cursor->paragraph(); 3726 lastFormatted = cursor->paragraph();
3726 if ( lastFormatted->prev() ) 3727 if ( lastFormatted->prev() )
3727 lastFormatted = lastFormatted->prev(); 3728 lastFormatted = lastFormatted->prev();
3728 doc->setRichTextInternal( t, cursor ); 3729 doc->setRichTextInternal( t, cursor );
3729 3730
3730 if ( undoEnabled && !isReadOnly() ) { 3731 if ( undoEnabled && !isReadOnly() ) {
3731 doc->setSelectionStart( QTextDocument::Temp, oldC ); 3732 doc->setSelectionStart( QTextDocument::Temp, oldC );
3732 doc->setSelectionEnd( QTextDocument::Temp, *cursor ); 3733 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
3733 3734
3734 checkUndoRedoInfo( UndoRedoInfo::Insert ); 3735 checkUndoRedoInfo( UndoRedoInfo::Insert );
3735 if ( !undoRedoInfo.valid() ) { 3736 if ( !undoRedoInfo.valid() ) {
3736 undoRedoInfo.id = oldC.paragraph()->paragId(); 3737 undoRedoInfo.id = oldC.paragraph()->paragId();
3737 undoRedoInfo.index = oldC.index(); 3738 undoRedoInfo.index = oldC.index();
3738 undoRedoInfo.d->text = QString::null; 3739 undoRedoInfo.d->text = QString::null;
3739 } 3740 }
3740 int oldLen = undoRedoInfo.d->text.length(); 3741 int oldLen = undoRedoInfo.d->text.length();
3741 if ( !doc->preProcessor() ) { 3742 if ( !doc->preProcessor() ) {
3742 QString txt = doc->selectedText( QTextDocument::Temp ); 3743 QString txt = doc->selectedText( QTextDocument::Temp );
3743 undoRedoInfo.d->text += txt; 3744 undoRedoInfo.d->text += txt;
3744 for ( int i = 0; i < (int)txt.length(); ++i ) { 3745 for ( int i = 0; i < (int)txt.length(); ++i ) {
3745 if ( txt[ i ] != '\n' && oldC.paragraph()->at( oldC.index() )->format() ) { 3746 if ( txt[ i ] != '\n' && oldC.paragraph()->at( oldC.index() )->format() ) {
3746 oldC.paragraph()->at( oldC.index() )->format()->addRef(); 3747 oldC.paragraph()->at( oldC.index() )->format()->addRef();
3747 undoRedoInfo.d->text. 3748 undoRedoInfo.d->text.
3748 setFormat( oldLen + i, oldC.paragraph()->at( oldC.index() )->format(), TRUE ); 3749 setFormat( oldLen + i, oldC.paragraph()->at( oldC.index() )->format(), TRUE );
3749 } 3750 }
3750 oldC.gotoNextLetter(); 3751 oldC.gotoNextLetter();
3751 } 3752 }
3752 } 3753 }
3753 undoRedoInfo.clear(); 3754 undoRedoInfo.clear();
3754 removeSelection( QTextDocument::Temp ); 3755 removeSelection( QTextDocument::Temp );
3755 } 3756 }
3756 3757
3757 formatMore(); 3758 formatMore();
3758 setModified(); 3759 setModified();
3759 emit textChanged(); 3760 emit textChanged();
3760 repaintChanged(); 3761 repaintChanged();
3761 ensureCursorVisible(); 3762 ensureCursorVisible();
3762 return; 3763 return;
3763 } 3764 }
3764 3765
3765#if defined(Q_OS_WIN32) 3766#if defined(Q_OS_WIN32)
3766 // Need to convert CRLF to LF 3767 // Need to convert CRLF to LF
3767 int index = t.find( QString::fromLatin1("\r\n"), 0 ); 3768 int index = t.find( QString::fromLatin1("\r\n"), 0 );
3768 while ( index != -1 ) { 3769 while ( index != -1 ) {
3769 t.replace( index, 2, QChar('\n') ); 3770 t.replace( index, 2, QChar('\n') );
3770 index = t.find( "\r\n", index ); 3771 index = t.find( "\r\n", index );
3771 } 3772 }
3772#elif defined(Q_OS_MAC) 3773#elif defined(Q_OS_MAC)
3773 //need to convert CR to LF 3774 //need to convert CR to LF
3774 for( unsigned int index = 0; index < t.length(); index++ ) 3775 for( unsigned int index = 0; index < t.length(); index++ )
3775 if(t[index] == '\r') 3776 if(t[index] == '\r')
3776 t[index] = '\n'; 3777 t[index] = '\n';
3777#endif 3778#endif
3778 for ( int i=0; (uint) i<t.length(); i++ ) { 3779 for ( int i=0; (uint) i<t.length(); i++ ) {
3779 if ( t[ i ] < ' ' && t[ i ] != '\n' && t[ i ] != '\t' ) 3780 if ( t[ i ] < ' ' && t[ i ] != '\n' && t[ i ] != '\t' )
3780 t[ i ] = ' '; 3781 t[ i ] = ' ';
3781 } 3782 }
3782 if ( !t.isEmpty() ) 3783 if ( !t.isEmpty() )
3783 insert( t, FALSE, TRUE, TRUE ); 3784 insert( t, FALSE, TRUE, TRUE );
3784 } 3785 }
3785} 3786}
3786 3787
3787#ifndef QT_NO_MIMECLIPBOARD 3788#ifndef QT_NO_MIMECLIPBOARD
3788/*! 3789/*!
3789 Prompts the user to choose a type from a list of text types available, 3790 Prompts the user to choose a type from a list of text types available,
3790 then copies text from the clipboard (if there is any) into the text 3791 then copies text from the clipboard (if there is any) into the text
3791 edit at the current text cursor position. Any selected text (in 3792 edit at the current text cursor position. Any selected text (in
3792 selection 0) is first deleted. 3793 selection 0) is first deleted.
3793*/ 3794*/
3794void QTextEdit::pasteSpecial( const QPoint& pt ) 3795void QTextEdit::pasteSpecial( const QPoint& pt )
3795{ 3796{
3796 QCString st = pickSpecial( QApplication::clipboard()->data(), TRUE, pt ); 3797 QCString st = pickSpecial( QApplication::clipboard()->data(), TRUE, pt );
3797 if ( !st.isEmpty() ) 3798 if ( !st.isEmpty() )
3798 pasteSubType( st ); 3799 pasteSubType( st );
3799} 3800}
3800#endif 3801#endif
3801#ifndef QT_NO_MIME 3802#ifndef QT_NO_MIME
3802QCString QTextEdit::pickSpecial( QMimeSource* ms, bool always_ask, const QPoint& pt ) 3803QCString QTextEdit::pickSpecial( QMimeSource* ms, bool always_ask, const QPoint& pt )
3803{ 3804{
3804 if ( ms ) { 3805 if ( ms ) {
3805#ifndef QT_NO_POPUPMENU 3806#ifndef QT_NO_POPUPMENU
3806 QPopupMenu popup( this, "qt_pickspecial_menu" ); 3807 QPopupMenu popup( this, "qt_pickspecial_menu" );
3807 QString fmt; 3808 QString fmt;
3808 int n = 0; 3809 int n = 0;
3809 QDict<void> done; 3810 QDict<void> done;
3810 for (int i = 0; !( fmt = ms->format( i ) ).isNull(); i++) { 3811 for (int i = 0; !( fmt = ms->format( i ) ).isNull(); i++) {
3811 int semi = fmt.find( ";" ); 3812 int semi = fmt.find( ";" );
3812 if ( semi >= 0 ) 3813 if ( semi >= 0 )
3813 fmt = fmt.left( semi ); 3814 fmt = fmt.left( semi );
3814 if ( fmt.left( 5 ) == "text/" ) { 3815 if ( fmt.left( 5 ) == "text/" ) {
3815 fmt = fmt.mid( 5 ); 3816 fmt = fmt.mid( 5 );
3816 if ( !done.find( fmt ) ) { 3817 if ( !done.find( fmt ) ) {
3817 done.insert( fmt,(void*)1 ); 3818 done.insert( fmt,(void*)1 );
3818 popup.insertItem( fmt, i ); 3819 popup.insertItem( fmt, i );
3819 n++; 3820 n++;
3820 } 3821 }
3821 } 3822 }
3822 } 3823 }
3823 if ( n ) { 3824 if ( n ) {
3824 int i = n ==1 && !always_ask ? popup.idAt( 0 ) : popup.exec( pt ); 3825 int i = n ==1 && !always_ask ? popup.idAt( 0 ) : popup.exec( pt );
3825 if ( i >= 0 ) 3826 if ( i >= 0 )
3826 return popup.text(i).latin1(); 3827 return popup.text(i).latin1();
3827 } 3828 }
3828#else 3829#else
3829 QString fmt; 3830 QString fmt;
3830 for (int i = 0; !( fmt = ms->format( i ) ).isNull(); i++) { 3831 for (int i = 0; !( fmt = ms->format( i ) ).isNull(); i++) {
3831 int semi = fmt.find( ";" ); 3832 int semi = fmt.find( ";" );
3832 if ( semi >= 0 ) 3833 if ( semi >= 0 )
3833 fmt = fmt.left( semi ); 3834 fmt = fmt.left( semi );
3834 if ( fmt.left( 5 ) == "text/" ) { 3835 if ( fmt.left( 5 ) == "text/" ) {
3835 fmt = fmt.mid( 5 ); 3836 fmt = fmt.mid( 5 );
3836 return fmt.latin1(); 3837 return fmt.latin1();
3837 } 3838 }
3838 } 3839 }
3839#endif 3840#endif
3840 } 3841 }
3841 return QCString(); 3842 return QCString();
3842} 3843}
3843#endif // QT_NO_MIME 3844#endif // QT_NO_MIME
3844#endif // QT_NO_CLIPBOARD 3845#endif // QT_NO_CLIPBOARD
3845 3846
3846/*! \enum QTextEdit::WordWrap 3847/*! \enum QTextEdit::WordWrap
3847 3848
3848 This enum defines the QTextEdit's word wrap modes. The following 3849 This enum defines the QTextEdit's word wrap modes. The following
3849 values are valid: 3850 values are valid:
3850 3851
3851 \value NoWrap Do not wrap the text. 3852 \value NoWrap Do not wrap the text.
3852 3853
3853 \value WidgetWidth Wrap the text at the current width of the 3854 \value WidgetWidth Wrap the text at the current width of the
3854 widget (this is the default). Wrapping is at whitespace by default; 3855 widget (this is the default). Wrapping is at whitespace by default;
3855 this can be changed with setWrapPolicy(). 3856 this can be changed with setWrapPolicy().
3856 3857
3857 \value FixedPixelWidth Wrap the text at a fixed number of pixels from 3858 \value FixedPixelWidth Wrap the text at a fixed number of pixels from
3858 the widget's left side. The number of pixels is set with 3859 the widget's left side. The number of pixels is set with
3859 wrapColumnOrWidth(). 3860 wrapColumnOrWidth().
3860 3861
3861 \value FixedColumnWidth Wrap the text at a fixed number of character 3862 \value FixedColumnWidth Wrap the text at a fixed number of character
3862 columns from the widget's left side. The number of characters is set 3863 columns from the widget's left side. The number of characters is set
3863 with wrapColumnOrWidth(). 3864 with wrapColumnOrWidth().
3864 This is useful if you need formatted text that can also be 3865 This is useful if you need formatted text that can also be
3865 displayed gracefully on devices with monospaced fonts, for example a 3866 displayed gracefully on devices with monospaced fonts, for example a
3866 standard VT100 terminal, where you might set wrapColumnOrWidth() to 3867 standard VT100 terminal, where you might set wrapColumnOrWidth() to
3867 80. 3868 80.
3868 3869
3869 \sa setWordWrap() wordWrap() 3870 \sa setWordWrap() wordWrap()
3870*/ 3871*/
3871 3872
3872/*! 3873/*!
3873 \property QTextEdit::wordWrap 3874 \property QTextEdit::wordWrap
3874 \brief the word wrap mode 3875 \brief the word wrap mode
3875 3876
3876 The default mode is \c WidgetWidth which causes words to be wrapped 3877 The default mode is \c WidgetWidth which causes words to be wrapped
3877 at the right edge of the text edit. Wrapping occurs at whitespace, 3878 at the right edge of the text edit. Wrapping occurs at whitespace,
3878 keeping whole words intact. If you want wrapping to occur within 3879 keeping whole words intact. If you want wrapping to occur within
3879 words use setWrapPolicy(). If you set a wrap mode of \c 3880 words use setWrapPolicy(). If you set a wrap mode of \c
3880 FixedPixelWidth or \c FixedColumnWidth you should also call 3881 FixedPixelWidth or \c FixedColumnWidth you should also call
3881 setWrapColumnOrWidth() with the width you want. 3882 setWrapColumnOrWidth() with the width you want.
3882 3883
3883 \sa WordWrap, wrapColumnOrWidth, wrapPolicy, 3884 \sa WordWrap, wrapColumnOrWidth, wrapPolicy,
3884*/ 3885*/
3885 3886
3886void QTextEdit::setWordWrap( WordWrap mode ) 3887void QTextEdit::setWordWrap( WordWrap mode )
3887{ 3888{
3888 if ( wrapMode == mode ) 3889 if ( wrapMode == mode )
3889 return; 3890 return;
3890 wrapMode = mode; 3891 wrapMode = mode;
3891 switch ( mode ) { 3892 switch ( mode ) {
3892 case NoWrap: 3893 case NoWrap:
3893 document()->formatter()->setWrapEnabled( FALSE ); 3894 document()->formatter()->setWrapEnabled( FALSE );
3894 document()->formatter()->setWrapAtColumn( -1 ); 3895 document()->formatter()->setWrapAtColumn( -1 );
3895 doc->setWidth( visibleWidth() ); 3896 doc->setWidth( visibleWidth() );
3896 doc->setMinimumWidth( -1 ); 3897 doc->setMinimumWidth( -1 );
3897 doc->invalidate(); 3898 doc->invalidate();
3898 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 3899 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3899 lastFormatted = doc->firstParagraph(); 3900 lastFormatted = doc->firstParagraph();
3900 interval = 0; 3901 interval = 0;
3901 formatMore(); 3902 formatMore();
3902 break; 3903 break;
3903 case WidgetWidth: 3904 case WidgetWidth:
3904 document()->formatter()->setWrapEnabled( TRUE ); 3905 document()->formatter()->setWrapEnabled( TRUE );
3905 document()->formatter()->setWrapAtColumn( -1 ); 3906 document()->formatter()->setWrapAtColumn( -1 );
3906 doResize(); 3907 doResize();
3907 break; 3908 break;
3908 case FixedPixelWidth: 3909 case FixedPixelWidth:
3909 document()->formatter()->setWrapEnabled( TRUE ); 3910 document()->formatter()->setWrapEnabled( TRUE );
3910 document()->formatter()->setWrapAtColumn( -1 ); 3911 document()->formatter()->setWrapAtColumn( -1 );
3911 if ( wrapWidth < 0 ) 3912 if ( wrapWidth < 0 )
3912 wrapWidth = 200; 3913 wrapWidth = 200;
3913 setWrapColumnOrWidth( wrapWidth ); 3914 setWrapColumnOrWidth( wrapWidth );
3914 break; 3915 break;
3915 case FixedColumnWidth: 3916 case FixedColumnWidth:
3916 if ( wrapWidth < 0 ) 3917 if ( wrapWidth < 0 )
3917 wrapWidth = 80; 3918 wrapWidth = 80;
3918 document()->formatter()->setWrapEnabled( TRUE ); 3919 document()->formatter()->setWrapEnabled( TRUE );
3919 document()->formatter()->setWrapAtColumn( wrapWidth ); 3920 document()->formatter()->setWrapAtColumn( wrapWidth );
3920 setWrapColumnOrWidth( wrapWidth ); 3921 setWrapColumnOrWidth( wrapWidth );
3921 break; 3922 break;
3922 } 3923 }
3923} 3924}
3924 3925
3925QTextEdit::WordWrap QTextEdit::wordWrap() const 3926QTextEdit::WordWrap QTextEdit::wordWrap() const
3926{ 3927{
3927 return wrapMode; 3928 return wrapMode;
3928} 3929}
3929 3930
3930/*! 3931/*!
3931 \property QTextEdit::wrapColumnOrWidth 3932 \property QTextEdit::wrapColumnOrWidth
3932 \brief the position (in pixels or columns depending on the wrap mode) where text will be wrapped 3933 \brief the position (in pixels or columns depending on the wrap mode) where text will be wrapped
3933 3934
3934 If the wrap mode is \c FixedPixelWidth, the value is the number 3935 If the wrap mode is \c FixedPixelWidth, the value is the number
3935 of pixels from the left edge of the text edit at which text should 3936 of pixels from the left edge of the text edit at which text should
3936 be wrapped. If the wrap mode is \c FixedColumnWidth, the value is 3937 be wrapped. If the wrap mode is \c FixedColumnWidth, the value is
3937 the column number (in character columns) from the left edge of the 3938 the column number (in character columns) from the left edge of the
3938 text edit at which text should be wrapped. 3939 text edit at which text should be wrapped.
3939 3940
3940 \sa wordWrap 3941 \sa wordWrap
3941 */ 3942 */
3942void QTextEdit::setWrapColumnOrWidth( int value ) 3943void QTextEdit::setWrapColumnOrWidth( int value )
3943{ 3944{
3944 wrapWidth = value; 3945 wrapWidth = value;
3945 if ( wrapMode == FixedColumnWidth ) { 3946 if ( wrapMode == FixedColumnWidth ) {
3946 document()->formatter()->setWrapAtColumn( wrapWidth ); 3947 document()->formatter()->setWrapAtColumn( wrapWidth );
3947 resizeContents( 0, 0 ); 3948 resizeContents( 0, 0 );
3948 doc->setWidth( visibleWidth() ); 3949 doc->setWidth( visibleWidth() );
3949 doc->setMinimumWidth( -1 ); 3950 doc->setMinimumWidth( -1 );
3950 } else if (wrapMode == FixedPixelWidth ) { 3951 } else if (wrapMode == FixedPixelWidth ) {
3951 document()->formatter()->setWrapAtColumn( -1 ); 3952 document()->formatter()->setWrapAtColumn( -1 );
3952 resizeContents( wrapWidth, 0 ); 3953 resizeContents( wrapWidth, 0 );
3953 doc->setWidth( wrapWidth ); 3954 doc->setWidth( wrapWidth );
3954 doc->setMinimumWidth( wrapWidth ); 3955 doc->setMinimumWidth( wrapWidth );
3955 } else { 3956 } else {
3956 return; 3957 return;
3957 } 3958 }
3958 doc->invalidate(); 3959 doc->invalidate();
3959 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 3960 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3960 lastFormatted = doc->firstParagraph(); 3961 lastFormatted = doc->firstParagraph();
3961 interval = 0; 3962 interval = 0;
3962 formatMore(); 3963 formatMore();
3963} 3964}
3964 3965
3965int QTextEdit::wrapColumnOrWidth() const 3966int QTextEdit::wrapColumnOrWidth() const
3966{ 3967{
3967 if ( wrapMode == WidgetWidth ) 3968 if ( wrapMode == WidgetWidth )
3968 return visibleWidth(); 3969 return visibleWidth();
3969 return wrapWidth; 3970 return wrapWidth;
3970} 3971}
3971 3972
3972 3973
3973/*! \enum QTextEdit::WrapPolicy 3974/*! \enum QTextEdit::WrapPolicy
3974 3975
3975 This enum defines where text can be wrapped in word wrap mode. 3976 This enum defines where text can be wrapped in word wrap mode.
3976 3977
3977 The following values are valid: 3978 The following values are valid:
3978 \value AtWhiteSpace Break lines at whitespace, e.g. spaces or 3979 \value AtWhiteSpace Break lines at whitespace, e.g. spaces or
3979 newlines. 3980 newlines.
3980 \value Anywhere Break anywhere, including within words. 3981 \value Anywhere Break anywhere, including within words.
3981 \value AtWordBoundary Don't use this deprecated value (it is a 3982 \value AtWordBoundary Don't use this deprecated value (it is a
3982 synonym for AtWhiteSpace which you should use instead). 3983 synonym for AtWhiteSpace which you should use instead).
3983 3984
3984 \sa setWrapPolicy() 3985 \sa setWrapPolicy()
3985*/ 3986*/
3986 3987
3987/*! 3988/*!
3988 \property QTextEdit::wrapPolicy 3989 \property QTextEdit::wrapPolicy
3989 \brief the word wrap policy, at whitespace or anywhere 3990 \brief the word wrap policy, at whitespace or anywhere
3990 3991
3991 Defines where text can be wrapped when word wrap mode is not 3992 Defines where text can be wrapped when word wrap mode is not
3992 \c NoWrap. The choices are \c AtWhiteSpace (the default) and \c 3993 \c NoWrap. The choices are \c AtWhiteSpace (the default) and \c
3993 Anywhere. 3994 Anywhere.
3994 3995
3995 \sa wordWrap 3996 \sa wordWrap
3996 */ 3997 */
3997 3998
3998void QTextEdit::setWrapPolicy( WrapPolicy policy ) 3999void QTextEdit::setWrapPolicy( WrapPolicy policy )
3999{ 4000{
4000 if ( wPolicy == policy ) 4001 if ( wPolicy == policy )
4001 return; 4002 return;
4002 wPolicy = policy; 4003 wPolicy = policy;
4003 QTextFormatter *formatter; 4004 QTextFormatter *formatter;
4004 if ( policy == AtWhiteSpace ) 4005 if ( policy == AtWhiteSpace )
4005 formatter = new QTextFormatterBreakWords; 4006 formatter = new QTextFormatterBreakWords;
4006 else 4007 else
4007 formatter = new QTextFormatterBreakInWords; 4008 formatter = new QTextFormatterBreakInWords;
4008 formatter->setWrapAtColumn( document()->formatter()->wrapAtColumn() ); 4009 formatter->setWrapAtColumn( document()->formatter()->wrapAtColumn() );
4009 formatter->setWrapEnabled( document()->formatter()->isWrapEnabled( 0 ) ); 4010 formatter->setWrapEnabled( document()->formatter()->isWrapEnabled( 0 ) );
4010 document()->setFormatter( formatter ); 4011 document()->setFormatter( formatter );
4011 doc->invalidate(); 4012 doc->invalidate();
4012 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4013 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
4013 lastFormatted = doc->firstParagraph(); 4014 lastFormatted = doc->firstParagraph();
4014 interval = 0; 4015 interval = 0;
4015 formatMore(); 4016 formatMore();
4016} 4017}
4017 4018
4018QTextEdit::WrapPolicy QTextEdit::wrapPolicy() const 4019QTextEdit::WrapPolicy QTextEdit::wrapPolicy() const
4019{ 4020{
4020 return wPolicy; 4021 return wPolicy;
4021} 4022}
4022 4023
4023/*! 4024/*!
4024 Deletes all the text in the text edit. 4025 Deletes all the text in the text edit.
4025 4026
4026 \sa cut() removeSelectedText() setText() 4027 \sa cut() removeSelectedText() setText()
4027 4028
4028*/ 4029*/
4029 4030
4030void QTextEdit::clear() 4031void QTextEdit::clear()
4031{ 4032{
4032 // make clear undoable 4033 // make clear undoable
4033 doc->selectAll( QTextDocument::Temp ); 4034 doc->selectAll( QTextDocument::Temp );
4034 removeSelectedText( QTextDocument::Temp ); 4035 removeSelectedText( QTextDocument::Temp );
4035 4036
4036 setContentsPos( 0, 0 ); 4037 setContentsPos( 0, 0 );
4037 if ( cursor->isValid() ) 4038 if ( cursor->isValid() )
4038 cursor->restoreState(); 4039 cursor->restoreState();
4039 doc->clear( TRUE ); 4040 doc->clear( TRUE );
4040 delete cursor; 4041 delete cursor;
4041 cursor = new QTextCursor( doc ); 4042 cursor = new QTextCursor( doc );
4042 lastFormatted = 0; 4043 lastFormatted = 0;
4043 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4044 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
4044 4045
4045 emit cursorPositionChanged( cursor ); 4046 emit cursorPositionChanged( cursor );
4046 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() ); 4047 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
4047} 4048}
4048 4049
4049int QTextEdit::undoDepth() const 4050int QTextEdit::undoDepth() const
4050{ 4051{
4051 return document()->undoDepth(); 4052 return document()->undoDepth();
4052} 4053}
4053 4054
4054/*! 4055/*!
4055 \property QTextEdit::length 4056 \property QTextEdit::length
4056 \brief the number of characters in the text 4057 \brief the number of characters in the text
4057 4058
4058*/ 4059*/
4059 4060
4060int QTextEdit::length() const 4061int QTextEdit::length() const
4061{ 4062{
4062 return document()->length(); 4063 return document()->length();
4063} 4064}
4064 4065
4065/*! 4066/*!
4066 \property QTextEdit::tabStopWidth 4067 \property QTextEdit::tabStopWidth
4067 \brief the tab stop width in pixels 4068 \brief the tab stop width in pixels
4068 4069
4069*/ 4070*/
4070 4071
4071int QTextEdit::tabStopWidth() const 4072int QTextEdit::tabStopWidth() const
4072{ 4073{
4073 return document()->tabStopWidth(); 4074 return document()->tabStopWidth();
4074} 4075}
4075 4076
4076void QTextEdit::setUndoDepth( int d ) 4077void QTextEdit::setUndoDepth( int d )
4077{ 4078{
4078 document()->setUndoDepth( d ); 4079 document()->setUndoDepth( d );
4079} 4080}
4080 4081
4081void QTextEdit::setTabStopWidth( int ts ) 4082void QTextEdit::setTabStopWidth( int ts )
4082{ 4083{
4083 document()->setTabStops( ts ); 4084 document()->setTabStops( ts );
4084 doc->invalidate(); 4085 doc->invalidate();
4085 lastFormatted = doc->firstParagraph(); 4086 lastFormatted = doc->firstParagraph();
4086 interval = 0; 4087 interval = 0;
4087 formatMore(); 4088 formatMore();
4088 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4089 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
4089} 4090}
4090 4091
4091/*! \reimp */ 4092/*! \reimp */
4092 4093
4093QSize QTextEdit::sizeHint() const 4094QSize QTextEdit::sizeHint() const
4094{ 4095{
4095 // ### calculate a reasonable one 4096 // ### calculate a reasonable one
4096 return QSize( 100, 100 ); 4097 return QSize( 100, 100 );
4097} 4098}
4098 4099
4099void QTextEdit::clearUndoRedo() 4100void QTextEdit::clearUndoRedo()
4100{ 4101{
4101 undoRedoInfo.clear(); 4102 undoRedoInfo.clear();
4102 emit undoAvailable( doc->commands()->isUndoAvailable() ); 4103 emit undoAvailable( doc->commands()->isUndoAvailable() );
4103 emit redoAvailable( doc->commands()->isRedoAvailable() ); 4104 emit redoAvailable( doc->commands()->isRedoAvailable() );
4104} 4105}
4105 4106
4106/*! \internal 4107/*! \internal
4107 4108
4108 \warning In Qt 3.1 we will provide a cleaer API for the 4109 \warning In Qt 3.1 we will provide a cleaer API for the
4109 functionality which is provided by this function and in Qt 4.0 this 4110 functionality which is provided by this function and in Qt 4.0 this
4110 function will go away. 4111 function will go away.
4111 4112
4112 This function gets the format of the character at position \a 4113 This function gets the format of the character at position \a
4113 index in paragraph \a para. Sets \a font to the character's font, \a 4114 index in paragraph \a para. Sets \a font to the character's font, \a
4114 color to the character's color and \a verticalAlignment to the 4115 color to the character's color and \a verticalAlignment to the
4115 character's vertical alignment. 4116 character's vertical alignment.
4116 4117
4117 Returns FALSE if \a para or \a index is out of range otherwise 4118 Returns FALSE if \a para or \a index is out of range otherwise
4118 returns TRUE. 4119 returns TRUE.
4119*/ 4120*/
4120 4121
4121bool QTextEdit::getFormat( int para, int index, QFont *font, QColor *color, VerticalAlignment *verticalAlignment ) 4122bool QTextEdit::getFormat( int para, int index, QFont *font, QColor *color, VerticalAlignment *verticalAlignment )
4122{ 4123{
4123 if ( !font || !color ) 4124 if ( !font || !color )
4124 return FALSE; 4125 return FALSE;
4125 QTextParagraph *p = doc->paragAt( para ); 4126 QTextParagraph *p = doc->paragAt( para );
4126 if ( !p ) 4127 if ( !p )
4127 return FALSE; 4128 return FALSE;
4128 if ( index < 0 || index >= p->length() ) 4129 if ( index < 0 || index >= p->length() )
4129 return FALSE; 4130 return FALSE;
4130 *font = p->at( index )->format()->font(); 4131 *font = p->at( index )->format()->font();
4131 *color = p->at( index )->format()->color(); 4132 *color = p->at( index )->format()->color();
4132 *verticalAlignment = (VerticalAlignment)p->at( index )->format()->vAlign(); 4133 *verticalAlignment = (VerticalAlignment)p->at( index )->format()->vAlign();
4133 return TRUE; 4134 return TRUE;
4134} 4135}
4135 4136
4136/*! \internal 4137/*! \internal
4137 4138
4138 \warning In Qt 3.1 we will provide a cleaer API for the 4139 \warning In Qt 3.1 we will provide a cleaer API for the
4139 functionality which is provided by this function and in Qt 4.0 this 4140 functionality which is provided by this function and in Qt 4.0 this
4140 function will go away. 4141 function will go away.
4141 4142
4142 This function gets the format of the paragraph \a para. Sets \a 4143 This function gets the format of the paragraph \a para. Sets \a
4143 font to the paragraphs's font, \a color to the paragraph's color, \a 4144 font to the paragraphs's font, \a color to the paragraph's color, \a
4144 verticalAlignment to the paragraph's vertical alignment, \a 4145 verticalAlignment to the paragraph's vertical alignment, \a
4145 alignment to the paragraph's alignment, \a displayMode to the 4146 alignment to the paragraph's alignment, \a displayMode to the
4146 paragraph's display mode, \a listStyle to the paragraph's list style 4147 paragraph's display mode, \a listStyle to the paragraph's list style
4147 (if the display mode is QStyleSheetItem::DisplayListItem) and \a 4148 (if the display mode is QStyleSheetItem::DisplayListItem) and \a
4148 listDepth to the depth of the list (if the display mode is 4149 listDepth to the depth of the list (if the display mode is
4149 QStyleSheetItem::DisplayListItem). 4150 QStyleSheetItem::DisplayListItem).
4150 4151
4151 Returns FALSE if \a para is out of range otherwise returns TRUE. 4152 Returns FALSE if \a para is out of range otherwise returns TRUE.
4152*/ 4153*/
4153 4154
4154bool QTextEdit::getParagraphFormat( int para, QFont *font, QColor *color, 4155bool QTextEdit::getParagraphFormat( int para, QFont *font, QColor *color,
4155 VerticalAlignment *verticalAlignment, int *alignment, 4156 VerticalAlignment *verticalAlignment, int *alignment,
4156 QStyleSheetItem::DisplayMode *displayMode, 4157 QStyleSheetItem::DisplayMode *displayMode,
4157 QStyleSheetItem::ListStyle *listStyle, 4158 QStyleSheetItem::ListStyle *listStyle,
4158 int *listDepth ) 4159 int *listDepth )
4159{ 4160{
4160 if ( !font || !color || !alignment || !displayMode || !listStyle ) 4161 if ( !font || !color || !alignment || !displayMode || !listStyle )
4161 return FALSE; 4162 return FALSE;
4162 QTextParagraph *p = doc->paragAt( para ); 4163 QTextParagraph *p = doc->paragAt( para );
4163 if ( !p ) 4164 if ( !p )
4164 return FALSE; 4165 return FALSE;
4165 *font = p->at(0)->format()->font(); 4166 *font = p->at(0)->format()->font();
4166 *color = p->at(0)->format()->color(); 4167 *color = p->at(0)->format()->color();
4167 *verticalAlignment = (VerticalAlignment)p->at(0)->format()->vAlign(); 4168 *verticalAlignment = (VerticalAlignment)p->at(0)->format()->vAlign();
4168 *alignment = p->alignment(); 4169 *alignment = p->alignment();
4169 *displayMode = p->isListItem() ? QStyleSheetItem::DisplayListItem : QStyleSheetItem::DisplayBlock; 4170 *displayMode = p->isListItem() ? QStyleSheetItem::DisplayListItem : QStyleSheetItem::DisplayBlock;
4170 *listStyle = p->listStyle(); 4171 *listStyle = p->listStyle();
4171 *listDepth = p->listDepth(); 4172 *listDepth = p->listDepth();
4172 return TRUE; 4173 return TRUE;
4173} 4174}
4174 4175
4175 4176
4176 4177
4177/*! 4178/*!
4178 4179
4179 This function is called to create a right mouse button popup menu 4180 This function is called to create a right mouse button popup menu
4180 at the document position \a pos. If you want to create a custom 4181 at the document position \a pos. If you want to create a custom
4181 popup menu, reimplement this function and return the created 4182 popup menu, reimplement this function and return the created
4182 popup menu. Ownership of the popup menu is transferred to the 4183 popup menu. Ownership of the popup menu is transferred to the
4183 caller. 4184 caller.
4184*/ 4185*/
4185 4186
4186QPopupMenu *QTextEdit::createPopupMenu( const QPoint& pos ) 4187QPopupMenu *QTextEdit::createPopupMenu( const QPoint& pos )
4187{ 4188{
4188#ifndef QT_NO_POPUPMENU 4189#ifndef QT_NO_POPUPMENU
4189 QPopupMenu *popup = new QPopupMenu( this, "qt_edit_menu" ); 4190 QPopupMenu *popup = new QPopupMenu( this, "qt_edit_menu" );
4190 if ( !isReadOnly() ) { 4191 if ( !isReadOnly() ) {
4191 d->id[ IdUndo ] = popup->insertItem( tr( "&Undo" ) + ACCEL_KEY( Z ) ); 4192 d->id[ IdUndo ] = popup->insertItem( tr( "&Undo" ) + ACCEL_KEY( Z ) );
4192 d->id[ IdRedo ] = popup->insertItem( tr( "&Redo" ) + ACCEL_KEY( Y ) ); 4193 d->id[ IdRedo ] = popup->insertItem( tr( "&Redo" ) + ACCEL_KEY( Y ) );
4193 popup->insertSeparator(); 4194 popup->insertSeparator();
4194 } 4195 }
4195#ifndef QT_NO_CLIPBOARD 4196#ifndef QT_NO_CLIPBOARD
4196 if ( !isReadOnly() ) 4197 if ( !isReadOnly() )
4197 d->id[ IdCut ] = popup->insertItem( tr( "Cu&t" ) + ACCEL_KEY( X ) ); 4198 d->id[ IdCut ] = popup->insertItem( tr( "Cu&t" ) + ACCEL_KEY( X ) );
4198 d->id[ IdCopy ] = popup->insertItem( tr( "&Copy" ) + ACCEL_KEY( C ) ); 4199 d->id[ IdCopy ] = popup->insertItem( tr( "&Copy" ) + ACCEL_KEY( C ) );
4199 if ( !isReadOnly() ) 4200 if ( !isReadOnly() )
4200 d->id[ IdPaste ] = popup->insertItem( tr( "&Paste" ) + ACCEL_KEY( V ) ); 4201 d->id[ IdPaste ] = popup->insertItem( tr( "&Paste" ) + ACCEL_KEY( V ) );
4201#endif 4202#endif
4202 if ( !isReadOnly() ) { 4203 if ( !isReadOnly() ) {
4203 d->id[ IdClear ] = popup->insertItem( tr( "Clear" ) ); 4204 d->id[ IdClear ] = popup->insertItem( tr( "Clear" ) );
4204 popup->insertSeparator(); 4205 popup->insertSeparator();
4205 } 4206 }
4206#if defined(Q_WS_X11) 4207#if defined(Q_WS_X11)
4207 d->id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) ); 4208 d->id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) );
4208#else 4209#else
4209 d->id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) + ACCEL_KEY( A ) ); 4210 d->id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) + ACCEL_KEY( A ) );
4210#endif 4211#endif
4211 popup->setItemEnabled( d->id[ IdUndo ], !isReadOnly() && doc->commands()->isUndoAvailable() ); 4212 popup->setItemEnabled( d->id[ IdUndo ], !isReadOnly() && doc->commands()->isUndoAvailable() );
4212 popup->setItemEnabled( d->id[ IdRedo ], !isReadOnly() && doc->commands()->isRedoAvailable() ); 4213 popup->setItemEnabled( d->id[ IdRedo ], !isReadOnly() && doc->commands()->isRedoAvailable() );
4213#ifndef QT_NO_CLIPBOARD 4214#ifndef QT_NO_CLIPBOARD
4214 popup->setItemEnabled( d->id[ IdCut ], !isReadOnly() && doc->hasSelection( QTextDocument::Standard, TRUE ) ); 4215 popup->setItemEnabled( d->id[ IdCut ], !isReadOnly() && doc->hasSelection( QTextDocument::Standard, TRUE ) );
4215 popup->setItemEnabled( d->id[ IdCopy ], doc->hasSelection( QTextDocument::Standard, TRUE ) ); 4216 popup->setItemEnabled( d->id[ IdCopy ], doc->hasSelection( QTextDocument::Standard, TRUE ) );
4216 popup->setItemEnabled( d->id[ IdPaste ], !isReadOnly() && !QApplication::clipboard()->text().isEmpty() ); 4217 popup->setItemEnabled( d->id[ IdPaste ], !isReadOnly() && !QApplication::clipboard()->text().isEmpty() );
4217#endif 4218#endif
4218 popup->setItemEnabled( d->id[ IdClear ], !isReadOnly() && !text().isEmpty() ); 4219 popup->setItemEnabled( d->id[ IdClear ], !isReadOnly() && !text().isEmpty() );
4219 popup->setItemEnabled( d->id[ IdSelectAll ], (bool)text().length() ); 4220 popup->setItemEnabled( d->id[ IdSelectAll ], (bool)text().length() );
4220 return popup; 4221 return popup;
4221#else 4222#else
4222 return 0; 4223 return 0;
4223#endif 4224#endif
4224} 4225}
4225 4226
4226/*! \overload 4227/*! \overload
4227 \obsolete 4228 \obsolete
4228 This function is called to create a right mouse button popup menu. 4229 This function is called to create a right mouse button popup menu.
4229 If you want to create a custom popup menu, reimplement this function 4230 If you want to create a custom popup menu, reimplement this function
4230 and return the created popup menu. Ownership of the popup menu is 4231 and return the created popup menu. Ownership of the popup menu is
4231 transferred to the caller. 4232 transferred to the caller.
4232 4233
4233 This function is only called if createPopupMenu( const QPoint & ) 4234 This function is only called if createPopupMenu( const QPoint & )
4234 returns 0. 4235 returns 0.
4235*/ 4236*/
4236 4237
4237QPopupMenu *QTextEdit::createPopupMenu() 4238QPopupMenu *QTextEdit::createPopupMenu()
4238{ 4239{
4239 return 0; 4240 return 0;
4240} 4241}
4241 4242
4242/*! \reimp */ 4243/*! \reimp */
4243 4244
4244void QTextEdit::setFont( const QFont &f ) 4245void QTextEdit::setFont( const QFont &f )
4245{ 4246{
4246 QFont old( QScrollView::font() ); 4247 QFont old( QScrollView::font() );
4247 QScrollView::setFont( f ); 4248 QScrollView::setFont( f );
4248 doc->setMinimumWidth( -1 ); 4249 doc->setMinimumWidth( -1 );
4249 doc->setDefaultFormat( f, doc->formatCollection()->defaultFormat()->color() ); 4250 doc->setDefaultFormat( f, doc->formatCollection()->defaultFormat()->color() );
4250 lastFormatted = doc->firstParagraph(); 4251 lastFormatted = doc->firstParagraph();
4251 formatMore(); 4252 formatMore();
4252 repaintChanged(); 4253 repaintChanged();
4253} 4254}
4254 4255
4255/*! \fn QTextEdit::zoomIn() 4256/*! \fn QTextEdit::zoomIn()
4256 4257
4257 \overload 4258 \overload
4258 4259
4259 Zooms in on the text by by making the base font size one 4260 Zooms in on the text by by making the base font size one
4260 point larger and recalculating all font sizes. This does not change 4261 point larger and recalculating all font sizes. This does not change
4261 the size of any images. 4262 the size of any images.
4262 4263
4263 \sa zoomOut() 4264 \sa zoomOut()
4264 4265
4265*/ 4266*/
4266 4267
4267/*! \fn QTextEdit::zoomOut() 4268/*! \fn QTextEdit::zoomOut()
4268 4269
4269 \overload 4270 \overload
4270 4271
4271 Zooms out on the text by by making the base font size one 4272 Zooms out on the text by by making the base font size one
4272 point smaller and recalculating all font sizes. This does not change 4273 point smaller and recalculating all font sizes. This does not change
4273 the size of any images. 4274 the size of any images.
4274 4275
4275 \sa zoomIn() 4276 \sa zoomIn()
4276*/ 4277*/
4277 4278
4278 4279
4279/*! 4280/*!
4280 Zooms in on the text by by making the base font size \a range 4281 Zooms in on the text by by making the base font size \a range
4281 points larger and recalculating all font sizes. This does not change 4282 points larger and recalculating all font sizes. This does not change
4282 the size of any images. 4283 the size of any images.
4283 4284
4284 \sa zoomOut() 4285 \sa zoomOut()
4285*/ 4286*/
4286 4287
4287void QTextEdit::zoomIn( int range ) 4288void QTextEdit::zoomIn( int range )
4288{ 4289{
4289 QFont f( QScrollView::font() ); 4290 QFont f( QScrollView::font() );
4290 f.setPointSize( f.pointSize() + range ); 4291 f.setPointSize( f.pointSize() + range );
4291 setFont( f ); 4292 setFont( f );
4292} 4293}
4293 4294
4294/*! Zooms out on the text by making the base font size \a range 4295/*! Zooms out on the text by making the base font size \a range
4295 points smaller and recalculating all font sizes. This does not 4296 points smaller and recalculating all font sizes. This does not
4296 change the size of any images. 4297 change the size of any images.
4297 4298
4298 \sa zoomIn() 4299 \sa zoomIn()
4299*/ 4300*/
4300 4301
4301void QTextEdit::zoomOut( int range ) 4302void QTextEdit::zoomOut( int range )
4302{ 4303{
4303 QFont f( QScrollView::font() ); 4304 QFont f( QScrollView::font() );
4304 f.setPointSize( QMAX( 1, f.pointSize() - range ) ); 4305 f.setPointSize( QMAX( 1, f.pointSize() - range ) );
4305 setFont( f ); 4306 setFont( f );
4306} 4307}
4307 4308
4308/*! Zooms the text by making the base font size \a size points and 4309/*! Zooms the text by making the base font size \a size points and
4309 recalculating all font sizes. This does not change the size of any 4310 recalculating all font sizes. This does not change the size of any
4310 images. 4311 images.
4311*/ 4312*/
4312 4313
4313void QTextEdit::zoomTo( int size ) 4314void QTextEdit::zoomTo( int size )
4314{ 4315{
4315 QFont f( QScrollView::font() ); 4316 QFont f( QScrollView::font() );
4316 f.setPointSize( size ); 4317 f.setPointSize( size );
4317 setFont( f ); 4318 setFont( f );
4318} 4319}
4319 4320
4320/*! 4321/*!
4321 \internal 4322 \internal
4322 4323
4323 QTextEdit is optimized for large amounts text. One of its 4324 QTextEdit is optimized for large amounts text. One of its
4324 optimizations is to format only the visible text, formatting the rest 4325 optimizations is to format only the visible text, formatting the rest
4325 on demand, e.g. as the user scrolls, so you don't usually need to 4326 on demand, e.g. as the user scrolls, so you don't usually need to
4326 call this function. 4327 call this function.
4327 4328
4328 In some situations you may want to force the whole text 4329 In some situations you may want to force the whole text
4329 to be formatted. For example, if after calling setText(), you wanted 4330 to be formatted. For example, if after calling setText(), you wanted
4330 to know the height of the document (using contentsHeight()), you 4331 to know the height of the document (using contentsHeight()), you
4331 would call this function first. 4332 would call this function first.
4332*/ 4333*/
4333 4334
4334void QTextEdit::sync() 4335void QTextEdit::sync()
4335{ 4336{
4336 while ( lastFormatted ) { 4337 while ( lastFormatted ) {
4337 lastFormatted->format(); 4338 lastFormatted->format();
4338 lastFormatted = lastFormatted->next(); 4339 lastFormatted = lastFormatted->next();
4339 } 4340 }
4340 resizeContents( contentsWidth(), doc->height() ); 4341 resizeContents( contentsWidth(), doc->height() );
4341} 4342}
4342 4343
4343/*! \reimp */ 4344/*! \reimp */
4344 4345
4345void QTextEdit::setEnabled( bool b ) 4346void QTextEdit::setEnabled( bool b )
4346{ 4347{
4347 QScrollView::setEnabled( b ); 4348 QScrollView::setEnabled( b );
4348 if ( !b ) { 4349 if ( !b ) {
4349 blinkTimer->stop(); 4350 blinkTimer->stop();
4350 drawCursor( FALSE ); 4351 drawCursor( FALSE );
4351 } 4352 }
4352 if ( textFormat() == PlainText ) { 4353 if ( textFormat() == PlainText ) {
4353 QTextFormat *f = doc->formatCollection()->defaultFormat(); 4354 QTextFormat *f = doc->formatCollection()->defaultFormat();
4354 f->setColor( colorGroup().text() ); 4355 f->setColor( colorGroup().text() );
4355 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4356 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
4356 } 4357 }
4357 if ( b ) { 4358 if ( b ) {
4358 blinkTimer->start( QApplication::cursorFlashTime() / 2 ); 4359 blinkTimer->start( QApplication::cursorFlashTime() / 2 );
4359 drawCursor( TRUE ); 4360 drawCursor( TRUE );
4360 } 4361 }
4361} 4362}
4362 4363
4363/*! 4364/*!
4364 Sets the background color of selection number \a selNum to \a back and 4365 Sets the background color of selection number \a selNum to \a back and
4365 specifies whether the text of this selection should be inverted with \a 4366 specifies whether the text of this selection should be inverted with \a
4366 invertText. 4367 invertText.
4367 4368
4368 This only works for \a selNum > 0. The default selection (\a selNum == 4369 This only works for \a selNum > 0. The default selection (\a selNum ==
4369 0) gets its attributes from the colorGroup() of this widget. 4370 0) gets its attributes from the colorGroup() of this widget.
4370*/ 4371*/
4371 4372
4372void QTextEdit::setSelectionAttributes( int selNum, const QColor &back, bool invertText ) 4373void QTextEdit::setSelectionAttributes( int selNum, const QColor &back, bool invertText )
4373{ 4374{
4374 if ( selNum < 1 ) 4375 if ( selNum < 1 )
4375 return; 4376 return;
4376 if ( selNum > doc->numSelections() ) 4377 if ( selNum > doc->numSelections() )
4377 doc->addSelection( selNum ); 4378 doc->addSelection( selNum );
4378 doc->setSelectionColor( selNum, back ); 4379 doc->setSelectionColor( selNum, back );
4379 doc->setInvertSelectionText( selNum, invertText ); 4380 doc->setInvertSelectionText( selNum, invertText );
4380} 4381}
4381 4382
4382/*! \reimp */ 4383/*! \reimp */
4383void QTextEdit::windowActivationChange( bool ) 4384void QTextEdit::windowActivationChange( bool )
4384{ 4385{
4385 if ( !isVisible() ) 4386 if ( !isVisible() )
4386 return; 4387 return;
4387 4388
4388 if ( palette().active() != palette().inactive() ) 4389 if ( palette().active() != palette().inactive() )
4389 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4390 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
4390} 4391}
4391 4392
4392void QTextEdit::setReadOnly( bool b ) 4393void QTextEdit::setReadOnly( bool b )
4393{ 4394{
4394 if ( readonly == b ) 4395 if ( readonly == b )
4395 return; 4396 return;
4396 readonly = b; 4397 readonly = b;
4397#ifndef QT_NO_CURSOR 4398#ifndef QT_NO_CURSOR
4398 if ( readonly ) 4399 if ( readonly )
4399 viewport()->setCursor( arrowCursor ); 4400 viewport()->setCursor( arrowCursor );
4400 else 4401 else
4401 viewport()->setCursor( ibeamCursor ); 4402 viewport()->setCursor( ibeamCursor );
4402#endif 4403#endif
4403} 4404}
4404 4405
4405/*! Scrolls to the bottom of the document and does formatting if 4406/*! Scrolls to the bottom of the document and does formatting if
4406 required */ 4407 required */
4407 4408
4408void QTextEdit::scrollToBottom() 4409void QTextEdit::scrollToBottom()
4409{ 4410{
4410 sync(); 4411 sync();
4411 setContentsPos( contentsX(), contentsHeight() - visibleHeight() ); 4412 setContentsPos( contentsX(), contentsHeight() - visibleHeight() );
4412} 4413}
4413 4414
4414/*! Returns the rectangle of the paragraph \a para in contents 4415/*! Returns the rectangle of the paragraph \a para in contents
4415 coordinates, or an invalid rectangle if \a para is out of range. 4416 coordinates, or an invalid rectangle if \a para is out of range.
4416*/ 4417*/
4417 4418
4418QRect QTextEdit::paragraphRect( int para ) const 4419QRect QTextEdit::paragraphRect( int para ) const
4419{ 4420{
4420 QTextEdit *that = (QTextEdit *)this; 4421 QTextEdit *that = (QTextEdit *)this;
4421 that->sync(); 4422 that->sync();
4422 QTextParagraph *p = doc->paragAt( para ); 4423 QTextParagraph *p = doc->paragAt( para );
4423 if ( !p ) 4424 if ( !p )
4424 return QRect( -1, -1, -1, -1 ); 4425 return QRect( -1, -1, -1, -1 );
4425 return p->rect(); 4426 return p->rect();
4426} 4427}
4427 4428
4428/*! 4429/*!
4429 Returns the paragraph which is at position \a pos (in contents 4430 Returns the paragraph which is at position \a pos (in contents
4430 coordinates), or -1 if there is no paragraph with index \a pos. 4431 coordinates), or -1 if there is no paragraph with index \a pos.
4431*/ 4432*/
4432 4433
4433int QTextEdit::paragraphAt( const QPoint &pos ) const 4434int QTextEdit::paragraphAt( const QPoint &pos ) const
4434{ 4435{
4435 QTextCursor c( doc ); 4436 QTextCursor c( doc );
4436 c.place( pos, doc->firstParagraph() ); 4437 c.place( pos, doc->firstParagraph() );
4437 if ( c.paragraph() ) 4438 if ( c.paragraph() )
4438 return c.paragraph()->paragId(); 4439 return c.paragraph()->paragId();
4439 return -1; 4440 return -1;
4440} 4441}
4441 4442
4442/*! 4443/*!
4443 Returns the index of the character (relative to its paragraph) at 4444 Returns the index of the character (relative to its paragraph) at
4444 position \a pos (in contents coordinates). If \a para is not null, 4445 position \a pos (in contents coordinates). If \a para is not null,
4445 \e *\a para is set to this paragraph. If there is no character at 4446 \e *\a para is set to this paragraph. If there is no character at
4446 \a pos, -1 is returned. 4447 \a pos, -1 is returned.
4447*/ 4448*/
4448 4449
4449int QTextEdit::charAt( const QPoint &pos, int *para ) const 4450int QTextEdit::charAt( const QPoint &pos, int *para ) const
4450{ 4451{
4451 QTextCursor c( doc ); 4452 QTextCursor c( doc );
4452 c.place( pos, doc->firstParagraph() ); 4453 c.place( pos, doc->firstParagraph() );
4453 if ( c.paragraph() ) { 4454 if ( c.paragraph() ) {
4454 if ( para ) 4455 if ( para )
4455 *para = c.paragraph()->paragId(); 4456 *para = c.paragraph()->paragId();
4456 return c.index(); 4457 return c.index();
4457 } 4458 }
4458 return -1; 4459 return -1;
4459} 4460}
4460 4461
4461/*! Sets the background color of the paragraph \a para to \a bg */ 4462/*! Sets the background color of the paragraph \a para to \a bg */
4462 4463
4463void QTextEdit::setParagraphBackgroundColor( int para, const QColor &bg ) 4464void QTextEdit::setParagraphBackgroundColor( int para, const QColor &bg )
4464{ 4465{
4465 QTextParagraph *p = doc->paragAt( para ); 4466 QTextParagraph *p = doc->paragAt( para );
4466 if ( !p ) 4467 if ( !p )
4467 return; 4468 return;
4468 p->setBackgroundColor( bg ); 4469 p->setBackgroundColor( bg );
4469 repaintChanged(); 4470 repaintChanged();
4470} 4471}
4471 4472
4472/*! Clears the background color of the paragraph \a para, so that the 4473/*! Clears the background color of the paragraph \a para, so that the
4473 default color is used again. 4474 default color is used again.
4474*/ 4475*/
4475 4476
4476void QTextEdit::clearParagraphBackground( int para ) 4477void QTextEdit::clearParagraphBackground( int para )
4477{ 4478{
4478 QTextParagraph *p = doc->paragAt( para ); 4479 QTextParagraph *p = doc->paragAt( para );
4479 if ( !p ) 4480 if ( !p )
4480 return; 4481 return;
4481 p->clearBackgroundColor(); 4482 p->clearBackgroundColor();
4482 repaintChanged(); 4483 repaintChanged();
4483} 4484}
4484 4485
4485/*! Returns the background color of the paragraph \a para or an 4486/*! Returns the background color of the paragraph \a para or an
4486 invalid color if \a para is out of range or the paragraph has no 4487 invalid color if \a para is out of range or the paragraph has no
4487 background set 4488 background set
4488*/ 4489*/
4489 4490
4490QColor QTextEdit::paragraphBackgroundColor( int para ) const 4491QColor QTextEdit::paragraphBackgroundColor( int para ) const
4491{ 4492{
4492 QTextParagraph *p = doc->paragAt( para ); 4493 QTextParagraph *p = doc->paragAt( para );
4493 if ( !p ) 4494 if ( !p )
4494 return QColor(); 4495 return QColor();
4495 QColor *c = p->backgroundColor(); 4496 QColor *c = p->backgroundColor();
4496 if ( c ) 4497 if ( c )
4497 return *c; 4498 return *c;
4498 return QColor(); 4499 return QColor();
4499} 4500}
4500 4501
4501/*! \property QTextEdit::undoRedoEnabled 4502/*! \property QTextEdit::undoRedoEnabled
4502 \brief whether undo/redo is enabled 4503 \brief whether undo/redo is enabled
4503 4504
4504 The default is TRUE. 4505 The default is TRUE.
4505*/ 4506*/
4506 4507
4507void QTextEdit::setUndoRedoEnabled( bool b ) 4508void QTextEdit::setUndoRedoEnabled( bool b )
4508{ 4509{
4509 undoEnabled = b; 4510 undoEnabled = b;
4510} 4511}
4511 4512
4512bool QTextEdit::isUndoRedoEnabled() const 4513bool QTextEdit::isUndoRedoEnabled() const
4513{ 4514{
4514 return undoEnabled; 4515 return undoEnabled;
4515} 4516}
4516 4517
4517/*! Returns whether undo is available */ 4518/*! Returns whether undo is available */
4518 4519
4519bool QTextEdit::isUndoAvailable() const 4520bool QTextEdit::isUndoAvailable() const
4520{ 4521{
4521 return doc->commands()->isUndoAvailable() || undoRedoInfo.valid(); 4522 return doc->commands()->isUndoAvailable() || undoRedoInfo.valid();
4522} 4523}
4523 4524
4524/*! Returns whether redo is available */ 4525/*! Returns whether redo is available */
4525 4526
4526bool QTextEdit::isRedoAvailable() const 4527bool QTextEdit::isRedoAvailable() const
4527{ 4528{
4528 return doc->commands()->isRedoAvailable(); 4529 return doc->commands()->isRedoAvailable();
4529} 4530}
4530 4531
4531void QTextEdit::ensureFormatted( QTextParagraph *p ) 4532void QTextEdit::ensureFormatted( QTextParagraph *p )
4532{ 4533{
4533 while ( !p->isValid() ) { 4534 while ( !p->isValid() ) {
4534 if ( !lastFormatted ) 4535 if ( !lastFormatted )
4535 return; 4536 return;
4536 formatMore(); 4537 formatMore();
4537 } 4538 }
4538} 4539}
4539 4540
4540/*! \internal */ 4541/*! \internal */
4541void QTextEdit::updateCursor( const QPoint & pos ) 4542void QTextEdit::updateCursor( const QPoint & pos )
4542{ 4543{
4543 if ( isReadOnly() && linksEnabled() ) { 4544 if ( isReadOnly() && linksEnabled() ) {
4544 QTextCursor c = *cursor; 4545 QTextCursor c = *cursor;
4545 placeCursor( pos, &c, TRUE ); 4546 placeCursor( pos, &c, TRUE );
4546 4547
4547#ifndef QT_NO_NETWORKPROTOCOL 4548#ifndef QT_NO_NETWORKPROTOCOL
4548 if ( c.paragraph() && c.paragraph()->at( c.index() ) && 4549 if ( c.paragraph() && c.paragraph()->at( c.index() ) &&
4549 c.paragraph()->at( c.index() )->isAnchor() && 4550 c.paragraph()->at( c.index() )->isAnchor() &&
4550 !c.paragraph()->at( c.index() )->anchorHref().isEmpty() ) { 4551 !c.paragraph()->at( c.index() )->anchorHref().isEmpty() ) {
4551 if ( c.index() < c.paragraph()->length() - 1 ) 4552 if ( c.index() < c.paragraph()->length() - 1 )
4552 onLink = c.paragraph()->at( c.index() )->anchorHref(); 4553 onLink = c.paragraph()->at( c.index() )->anchorHref();
4553 else 4554 else
4554 onLink = QString::null; 4555 onLink = QString::null;
4555 4556
4556#ifndef QT_NO_CURSOR 4557#ifndef QT_NO_CURSOR
4557 viewport()->setCursor( onLink.isEmpty() ? arrowCursor : pointingHandCursor ); 4558 viewport()->setCursor( onLink.isEmpty() ? arrowCursor : pointingHandCursor );
4558#endif 4559#endif
4559 QUrl u( doc->context(), onLink, TRUE ); 4560 QUrl u( doc->context(), onLink, TRUE );
4560 emitHighlighted( u.toString( FALSE, FALSE ) ); 4561 emitHighlighted( u.toString( FALSE, FALSE ) );
4561 } else { 4562 } else {
4562#ifndef QT_NO_CURSOR 4563#ifndef QT_NO_CURSOR
4563 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 4564 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
4564#endif 4565#endif
4565 onLink = QString::null; 4566 onLink = QString::null;
4566 emitHighlighted( QString::null ); 4567 emitHighlighted( QString::null );
4567 } 4568 }
4568#endif 4569#endif
4569 } 4570 }
4570} 4571}
4571 4572
4572void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c ) 4573void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c )
4573{ 4574{
4574 placeCursor( pos, c, FALSE ); 4575 placeCursor( pos, c, FALSE );
4575} 4576}