-rw-r--r-- | noncore/apps/opie-write/qtextedit.cpp | 2469 |
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,467 +1,467 @@ | |||
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 | ||
47 | using namespace Qt3; | 47 | using namespace Qt3; |
48 | 48 | ||
49 | static bool qt_enable_richtext_copy = FALSE; | 49 | static bool qt_enable_richtext_copy = FALSE; |
50 | 50 | ||
51 | struct QUndoRedoInfoPrivate | 51 | struct QUndoRedoInfoPrivate |
52 | { | 52 | { |
53 | QTextString text; | 53 | QTextString text; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | namespace Qt3 { | 56 | namespace Qt3 { |
57 | 57 | ||
58 | class QTextEditPrivate | 58 | class QTextEditPrivate |
59 | { | 59 | { |
60 | public: | 60 | public: |
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 | ||
76 | static bool block_set_alignment = FALSE; | 76 | static 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 |
@@ -558,4018 +558,4019 @@ static bool block_set_alignment = FALSE; | |||
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 | ||
625 | QTextEdit::QTextEdit( QWidget *parent, const char *name ) | 625 | QTextEdit::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 | ||
653 | QTextEdit::QTextEdit( const QString& text, const QString& context, | 653 | QTextEdit::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 | ||
664 | QTextEdit::~QTextEdit() | 664 | QTextEdit::~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 | ||
673 | void QTextEdit::init() | 673 | void 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 | ||
747 | void QTextEdit::paintDocument( bool drawAll, QPainter *p, int cx, int cy, int cw, int ch ) | 748 | void 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 | ||
779 | void QTextEdit::drawContents( QPainter *p, int cx, int cy, int cw, int ch ) | 780 | void 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 | ||
796 | void QTextEdit::drawContents( QPainter * ) | 797 | void QTextEdit::drawContents( QPainter * ) |
797 | { | 798 | { |
798 | } | 799 | } |
799 | 800 | ||
800 | /*! \reimp */ | 801 | /*! \reimp */ |
801 | 802 | ||
802 | bool QTextEdit::event( QEvent *e ) | 803 | bool 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 | ||
889 | void QTextEdit::keyPressEvent( QKeyEvent *e ) | 890 | void 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 | ||
1155 | void QTextEdit::doKeyboardAction( KeyboardAction action ) | 1156 | void 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 | ||
1262 | void QTextEdit::readFormats( QTextCursor &c1, QTextCursor &c2, QTextString &text, bool fillStyles ) | 1263 | void 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 | ||
1304 | void QTextEdit::removeSelection( int selNum ) | 1305 | void 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 | ||
1317 | void QTextEdit::removeSelectedText( int selNum ) | 1318 | void 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 | ||
1382 | void QTextEdit::moveCursor( CursorAction action, bool select ) | 1383 | void 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 | ||
1427 | void QTextEdit::moveCursor( CursorAction action ) | 1428 | void 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 | ||
1474 | void QTextEdit::resizeEvent( QResizeEvent *e ) | 1475 | void 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 | ||
1483 | void QTextEdit::viewportResizeEvent( QResizeEvent *e ) | 1484 | void 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 | ||
1502 | void QTextEdit::ensureCursorVisible() | 1503 | void 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 | */ |
1523 | void QTextEdit::drawCursor( bool visible ) | 1524 | void 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 | ||
1565 | enum { | 1566 | enum { |
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 |
1577 | void QTextEdit::contentsWheelEvent( QWheelEvent *e ) | 1578 | void 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 | ||
1594 | void QTextEdit::contentsMousePressEvent( QMouseEvent *e ) | 1595 | void 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 | ||
1674 | void QTextEdit::contentsMouseMoveEvent( QMouseEvent *e ) | 1675 | void 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 | ||
1707 | void QTextEdit::contentsMouseReleaseEvent( QMouseEvent * e ) | 1708 | void 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 | ||
1750 | void QTextEdit::contentsMouseDoubleClickEvent( QMouseEvent * ) | 1751 | void 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 | ||
1774 | void QTextEdit::contentsDragEnterEvent( QDragEnterEvent *e ) | 1775 | void 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 | ||
1786 | void QTextEdit::contentsDragMoveEvent( QDragMoveEvent *e ) | 1787 | void 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 | ||
1800 | void QTextEdit::contentsDragLeaveEvent( QDragLeaveEvent * ) | 1801 | void QTextEdit::contentsDragLeaveEvent( QDragLeaveEvent * ) |
1801 | { | 1802 | { |
1802 | inDnD = FALSE; | 1803 | inDnD = FALSE; |
1803 | } | 1804 | } |
1804 | 1805 | ||
1805 | /*! \reimp */ | 1806 | /*! \reimp */ |
1806 | 1807 | ||
1807 | void QTextEdit::contentsDropEvent( QDropEvent *e ) | 1808 | void 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 | ||
1876 | void QTextEdit::autoScrollTimerDone() | 1877 | void 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 | ||
1882 | void QTextEdit::handleMouseMove( const QPoint& pos ) | 1883 | void 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 | ||
1963 | void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c, bool link ) | 1964 | void 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 | ||
1975 | void QTextEdit::updateMicroFocusHint() | 1976 | void 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 | ||
1993 | void QTextEdit::formatMore() | 1994 | void 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 | ||
2032 | void QTextEdit::doResize() | 2033 | void 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 | ||
2048 | void QTextEdit::doChangeInterval() | 2049 | void QTextEdit::doChangeInterval() |
2049 | { | 2050 | { |
2050 | interval = 0; | 2051 | interval = 0; |
2051 | } | 2052 | } |
2052 | 2053 | ||
2053 | /*! \reimp */ | 2054 | /*! \reimp */ |
2054 | 2055 | ||
2055 | bool QTextEdit::eventFilter( QObject *o, QEvent *e ) | 2056 | bool 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 | ||
2083 | void QTextEdit::insert( const QString &text, bool indent, bool checkNewLine, bool removeSelected ) | 2084 | void 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 | ||
2147 | void QTextEdit::insertAt( const QString &text, int para, int index ) | 2148 | void 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 | ||
2165 | void QTextEdit::insertParagraph( const QString &text, int para ) | 2166 | void 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 | ||
2182 | void QTextEdit::removeParagraph( int para ) | 2183 | void 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 | ||
2235 | void QTextEdit::undo() | 2236 | void 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 | ||
2276 | void QTextEdit::redo() | 2277 | void 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 | ||
2314 | void QTextEdit::paste() | 2315 | void 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 | ||
2324 | void QTextEdit::checkUndoRedoInfo( UndoRedoInfo::Type t ) | 2325 | void 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 | ||
2338 | void QTextEdit::repaintChanged() | 2339 | void 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 | ||
2356 | void QTextEdit::cut() | 2357 | void 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 | ||
2375 | void QTextEdit::copy() | 2376 | void 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 | ||
2387 | void QTextEdit::indent() | 2388 | void 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 | ||
2409 | bool QTextEdit::focusNextPrevChild( bool n ) | 2410 | bool 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 | ||
2429 | void QTextEdit::setFormat( QTextFormat *f, int flags ) | 2430 | void 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 | ||
2478 | void QTextEdit::setPalette( const QPalette &p ) | 2479 | void 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 | ||
2501 | void QTextEdit::setParagType( QStyleSheetItem::DisplayMode dm, QStyleSheetItem::ListStyle listStyle ) | 2502 | void 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 | ||
2550 | void QTextEdit::setAlignment( int a ) | 2551 | void 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 | ||
2588 | void QTextEdit::updateCurrentFormat() | 2589 | void 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 | ||
2622 | void QTextEdit::setItalic( bool b ) | 2623 | void 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 | ||
2637 | void QTextEdit::setBold( bool b ) | 2638 | void 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 | ||
2652 | void QTextEdit::setUnderline( bool b ) | 2653 | void 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 | ||
2666 | void QTextEdit::setFamily( const QString &fontFamily ) | 2667 | void 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 | ||
2683 | void QTextEdit::setPointSize( int s ) | 2684 | void 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 | ||
2697 | void QTextEdit::setColor( const QColor &c ) | 2698 | void 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 | ||
2711 | void QTextEdit::setVerticalAlignment( VerticalAlignment a ) | 2712 | void 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 | ||
2719 | void QTextEdit::setFontInternal( const QFont &f_ ) | 2720 | void 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 | ||
2728 | QString QTextEdit::text() const | 2729 | QString 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 | ||
2743 | QString QTextEdit::text( int para ) const | 2744 | QString 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 | ||
2768 | void QTextEdit::setText( const QString &text, const QString &context ) | 2769 | void 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 | ||
2862 | bool QTextEdit::find( const QString &expr, bool cs, bool wo, bool forward, | 2863 | bool 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 | ||
2897 | void QTextEdit::blinkCursor() | 2898 | void 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 | ||
2913 | void QTextEdit::setCursorPosition( int para, int index ) | 2914 | void 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 | ||
2940 | void QTextEdit::getCursorPosition( int *para, int *index ) const | 2941 | void 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 | ||
2963 | void QTextEdit::setSelection( int paraFrom, int indexFrom, | 2964 | void 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 | ||
3020 | void QTextEdit::getSelection( int *paraFrom, int *indexFrom, | 3021 | void 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 | ||
3054 | void QTextEdit::setTextFormat( TextFormat format ) | 3055 | void QTextEdit::setTextFormat( TextFormat format ) |
3055 | { | 3056 | { |
3056 | doc->setTextFormat( format ); | 3057 | doc->setTextFormat( format ); |
3057 | } | 3058 | } |
3058 | 3059 | ||
3059 | Qt::TextFormat QTextEdit::textFormat() const | 3060 | Qt::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 | ||
3068 | int QTextEdit::paragraphs() const | 3069 | int 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 | ||
3078 | int QTextEdit::linesOfParagraph( int para ) const | 3079 | int 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 | ||
3091 | int QTextEdit::paragraphLength( int para ) const | 3092 | int 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 | ||
3107 | int QTextEdit::lines() const | 3108 | int 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 | ||
3127 | int QTextEdit::lineOfChar( int para, int index ) | 3128 | int 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 | ||
3141 | void QTextEdit::setModified( bool m ) | 3142 | void 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 | ||
3155 | bool QTextEdit::isModified() const | 3156 | bool QTextEdit::isModified() const |
3156 | { | 3157 | { |
3157 | return modified; | 3158 | return modified; |
3158 | } | 3159 | } |
3159 | 3160 | ||
3160 | void QTextEdit::setModified() | 3161 | void 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 | ||
3172 | bool QTextEdit::italic() const | 3173 | bool 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 | ||
3183 | bool QTextEdit::bold() const | 3184 | bool 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 | ||
3195 | bool QTextEdit::underline() const | 3196 | bool 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 | ||
3206 | QString QTextEdit::family() const | 3207 | QString 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 | ||
3218 | int QTextEdit::pointSize() const | 3219 | int 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 | ||
3229 | QColor QTextEdit::color() const | 3230 | QColor 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 | ||
3241 | QFont QTextEdit::font() const | 3242 | QFont 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 | ||
3252 | int QTextEdit::alignment() const | 3253 | int QTextEdit::alignment() const |
3253 | { | 3254 | { |
3254 | return currentAlignment; | 3255 | return currentAlignment; |
3255 | } | 3256 | } |
3256 | 3257 | ||
3257 | void QTextEdit::startDrag() | 3258 | void 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 | ||
3281 | void QTextEdit::selectAll( bool select ) | 3282 | void 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 | ||
3295 | void QTextEdit::UndoRedoInfo::clear() | 3296 | void 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 | ||
3325 | void QTextEdit::del() | 3326 | void 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 | ||
3336 | QTextEdit::UndoRedoInfo::UndoRedoInfo( QTextDocument *dc ) | 3337 | QTextEdit::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 | ||
3345 | QTextEdit::UndoRedoInfo::~UndoRedoInfo() | 3346 | QTextEdit::UndoRedoInfo::~UndoRedoInfo() |
3346 | { | 3347 | { |
3347 | delete d; | 3348 | delete d; |
3348 | } | 3349 | } |
3349 | 3350 | ||
3350 | bool QTextEdit::UndoRedoInfo::valid() const | 3351 | bool 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 | ||
3361 | void QTextEdit::resetFormat() | 3362 | void 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 | ||
3373 | QStyleSheet* QTextEdit::styleSheet() const | 3374 | QStyleSheet* 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 | ||
3384 | void QTextEdit::setStyleSheet( QStyleSheet* styleSheet ) | 3385 | void 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 | ||
3397 | void QTextEdit::setPaper( const QBrush& pap ) | 3398 | void 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 | ||
3404 | QBrush QTextEdit::paper() const | 3405 | QBrush 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 | ||
3419 | void QTextEdit::setLinkUnderline( bool b ) | 3420 | void QTextEdit::setLinkUnderline( bool b ) |
3420 | { | 3421 | { |
3421 | doc->setUnderlineLinks( b ); | 3422 | doc->setUnderlineLinks( b ); |
3422 | } | 3423 | } |
3423 | 3424 | ||
3424 | bool QTextEdit::linkUnderline() const | 3425 | bool 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 | ||
3435 | void QTextEdit::setMimeSourceFactory( QMimeSourceFactory* factory ) | 3436 | void 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 | ||
3446 | QMimeSourceFactory* QTextEdit::mimeSourceFactory() const | 3447 | QMimeSourceFactory* 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 | ||
3456 | int QTextEdit::heightForWidth( int w ) const | 3457 | int 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 | ||
3471 | void QTextEdit::append( const QString &text ) | 3472 | void 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 | ||
3524 | bool QTextEdit::hasSelectedText() const | 3525 | bool 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 | ||
3540 | QString QTextEdit::selectedText() const | 3541 | QString QTextEdit::selectedText() const |
3541 | { | 3542 | { |
3542 | return doc->selectedText( QTextDocument::Standard ); | 3543 | return doc->selectedText( QTextDocument::Standard ); |
3543 | } | 3544 | } |
3544 | 3545 | ||
3545 | bool QTextEdit::handleReadOnlyKeyEvent( QKeyEvent *e ) | 3546 | bool 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 | ||
3608 | QString QTextEdit::context() const | 3609 | QString 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 | ||
3622 | QString QTextEdit::documentTitle() const | 3623 | QString QTextEdit::documentTitle() const |
3623 | { | 3624 | { |
3624 | return doc->attributes()[ "title" ]; | 3625 | return doc->attributes()[ "title" ]; |
3625 | } | 3626 | } |
3626 | 3627 | ||
3627 | void QTextEdit::makeParagVisible( QTextParagraph *p ) | 3628 | void 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 | ||
3638 | void QTextEdit::scrollToAnchor( const QString& name ) | 3639 | void 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 | ||
3670 | QString QTextEdit::anchorAt( const QPoint& pos ) | 3671 | QString 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 | ||
3677 | void QTextEdit::documentWidthChanged( int w ) | 3678 | void 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 | ||
3687 | void QTextEdit::updateStyles() | 3688 | void QTextEdit::updateStyles() |
3688 | { | 3689 | { |
3689 | } | 3690 | } |
3690 | 3691 | ||
3691 | void QTextEdit::setDocument( QTextDocument *dc ) | 3692 | void 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 | */ |
3715 | void QTextEdit::pasteSubType( const QCString& subtype ) | 3716 | void 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 | */ |
3794 | void QTextEdit::pasteSpecial( const QPoint& pt ) | 3795 | void 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 |
3802 | QCString QTextEdit::pickSpecial( QMimeSource* ms, bool always_ask, const QPoint& pt ) | 3803 | QCString 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 | ||
3886 | void QTextEdit::setWordWrap( WordWrap mode ) | 3887 | void 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 | ||
3925 | QTextEdit::WordWrap QTextEdit::wordWrap() const | 3926 | QTextEdit::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 | */ |
3942 | void QTextEdit::setWrapColumnOrWidth( int value ) | 3943 | void 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 | ||
3965 | int QTextEdit::wrapColumnOrWidth() const | 3966 | int 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 | ||
3998 | void QTextEdit::setWrapPolicy( WrapPolicy policy ) | 3999 | void 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 | ||
4018 | QTextEdit::WrapPolicy QTextEdit::wrapPolicy() const | 4019 | QTextEdit::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 | ||
4030 | void QTextEdit::clear() | 4031 | void 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 | ||
4049 | int QTextEdit::undoDepth() const | 4050 | int 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 | ||
4060 | int QTextEdit::length() const | 4061 | int 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 | ||
4071 | int QTextEdit::tabStopWidth() const | 4072 | int QTextEdit::tabStopWidth() const |
4072 | { | 4073 | { |
4073 | return document()->tabStopWidth(); | 4074 | return document()->tabStopWidth(); |
4074 | } | 4075 | } |
4075 | 4076 | ||
4076 | void QTextEdit::setUndoDepth( int d ) | 4077 | void QTextEdit::setUndoDepth( int d ) |
4077 | { | 4078 | { |
4078 | document()->setUndoDepth( d ); | 4079 | document()->setUndoDepth( d ); |
4079 | } | 4080 | } |
4080 | 4081 | ||
4081 | void QTextEdit::setTabStopWidth( int ts ) | 4082 | void 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 | ||
4093 | QSize QTextEdit::sizeHint() const | 4094 | QSize 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 | ||
4099 | void QTextEdit::clearUndoRedo() | 4100 | void 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 | ||
4121 | bool QTextEdit::getFormat( int para, int index, QFont *font, QColor *color, VerticalAlignment *verticalAlignment ) | 4122 | bool 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 | ||
4154 | bool QTextEdit::getParagraphFormat( int para, QFont *font, QColor *color, | 4155 | bool 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 | ||
4186 | QPopupMenu *QTextEdit::createPopupMenu( const QPoint& pos ) | 4187 | QPopupMenu *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 | ||
4237 | QPopupMenu *QTextEdit::createPopupMenu() | 4238 | QPopupMenu *QTextEdit::createPopupMenu() |
4238 | { | 4239 | { |
4239 | return 0; | 4240 | return 0; |
4240 | } | 4241 | } |
4241 | 4242 | ||
4242 | /*! \reimp */ | 4243 | /*! \reimp */ |
4243 | 4244 | ||
4244 | void QTextEdit::setFont( const QFont &f ) | 4245 | void 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 | ||
4287 | void QTextEdit::zoomIn( int range ) | 4288 | void 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 | ||
4301 | void QTextEdit::zoomOut( int range ) | 4302 | void 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 | ||
4313 | void QTextEdit::zoomTo( int size ) | 4314 | void 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 | ||
4334 | void QTextEdit::sync() | 4335 | void 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 | ||
4345 | void QTextEdit::setEnabled( bool b ) | 4346 | void 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 | ||
4372 | void QTextEdit::setSelectionAttributes( int selNum, const QColor &back, bool invertText ) | 4373 | void 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 */ |
4383 | void QTextEdit::windowActivationChange( bool ) | 4384 | void 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 | ||
4392 | void QTextEdit::setReadOnly( bool b ) | 4393 | void 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 | ||
4408 | void QTextEdit::scrollToBottom() | 4409 | void 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 | ||
4418 | QRect QTextEdit::paragraphRect( int para ) const | 4419 | QRect 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 | ||
4433 | int QTextEdit::paragraphAt( const QPoint &pos ) const | 4434 | int 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 | ||
4449 | int QTextEdit::charAt( const QPoint &pos, int *para ) const | 4450 | int 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 | ||
4463 | void QTextEdit::setParagraphBackgroundColor( int para, const QColor &bg ) | 4464 | void 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 | ||
4476 | void QTextEdit::clearParagraphBackground( int para ) | 4477 | void 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 | ||
4490 | QColor QTextEdit::paragraphBackgroundColor( int para ) const | 4491 | QColor 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 | ||
4507 | void QTextEdit::setUndoRedoEnabled( bool b ) | 4508 | void QTextEdit::setUndoRedoEnabled( bool b ) |
4508 | { | 4509 | { |
4509 | undoEnabled = b; | 4510 | undoEnabled = b; |
4510 | } | 4511 | } |
4511 | 4512 | ||
4512 | bool QTextEdit::isUndoRedoEnabled() const | 4513 | bool 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 | ||
4519 | bool QTextEdit::isUndoAvailable() const | 4520 | bool 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 | ||
4526 | bool QTextEdit::isRedoAvailable() const | 4527 | bool QTextEdit::isRedoAvailable() const |
4527 | { | 4528 | { |
4528 | return doc->commands()->isRedoAvailable(); | 4529 | return doc->commands()->isRedoAvailable(); |
4529 | } | 4530 | } |
4530 | 4531 | ||
4531 | void QTextEdit::ensureFormatted( QTextParagraph *p ) | 4532 | void 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 */ |
4541 | void QTextEdit::updateCursor( const QPoint & pos ) | 4542 | void 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 | ||
4572 | void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c ) | 4573 | void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c ) |
4573 | { | 4574 | { |
4574 | placeCursor( pos, c, FALSE ); | 4575 | placeCursor( pos, c, FALSE ); |
4575 | } | 4576 | } |