1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the Qt3Support module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "q3textedit.h"
|
---|
43 |
|
---|
44 | #ifndef QT_NO_TEXTEDIT
|
---|
45 |
|
---|
46 | #include <private/q3richtext_p.h>
|
---|
47 | #include "qpainter.h"
|
---|
48 | #include "qpen.h"
|
---|
49 | #include "qbrush.h"
|
---|
50 | #include "qpixmap.h"
|
---|
51 | #include "qfont.h"
|
---|
52 | #include "qcolor.h"
|
---|
53 | #include "qstyle.h"
|
---|
54 | #include "qsize.h"
|
---|
55 | #include "qevent.h"
|
---|
56 | #include "qtimer.h"
|
---|
57 | #include "qapplication.h"
|
---|
58 | #include "q3listbox.h"
|
---|
59 | #include "qclipboard.h"
|
---|
60 | #include "qcolordialog.h"
|
---|
61 | #include "q3stylesheet.h"
|
---|
62 | #include "q3dragobject.h"
|
---|
63 | #include "qurl.h"
|
---|
64 | #include "qcursor.h"
|
---|
65 | #include "qregexp.h"
|
---|
66 | #include "q3popupmenu.h"
|
---|
67 | #include "qstack.h"
|
---|
68 | #include "qmetaobject.h"
|
---|
69 | #include "q3textbrowser.h"
|
---|
70 | #include "private/q3syntaxhighlighter_p.h"
|
---|
71 | #include "qtextformat.h"
|
---|
72 | #ifndef QT_NO_IM
|
---|
73 | #include <qinputcontext.h>
|
---|
74 | #endif
|
---|
75 |
|
---|
76 | #ifndef QT_NO_ACCEL
|
---|
77 | #include <qkeysequence.h>
|
---|
78 | #define ACCEL_KEY(k) QLatin1Char('\t') + QString(QKeySequence(Qt::CTRL | Qt::Key_ ## k))
|
---|
79 | #else
|
---|
80 | #define ACCEL_KEY(k) QLatin1Char('\t' )+ QString::fromLatin1("Ctrl+" #k)
|
---|
81 | #endif
|
---|
82 |
|
---|
83 | #ifdef QT_TEXTEDIT_OPTIMIZATION
|
---|
84 | #define LOGOFFSET(i) d->logOffset + i
|
---|
85 | #endif
|
---|
86 |
|
---|
87 | QT_BEGIN_NAMESPACE
|
---|
88 |
|
---|
89 | struct QUndoRedoInfoPrivate
|
---|
90 | {
|
---|
91 | Q3TextString text;
|
---|
92 | };
|
---|
93 |
|
---|
94 | class Q3TextEditPrivate
|
---|
95 | {
|
---|
96 | public:
|
---|
97 | Q3TextEditPrivate()
|
---|
98 | :preeditStart(-1),preeditLength(-1),numPreeditSelections(0),ensureCursorVisibleInShowEvent(false),
|
---|
99 | tabChangesFocus(false),
|
---|
100 | #ifndef QT_NO_CLIPBOARD
|
---|
101 | clipboard_mode(QClipboard::Clipboard),
|
---|
102 | #endif
|
---|
103 | #ifdef QT_TEXTEDIT_OPTIMIZATION
|
---|
104 | od(0), optimMode(false),
|
---|
105 | maxLogLines(-1),
|
---|
106 | logOffset(0),
|
---|
107 | #endif
|
---|
108 | autoFormatting((uint)Q3TextEdit::AutoAll),
|
---|
109 | cursorRepaintMode(false),
|
---|
110 | cursorBlinkActive(false)
|
---|
111 |
|
---|
112 | {
|
---|
113 | for (int i=0; i<7; i++)
|
---|
114 | id[i] = 0;
|
---|
115 | }
|
---|
116 | int id[7];
|
---|
117 | int preeditStart;
|
---|
118 | int preeditLength;
|
---|
119 | int numPreeditSelections;
|
---|
120 | uint ensureCursorVisibleInShowEvent : 1;
|
---|
121 | uint tabChangesFocus : 1;
|
---|
122 | QString scrollToAnchor; // used to deferr scrollToAnchor() until the show event when we are resized
|
---|
123 | QString pressedName;
|
---|
124 | QString onName;
|
---|
125 | #ifndef QT_NO_CLIPBOARD
|
---|
126 | QClipboard::Mode clipboard_mode;
|
---|
127 | #endif
|
---|
128 | QTimer *trippleClickTimer;
|
---|
129 | QPoint trippleClickPoint;
|
---|
130 | #ifdef QT_TEXTEDIT_OPTIMIZATION
|
---|
131 | Q3TextEditOptimPrivate * od;
|
---|
132 | bool optimMode : 1;
|
---|
133 | int maxLogLines;
|
---|
134 | int logOffset;
|
---|
135 | #endif
|
---|
136 | Q3TextEdit::AutoFormatting autoFormatting;
|
---|
137 | uint cursorRepaintMode : 1;
|
---|
138 | uint cursorBlinkActive : 1;
|
---|
139 | };
|
---|
140 |
|
---|
141 | #ifndef QT_NO_MIME
|
---|
142 | class Q3RichTextDrag : public Q3TextDrag
|
---|
143 | {
|
---|
144 | public:
|
---|
145 | Q3RichTextDrag(QWidget *dragSource = 0, const char *name = 0);
|
---|
146 |
|
---|
147 | void setPlainText(const QString &txt) { setText(txt); }
|
---|
148 | void setRichText(const QString &txt) { richTxt = txt; }
|
---|
149 |
|
---|
150 | virtual QByteArray encodedData(const char *mime) const;
|
---|
151 | virtual const char* format(int i) const;
|
---|
152 |
|
---|
153 | static bool decode(QMimeSource *e, QString &str, const QString &mimetype,
|
---|
154 | const QString &subtype);
|
---|
155 | static bool canDecode(QMimeSource* e);
|
---|
156 |
|
---|
157 | private:
|
---|
158 | QString richTxt;
|
---|
159 |
|
---|
160 | };
|
---|
161 |
|
---|
162 | Q3RichTextDrag::Q3RichTextDrag(QWidget *dragSource, const char *name)
|
---|
163 | : Q3TextDrag(dragSource, name)
|
---|
164 | {
|
---|
165 | }
|
---|
166 |
|
---|
167 | QByteArray Q3RichTextDrag::encodedData(const char *mime) const
|
---|
168 | {
|
---|
169 | if (qstrcmp("application/x-qrichtext", mime) == 0) {
|
---|
170 | return richTxt.toUtf8(); // #### perhaps we should use USC2 instead?
|
---|
171 | } else
|
---|
172 | return Q3TextDrag::encodedData(mime);
|
---|
173 | }
|
---|
174 |
|
---|
175 | bool Q3RichTextDrag::decode(QMimeSource *e, QString &str, const QString &mimetype,
|
---|
176 | const QString &subtype)
|
---|
177 | {
|
---|
178 | if (mimetype == QLatin1String("application/x-qrichtext")) {
|
---|
179 | // do richtext decode
|
---|
180 | const char *mime;
|
---|
181 | int i;
|
---|
182 | for (i = 0; (mime = e->format(i)); ++i) {
|
---|
183 | if (qstrcmp("application/x-qrichtext", mime) != 0)
|
---|
184 | continue;
|
---|
185 | str = QString::fromUtf8(e->encodedData(mime));
|
---|
186 | return true;
|
---|
187 | }
|
---|
188 | return false;
|
---|
189 | }
|
---|
190 |
|
---|
191 | // do a regular text decode
|
---|
192 | QString st = subtype;
|
---|
193 | return Q3TextDrag::decode(e, str, st);
|
---|
194 | }
|
---|
195 |
|
---|
196 | bool Q3RichTextDrag::canDecode(QMimeSource* e)
|
---|
197 | {
|
---|
198 | if (e->provides("application/x-qrichtext"))
|
---|
199 | return true;
|
---|
200 | return Q3TextDrag::canDecode(e);
|
---|
201 | }
|
---|
202 |
|
---|
203 | const char* Q3RichTextDrag::format(int i) const
|
---|
204 | {
|
---|
205 | if (Q3TextDrag::format(i))
|
---|
206 | return Q3TextDrag::format(i);
|
---|
207 | if (Q3TextDrag::format(i-1))
|
---|
208 | return "application/x-qrichtext";
|
---|
209 | return 0;
|
---|
210 | }
|
---|
211 |
|
---|
212 | #endif
|
---|
213 |
|
---|
214 | static bool block_set_alignment = false;
|
---|
215 |
|
---|
216 | /*!
|
---|
217 | \class Q3TextEdit
|
---|
218 | \brief The Q3TextEdit widget provides a powerful single-page rich text editor.
|
---|
219 |
|
---|
220 | \compat
|
---|
221 |
|
---|
222 | \tableofcontents
|
---|
223 |
|
---|
224 | \section1 Introduction and Concepts
|
---|
225 |
|
---|
226 | Q3TextEdit is an advanced WYSIWYG viewer/editor supporting rich
|
---|
227 | text formatting using HTML-style tags. It is optimized to handle
|
---|
228 | large documents and to respond quickly to user input.
|
---|
229 |
|
---|
230 | Q3TextEdit has four modes of operation:
|
---|
231 | \table
|
---|
232 | \header \i Mode \i Command \i Notes
|
---|
233 | \row \i Plain Text Editor \i setTextFormat(Qt::PlainText)
|
---|
234 | \i Set text with setText(); text() returns plain text. Text
|
---|
235 | attributes (e.g. colors) can be set, but plain text is always
|
---|
236 | returned.
|
---|
237 | \row \i Rich Text Editor \i setTextFormat(Qt::RichText)
|
---|
238 | \i Set text with setText(); text() returns rich text. Rich
|
---|
239 | text editing is fairly limited. You can't set margins or
|
---|
240 | insert images for example (although you can read and
|
---|
241 | correctly display files that have margins set and that
|
---|
242 | include images). This mode is mostly useful for editing small
|
---|
243 | amounts of rich text.
|
---|
244 | \row \i Text Viewer \i setReadOnly(true)
|
---|
245 | \i Set text with setText() or append() (which has no undo
|
---|
246 | history so is faster and uses less memory); text() returns
|
---|
247 | plain or rich text depending on the textFormat(). This mode
|
---|
248 | can correctly display a large subset of HTML tags.
|
---|
249 | \row \i Log Viewer \i setTextFormat(Qt::LogText)
|
---|
250 | \i Append text using append(). The widget is set to be read
|
---|
251 | only and rich text support is disabled although a few HTML
|
---|
252 | tags (for color, bold, italic and underline) may be used.
|
---|
253 | (See \link #logtextmode Qt::LogText mode\endlink for details.)
|
---|
254 | \endtable
|
---|
255 |
|
---|
256 | Q3TextEdit can be used as a syntax highlighting editor when used in
|
---|
257 | conjunction with QSyntaxHighlighter.
|
---|
258 |
|
---|
259 | We recommend that you always call setTextFormat() to set the mode
|
---|
260 | you want to use. If you use Qt::AutoText then setText() and
|
---|
261 | append() will try to determine whether the text they are given is
|
---|
262 | plain text or rich text. If you use Qt::RichText then setText() and
|
---|
263 | append() will assume that the text they are given is rich text.
|
---|
264 | insert() simply inserts the text it is given.
|
---|
265 |
|
---|
266 | Q3TextEdit works on paragraphs and characters. A paragraph is a
|
---|
267 | formatted string which is word-wrapped to fit into the width of
|
---|
268 | the widget. By default when reading plain text, one newline
|
---|
269 | signify a paragraph. A document consists of zero or more
|
---|
270 | paragraphs, indexed from 0. Characters are indexed on a
|
---|
271 | per-paragraph basis, also indexed from 0. The words in the
|
---|
272 | paragraph are aligned in accordance with the paragraph's
|
---|
273 | alignment(). Paragraphs are separated by hard line breaks. Each
|
---|
274 | character within a paragraph has its own attributes, for example,
|
---|
275 | font and color.
|
---|
276 |
|
---|
277 | The text edit documentation uses the following concepts:
|
---|
278 | \list
|
---|
279 | \i \e{current format} --
|
---|
280 | this is the format at the current cursor position, \e and it
|
---|
281 | is the format of the selected text if any.
|
---|
282 | \i \e{current paragraph} -- the paragraph which contains the
|
---|
283 | cursor.
|
---|
284 | \endlist
|
---|
285 |
|
---|
286 | Q3TextEdit can display images (using Q3MimeSourceFactory), lists and
|
---|
287 | tables. If the text is too large to view within the text edit's
|
---|
288 | viewport, scroll bars will appear. The text edit can load both
|
---|
289 | plain text and HTML files (a subset of HTML 3.2 and 4). The
|
---|
290 | rendering style and the set of valid tags are defined by a
|
---|
291 | styleSheet(). Custom tags can be created and placed in a custom
|
---|
292 | style sheet. Change the style sheet with \l{setStyleSheet()}; see
|
---|
293 | Q3StyleSheet for details. The images identified by image tags are
|
---|
294 | displayed if they can be interpreted using the text edit's
|
---|
295 | \l{Q3MimeSourceFactory}; see setMimeSourceFactory().
|
---|
296 |
|
---|
297 | If you want a text browser with more navigation use QTextBrowser.
|
---|
298 | If you just need to display a small piece of rich text use QLabel
|
---|
299 | or QSimpleRichText.
|
---|
300 |
|
---|
301 | If you create a new Q3TextEdit, and want to allow the user to edit
|
---|
302 | rich text, call setTextFormat(Qt::RichText) to ensure that the
|
---|
303 | text is treated as rich text. (Rich text uses HTML tags to set
|
---|
304 | text formatting attributes. See Q3StyleSheet for information on the
|
---|
305 | HTML tags that are supported.). If you don't call setTextFormat()
|
---|
306 | explicitly the text edit will guess from the text itself whether
|
---|
307 | it is rich text or plain text. This means that if the text looks
|
---|
308 | like HTML or XML it will probably be interpreted as rich text, so
|
---|
309 | you should call setTextFormat(Qt::PlainText) to preserve such
|
---|
310 | text.
|
---|
311 |
|
---|
312 | Note that we do not intend to add a full-featured web browser
|
---|
313 | widget to Qt (because that would easily double Qt's size and only
|
---|
314 | a few applications would benefit from it). The rich
|
---|
315 | text support in Qt is designed to provide a fast, portable and
|
---|
316 | efficient way to add reasonable online help facilities to
|
---|
317 | applications, and to provide a basis for rich text editors.
|
---|
318 |
|
---|
319 | \section1 Using Q3TextEdit as a Display Widget
|
---|
320 |
|
---|
321 | Q3TextEdit can display a large HTML subset, including tables and
|
---|
322 | images.
|
---|
323 |
|
---|
324 | The text is set or replaced using setText() which deletes any
|
---|
325 | existing text and replaces it with the text passed in the
|
---|
326 | setText() call. If you call setText() with legacy HTML (with
|
---|
327 | setTextFormat(Qt::RichText) in force), and then call text(), the text
|
---|
328 | that is returned may have different markup, but will render the
|
---|
329 | same. Text can be inserted with insert(), paste(), pasteSubType()
|
---|
330 | and append(). Text that is appended does not go into the undo
|
---|
331 | history; this makes append() faster and consumes less memory. Text
|
---|
332 | can also be cut(). The entire text is deleted with clear() and the
|
---|
333 | selected text is deleted with removeSelectedText(). Selected
|
---|
334 | (marked) text can also be deleted with del() (which will delete
|
---|
335 | the character to the right of the cursor if no text is selected).
|
---|
336 |
|
---|
337 | Loading and saving text is achieved using setText() and text(),
|
---|
338 | for example:
|
---|
339 | \snippet doc/src/snippets/code/src_qt3support_text_q3textedit.cpp 0
|
---|
340 |
|
---|
341 | By default the text edit wraps words at whitespace to fit within
|
---|
342 | the text edit widget. The setWordWrap() function is used to
|
---|
343 | specify the kind of word wrap you want, or \c NoWrap if you don't
|
---|
344 | want any wrapping. Call setWordWrap() to set a fixed pixel width
|
---|
345 | \c FixedPixelWidth, or character column (e.g. 80 column) \c
|
---|
346 | FixedColumnWidth with the pixels or columns specified with
|
---|
347 | setWrapColumnOrWidth(). If you use word wrap to the widget's width
|
---|
348 | \c WidgetWidth, you can specify whether to break on whitespace or
|
---|
349 | anywhere with setWrapPolicy().
|
---|
350 |
|
---|
351 | The background color is set differently than other widgets, using
|
---|
352 | setPaper(). You specify a brush style which could be a plain color
|
---|
353 | or a complex pixmap.
|
---|
354 |
|
---|
355 | Hypertext links are automatically underlined; this can be changed
|
---|
356 | with setLinkUnderline(). The tab stop width is set with
|
---|
357 | setTabStopWidth().
|
---|
358 |
|
---|
359 | The zoomIn() and zoomOut() functions can be used to resize the
|
---|
360 | text by increasing (decreasing for zoomOut()) the point size used.
|
---|
361 | Images are not affected by the zoom functions.
|
---|
362 |
|
---|
363 | The lines() function returns the number of lines in the text and
|
---|
364 | paragraphs() returns the number of paragraphs. The number of lines
|
---|
365 | within a particular paragraph is returned by linesOfParagraph().
|
---|
366 | The length of the entire text in characters is returned by
|
---|
367 | length().
|
---|
368 |
|
---|
369 | You can scroll to an anchor in the text, e.g.
|
---|
370 | \c{<a name="anchor">} with scrollToAnchor(). The find() function
|
---|
371 | can be used to find and select a given string within the text.
|
---|
372 |
|
---|
373 | A read-only Q3TextEdit provides the same functionality as the
|
---|
374 | (obsolete) QTextView. (QTextView is still supplied for
|
---|
375 | compatibility with old code.)
|
---|
376 |
|
---|
377 | \section2 Read-only key bindings
|
---|
378 |
|
---|
379 | When Q3TextEdit is used read-only the key-bindings are limited to
|
---|
380 | navigation, and text may only be selected with the mouse:
|
---|
381 | \table
|
---|
382 | \header \i Keypresses \i Action
|
---|
383 | \row \i Up \i Move one line up
|
---|
384 | \row \i Down \i Move one line down
|
---|
385 | \row \i Left \i Move one character left
|
---|
386 | \row \i Right \i Move one character right
|
---|
387 | \row \i PageUp \i Move one (viewport) page up
|
---|
388 | \row \i PageDown \i Move one (viewport) page down
|
---|
389 | \row \i Home \i Move to the beginning of the text
|
---|
390 | \row \i End \i Move to the end of the text
|
---|
391 | \row \i Shift+Wheel
|
---|
392 | \i Scroll the page horizontally (the Wheel is the mouse wheel)
|
---|
393 | \row \i Ctrl+Wheel \i Zoom the text
|
---|
394 | \endtable
|
---|
395 |
|
---|
396 | The text edit may be able to provide some meta-information. For
|
---|
397 | example, the documentTitle() function will return the text from
|
---|
398 | within HTML \c{<title>} tags.
|
---|
399 |
|
---|
400 | The text displayed in a text edit has a \e context. The context is
|
---|
401 | a path which the text edit's Q3MimeSourceFactory uses to resolve
|
---|
402 | the locations of files and images. It is passed to the
|
---|
403 | mimeSourceFactory() when quering data. (See Q3TextEdit() and
|
---|
404 | \l{context()}.)
|
---|
405 |
|
---|
406 | \target logtextmode
|
---|
407 | \section2 Using Q3TextEdit in Qt::LogText Mode
|
---|
408 |
|
---|
409 | Setting the text format to Qt::LogText puts the widget in a special
|
---|
410 | mode which is optimized for very large texts. In this mode editing
|
---|
411 | and rich text support are disabled (the widget is explicitly set
|
---|
412 | to read-only mode). This allows the text to be stored in a
|
---|
413 | different, more memory efficient manner. However, a certain degree
|
---|
414 | of text formatting is supported through the use of formatting
|
---|
415 | tags. A tag is delimited by \c < and \c {>}. The characters \c
|
---|
416 | {<}, \c > and \c & are escaped by using \c {<}, \c {>} and
|
---|
417 | \c {&}. A tag pair consists of a left and a right tag (or
|
---|
418 | open/close tags). Left-tags mark the starting point for
|
---|
419 | formatting, while right-tags mark the ending point. A right-tag
|
---|
420 | always start with a \c / before the tag keyword. For example \c
|
---|
421 | <b> and \c </b> are a tag pair. Tags can be nested, but they
|
---|
422 | have to be closed in the same order as they are opened. For
|
---|
423 | example, \c <b><u></u></b> is valid, while \c
|
---|
424 | <b><u></b></u> will output an error message.
|
---|
425 |
|
---|
426 | By using tags it is possible to change the color, bold, italic and
|
---|
427 | underline settings for a piece of text. A color can be specified
|
---|
428 | by using the HTML font tag \c {<font color=colorname>}. The color
|
---|
429 | name can be one of the color names from the X11 color database, or
|
---|
430 | a RGB hex value (e.g \c {#00ff00}). Example of valid color tags:
|
---|
431 | \c {<font color=red>}, \c{<font color="light blue">},\c {<font
|
---|
432 | color="#223344">}. Bold, italic and underline settings can be
|
---|
433 | specified by the tags \c {<b>}, \c <i> and \c {<u>}. Note that a
|
---|
434 | tag does not necessarily have to be closed. A valid example:
|
---|
435 | \snippet doc/src/snippets/code/src_qt3support_text_q3textedit.cpp 1
|
---|
436 |
|
---|
437 | Stylesheets can also be used in Qt::LogText mode. To create and use a
|
---|
438 | custom tag, you could do the following:
|
---|
439 | \snippet doc/src/snippets/code/src_qt3support_text_q3textedit.cpp 2
|
---|
440 | Note that only the color, bold, underline and italic attributes of
|
---|
441 | a Q3StyleSheetItem is used in Qt::LogText mode.
|
---|
442 |
|
---|
443 | Note that you can use setMaxLogLines() to limit the number of
|
---|
444 | lines the widget can hold in Qt::LogText mode.
|
---|
445 |
|
---|
446 | There are a few things that you need to be aware of when the
|
---|
447 | widget is in this mode:
|
---|
448 | \list
|
---|
449 | \i Functions that deal with rich text formatting and cursor
|
---|
450 | movement will not work or return anything valid.
|
---|
451 | \i Lines are equivalent to paragraphs.
|
---|
452 | \endlist
|
---|
453 |
|
---|
454 | \section1 Using Q3TextEdit as an Editor
|
---|
455 |
|
---|
456 | All the information about using Q3TextEdit as a display widget also
|
---|
457 | applies here.
|
---|
458 |
|
---|
459 | The current format's attributes are set with setItalic(),
|
---|
460 | setBold(), setUnderline(), setFamily() (font family),
|
---|
461 | setPointSize(), setColor() and setCurrentFont(). The current
|
---|
462 | paragraph's alignment is set with setAlignment().
|
---|
463 |
|
---|
464 | Use setSelection() to select text. The setSelectionAttributes()
|
---|
465 | function is used to indicate how selected text should be
|
---|
466 | displayed. Use hasSelectedText() to find out if any text is
|
---|
467 | selected. The currently selected text's position is available
|
---|
468 | using getSelection() and the selected text itself is returned by
|
---|
469 | selectedText(). The selection can be copied to the clipboard with
|
---|
470 | copy(), or cut to the clipboard with cut(). It can be deleted with
|
---|
471 | removeSelectedText(). The entire text can be selected (or
|
---|
472 | unselected) using selectAll(). Q3TextEdit supports multiple
|
---|
473 | selections. Most of the selection functions operate on the default
|
---|
474 | selection, selection 0. If the user presses a non-selecting key,
|
---|
475 | e.g. a cursor key without also holding down Shift, all selections
|
---|
476 | are cleared.
|
---|
477 |
|
---|
478 | Set and get the position of the cursor with setCursorPosition()
|
---|
479 | and getCursorPosition() respectively. When the cursor is moved,
|
---|
480 | the signals currentFontChanged(), currentColorChanged() and
|
---|
481 | currentAlignmentChanged() are emitted to reflect the font, color
|
---|
482 | and alignment at the new cursor position.
|
---|
483 |
|
---|
484 | If the text changes, the textChanged() signal is emitted, and if
|
---|
485 | the user inserts a new line by pressing Return or Enter,
|
---|
486 | returnPressed() is emitted. The isModified() function will return
|
---|
487 | true if the text has been modified.
|
---|
488 |
|
---|
489 | Q3TextEdit provides command-based undo and redo. To set the depth
|
---|
490 | of the command history use setUndoDepth() which defaults to 100
|
---|
491 | steps. To undo or redo the last operation call undo() or redo().
|
---|
492 | The signals undoAvailable() and redoAvailable() indicate whether
|
---|
493 | the undo and redo operations can be executed.
|
---|
494 |
|
---|
495 | \section2 Editing key bindings
|
---|
496 |
|
---|
497 | The list of key-bindings which are implemented for editing:
|
---|
498 | \table
|
---|
499 | \header \i Keypresses \i Action
|
---|
500 | \row \i Backspace \i Delete the character to the left of the cursor
|
---|
501 | \row \i Delete \i Delete the character to the right of the cursor
|
---|
502 | \row \i Ctrl+A \i Move the cursor to the beginning of the line
|
---|
503 | \row \i Ctrl+B \i Move the cursor one character left
|
---|
504 | \row \i Ctrl+C \i Copy the marked text to the clipboard (also
|
---|
505 | Ctrl+Insert under Windows)
|
---|
506 | \row \i Ctrl+D \i Delete the character to the right of the cursor
|
---|
507 | \row \i Ctrl+E \i Move the cursor to the end of the line
|
---|
508 | \row \i Ctrl+F \i Move the cursor one character right
|
---|
509 | \row \i Ctrl+H \i Delete the character to the left of the cursor
|
---|
510 | \row \i Ctrl+K \i Delete to end of line
|
---|
511 | \row \i Ctrl+N \i Move the cursor one line down
|
---|
512 | \row \i Ctrl+P \i Move the cursor one line up
|
---|
513 | \row \i Ctrl+V \i Paste the clipboard text into line edit
|
---|
514 | (also Shift+Insert under Windows)
|
---|
515 | \row \i Ctrl+X \i Cut the marked text, copy to clipboard
|
---|
516 | (also Shift+Delete under Windows)
|
---|
517 | \row \i Ctrl+Z \i Undo the last operation
|
---|
518 | \row \i Ctrl+Y \i Redo the last operation
|
---|
519 | \row \i Left \i Move the cursor one character left
|
---|
520 | \row \i Ctrl+Left \i Move the cursor one word left
|
---|
521 | \row \i Right \i Move the cursor one character right
|
---|
522 | \row \i Ctrl+Right \i Move the cursor one word right
|
---|
523 | \row \i Up \i Move the cursor one line up
|
---|
524 | \row \i Ctrl+Qt::Up \i Move the cursor one word up
|
---|
525 | \row \i DownArrow \i Move the cursor one line down
|
---|
526 | \row \i Ctrl+Down \i Move the cursor one word down
|
---|
527 | \row \i PageUp \i Move the cursor one page up
|
---|
528 | \row \i PageDown \i Move the cursor one page down
|
---|
529 | \row \i Home \i Move the cursor to the beginning of the line
|
---|
530 | \row \i Ctrl+Home \i Move the cursor to the beginning of the text
|
---|
531 | \row \i End \i Move the cursor to the end of the line
|
---|
532 | \row \i Ctrl+End \i Move the cursor to the end of the text
|
---|
533 | \row \i Shift+Wheel \i Scroll the page horizontally
|
---|
534 | (the Wheel is the mouse wheel)
|
---|
535 | \row \i Ctrl+Wheel \i Zoom the text
|
---|
536 | \endtable
|
---|
537 |
|
---|
538 | To select (mark) text hold down the Shift key whilst pressing one
|
---|
539 | of the movement keystrokes, for example, \e{Shift+Right}
|
---|
540 | will select the character to the right, and \e{Shift+Ctrl+Right} will select the word to the right, etc.
|
---|
541 |
|
---|
542 | By default the text edit widget operates in insert mode so all
|
---|
543 | text that the user enters is inserted into the text edit and any
|
---|
544 | text to the right of the cursor is moved out of the way. The mode
|
---|
545 | can be changed to overwrite, where new text overwrites any text to
|
---|
546 | the right of the cursor, using setOverwriteMode().
|
---|
547 | */
|
---|
548 |
|
---|
549 | /*!
|
---|
550 | \enum Q3TextEdit::AutoFormattingFlag
|
---|
551 |
|
---|
552 | \value AutoNone Do not perform any automatic formatting
|
---|
553 | \value AutoBulletList Only automatically format bulletted lists
|
---|
554 | \value AutoAll Apply all available autoformatting
|
---|
555 | */
|
---|
556 |
|
---|
557 |
|
---|
558 | /*!
|
---|
559 | \enum Q3TextEdit::KeyboardAction
|
---|
560 |
|
---|
561 | This enum is used by doKeyboardAction() to specify which action
|
---|
562 | should be executed:
|
---|
563 |
|
---|
564 | \value ActionBackspace Delete the character to the left of the
|
---|
565 | cursor.
|
---|
566 |
|
---|
567 | \value ActionDelete Delete the character to the right of the
|
---|
568 | cursor.
|
---|
569 |
|
---|
570 | \value ActionReturn Split the paragraph at the cursor position.
|
---|
571 |
|
---|
572 | \value ActionKill If the cursor is not at the end of the
|
---|
573 | paragraph, delete the text from the cursor position until the end
|
---|
574 | of the paragraph. If the cursor is at the end of the paragraph,
|
---|
575 | delete the hard line break at the end of the paragraph: this will
|
---|
576 | cause this paragraph to be joined with the following paragraph.
|
---|
577 |
|
---|
578 | \value ActionWordBackspace Delete the word to the left of the
|
---|
579 | cursor position.
|
---|
580 |
|
---|
581 | \value ActionWordDelete Delete the word to the right of the
|
---|
582 | cursor position
|
---|
583 |
|
---|
584 | */
|
---|
585 |
|
---|
586 | /*!
|
---|
587 | \enum Q3TextEdit::VerticalAlignment
|
---|
588 |
|
---|
589 | This enum is used to set the vertical alignment of the text.
|
---|
590 |
|
---|
591 | \value AlignNormal Normal alignment
|
---|
592 | \value AlignSuperScript Superscript
|
---|
593 | \value AlignSubScript Subscript
|
---|
594 | */
|
---|
595 |
|
---|
596 | /*!
|
---|
597 | \enum Q3TextEdit::TextInsertionFlags
|
---|
598 |
|
---|
599 | \internal
|
---|
600 |
|
---|
601 | \value RedoIndentation
|
---|
602 | \value CheckNewLines
|
---|
603 | \value RemoveSelected
|
---|
604 | */
|
---|
605 |
|
---|
606 |
|
---|
607 | /*!
|
---|
608 | \fn void Q3TextEdit::copyAvailable(bool yes)
|
---|
609 |
|
---|
610 | This signal is emitted when text is selected or de-selected in the
|
---|
611 | text edit.
|
---|
612 |
|
---|
613 | When text is selected this signal will be emitted with \a yes set
|
---|
614 | to true. If no text has been selected or if the selected text is
|
---|
615 | de-selected this signal is emitted with \a yes set to false.
|
---|
616 |
|
---|
617 | If \a yes is true then copy() can be used to copy the selection to
|
---|
618 | the clipboard. If \a yes is false then copy() does nothing.
|
---|
619 |
|
---|
620 | \sa selectionChanged()
|
---|
621 | */
|
---|
622 |
|
---|
623 |
|
---|
624 | /*!
|
---|
625 | \fn void Q3TextEdit::textChanged()
|
---|
626 |
|
---|
627 | This signal is emitted whenever the text in the text edit changes.
|
---|
628 |
|
---|
629 | \sa setText() append()
|
---|
630 | */
|
---|
631 |
|
---|
632 | /*!
|
---|
633 | \fn void Q3TextEdit::selectionChanged()
|
---|
634 |
|
---|
635 | This signal is emitted whenever the selection changes.
|
---|
636 |
|
---|
637 | \sa setSelection() copyAvailable()
|
---|
638 | */
|
---|
639 |
|
---|
640 | /*! \fn Q3TextDocument *Q3TextEdit::document() const
|
---|
641 |
|
---|
642 | \internal
|
---|
643 |
|
---|
644 | This function returns the Q3TextDocument which is used by the text
|
---|
645 | edit.
|
---|
646 | */
|
---|
647 |
|
---|
648 | /*! \fn void Q3TextEdit::setDocument(Q3TextDocument *doc)
|
---|
649 |
|
---|
650 | \internal
|
---|
651 |
|
---|
652 | This function sets the Q3TextDocument which should be used by the text
|
---|
653 | edit to \a doc. This can be used, for example, if you want to
|
---|
654 | display a document using multiple views. You would create a
|
---|
655 | Q3TextDocument and set it to the text edits which should display it.
|
---|
656 | You would need to connect to the textChanged() and
|
---|
657 | selectionChanged() signals of all the text edits and update them all
|
---|
658 | accordingly (preferably with a slight delay for efficiency reasons).
|
---|
659 | */
|
---|
660 |
|
---|
661 | /*!
|
---|
662 | \enum Q3TextEdit::CursorAction
|
---|
663 |
|
---|
664 | This enum is used by moveCursor() to specify in which direction
|
---|
665 | the cursor should be moved:
|
---|
666 |
|
---|
667 | \value MoveBackward Moves the cursor one character backward
|
---|
668 |
|
---|
669 | \value MoveWordBackward Moves the cursor one word backward
|
---|
670 |
|
---|
671 | \value MoveForward Moves the cursor one character forward
|
---|
672 |
|
---|
673 | \value MoveWordForward Moves the cursor one word forward
|
---|
674 |
|
---|
675 | \value MoveUp Moves the cursor up one line
|
---|
676 |
|
---|
677 | \value MoveDown Moves the cursor down one line
|
---|
678 |
|
---|
679 | \value MoveLineStart Moves the cursor to the beginning of the line
|
---|
680 |
|
---|
681 | \value MoveLineEnd Moves the cursor to the end of the line
|
---|
682 |
|
---|
683 | \value MoveHome Moves the cursor to the beginning of the document
|
---|
684 |
|
---|
685 | \value MoveEnd Moves the cursor to the end of the document
|
---|
686 |
|
---|
687 | \value MovePgUp Moves the cursor one viewport page up
|
---|
688 |
|
---|
689 | \value MovePgDown Moves the cursor one viewport page down
|
---|
690 | */
|
---|
691 |
|
---|
692 | /*!
|
---|
693 | \property Q3TextEdit::overwriteMode
|
---|
694 | \brief the text edit's overwrite mode
|
---|
695 |
|
---|
696 | If false (the default) characters entered by the user are inserted
|
---|
697 | with any characters to the right being moved out of the way. If
|
---|
698 | true, the editor is in overwrite mode, i.e. characters entered by
|
---|
699 | the user overwrite any characters to the right of the cursor
|
---|
700 | position.
|
---|
701 | */
|
---|
702 |
|
---|
703 | /*!
|
---|
704 | \fn void Q3TextEdit::setCurrentFont(const QFont &f)
|
---|
705 |
|
---|
706 | Sets the font of the current format to \a f.
|
---|
707 |
|
---|
708 | If the widget is in Qt::LogText mode this function will do
|
---|
709 | nothing. Use setFont() instead.
|
---|
710 |
|
---|
711 | \sa currentFont() setPointSize() setFamily()
|
---|
712 | */
|
---|
713 |
|
---|
714 | /*!
|
---|
715 | \property Q3TextEdit::undoDepth
|
---|
716 | \brief the depth of the undo history
|
---|
717 |
|
---|
718 | The maximum number of steps in the undo/redo history. The default
|
---|
719 | is 100.
|
---|
720 |
|
---|
721 | \sa undo() redo()
|
---|
722 | */
|
---|
723 |
|
---|
724 | /*!
|
---|
725 | \fn void Q3TextEdit::undoAvailable(bool yes)
|
---|
726 |
|
---|
727 | This signal is emitted when the availability of undo changes. If
|
---|
728 | \a yes is true, then undo() will work until undoAvailable(false)
|
---|
729 | is next emitted.
|
---|
730 |
|
---|
731 | \sa undo() undoDepth()
|
---|
732 | */
|
---|
733 |
|
---|
734 | /*!
|
---|
735 | \fn void Q3TextEdit::modificationChanged(bool m)
|
---|
736 |
|
---|
737 | This signal is emitted when the modification status of the
|
---|
738 | document has changed. If \a m is true, the document was modified,
|
---|
739 | otherwise the modification state has been reset to unmodified.
|
---|
740 |
|
---|
741 | \sa modified
|
---|
742 | */
|
---|
743 |
|
---|
744 | /*!
|
---|
745 | \fn void Q3TextEdit::redoAvailable(bool yes)
|
---|
746 |
|
---|
747 | This signal is emitted when the availability of redo changes. If
|
---|
748 | \a yes is true, then redo() will work until redoAvailable(false)
|
---|
749 | is next emitted.
|
---|
750 |
|
---|
751 | \sa redo() undoDepth()
|
---|
752 | */
|
---|
753 |
|
---|
754 | /*!
|
---|
755 | \fn void Q3TextEdit::currentFontChanged(const QFont &f)
|
---|
756 |
|
---|
757 | This signal is emitted if the font of the current format has
|
---|
758 | changed.
|
---|
759 |
|
---|
760 | The new font is \a f.
|
---|
761 |
|
---|
762 | \sa setCurrentFont()
|
---|
763 | */
|
---|
764 |
|
---|
765 | /*!
|
---|
766 | \fn void Q3TextEdit::currentColorChanged(const QColor &c)
|
---|
767 |
|
---|
768 | This signal is emitted if the color of the current format has
|
---|
769 | changed.
|
---|
770 |
|
---|
771 | The new color is \a c.
|
---|
772 |
|
---|
773 | \sa setColor()
|
---|
774 | */
|
---|
775 |
|
---|
776 | /*!
|
---|
777 | \fn void Q3TextEdit::currentVerticalAlignmentChanged(Q3TextEdit::VerticalAlignment a)
|
---|
778 |
|
---|
779 | This signal is emitted if the vertical alignment of the current
|
---|
780 | format has changed.
|
---|
781 |
|
---|
782 | The new vertical alignment is \a a.
|
---|
783 | */
|
---|
784 |
|
---|
785 | /*!
|
---|
786 | \fn void Q3TextEdit::currentAlignmentChanged(int a)
|
---|
787 |
|
---|
788 | This signal is emitted if the alignment of the current paragraph
|
---|
789 | has changed.
|
---|
790 |
|
---|
791 | The new alignment is \a a.
|
---|
792 |
|
---|
793 | \sa setAlignment()
|
---|
794 | */
|
---|
795 |
|
---|
796 | /*!
|
---|
797 | \fn void Q3TextEdit::cursorPositionChanged(Q3TextCursor *c)
|
---|
798 |
|
---|
799 | \internal
|
---|
800 | */
|
---|
801 |
|
---|
802 | /*!
|
---|
803 | \fn void Q3TextEdit::cursorPositionChanged(int para, int pos)
|
---|
804 |
|
---|
805 | \overload
|
---|
806 |
|
---|
807 | This signal is emitted if the position of the cursor has changed.
|
---|
808 | \a para contains the paragraph index and \a pos contains the
|
---|
809 | character position within the paragraph.
|
---|
810 |
|
---|
811 | \sa setCursorPosition()
|
---|
812 | */
|
---|
813 |
|
---|
814 | /*!
|
---|
815 | \fn void Q3TextEdit::clicked(int para, int pos)
|
---|
816 |
|
---|
817 | This signal is emitted when the mouse is clicked on the paragraph
|
---|
818 | \a para at character position \a pos.
|
---|
819 |
|
---|
820 | \sa doubleClicked()
|
---|
821 | */
|
---|
822 |
|
---|
823 | /*! \fn void Q3TextEdit::doubleClicked(int para, int pos)
|
---|
824 |
|
---|
825 | This signal is emitted when the mouse is double-clicked on the
|
---|
826 | paragraph \a para at character position \a pos.
|
---|
827 |
|
---|
828 | \sa clicked()
|
---|
829 | */
|
---|
830 |
|
---|
831 |
|
---|
832 | /*!
|
---|
833 | \fn void Q3TextEdit::returnPressed()
|
---|
834 |
|
---|
835 | This signal is emitted if the user pressed the Return or the Enter
|
---|
836 | key.
|
---|
837 | */
|
---|
838 |
|
---|
839 | /*!
|
---|
840 | \fn Q3TextCursor *Q3TextEdit::textCursor() const
|
---|
841 |
|
---|
842 | Returns the text edit's text cursor.
|
---|
843 |
|
---|
844 | \warning Q3TextCursor is not in the public API, but in special
|
---|
845 | circumstances you might wish to use it.
|
---|
846 | */
|
---|
847 |
|
---|
848 | /*!
|
---|
849 | Constructs an empty Q3TextEdit called \a name, with parent \a
|
---|
850 | parent.
|
---|
851 | */
|
---|
852 |
|
---|
853 | Q3TextEdit::Q3TextEdit(QWidget *parent, const char *name)
|
---|
854 | : Q3ScrollView(parent, name, Qt::WStaticContents | Qt::WNoAutoErase),
|
---|
855 | doc(new Q3TextDocument(0)), undoRedoInfo(doc)
|
---|
856 | {
|
---|
857 | init();
|
---|
858 | }
|
---|
859 |
|
---|
860 | /*!
|
---|
861 | Constructs a Q3TextEdit called \a name, with parent \a parent. The
|
---|
862 | text edit will display the text \a text using context \a context.
|
---|
863 |
|
---|
864 | The \a context is a path which the text edit's Q3MimeSourceFactory
|
---|
865 | uses to resolve the locations of files and images. It is passed to
|
---|
866 | the mimeSourceFactory() when quering data.
|
---|
867 |
|
---|
868 | For example if the text contains an image tag,
|
---|
869 | \c{<img src="image.png">}, and the context is "path/to/look/in", the
|
---|
870 | Q3MimeSourceFactory will try to load the image from
|
---|
871 | "path/to/look/in/image.png". If the tag was
|
---|
872 | \c{<img src="/image.png">}, the context will not be used (because
|
---|
873 | Q3MimeSourceFactory recognizes that we have used an absolute path)
|
---|
874 | and will try to load "/image.png". The context is applied in exactly
|
---|
875 | the same way to \e hrefs, for example,
|
---|
876 | \c{<a href="target.html">Target</a>}, would resolve to
|
---|
877 | "path/to/look/in/target.html".
|
---|
878 | */
|
---|
879 |
|
---|
880 | Q3TextEdit::Q3TextEdit(const QString& text, const QString& context,
|
---|
881 | QWidget *parent, const char *name)
|
---|
882 | : Q3ScrollView(parent, name, Qt::WStaticContents | Qt::WNoAutoErase),
|
---|
883 | doc(new Q3TextDocument(0)), undoRedoInfo(doc)
|
---|
884 | {
|
---|
885 | init();
|
---|
886 | setText(text, context);
|
---|
887 | }
|
---|
888 |
|
---|
889 | /*!
|
---|
890 | Destructor.
|
---|
891 | */
|
---|
892 |
|
---|
893 | Q3TextEdit::~Q3TextEdit()
|
---|
894 | {
|
---|
895 | delete undoRedoInfo.d;
|
---|
896 | undoRedoInfo.d = 0;
|
---|
897 | delete cursor;
|
---|
898 | delete doc;
|
---|
899 | #ifdef QT_TEXTEDIT_OPTIMIZATION
|
---|
900 | delete d->od;
|
---|
901 | #endif
|
---|
902 | delete d;
|
---|
903 | }
|
---|
904 |
|
---|
905 | void Q3TextEdit::init()
|
---|
906 | {
|
---|
907 | d = new Q3TextEditPrivate;
|
---|
908 | doc->formatCollection()->setPaintDevice(this);
|
---|
909 | undoEnabled = true;
|
---|
910 | readonly = true;
|
---|
911 | setReadOnly(false);
|
---|
912 | setFrameStyle(LineEditPanel | Sunken);
|
---|
913 | connect(doc, SIGNAL(minimumWidthChanged(int)),
|
---|
914 | this, SLOT(documentWidthChanged(int)));
|
---|
915 |
|
---|
916 | mousePressed = false;
|
---|
917 | inDoubleClick = false;
|
---|
918 | modified = false;
|
---|
919 | mightStartDrag = false;
|
---|
920 | onLink.clear();
|
---|
921 | d->onName.clear();
|
---|
922 | overWrite = false;
|
---|
923 | wrapMode = WidgetWidth;
|
---|
924 | wrapWidth = -1;
|
---|
925 | wPolicy = AtWhiteSpace;
|
---|
926 | inDnD = false;
|
---|
927 | doc->setFormatter(new Q3TextFormatterBreakWords);
|
---|
928 | QFont f = Q3ScrollView::font();
|
---|
929 | if (f.kerning())
|
---|
930 | f.setKerning(false);
|
---|
931 | doc->formatCollection()->defaultFormat()->setFont(f);
|
---|
932 | doc->formatCollection()->defaultFormat()->setColor(palette().color(QPalette::Text));
|
---|
933 | currentFormat = doc->formatCollection()->defaultFormat();
|
---|
934 | currentAlignment = Qt::AlignAuto;
|
---|
935 |
|
---|
936 | setBackgroundRole(QPalette::Base);
|
---|
937 | viewport()->setBackgroundRole(QPalette::Base);
|
---|
938 |
|
---|
939 | viewport()->setAcceptDrops(true);
|
---|
940 | resizeContents(0, doc->lastParagraph() ?
|
---|
941 | (doc->lastParagraph()->paragId() + 1) * doc->formatCollection()->defaultFormat()->height() : 0);
|
---|
942 |
|
---|
943 | setAttribute(Qt::WA_KeyCompression, true);
|
---|
944 | viewport()->setMouseTracking(true);
|
---|
945 | #ifndef QT_NO_CURSOR
|
---|
946 | viewport()->setCursor(isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor);
|
---|
947 | #endif
|
---|
948 | cursor = new Q3TextCursor(doc);
|
---|
949 |
|
---|
950 | formatTimer = new QTimer(this);
|
---|
951 | connect(formatTimer, SIGNAL(timeout()),
|
---|
952 | this, SLOT(formatMore()));
|
---|
953 | lastFormatted = doc->firstParagraph();
|
---|
954 |
|
---|
955 | scrollTimer = new QTimer(this);
|
---|
956 | connect(scrollTimer, SIGNAL(timeout()),
|
---|
957 | this, SLOT(autoScrollTimerDone()));
|
---|
958 |
|
---|
959 | interval = 0;
|
---|
960 | changeIntervalTimer = new QTimer(this);
|
---|
961 | connect(changeIntervalTimer, SIGNAL(timeout()),
|
---|
962 | this, SLOT(doChangeInterval()));
|
---|
963 |
|
---|
964 | cursorVisible = true;
|
---|
965 | blinkTimer = new QTimer(this);
|
---|
966 | connect(blinkTimer, SIGNAL(timeout()),
|
---|
967 | this, SLOT(blinkCursor()));
|
---|
968 |
|
---|
969 | #ifndef QT_NO_DRAGANDDROP
|
---|
970 | dragStartTimer = new QTimer(this);
|
---|
971 | connect(dragStartTimer, SIGNAL(timeout()),
|
---|
972 | this, SLOT(startDrag()));
|
---|
973 | #endif
|
---|
974 |
|
---|
|
---|