src/gui/widgets/qtextedit.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qtextedit_p.h"
       
    43 #include "qlineedit.h"
       
    44 #include "qtextbrowser.h"
       
    45 
       
    46 #ifndef QT_NO_TEXTEDIT
       
    47 #include <qfont.h>
       
    48 #include <qpainter.h>
       
    49 #include <qevent.h>
       
    50 #include <qdebug.h>
       
    51 #include <qmime.h>
       
    52 #include <qdrag.h>
       
    53 #include <qclipboard.h>
       
    54 #include <qmenu.h>
       
    55 #include <qstyle.h>
       
    56 #include <qtimer.h>
       
    57 #include "private/qtextdocumentlayout_p.h"
       
    58 #include "qtextdocument.h"
       
    59 #include "private/qtextdocument_p.h"
       
    60 #include "qtextlist.h"
       
    61 #include "private/qtextcontrol_p.h"
       
    62 
       
    63 #include <qtextformat.h>
       
    64 #include <qdatetime.h>
       
    65 #include <qapplication.h>
       
    66 #include <limits.h>
       
    67 #include <qtexttable.h>
       
    68 #include <qvariant.h>
       
    69 
       
    70 #include <qinputcontext.h>
       
    71 #endif
       
    72 
       
    73 QT_BEGIN_NAMESPACE
       
    74 
       
    75 
       
    76 #ifndef QT_NO_TEXTEDIT
       
    77 static inline bool shouldEnableInputMethod(QTextEdit *textedit)
       
    78 {
       
    79     return !textedit->isReadOnly();
       
    80 }
       
    81 
       
    82 class QTextEditControl : public QTextControl
       
    83 {
       
    84 public:
       
    85     inline QTextEditControl(QObject *parent) : QTextControl(parent) {}
       
    86 
       
    87     virtual QMimeData *createMimeDataFromSelection() const {
       
    88         QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
       
    89         if (!ed)
       
    90             return QTextControl::createMimeDataFromSelection();
       
    91         return ed->createMimeDataFromSelection();
       
    92     }
       
    93     virtual bool canInsertFromMimeData(const QMimeData *source) const {
       
    94         QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
       
    95         if (!ed)
       
    96             return QTextControl::canInsertFromMimeData(source);
       
    97         return ed->canInsertFromMimeData(source);
       
    98     }
       
    99     virtual void insertFromMimeData(const QMimeData *source) {
       
   100         QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
       
   101         if (!ed)
       
   102             QTextControl::insertFromMimeData(source);
       
   103         else
       
   104             ed->insertFromMimeData(source);
       
   105     }
       
   106 };
       
   107 
       
   108 QTextEditPrivate::QTextEditPrivate()
       
   109     : control(0),
       
   110       autoFormatting(QTextEdit::AutoNone), tabChangesFocus(false),
       
   111       lineWrap(QTextEdit::WidgetWidth), lineWrapColumnOrWidth(0),
       
   112       wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0),
       
   113       textFormat(Qt::AutoText)
       
   114 {
       
   115     ignoreAutomaticScrollbarAdjustment = false;
       
   116     preferRichText = false;
       
   117     showCursorOnInitialShow = true;
       
   118     inDrag = false;
       
   119 #ifdef Q_WS_WIN
       
   120     setSingleFingerPanEnabled(true);
       
   121 #endif
       
   122 }
       
   123 
       
   124 void QTextEditPrivate::createAutoBulletList()
       
   125 {
       
   126     QTextCursor cursor = control->textCursor();
       
   127     cursor.beginEditBlock();
       
   128 
       
   129     QTextBlockFormat blockFmt = cursor.blockFormat();
       
   130 
       
   131     QTextListFormat listFmt;
       
   132     listFmt.setStyle(QTextListFormat::ListDisc);
       
   133     listFmt.setIndent(blockFmt.indent() + 1);
       
   134 
       
   135     blockFmt.setIndent(0);
       
   136     cursor.setBlockFormat(blockFmt);
       
   137 
       
   138     cursor.createList(listFmt);
       
   139 
       
   140     cursor.endEditBlock();
       
   141     control->setTextCursor(cursor);
       
   142 }
       
   143 
       
   144 void QTextEditPrivate::init(const QString &html)
       
   145 {
       
   146     Q_Q(QTextEdit);
       
   147     control = new QTextEditControl(q);
       
   148     control->setPalette(q->palette());
       
   149 
       
   150     QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
       
   151     QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
       
   152     QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
       
   153     QObject::connect(control, SIGNAL(visibilityRequest(QRectF)), q, SLOT(_q_ensureVisible(QRectF)));
       
   154     QObject::connect(control, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
       
   155                      q, SLOT(_q_currentCharFormatChanged(QTextCharFormat)));
       
   156 
       
   157     QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
       
   158     QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
       
   159     QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
       
   160     QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
       
   161     QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
       
   162     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
       
   163 
       
   164     QTextDocument *doc = control->document();
       
   165     // set a null page size initially to avoid any relayouting until the textedit
       
   166     // is shown. relayoutDocument() will take care of setting the page size to the
       
   167     // viewport dimensions later.
       
   168     doc->setPageSize(QSize(0, 0));
       
   169     doc->documentLayout()->setPaintDevice(viewport);
       
   170     doc->setDefaultFont(q->font());
       
   171     doc->setUndoRedoEnabled(false); // flush undo buffer.
       
   172     doc->setUndoRedoEnabled(true);
       
   173 
       
   174     if (!html.isEmpty())
       
   175         control->setHtml(html);
       
   176 
       
   177     hbar->setSingleStep(20);
       
   178     vbar->setSingleStep(20);
       
   179 
       
   180     viewport->setBackgroundRole(QPalette::Base);
       
   181     q->setAcceptDrops(true);
       
   182     q->setFocusPolicy(Qt::WheelFocus);
       
   183     q->setAttribute(Qt::WA_KeyCompression);
       
   184     q->setAttribute(Qt::WA_InputMethodEnabled);
       
   185 
       
   186 #ifndef QT_NO_CURSOR
       
   187     viewport->setCursor(Qt::IBeamCursor);
       
   188 #endif
       
   189 }
       
   190 
       
   191 void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
       
   192 {
       
   193     if (!contentsRect.isValid()) {
       
   194         viewport->update();
       
   195         return;
       
   196     }
       
   197     const int xOffset = horizontalOffset();
       
   198     const int yOffset = verticalOffset();
       
   199     const QRectF visibleRect(xOffset, yOffset, viewport->width(), viewport->height());
       
   200 
       
   201     QRect r = contentsRect.intersected(visibleRect).toAlignedRect();
       
   202     if (r.isEmpty())
       
   203         return;
       
   204 
       
   205     r.translate(-xOffset, -yOffset);
       
   206     viewport->update(r);
       
   207 }
       
   208 
       
   209 void QTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
       
   210 {
       
   211     QTextCursor cursor = control->textCursor();
       
   212     bool moved = false;
       
   213     qreal lastY = control->cursorRect(cursor).top();
       
   214     qreal distance = 0;
       
   215     // move using movePosition to keep the cursor's x
       
   216     do {
       
   217         qreal y = control->cursorRect(cursor).top();
       
   218         distance += qAbs(y - lastY);
       
   219         lastY = y;
       
   220         moved = cursor.movePosition(op, moveMode);
       
   221     } while (moved && distance < viewport->height());
       
   222 
       
   223     if (moved) {
       
   224         if (op == QTextCursor::Up) {
       
   225             cursor.movePosition(QTextCursor::Down, moveMode);
       
   226             vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
       
   227         } else {
       
   228             cursor.movePosition(QTextCursor::Up, moveMode);
       
   229             vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
       
   230         }
       
   231     }
       
   232     control->setTextCursor(cursor);
       
   233 }
       
   234 
       
   235 #ifndef QT_NO_SCROLLBAR
       
   236 static QSize documentSize(QTextControl *control)
       
   237 {
       
   238     QTextDocument *doc = control->document();
       
   239     QAbstractTextDocumentLayout *layout = doc->documentLayout();
       
   240 
       
   241     QSize docSize;
       
   242 
       
   243     if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
       
   244         docSize = tlayout->dynamicDocumentSize().toSize();
       
   245         int percentageDone = tlayout->layoutStatus();
       
   246         // extrapolate height
       
   247         if (percentageDone > 0)
       
   248             docSize.setHeight(docSize.height() * 100 / percentageDone);
       
   249     } else {
       
   250         docSize = layout->documentSize().toSize();
       
   251     }
       
   252 
       
   253     return docSize;
       
   254 }
       
   255 
       
   256 void QTextEditPrivate::_q_adjustScrollbars()
       
   257 {
       
   258     if (ignoreAutomaticScrollbarAdjustment)
       
   259         return;
       
   260     ignoreAutomaticScrollbarAdjustment = true; // avoid recursion, #106108
       
   261 
       
   262     QSize viewportSize = viewport->size();
       
   263     QSize docSize = documentSize(control);
       
   264 
       
   265     // due to the recursion guard we have to repeat this step a few times,
       
   266     // as adding/removing a scroll bar will cause the document or viewport
       
   267     // size to change
       
   268     // ideally we should loop until the viewport size and doc size stabilize,
       
   269     // but in corner cases they might fluctuate, so we need to limit the
       
   270     // number of iterations
       
   271     for (int i = 0; i < 4; ++i) {
       
   272         hbar->setRange(0, docSize.width() - viewportSize.width());
       
   273         hbar->setPageStep(viewportSize.width());
       
   274 
       
   275         vbar->setRange(0, docSize.height() - viewportSize.height());
       
   276         vbar->setPageStep(viewportSize.height());
       
   277 
       
   278         // if we are in left-to-right mode widening the document due to
       
   279         // lazy layouting does not require a repaint. If in right-to-left
       
   280         // the scroll bar has the value zero and it visually has the maximum
       
   281         // value (it is visually at the right), then widening the document
       
   282         // keeps it at value zero but visually adjusts it to the new maximum
       
   283         // on the right, hence we need an update.
       
   284         if (q_func()->isRightToLeft())
       
   285             viewport->update();
       
   286 
       
   287         _q_showOrHideScrollBars();
       
   288 
       
   289         const QSize oldViewportSize = viewportSize;
       
   290         const QSize oldDocSize = docSize;
       
   291 
       
   292         // make sure the document is layouted if the viewport width changes
       
   293         viewportSize = viewport->size();
       
   294         if (viewportSize.width() != oldViewportSize.width())
       
   295             relayoutDocument();
       
   296 
       
   297         docSize = documentSize(control);
       
   298         if (viewportSize == oldViewportSize && docSize == oldDocSize)
       
   299             break;
       
   300     }
       
   301     ignoreAutomaticScrollbarAdjustment = false;
       
   302 }
       
   303 #endif
       
   304 
       
   305 // rect is in content coordinates
       
   306 void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
       
   307 {
       
   308     const QRect rect = _rect.toRect();
       
   309     if ((vbar->isVisible() && vbar->maximum() < rect.bottom())
       
   310         || (hbar->isVisible() && hbar->maximum() < rect.right()))
       
   311         _q_adjustScrollbars();
       
   312     const int visibleWidth = viewport->width();
       
   313     const int visibleHeight = viewport->height();
       
   314     const bool rtl = q_func()->isRightToLeft();
       
   315 
       
   316     if (rect.x() < horizontalOffset()) {
       
   317         if (rtl)
       
   318             hbar->setValue(hbar->maximum() - rect.x());
       
   319         else
       
   320             hbar->setValue(rect.x());
       
   321     } else if (rect.x() + rect.width() > horizontalOffset() + visibleWidth) {
       
   322         if (rtl)
       
   323             hbar->setValue(hbar->maximum() - (rect.x() + rect.width() - visibleWidth));
       
   324         else
       
   325             hbar->setValue(rect.x() + rect.width() - visibleWidth);
       
   326     }
       
   327 
       
   328     if (rect.y() < verticalOffset())
       
   329         vbar->setValue(rect.y());
       
   330     else if (rect.y() + rect.height() > verticalOffset() + visibleHeight)
       
   331         vbar->setValue(rect.y() + rect.height() - visibleHeight);
       
   332 }
       
   333 
       
   334 /*!
       
   335     \class QTextEdit
       
   336     \brief The QTextEdit class provides a widget that is used to edit and display
       
   337     both plain and rich text.
       
   338 
       
   339     \ingroup richtext-processing
       
   340 
       
   341 
       
   342     \tableofcontents
       
   343 
       
   344     \section1 Introduction and Concepts
       
   345 
       
   346     QTextEdit is an advanced WYSIWYG viewer/editor supporting rich
       
   347     text formatting using HTML-style tags. It is optimized to handle
       
   348     large documents and to respond quickly to user input.
       
   349 
       
   350     QTextEdit works on paragraphs and characters. A paragraph is a
       
   351     formatted string which is word-wrapped to fit into the width of
       
   352     the widget. By default when reading plain text, one newline
       
   353     signifies a paragraph. A document consists of zero or more
       
   354     paragraphs. The words in the paragraph are aligned in accordance
       
   355     with the paragraph's alignment. Paragraphs are separated by hard
       
   356     line breaks. Each character within a paragraph has its own
       
   357     attributes, for example, font and color.
       
   358 
       
   359     QTextEdit can display images, lists and tables. If the text is
       
   360     too large to view within the text edit's viewport, scroll bars will
       
   361     appear. The text edit can load both plain text and HTML files (a
       
   362     subset of HTML 3.2 and 4).
       
   363 
       
   364     If you just need to display a small piece of rich text use QLabel.
       
   365 
       
   366     The rich text support in Qt is designed to provide a fast, portable and
       
   367     efficient way to add reasonable online help facilities to
       
   368     applications, and to provide a basis for rich text editors. If
       
   369     you find the HTML support insufficient for your needs you may consider
       
   370     the use of QtWebKit, which provides a full-featured web browser
       
   371     widget.
       
   372 
       
   373     The shape of the mouse cursor on a QTextEdit is Qt::IBeamCursor by default.
       
   374     It can be changed through the viewport()'s cursor property.
       
   375 
       
   376     \section1 Using QTextEdit as a Display Widget
       
   377 
       
   378     QTextEdit can display a large HTML subset, including tables and
       
   379     images.
       
   380 
       
   381     The text is set or replaced using setHtml() which deletes any
       
   382     existing text and replaces it with the text passed in the
       
   383     setHtml() call. If you call setHtml() with legacy HTML, and then
       
   384     call toHtml(), the text that is returned may have different markup,
       
   385     but will render the same. The entire text can be deleted with clear().
       
   386 
       
   387     Text itself can be inserted using the QTextCursor class or using the
       
   388     convenience functions insertHtml(), insertPlainText(), append() or
       
   389     paste(). QTextCursor is also able to insert complex objects like tables
       
   390     or lists into the document, and it deals with creating selections
       
   391     and applying changes to selected text.
       
   392 
       
   393     By default the text edit wraps words at whitespace to fit within
       
   394     the text edit widget. The setLineWrapMode() function is used to
       
   395     specify the kind of line wrap you want, or \l NoWrap if you don't
       
   396     want any wrapping. Call setLineWrapMode() to set a fixed pixel width
       
   397     \l FixedPixelWidth, or character column (e.g. 80 column) \l
       
   398     FixedColumnWidth with the pixels or columns specified with
       
   399     setLineWrapColumnOrWidth(). If you use word wrap to the widget's width
       
   400     \l WidgetWidth, you can specify whether to break on whitespace or
       
   401     anywhere with setWordWrapMode().
       
   402 
       
   403     The find() function can be used to find and select a given string
       
   404     within the text.
       
   405 
       
   406     If you want to limit the total number of paragraphs in a QTextEdit,
       
   407     as it is for example open useful in a log viewer, then you can use
       
   408     QTextDocument's maximumBlockCount property for that.
       
   409 
       
   410     \section2 Read-only Key Bindings
       
   411 
       
   412     When QTextEdit is used read-only the key bindings are limited to
       
   413     navigation, and text may only be selected with the mouse:
       
   414     \table
       
   415     \header \i Keypresses \i Action
       
   416     \row \i Up        \i Moves one line up.
       
   417     \row \i Down        \i Moves one line down.
       
   418     \row \i Left        \i Moves one character to the left.
       
   419     \row \i Right        \i Moves one character to the right.
       
   420     \row \i PageUp        \i Moves one (viewport) page up.
       
   421     \row \i PageDown        \i Moves one (viewport) page down.
       
   422     \row \i Home        \i Moves to the beginning of the text.
       
   423     \row \i End                \i Moves to the end of the text.
       
   424     \row \i Alt+Wheel
       
   425          \i Scrolls the page horizontally (the Wheel is the mouse wheel).
       
   426     \row \i Ctrl+Wheel        \i Zooms the text.
       
   427     \row \i Ctrl+A            \i Selects all text.
       
   428     \endtable
       
   429 
       
   430     The text edit may be able to provide some meta-information. For
       
   431     example, the documentTitle() function will return the text from
       
   432     within HTML \c{<title>} tags.
       
   433 
       
   434     \section1 Using QTextEdit as an Editor
       
   435 
       
   436     All the information about using QTextEdit as a display widget also
       
   437     applies here.
       
   438 
       
   439     The current char format's attributes are set with setFontItalic(),
       
   440     setFontWeight(), setFontUnderline(), setFontFamily(),
       
   441     setFontPointSize(), setTextColor() and setCurrentFont(). The current
       
   442     paragraph's alignment is set with setAlignment().
       
   443 
       
   444     Selection of text is handled by the QTextCursor class, which provides
       
   445     functionality for creating selections, retrieving the text contents or
       
   446     deleting selections. You can retrieve the object that corresponds with
       
   447     the user-visible cursor using the textCursor() method. If you want to set
       
   448     a selection in QTextEdit just create one on a QTextCursor object and
       
   449     then make that cursor the visible cursor using setTextCursor(). The selection
       
   450     can be copied to the clipboard with copy(), or cut to the clipboard with
       
   451     cut(). The entire text can be selected using selectAll().
       
   452 
       
   453     When the cursor is moved and the underlying formatting attributes change,
       
   454     the currentCharFormatChanged() signal is emitted to reflect the new attributes
       
   455     at the new cursor position.
       
   456 
       
   457     QTextEdit holds a QTextDocument object which can be retrieved using the
       
   458     document() method. You can also set your own document object using setDocument().
       
   459     QTextDocument emits a textChanged() signal if the text changes and it also
       
   460     provides a isModified() function which will return true if the text has been
       
   461     modified since it was either loaded or since the last call to setModified
       
   462     with false as argument. In addition it provides methods for undo and redo.
       
   463 
       
   464     \section2 Drag and Drop
       
   465 
       
   466     QTextEdit also supports custom drag and drop behavior. By default,
       
   467     QTextEdit will insert plain text, HTML and rich text when the user drops
       
   468     data of these MIME types onto a document. Reimplement
       
   469     canInsertFromMimeData() and insertFromMimeData() to add support for
       
   470     additional MIME types.
       
   471 
       
   472     For example, to allow the user to drag and drop an image onto a QTextEdit,
       
   473     you could the implement these functions in the following way:
       
   474 
       
   475     \snippet doc/src/snippets/textdocument-imagedrop/textedit.cpp 0
       
   476 
       
   477     We add support for image MIME types by returning true. For all other
       
   478     MIME types, we use the default implementation.
       
   479 
       
   480     \snippet doc/src/snippets/textdocument-imagedrop/textedit.cpp 1
       
   481 
       
   482     We unpack the image from the QVariant held by the MIME source and insert
       
   483     it into the document as a resource.
       
   484 
       
   485     \section2 Editing Key Bindings
       
   486 
       
   487     The list of key bindings which are implemented for editing:
       
   488     \table
       
   489     \header \i Keypresses \i Action
       
   490     \row \i Backspace \i Deletes the character to the left of the cursor.
       
   491     \row \i Delete \i Deletes the character to the right of the cursor.
       
   492     \row \i Ctrl+C \i Copy the selected text to the clipboard.
       
   493     \row \i Ctrl+Insert \i Copy the selected text to the clipboard.
       
   494     \row \i Ctrl+K \i Deletes to the end of the line.
       
   495     \row \i Ctrl+V \i Pastes the clipboard text into text edit.
       
   496     \row \i Shift+Insert \i Pastes the clipboard text into text edit.
       
   497     \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
       
   498     \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
       
   499     \row \i Ctrl+Z \i Undoes the last operation.
       
   500     \row \i Ctrl+Y \i Redoes the last operation.
       
   501     \row \i Left \i Moves the cursor one character to the left.
       
   502     \row \i Ctrl+Left \i Moves the cursor one word to the left.
       
   503     \row \i Right \i Moves the cursor one character to the right.
       
   504     \row \i Ctrl+Right \i Moves the cursor one word to the right.
       
   505     \row \i Up \i Moves the cursor one line up.
       
   506     \row \i Down \i Moves the cursor one line down.
       
   507     \row \i PageUp \i Moves the cursor one page up.
       
   508     \row \i PageDown \i Moves the cursor one page down.
       
   509     \row \i Home \i Moves the cursor to the beginning of the line.
       
   510     \row \i Ctrl+Home \i Moves the cursor to the beginning of the text.
       
   511     \row \i End \i Moves the cursor to the end of the line.
       
   512     \row \i Ctrl+End \i Moves the cursor to the end of the text.
       
   513     \row \i Alt+Wheel \i Scrolls the page horizontally (the Wheel is the mouse wheel).
       
   514     \endtable
       
   515 
       
   516     To select (mark) text hold down the Shift key whilst pressing one
       
   517     of the movement keystrokes, for example, \e{Shift+Right}
       
   518     will select the character to the right, and \e{Shift+Ctrl+Right} will select the word to the right, etc.
       
   519 
       
   520     \sa QTextDocument, QTextCursor, {Application Example},
       
   521         {Syntax Highlighter Example}, {Rich Text Processing}
       
   522 */
       
   523 
       
   524 /*!
       
   525     \property QTextEdit::plainText
       
   526     \since 4.3
       
   527 
       
   528     This property gets and sets the text editor's contents as plain
       
   529     text. Previous contents are removed and undo/redo history is reset
       
   530     when the property is set.
       
   531 
       
   532     If the text edit has another content type, it will not be replaced
       
   533     by plain text if you call toPlainText().
       
   534 
       
   535     By default, for an editor with no contents, this property contains
       
   536     an empty string.
       
   537 
       
   538     \sa html
       
   539 */
       
   540 
       
   541 /*!
       
   542     \property QTextEdit::undoRedoEnabled
       
   543     \brief whether undo and redo are enabled
       
   544 
       
   545     Users are only able to undo or redo actions if this property is
       
   546     true, and if there is an action that can be undone (or redone).
       
   547 */
       
   548 
       
   549 /*!
       
   550     \enum QTextEdit::LineWrapMode
       
   551 
       
   552     \value NoWrap
       
   553     \value WidgetWidth
       
   554     \value FixedPixelWidth
       
   555     \value FixedColumnWidth
       
   556 */
       
   557 
       
   558 /*!
       
   559     \enum QTextEdit::AutoFormattingFlag
       
   560 
       
   561     \value AutoNone Don't do any automatic formatting.
       
   562     \value AutoBulletList Automatically create bullet lists (e.g. when
       
   563     the user enters an asterisk ('*') in the left most column, or
       
   564     presses Enter in an existing list item.
       
   565     \value AutoAll Apply all automatic formatting. Currently only
       
   566     automatic bullet lists are supported.
       
   567 */
       
   568 
       
   569 #ifdef QT3_SUPPORT
       
   570 /*!
       
   571     \enum QTextEdit::CursorAction
       
   572     \compat
       
   573 
       
   574     \value MoveBackward
       
   575     \value MoveForward
       
   576     \value MoveWordBackward
       
   577     \value MoveWordForward
       
   578     \value MoveUp
       
   579     \value MoveDown
       
   580     \value MoveLineStart
       
   581     \value MoveLineEnd
       
   582     \value MoveHome
       
   583     \value MoveEnd
       
   584     \value MovePageUp
       
   585     \value MovePageDown
       
   586 
       
   587     \omitvalue MovePgUp
       
   588     \omitvalue MovePgDown
       
   589 */
       
   590 #endif
       
   591 
       
   592 /*!
       
   593     Constructs an empty QTextEdit with parent \a
       
   594     parent.
       
   595 */
       
   596 QTextEdit::QTextEdit(QWidget *parent)
       
   597     : QAbstractScrollArea(*new QTextEditPrivate, parent)
       
   598 {
       
   599     Q_D(QTextEdit);
       
   600     d->init();
       
   601 }
       
   602 
       
   603 /*!
       
   604     \internal
       
   605 */
       
   606 QTextEdit::QTextEdit(QTextEditPrivate &dd, QWidget *parent)
       
   607     : QAbstractScrollArea(dd, parent)
       
   608 {
       
   609     Q_D(QTextEdit);
       
   610     d->init();
       
   611 }
       
   612 
       
   613 /*!
       
   614     Constructs a QTextEdit with parent \a parent. The text edit will display
       
   615     the text \a text. The text is interpreted as html.
       
   616 */
       
   617 QTextEdit::QTextEdit(const QString &text, QWidget *parent)
       
   618     : QAbstractScrollArea(*new QTextEditPrivate, parent)
       
   619 {
       
   620     Q_D(QTextEdit);
       
   621     d->init(text);
       
   622 }
       
   623 
       
   624 #ifdef QT3_SUPPORT
       
   625 /*!
       
   626     Use one of the constructors that doesn't take the \a name
       
   627     argument and then use setObjectName() instead.
       
   628 */
       
   629 QTextEdit::QTextEdit(QWidget *parent, const char *name)
       
   630     : QAbstractScrollArea(*new QTextEditPrivate, parent)
       
   631 {
       
   632     Q_D(QTextEdit);
       
   633     d->init();
       
   634     setObjectName(QString::fromAscii(name));
       
   635 }
       
   636 #endif
       
   637 
       
   638 
       
   639 /*!
       
   640     Destructor.
       
   641 */
       
   642 QTextEdit::~QTextEdit()
       
   643 {
       
   644 }
       
   645 
       
   646 /*!
       
   647     Returns the point size of the font of the current format.
       
   648 
       
   649     \sa setFontFamily() setCurrentFont() setFontPointSize()
       
   650 */
       
   651 qreal QTextEdit::fontPointSize() const
       
   652 {
       
   653     Q_D(const QTextEdit);
       
   654     return d->control->textCursor().charFormat().fontPointSize();
       
   655 }
       
   656 
       
   657 /*!
       
   658     Returns the font family of the current format.
       
   659 
       
   660     \sa setFontFamily() setCurrentFont() setFontPointSize()
       
   661 */
       
   662 QString QTextEdit::fontFamily() const
       
   663 {
       
   664     Q_D(const QTextEdit);
       
   665     return d->control->textCursor().charFormat().fontFamily();
       
   666 }
       
   667 
       
   668 /*!
       
   669     Returns the font weight of the current format.
       
   670 
       
   671     \sa setFontWeight() setCurrentFont() setFontPointSize() QFont::Weight
       
   672 */
       
   673 int QTextEdit::fontWeight() const
       
   674 {
       
   675     Q_D(const QTextEdit);
       
   676     return d->control->textCursor().charFormat().fontWeight();
       
   677 }
       
   678 
       
   679 /*!
       
   680     Returns true if the font of the current format is underlined; otherwise returns
       
   681     false.
       
   682 
       
   683     \sa setFontUnderline()
       
   684 */
       
   685 bool QTextEdit::fontUnderline() const
       
   686 {
       
   687     Q_D(const QTextEdit);
       
   688     return d->control->textCursor().charFormat().fontUnderline();
       
   689 }
       
   690 
       
   691 /*!
       
   692     Returns true if the font of the current format is italic; otherwise returns
       
   693     false.
       
   694 
       
   695     \sa setFontItalic()
       
   696 */
       
   697 bool QTextEdit::fontItalic() const
       
   698 {
       
   699     Q_D(const QTextEdit);
       
   700     return d->control->textCursor().charFormat().fontItalic();
       
   701 }
       
   702 
       
   703 /*!
       
   704     Returns the text color of the current format.
       
   705 
       
   706     \sa setTextColor()
       
   707 */
       
   708 QColor QTextEdit::textColor() const
       
   709 {
       
   710     Q_D(const QTextEdit);
       
   711     return d->control->textCursor().charFormat().foreground().color();
       
   712 }
       
   713 
       
   714 /*!
       
   715     \since 4.4
       
   716 
       
   717     Returns the text background color of the current format.
       
   718 
       
   719     \sa setTextBackgroundColor()
       
   720 */
       
   721 QColor QTextEdit::textBackgroundColor() const
       
   722 {
       
   723     Q_D(const QTextEdit);
       
   724     return d->control->textCursor().charFormat().background().color();
       
   725 }
       
   726 
       
   727 /*!
       
   728     Returns the font of the current format.
       
   729 
       
   730     \sa setCurrentFont() setFontFamily() setFontPointSize()
       
   731 */
       
   732 QFont QTextEdit::currentFont() const
       
   733 {
       
   734     Q_D(const QTextEdit);
       
   735     return d->control->textCursor().charFormat().font();
       
   736 }
       
   737 
       
   738 /*!
       
   739     Sets the alignment of the current paragraph to \a a. Valid
       
   740     alignments are Qt::AlignLeft, Qt::AlignRight,
       
   741     Qt::AlignJustify and Qt::AlignCenter (which centers
       
   742     horizontally).
       
   743 */
       
   744 void QTextEdit::setAlignment(Qt::Alignment a)
       
   745 {
       
   746     Q_D(QTextEdit);
       
   747     QTextBlockFormat fmt;
       
   748     fmt.setAlignment(a);
       
   749     QTextCursor cursor = d->control->textCursor();
       
   750     cursor.mergeBlockFormat(fmt);
       
   751     d->control->setTextCursor(cursor);
       
   752 }
       
   753 
       
   754 /*!
       
   755     Returns the alignment of the current paragraph.
       
   756 
       
   757     \sa setAlignment()
       
   758 */
       
   759 Qt::Alignment QTextEdit::alignment() const
       
   760 {
       
   761     Q_D(const QTextEdit);
       
   762     return d->control->textCursor().blockFormat().alignment();
       
   763 }
       
   764 
       
   765 /*!
       
   766     Makes \a document the new document of the text editor.
       
   767 
       
   768     \note The editor \e{does not take ownership of the document} unless it
       
   769     is the document's parent object. The parent object of the provided document
       
   770     remains the owner of the object.
       
   771 
       
   772     If the current document is a child of the text editor, then it is deleted.
       
   773 
       
   774     \sa document()
       
   775 */
       
   776 void QTextEdit::setDocument(QTextDocument *document)
       
   777 {
       
   778     Q_D(QTextEdit);
       
   779     d->control->setDocument(document);
       
   780     d->updateDefaultTextOption();
       
   781     d->relayoutDocument();
       
   782 }
       
   783 
       
   784 /*!
       
   785     Returns a pointer to the underlying document.
       
   786 
       
   787     \sa setDocument()
       
   788 */
       
   789 QTextDocument *QTextEdit::document() const
       
   790 {
       
   791     Q_D(const QTextEdit);
       
   792     return d->control->document();
       
   793 }
       
   794 
       
   795 /*!
       
   796     Sets the visible \a cursor.
       
   797 */
       
   798 void QTextEdit::setTextCursor(const QTextCursor &cursor)
       
   799 {
       
   800     Q_D(QTextEdit);
       
   801     d->control->setTextCursor(cursor);
       
   802 }
       
   803 
       
   804 /*!
       
   805     Returns a copy of the QTextCursor that represents the currently visible cursor.
       
   806     Note that changes on the returned cursor do not affect QTextEdit's cursor; use
       
   807     setTextCursor() to update the visible cursor.
       
   808  */
       
   809 QTextCursor QTextEdit::textCursor() const
       
   810 {
       
   811     Q_D(const QTextEdit);
       
   812     return d->control->textCursor();
       
   813 }
       
   814 
       
   815 /*!
       
   816     Sets the font family of the current format to \a fontFamily.
       
   817 
       
   818     \sa fontFamily() setCurrentFont()
       
   819 */
       
   820 void QTextEdit::setFontFamily(const QString &fontFamily)
       
   821 {
       
   822     QTextCharFormat fmt;
       
   823     fmt.setFontFamily(fontFamily);
       
   824     mergeCurrentCharFormat(fmt);
       
   825 }
       
   826 
       
   827 /*!
       
   828     Sets the point size of the current format to \a s.
       
   829 
       
   830     Note that if \a s is zero or negative, the behavior of this
       
   831     function is not defined.
       
   832 
       
   833     \sa fontPointSize() setCurrentFont() setFontFamily()
       
   834 */
       
   835 void QTextEdit::setFontPointSize(qreal s)
       
   836 {
       
   837     QTextCharFormat fmt;
       
   838     fmt.setFontPointSize(s);
       
   839     mergeCurrentCharFormat(fmt);
       
   840 }
       
   841 
       
   842 /*!
       
   843     \fn void QTextEdit::setFontWeight(int weight)
       
   844 
       
   845     Sets the font weight of the current format to the given \a weight,
       
   846     where the value used is in the range defined by the QFont::Weight
       
   847     enum.
       
   848 
       
   849     \sa fontWeight(), setCurrentFont(), setFontFamily()
       
   850 */
       
   851 void QTextEdit::setFontWeight(int w)
       
   852 {
       
   853     QTextCharFormat fmt;
       
   854     fmt.setFontWeight(w);
       
   855     mergeCurrentCharFormat(fmt);
       
   856 }
       
   857 
       
   858 /*!
       
   859     If \a underline is true, sets the current format to underline;
       
   860     otherwise sets the current format to non-underline.
       
   861 
       
   862     \sa fontUnderline()
       
   863 */
       
   864 void QTextEdit::setFontUnderline(bool underline)
       
   865 {
       
   866     QTextCharFormat fmt;
       
   867     fmt.setFontUnderline(underline);
       
   868     mergeCurrentCharFormat(fmt);
       
   869 }
       
   870 
       
   871 /*!
       
   872     If \a italic is true, sets the current format to italic;
       
   873     otherwise sets the current format to non-italic.
       
   874 
       
   875     \sa fontItalic()
       
   876 */
       
   877 void QTextEdit::setFontItalic(bool italic)
       
   878 {
       
   879     QTextCharFormat fmt;
       
   880     fmt.setFontItalic(italic);
       
   881     mergeCurrentCharFormat(fmt);
       
   882 }
       
   883 
       
   884 /*!
       
   885     Sets the text color of the current format to \a c.
       
   886 
       
   887     \sa textColor()
       
   888 */
       
   889 void QTextEdit::setTextColor(const QColor &c)
       
   890 {
       
   891     QTextCharFormat fmt;
       
   892     fmt.setForeground(QBrush(c));
       
   893     mergeCurrentCharFormat(fmt);
       
   894 }
       
   895 
       
   896 /*!
       
   897     \since 4.4
       
   898 
       
   899     Sets the text background color of the current format to \a c.
       
   900 
       
   901     \sa textBackgroundColor()
       
   902 */
       
   903 void QTextEdit::setTextBackgroundColor(const QColor &c)
       
   904 {
       
   905     QTextCharFormat fmt;
       
   906     fmt.setBackground(QBrush(c));
       
   907     mergeCurrentCharFormat(fmt);
       
   908 }
       
   909 
       
   910 /*!
       
   911     Sets the font of the current format to \a f.
       
   912 
       
   913     \sa currentFont() setFontPointSize() setFontFamily()
       
   914 */
       
   915 void QTextEdit::setCurrentFont(const QFont &f)
       
   916 {
       
   917     QTextCharFormat fmt;
       
   918     fmt.setFont(f);
       
   919     mergeCurrentCharFormat(fmt);
       
   920 }
       
   921 
       
   922 /*!
       
   923     \since 4.2
       
   924 
       
   925     Undoes the last operation.
       
   926 
       
   927     If there is no operation to undo, i.e. there is no undo step in
       
   928     the undo/redo history, nothing happens.
       
   929 
       
   930     \sa redo()
       
   931 */
       
   932 void QTextEdit::undo()
       
   933 {
       
   934     Q_D(QTextEdit);
       
   935     d->control->undo();
       
   936 }
       
   937 
       
   938 void QTextEdit::redo()
       
   939 {
       
   940     Q_D(QTextEdit);
       
   941     d->control->redo();
       
   942 }
       
   943 
       
   944 /*!
       
   945     \fn void QTextEdit::undo() const
       
   946     \fn void QTextEdit::redo() const
       
   947     \overload
       
   948 
       
   949     Use the non-const overload instead.
       
   950 */
       
   951 
       
   952 /*!
       
   953     \fn void QTextEdit::redo()
       
   954     \since 4.2
       
   955 
       
   956     Redoes the last operation.
       
   957 
       
   958     If there is no operation to redo, i.e. there is no redo step in
       
   959     the undo/redo history, nothing happens.
       
   960 
       
   961     \sa undo()
       
   962 */
       
   963 
       
   964 #ifndef QT_NO_CLIPBOARD
       
   965 /*!
       
   966     Copies the selected text to the clipboard and deletes it from
       
   967     the text edit.
       
   968 
       
   969     If there is no selected text nothing happens.
       
   970 
       
   971     \sa copy() paste()
       
   972 */
       
   973 
       
   974 void QTextEdit::cut()
       
   975 {
       
   976     Q_D(QTextEdit);
       
   977     d->control->cut();
       
   978 }
       
   979 
       
   980 /*!
       
   981     Copies any selected text to the clipboard.
       
   982 
       
   983     \sa copyAvailable()
       
   984 */
       
   985 
       
   986 void QTextEdit::copy()
       
   987 {
       
   988     Q_D(QTextEdit);
       
   989     d->control->copy();
       
   990 }
       
   991 
       
   992 /*!
       
   993     Pastes the text from the clipboard into the text edit at the
       
   994     current cursor position.
       
   995 
       
   996     If there is no text in the clipboard nothing happens.
       
   997 
       
   998     To change the behavior of this function, i.e. to modify what
       
   999     QTextEdit can paste and how it is being pasted, reimplement the
       
  1000     virtual canInsertFromMimeData() and insertFromMimeData()
       
  1001     functions.
       
  1002 
       
  1003     \sa cut() copy()
       
  1004 */
       
  1005 
       
  1006 void QTextEdit::paste()
       
  1007 {
       
  1008     Q_D(QTextEdit);
       
  1009     d->control->paste();
       
  1010 }
       
  1011 #endif
       
  1012 
       
  1013 /*!
       
  1014     Deletes all the text in the text edit.
       
  1015 
       
  1016     Note that the undo/redo history is cleared by this function.
       
  1017 
       
  1018     \sa cut() setPlainText() setHtml()
       
  1019 */
       
  1020 void QTextEdit::clear()
       
  1021 {
       
  1022     Q_D(QTextEdit);
       
  1023     // clears and sets empty content
       
  1024     d->control->clear();
       
  1025 }
       
  1026 
       
  1027 
       
  1028 /*!
       
  1029     Selects all text.
       
  1030 
       
  1031     \sa copy() cut() textCursor()
       
  1032  */
       
  1033 void QTextEdit::selectAll()
       
  1034 {
       
  1035     Q_D(QTextEdit);
       
  1036     d->control->selectAll();
       
  1037 }
       
  1038 
       
  1039 /*! \internal
       
  1040 */
       
  1041 bool QTextEdit::event(QEvent *e)
       
  1042 {
       
  1043     Q_D(QTextEdit);
       
  1044 #ifndef QT_NO_CONTEXTMENU
       
  1045     if (e->type() == QEvent::ContextMenu
       
  1046         && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
       
  1047         Q_D(QTextEdit);
       
  1048         ensureCursorVisible();
       
  1049         const QPoint cursorPos = cursorRect().center();
       
  1050         QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
       
  1051         ce.setAccepted(e->isAccepted());
       
  1052         const bool result = QAbstractScrollArea::event(&ce);
       
  1053         e->setAccepted(ce.isAccepted());
       
  1054         return result;
       
  1055     } else if (e->type() == QEvent::ShortcutOverride
       
  1056                || e->type() == QEvent::ToolTip) {
       
  1057         d->sendControlEvent(e);
       
  1058     }
       
  1059 #endif // QT_NO_CONTEXTMENU
       
  1060 #ifdef QT_KEYPAD_NAVIGATION
       
  1061     if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
       
  1062         if (QApplication::keypadNavigationEnabled())
       
  1063             d->sendControlEvent(e);
       
  1064     }
       
  1065 #endif
       
  1066     return QAbstractScrollArea::event(e);
       
  1067 }
       
  1068 
       
  1069 /*! \internal
       
  1070 */
       
  1071 
       
  1072 void QTextEdit::timerEvent(QTimerEvent *e)
       
  1073 {
       
  1074     Q_D(QTextEdit);
       
  1075     if (e->timerId() == d->autoScrollTimer.timerId()) {
       
  1076         QRect visible = d->viewport->rect();
       
  1077         QPoint pos;
       
  1078         if (d->inDrag) {
       
  1079             pos = d->autoScrollDragPos;
       
  1080             visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
       
  1081                            -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
       
  1082         } else {
       
  1083             const QPoint globalPos = QCursor::pos();
       
  1084             pos = d->viewport->mapFromGlobal(globalPos);
       
  1085             QMouseEvent ev(QEvent::MouseMove, pos, globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
       
  1086             mouseMoveEvent(&ev);
       
  1087         }
       
  1088         int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
       
  1089         int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
       
  1090         int delta = qMax(deltaX, deltaY);
       
  1091         if (delta >= 0) {
       
  1092             if (delta < 7)
       
  1093                 delta = 7;
       
  1094             int timeout = 4900 / (delta * delta);
       
  1095             d->autoScrollTimer.start(timeout, this);
       
  1096 
       
  1097             if (deltaY > 0)
       
  1098                 d->vbar->triggerAction(pos.y() < visible.center().y() ?
       
  1099                                        QAbstractSlider::SliderSingleStepSub
       
  1100                                        : QAbstractSlider::SliderSingleStepAdd);
       
  1101             if (deltaX > 0)
       
  1102                 d->hbar->triggerAction(pos.x() < visible.center().x() ?
       
  1103                                        QAbstractSlider::SliderSingleStepSub
       
  1104                                        : QAbstractSlider::SliderSingleStepAdd);
       
  1105         }
       
  1106     }
       
  1107 #ifdef QT_KEYPAD_NAVIGATION
       
  1108     else if (e->timerId() == d->deleteAllTimer.timerId()) {
       
  1109         d->deleteAllTimer.stop();
       
  1110         clear();
       
  1111     }
       
  1112 #endif
       
  1113 }
       
  1114 
       
  1115 /*!
       
  1116     Changes the text of the text edit to the string \a text.
       
  1117     Any previous text is removed.
       
  1118 
       
  1119     \a text is interpreted as plain text.
       
  1120 
       
  1121     Note that the undo/redo history is cleared by this function.
       
  1122 
       
  1123     \sa toPlainText()
       
  1124 */
       
  1125 
       
  1126 void QTextEdit::setPlainText(const QString &text)
       
  1127 {
       
  1128     Q_D(QTextEdit);
       
  1129     d->control->setPlainText(text);
       
  1130     d->preferRichText = false;
       
  1131 }
       
  1132 
       
  1133 /*!
       
  1134     \fn QString QTextEdit::toPlainText() const
       
  1135 
       
  1136     Returns the text of the text edit as plain text.
       
  1137 
       
  1138     \sa QTextEdit::setPlainText()
       
  1139  */
       
  1140 
       
  1141 
       
  1142 /*!
       
  1143     \property QTextEdit::html
       
  1144 
       
  1145     This property provides an HTML interface to the text of the text edit.
       
  1146 
       
  1147     toHtml() returns the text of the text edit as html.
       
  1148 
       
  1149     setHtml() changes the text of the text edit.  Any previous text is
       
  1150     removed and the undo/redo history is cleared. The input text is
       
  1151     interpreted as rich text in html format.
       
  1152 
       
  1153     \note It is the responsibility of the caller to make sure that the
       
  1154     text is correctly decoded when a QString containing HTML is created
       
  1155     and passed to setHtml().
       
  1156 
       
  1157     By default, for a newly-created, empty document, this property contains
       
  1158     text to describe an HTML 4.0 document with no body text.
       
  1159 
       
  1160     \sa {Supported HTML Subset}, plainText
       
  1161 */
       
  1162 
       
  1163 #ifndef QT_NO_TEXTHTMLPARSER
       
  1164 void QTextEdit::setHtml(const QString &text)
       
  1165 {
       
  1166     Q_D(QTextEdit);
       
  1167     d->control->setHtml(text);
       
  1168     d->preferRichText = true;
       
  1169 }
       
  1170 #endif
       
  1171 
       
  1172 /*! \reimp
       
  1173 */
       
  1174 void QTextEdit::keyPressEvent(QKeyEvent *e)
       
  1175 {
       
  1176     Q_D(QTextEdit);
       
  1177 
       
  1178 #ifdef QT_KEYPAD_NAVIGATION
       
  1179     switch (e->key()) {
       
  1180         case Qt::Key_Select:
       
  1181             if (QApplication::keypadNavigationEnabled()) {
       
  1182                 // code assumes linksaccessible + editable isn't meaningful
       
  1183                 if (d->control->textInteractionFlags() & Qt::TextEditable) {
       
  1184                     setEditFocus(!hasEditFocus());
       
  1185                 } else {
       
  1186                     if (!hasEditFocus())
       
  1187                         setEditFocus(true);
       
  1188                     else {
       
  1189                         QTextCursor cursor = d->control->textCursor();
       
  1190                         QTextCharFormat charFmt = cursor.charFormat();
       
  1191                         if (!(d->control->textInteractionFlags() & Qt::LinksAccessibleByKeyboard)
       
  1192                             || !cursor.hasSelection() || charFmt.anchorHref().isEmpty()) {
       
  1193                             e->accept();
       
  1194                             return;
       
  1195                         }
       
  1196                     }
       
  1197                 }
       
  1198             }
       
  1199             break;
       
  1200         case Qt::Key_Back:
       
  1201         case Qt::Key_No:
       
  1202             if (!QApplication::keypadNavigationEnabled()
       
  1203                     || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) {
       
  1204                 e->ignore();
       
  1205                 return;
       
  1206             }
       
  1207             break;
       
  1208         default:
       
  1209             if (QApplication::keypadNavigationEnabled()) {
       
  1210                 if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
       
  1211                     if (e->text()[0].isPrint()) {
       
  1212                         setEditFocus(true);
       
  1213                         clear();
       
  1214                     } else {
       
  1215                         e->ignore();
       
  1216                         return;
       
  1217                     }
       
  1218                 }
       
  1219             }
       
  1220             break;
       
  1221     }
       
  1222 #endif
       
  1223 #ifndef QT_NO_SHORTCUT
       
  1224 
       
  1225     Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
       
  1226 
       
  1227     if (tif & Qt::TextSelectableByKeyboard){
       
  1228         if (e == QKeySequence::SelectPreviousPage) {
       
  1229             e->accept();
       
  1230             d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
       
  1231             return;
       
  1232         } else if (e ==QKeySequence::SelectNextPage) {
       
  1233             e->accept();
       
  1234             d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
       
  1235             return;
       
  1236         }
       
  1237     }
       
  1238     if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
       
  1239         if (e == QKeySequence::MoveToPreviousPage) {
       
  1240             e->accept();
       
  1241             d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
       
  1242             return;
       
  1243         } else if (e == QKeySequence::MoveToNextPage) {
       
  1244             e->accept();
       
  1245             d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
       
  1246             return;
       
  1247         }
       
  1248     }
       
  1249 #endif // QT_NO_SHORTCUT
       
  1250 
       
  1251     if (!(tif & Qt::TextEditable)) {
       
  1252         switch (e->key()) {
       
  1253             case Qt::Key_Space:
       
  1254                 e->accept();
       
  1255                 if (e->modifiers() & Qt::ShiftModifier)
       
  1256                     d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
       
  1257                 else
       
  1258                     d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
       
  1259                 break;
       
  1260             default:
       
  1261                 d->sendControlEvent(e);
       
  1262                 if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
       
  1263                     if (e->key() == Qt::Key_Home) {
       
  1264                         d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
       
  1265                         e->accept();
       
  1266                     } else if (e->key() == Qt::Key_End) {
       
  1267                         d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
       
  1268                         e->accept();
       
  1269                     }
       
  1270                 }
       
  1271                 if (!e->isAccepted()) {
       
  1272                     QAbstractScrollArea::keyPressEvent(e);
       
  1273                 }
       
  1274         }
       
  1275         return;
       
  1276     }
       
  1277 
       
  1278     {
       
  1279         QTextCursor cursor = d->control->textCursor();
       
  1280         const QString text = e->text();
       
  1281         if (cursor.atBlockStart()
       
  1282             && (d->autoFormatting & AutoBulletList)
       
  1283             && (text.length() == 1)
       
  1284             && (text.at(0) == QLatin1Char('-') || text.at(0) == QLatin1Char('*'))
       
  1285             && (!cursor.currentList())) {
       
  1286 
       
  1287             d->createAutoBulletList();
       
  1288             e->accept();
       
  1289             return;
       
  1290         }
       
  1291     }
       
  1292 
       
  1293     d->sendControlEvent(e);
       
  1294 #ifdef QT_KEYPAD_NAVIGATION
       
  1295     if (!e->isAccepted()) {
       
  1296         switch (e->key()) {
       
  1297             case Qt::Key_Up:
       
  1298             case Qt::Key_Down:
       
  1299                 if (QApplication::keypadNavigationEnabled()) {
       
  1300                     // Cursor position didn't change, so we want to leave
       
  1301                     // these keys to change focus.
       
  1302                     e->ignore();
       
  1303                     return;
       
  1304                 }
       
  1305                 break;
       
  1306             case Qt::Key_Back:
       
  1307                 if (!e->isAutoRepeat()) {
       
  1308                     if (QApplication::keypadNavigationEnabled()) {
       
  1309                         if (document()->isEmpty() || !(d->control->textInteractionFlags() & Qt::TextEditable)) {
       
  1310                             setEditFocus(false);
       
  1311                             e->accept();
       
  1312                         } else if (!d->deleteAllTimer.isActive()) {
       
  1313                             e->accept();
       
  1314                             d->deleteAllTimer.start(750, this);
       
  1315                         }
       
  1316                     } else {
       
  1317                         e->ignore();
       
  1318                         return;
       
  1319                     }
       
  1320                 }
       
  1321                 break;
       
  1322             default: break;
       
  1323         }
       
  1324     }
       
  1325 #endif
       
  1326 }
       
  1327 
       
  1328 /*! \reimp
       
  1329 */
       
  1330 void QTextEdit::keyReleaseEvent(QKeyEvent *e)
       
  1331 {
       
  1332 #ifdef QT_KEYPAD_NAVIGATION
       
  1333     Q_D(QTextEdit);
       
  1334     if (QApplication::keypadNavigationEnabled()) {
       
  1335         if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
       
  1336             && d->deleteAllTimer.isActive()) {
       
  1337             d->deleteAllTimer.stop();
       
  1338             QTextCursor cursor = d->control->textCursor();
       
  1339             QTextBlockFormat blockFmt = cursor.blockFormat();
       
  1340 
       
  1341             QTextList *list = cursor.currentList();
       
  1342             if (list && cursor.atBlockStart()) {
       
  1343                 list->remove(cursor.block());
       
  1344             } else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
       
  1345                 blockFmt.setIndent(blockFmt.indent() - 1);
       
  1346                 cursor.setBlockFormat(blockFmt);
       
  1347             } else {
       
  1348                 cursor.deletePreviousChar();
       
  1349             }
       
  1350             setTextCursor(cursor);
       
  1351             e->accept();
       
  1352             return;
       
  1353         }
       
  1354     }
       
  1355 #endif
       
  1356     e->ignore();
       
  1357 }
       
  1358 
       
  1359 /*!
       
  1360     Loads the resource specified by the given \a type and \a name.
       
  1361 
       
  1362     This function is an extension of QTextDocument::loadResource().
       
  1363 
       
  1364     \sa QTextDocument::loadResource()
       
  1365 */
       
  1366 QVariant QTextEdit::loadResource(int type, const QUrl &name)
       
  1367 {
       
  1368     Q_UNUSED(type);
       
  1369     Q_UNUSED(name);
       
  1370     return QVariant();
       
  1371 }
       
  1372 
       
  1373 /*! \reimp
       
  1374 */
       
  1375 void QTextEdit::resizeEvent(QResizeEvent *e)
       
  1376 {
       
  1377     Q_D(QTextEdit);
       
  1378 
       
  1379     if (d->lineWrap == NoWrap) {
       
  1380         QTextDocument *doc = d->control->document();
       
  1381         QVariant alignmentProperty = doc->documentLayout()->property("contentHasAlignment");
       
  1382 
       
  1383         if (!doc->pageSize().isNull()
       
  1384             && alignmentProperty.type() == QVariant::Bool
       
  1385             && !alignmentProperty.toBool()) {
       
  1386 
       
  1387             d->_q_adjustScrollbars();
       
  1388             return;
       
  1389         }
       
  1390     }
       
  1391 
       
  1392     if (d->lineWrap != FixedPixelWidth
       
  1393         && e->oldSize().width() != e->size().width())
       
  1394         d->relayoutDocument();
       
  1395     else
       
  1396         d->_q_adjustScrollbars();
       
  1397 }
       
  1398 
       
  1399 void QTextEditPrivate::relayoutDocument()
       
  1400 {
       
  1401     QTextDocument *doc = control->document();
       
  1402     QAbstractTextDocumentLayout *layout = doc->documentLayout();
       
  1403 
       
  1404     if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
       
  1405         if (lineWrap == QTextEdit::FixedColumnWidth)
       
  1406             tlayout->setFixedColumnWidth(lineWrapColumnOrWidth);
       
  1407         else
       
  1408             tlayout->setFixedColumnWidth(-1);
       
  1409     }
       
  1410 
       
  1411     QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout);
       
  1412     QSize lastUsedSize;
       
  1413     if (tlayout)
       
  1414         lastUsedSize = tlayout->dynamicDocumentSize().toSize();
       
  1415     else
       
  1416         lastUsedSize = layout->documentSize().toSize();
       
  1417 
       
  1418     // ignore calls to _q_adjustScrollbars caused by an emission of the
       
  1419     // usedSizeChanged() signal in the layout, as we're calling it
       
  1420     // later on our own anyway (or deliberately not) .
       
  1421     const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
       
  1422     ignoreAutomaticScrollbarAdjustment = true;
       
  1423 
       
  1424     int width = viewport->width();
       
  1425     if (lineWrap == QTextEdit::FixedPixelWidth)
       
  1426         width = lineWrapColumnOrWidth;
       
  1427     else if (lineWrap == QTextEdit::NoWrap) {
       
  1428         QVariant alignmentProperty = doc->documentLayout()->property("contentHasAlignment");
       
  1429         if (alignmentProperty.type() == QVariant::Bool && !alignmentProperty.toBool()) {
       
  1430 
       
  1431             width = 0;
       
  1432         }
       
  1433     }
       
  1434 
       
  1435     doc->setPageSize(QSize(width, -1));
       
  1436     if (tlayout)
       
  1437         tlayout->ensureLayouted(verticalOffset() + viewport->height());
       
  1438 
       
  1439     ignoreAutomaticScrollbarAdjustment = oldIgnoreScrollbarAdjustment;
       
  1440 
       
  1441     QSize usedSize;
       
  1442     if (tlayout)
       
  1443         usedSize = tlayout->dynamicDocumentSize().toSize();
       
  1444     else
       
  1445         usedSize = layout->documentSize().toSize();
       
  1446 
       
  1447     // this is an obscure situation in the layout that can happen:
       
  1448     // if a character at the end of a line is the tallest one and therefore
       
  1449     // influencing the total height of the line and the line right below it
       
  1450     // is always taller though, then it can happen that if due to line breaking
       
  1451     // that tall character wraps into the lower line the document not only shrinks
       
  1452     // horizontally (causing the character to wrap in the first place) but also
       
  1453     // vertically, because the original line is now smaller and the one below kept
       
  1454     // its size. So a layout with less width _can_ take up less vertical space, too.
       
  1455     // If the wider case causes a vertical scroll bar to appear and the narrower one
       
  1456     // (narrower because the vertical scroll bar takes up horizontal space)) to disappear
       
  1457     // again then we have an endless loop, as _q_adjustScrollBars sets new ranges on the
       
  1458     // scroll bars, the QAbstractScrollArea will find out about it and try to show/hide
       
  1459     // the scroll bars again. That's why we try to detect this case here and break out.
       
  1460     //
       
  1461     // (if you change this please also check the layoutingLoop() testcase in
       
  1462     // QTextEdit's autotests)
       
  1463     if (lastUsedSize.isValid()
       
  1464         && !vbar->isHidden()
       
  1465         && viewport->width() < lastUsedSize.width()
       
  1466         && usedSize.height() < lastUsedSize.height()
       
  1467         && usedSize.height() <= viewport->height())
       
  1468         return;
       
  1469 
       
  1470     _q_adjustScrollbars();
       
  1471 }
       
  1472 
       
  1473 void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
       
  1474 {
       
  1475     const int xOffset = horizontalOffset();
       
  1476     const int yOffset = verticalOffset();
       
  1477 
       
  1478     QRect r = e->rect();
       
  1479     p->translate(-xOffset, -yOffset);
       
  1480     r.translate(xOffset, yOffset);
       
  1481 
       
  1482     QTextDocument *doc = control->document();
       
  1483     QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
       
  1484 
       
  1485     // the layout might need to expand the root frame to
       
  1486     // the viewport if NoWrap is set
       
  1487     if (layout)
       
  1488         layout->setViewport(viewport->rect());
       
  1489 
       
  1490     control->drawContents(p, r, q_func());
       
  1491 
       
  1492     if (layout)
       
  1493         layout->setViewport(QRect());
       
  1494 }
       
  1495 
       
  1496 /*! \fn void QTextEdit::paintEvent(QPaintEvent *event)
       
  1497 
       
  1498 This event handler can be reimplemented in a subclass to receive paint events passed in \a event.
       
  1499 It is usually unnecessary to reimplement this function in a subclass of QTextEdit.
       
  1500 
       
  1501 \warning The underlying text document must not be modified from within a reimplementation
       
  1502 of this function.
       
  1503 */
       
  1504 void QTextEdit::paintEvent(QPaintEvent *e)
       
  1505 {
       
  1506     Q_D(QTextEdit);
       
  1507     QPainter p(d->viewport);
       
  1508     d->paint(&p, e);
       
  1509 }
       
  1510 
       
  1511 void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
       
  1512 {
       
  1513     Q_Q(QTextEdit);
       
  1514     emit q->currentCharFormatChanged(fmt);
       
  1515 #ifdef QT3_SUPPORT
       
  1516     // compat signals
       
  1517     emit q->currentFontChanged(fmt.font());
       
  1518     emit q->currentColorChanged(fmt.foreground().color());
       
  1519 #endif
       
  1520 }
       
  1521 
       
  1522 void QTextEditPrivate::updateDefaultTextOption()
       
  1523 {
       
  1524     QTextDocument *doc = control->document();
       
  1525 
       
  1526     QTextOption opt = doc->defaultTextOption();
       
  1527     QTextOption::WrapMode oldWrapMode = opt.wrapMode();
       
  1528 
       
  1529     if (lineWrap == QTextEdit::NoWrap)
       
  1530         opt.setWrapMode(QTextOption::NoWrap);
       
  1531     else
       
  1532         opt.setWrapMode(wordWrap);
       
  1533 
       
  1534     if (opt.wrapMode() != oldWrapMode)
       
  1535         doc->setDefaultTextOption(opt);
       
  1536 }
       
  1537 
       
  1538 /*! \reimp
       
  1539 */
       
  1540 void QTextEdit::mousePressEvent(QMouseEvent *e)
       
  1541 {
       
  1542     Q_D(QTextEdit);
       
  1543 #ifdef QT_KEYPAD_NAVIGATION
       
  1544     if (QApplication::keypadNavigationEnabled() && !hasEditFocus())
       
  1545         setEditFocus(true);
       
  1546 #endif
       
  1547     d->sendControlEvent(e);
       
  1548 }
       
  1549 
       
  1550 /*! \reimp
       
  1551 */
       
  1552 void QTextEdit::mouseMoveEvent(QMouseEvent *e)
       
  1553 {
       
  1554     Q_D(QTextEdit);
       
  1555     d->inDrag = false; // paranoia
       
  1556     const QPoint pos = e->pos();
       
  1557     d->sendControlEvent(e);
       
  1558     if (!(e->buttons() & Qt::LeftButton))
       
  1559         return;
       
  1560     QRect visible = d->viewport->rect();
       
  1561     if (visible.contains(pos))
       
  1562         d->autoScrollTimer.stop();
       
  1563     else if (!d->autoScrollTimer.isActive())
       
  1564         d->autoScrollTimer.start(100, this);
       
  1565 }
       
  1566 
       
  1567 /*! \reimp
       
  1568 */
       
  1569 void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
       
  1570 {
       
  1571     Q_D(QTextEdit);
       
  1572     d->sendControlEvent(e);
       
  1573     if (d->autoScrollTimer.isActive()) {
       
  1574         d->autoScrollTimer.stop();
       
  1575         ensureCursorVisible();
       
  1576     }
       
  1577     d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
       
  1578     d->clickCausedFocus = 0;
       
  1579 }
       
  1580 
       
  1581 /*! \reimp
       
  1582 */
       
  1583 void QTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
       
  1584 {
       
  1585     Q_D(QTextEdit);
       
  1586     d->sendControlEvent(e);
       
  1587 }
       
  1588 
       
  1589 /*! \reimp
       
  1590 */
       
  1591 bool QTextEdit::focusNextPrevChild(bool next)
       
  1592 {
       
  1593     Q_D(const QTextEdit);
       
  1594     if (!d->tabChangesFocus && d->control->textInteractionFlags() & Qt::TextEditable)
       
  1595         return false;
       
  1596     return QAbstractScrollArea::focusNextPrevChild(next);
       
  1597 }
       
  1598 
       
  1599 #ifndef QT_NO_CONTEXTMENU
       
  1600 /*!
       
  1601   \fn void QTextEdit::contextMenuEvent(QContextMenuEvent *event)
       
  1602 
       
  1603   Shows the standard context menu created with createStandardContextMenu().
       
  1604 
       
  1605   If you do not want the text edit to have a context menu, you can set
       
  1606   its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
       
  1607   customize the context menu, reimplement this function. If you want
       
  1608   to extend the standard context menu, reimplement this function, call
       
  1609   createStandardContextMenu() and extend the menu returned.
       
  1610 
       
  1611   Information about the event is passed in the \a event object.
       
  1612 
       
  1613   \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 0
       
  1614 */
       
  1615 void QTextEdit::contextMenuEvent(QContextMenuEvent *e)
       
  1616 {
       
  1617     Q_D(QTextEdit);
       
  1618     d->sendControlEvent(e);
       
  1619 }
       
  1620 #endif // QT_NO_CONTEXTMENU
       
  1621 
       
  1622 #ifndef QT_NO_DRAGANDDROP
       
  1623 /*! \reimp
       
  1624 */
       
  1625 void QTextEdit::dragEnterEvent(QDragEnterEvent *e)
       
  1626 {
       
  1627     Q_D(QTextEdit);
       
  1628     d->inDrag = true;
       
  1629     d->sendControlEvent(e);
       
  1630 }
       
  1631 
       
  1632 /*! \reimp
       
  1633 */
       
  1634 void QTextEdit::dragLeaveEvent(QDragLeaveEvent *e)
       
  1635 {
       
  1636     Q_D(QTextEdit);
       
  1637     d->inDrag = false;
       
  1638     d->autoScrollTimer.stop();
       
  1639     d->sendControlEvent(e);
       
  1640 }
       
  1641 
       
  1642 /*! \reimp
       
  1643 */
       
  1644 void QTextEdit::dragMoveEvent(QDragMoveEvent *e)
       
  1645 {
       
  1646     Q_D(QTextEdit);
       
  1647     d->autoScrollDragPos = e->pos();
       
  1648     if (!d->autoScrollTimer.isActive())
       
  1649         d->autoScrollTimer.start(100, this);
       
  1650     d->sendControlEvent(e);
       
  1651 }
       
  1652 
       
  1653 /*! \reimp
       
  1654 */
       
  1655 void QTextEdit::dropEvent(QDropEvent *e)
       
  1656 {
       
  1657     Q_D(QTextEdit);
       
  1658     d->inDrag = false;
       
  1659     d->autoScrollTimer.stop();
       
  1660     d->sendControlEvent(e);
       
  1661 }
       
  1662 
       
  1663 #endif // QT_NO_DRAGANDDROP
       
  1664 
       
  1665 /*! \reimp
       
  1666  */
       
  1667 void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
       
  1668 {
       
  1669     Q_D(QTextEdit);
       
  1670 #ifdef QT_KEYPAD_NAVIGATION
       
  1671     if (d->control->textInteractionFlags() & Qt::TextEditable
       
  1672         && QApplication::keypadNavigationEnabled()
       
  1673         && !hasEditFocus()) {
       
  1674         setEditFocus(true);
       
  1675         selectAll();    // so text is replaced rather than appended to
       
  1676     }
       
  1677 #endif
       
  1678     d->sendControlEvent(e);
       
  1679     ensureCursorVisible();
       
  1680 }
       
  1681 
       
  1682 /*!\reimp
       
  1683 */
       
  1684 void QTextEdit::scrollContentsBy(int dx, int dy)
       
  1685 {
       
  1686     Q_D(QTextEdit);
       
  1687     if (isRightToLeft())
       
  1688         dx = -dx;
       
  1689     d->viewport->scroll(dx, dy);
       
  1690 }
       
  1691 
       
  1692 /*!\reimp
       
  1693 */
       
  1694 QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
       
  1695 {
       
  1696     Q_D(const QTextEdit);
       
  1697     QVariant v = d->control->inputMethodQuery(property);
       
  1698     const QPoint offset(-d->horizontalOffset(), -d->verticalOffset());
       
  1699     if (v.type() == QVariant::RectF)
       
  1700         v = v.toRectF().toRect().translated(offset);
       
  1701     else if (v.type() == QVariant::PointF)
       
  1702         v = v.toPointF().toPoint() + offset;
       
  1703     else if (v.type() == QVariant::Rect)
       
  1704         v = v.toRect().translated(offset);
       
  1705     else if (v.type() == QVariant::Point)
       
  1706         v = v.toPoint() + offset;
       
  1707     return v;
       
  1708 }
       
  1709 
       
  1710 /*! \reimp
       
  1711 */
       
  1712 void QTextEdit::focusInEvent(QFocusEvent *e)
       
  1713 {
       
  1714     Q_D(QTextEdit);
       
  1715     if (e->reason() == Qt::MouseFocusReason) {
       
  1716         d->clickCausedFocus = 1;
       
  1717     }
       
  1718     QAbstractScrollArea::focusInEvent(e);
       
  1719     d->sendControlEvent(e);
       
  1720 }
       
  1721 
       
  1722 /*! \reimp
       
  1723 */
       
  1724 void QTextEdit::focusOutEvent(QFocusEvent *e)
       
  1725 {
       
  1726     Q_D(QTextEdit);
       
  1727     QAbstractScrollArea::focusOutEvent(e);
       
  1728     d->sendControlEvent(e);
       
  1729 }
       
  1730 
       
  1731 /*! \reimp
       
  1732 */
       
  1733 void QTextEdit::showEvent(QShowEvent *)
       
  1734 {
       
  1735     Q_D(QTextEdit);
       
  1736     if (!d->anchorToScrollToWhenVisible.isEmpty()) {
       
  1737         scrollToAnchor(d->anchorToScrollToWhenVisible);
       
  1738         d->anchorToScrollToWhenVisible.clear();
       
  1739         d->showCursorOnInitialShow = false;
       
  1740     } else if (d->showCursorOnInitialShow) {
       
  1741         d->showCursorOnInitialShow = false;
       
  1742         ensureCursorVisible();
       
  1743     }
       
  1744 }
       
  1745 
       
  1746 /*! \reimp
       
  1747 */
       
  1748 void QTextEdit::changeEvent(QEvent *e)
       
  1749 {
       
  1750     Q_D(QTextEdit);
       
  1751     QAbstractScrollArea::changeEvent(e);
       
  1752     if (e->type() == QEvent::ApplicationFontChange
       
  1753         || e->type() == QEvent::FontChange) {
       
  1754         d->control->document()->setDefaultFont(font());
       
  1755     }  else if(e->type() == QEvent::ActivationChange) {
       
  1756         if (!isActiveWindow())
       
  1757             d->autoScrollTimer.stop();
       
  1758     } else if (e->type() == QEvent::EnabledChange) {
       
  1759         e->setAccepted(isEnabled());
       
  1760         d->control->setPalette(palette());
       
  1761         d->sendControlEvent(e);
       
  1762     } else if (e->type() == QEvent::PaletteChange) {
       
  1763         d->control->setPalette(palette());
       
  1764     } else if (e->type() == QEvent::LayoutDirectionChange) {
       
  1765         d->sendControlEvent(e);
       
  1766     }
       
  1767 }
       
  1768 
       
  1769 /*! \reimp
       
  1770 */
       
  1771 #ifndef QT_NO_WHEELEVENT
       
  1772 void QTextEdit::wheelEvent(QWheelEvent *e)
       
  1773 {
       
  1774     Q_D(QTextEdit);
       
  1775     if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
       
  1776         if (e->modifiers() & Qt::ControlModifier) {
       
  1777             const int delta = e->delta();
       
  1778             if (delta < 0)
       
  1779                 zoomOut();
       
  1780             else if (delta > 0)
       
  1781                 zoomIn();
       
  1782             return;
       
  1783         }
       
  1784     }
       
  1785     QAbstractScrollArea::wheelEvent(e);
       
  1786     updateMicroFocus();
       
  1787 }
       
  1788 #endif
       
  1789 
       
  1790 #ifndef QT_NO_CONTEXTMENU
       
  1791 /*!  This function creates the standard context menu which is shown
       
  1792   when the user clicks on the text edit with the right mouse
       
  1793   button. It is called from the default contextMenuEvent() handler.
       
  1794   The popup menu's ownership is transferred to the caller.
       
  1795 
       
  1796   We recommend that you use the createStandardContextMenu(QPoint) version instead
       
  1797   which will enable the actions that are sensitive to where the user clicked.
       
  1798 */
       
  1799 
       
  1800 QMenu *QTextEdit::createStandardContextMenu()
       
  1801 {
       
  1802     Q_D(QTextEdit);
       
  1803     return d->control->createStandardContextMenu(QPointF(), this);
       
  1804 }
       
  1805 
       
  1806 /*!
       
  1807   \since 4.4
       
  1808   This function creates the standard context menu which is shown
       
  1809   when the user clicks on the text edit with the right mouse
       
  1810   button. It is called from the default contextMenuEvent() handler
       
  1811   and it takes the \a position of where the mouse click was.
       
  1812   This can enable actions that are sensitive to the position where the user clicked.
       
  1813   The popup menu's ownership is transferred to the caller.
       
  1814 */
       
  1815 
       
  1816 QMenu *QTextEdit::createStandardContextMenu(const QPoint &position)
       
  1817 {
       
  1818     Q_D(QTextEdit);
       
  1819     return d->control->createStandardContextMenu(position, this);
       
  1820 }
       
  1821 #endif // QT_NO_CONTEXTMENU
       
  1822 
       
  1823 /*!
       
  1824   returns a QTextCursor at position \a pos (in viewport coordinates).
       
  1825 */
       
  1826 QTextCursor QTextEdit::cursorForPosition(const QPoint &pos) const
       
  1827 {
       
  1828     Q_D(const QTextEdit);
       
  1829     return d->control->cursorForPosition(d->mapToContents(pos));
       
  1830 }
       
  1831 
       
  1832 /*!
       
  1833   returns a rectangle (in viewport coordinates) that includes the
       
  1834   \a cursor.
       
  1835  */
       
  1836 QRect QTextEdit::cursorRect(const QTextCursor &cursor) const
       
  1837 {
       
  1838     Q_D(const QTextEdit);
       
  1839     if (cursor.isNull())
       
  1840         return QRect();
       
  1841 
       
  1842     QRect r = d->control->cursorRect(cursor).toRect();
       
  1843     r.translate(-d->horizontalOffset(),-d->verticalOffset());
       
  1844     return r;
       
  1845 }
       
  1846 
       
  1847 /*!
       
  1848   returns a rectangle (in viewport coordinates) that includes the
       
  1849   cursor of the text edit.
       
  1850  */
       
  1851 QRect QTextEdit::cursorRect() const
       
  1852 {
       
  1853     Q_D(const QTextEdit);
       
  1854     QRect r = d->control->cursorRect().toRect();
       
  1855     r.translate(-d->horizontalOffset(),-d->verticalOffset());
       
  1856     return r;
       
  1857 }
       
  1858 
       
  1859 
       
  1860 /*!
       
  1861     Returns the reference of the anchor at position \a pos, or an
       
  1862     empty string if no anchor exists at that point.
       
  1863 */
       
  1864 QString QTextEdit::anchorAt(const QPoint& pos) const
       
  1865 {
       
  1866     Q_D(const QTextEdit);
       
  1867     return d->control->anchorAt(d->mapToContents(pos));
       
  1868 }
       
  1869 
       
  1870 /*!
       
  1871    \property QTextEdit::overwriteMode
       
  1872    \since 4.1
       
  1873    \brief whether text entered by the user will overwrite existing text
       
  1874 
       
  1875    As with many text editors, the text editor widget can be configured
       
  1876    to insert or overwrite existing text with new text entered by the user.
       
  1877 
       
  1878    If this property is true, existing text is overwritten, character-for-character
       
  1879    by new text; otherwise, text is inserted at the cursor position, displacing
       
  1880    existing text.
       
  1881 
       
  1882    By default, this property is false (new text does not overwrite existing text).
       
  1883 */
       
  1884 
       
  1885 bool QTextEdit::overwriteMode() const
       
  1886 {
       
  1887     Q_D(const QTextEdit);
       
  1888     return d->control->overwriteMode();
       
  1889 }
       
  1890 
       
  1891 void QTextEdit::setOverwriteMode(bool overwrite)
       
  1892 {
       
  1893     Q_D(QTextEdit);
       
  1894     d->control->setOverwriteMode(overwrite);
       
  1895 }
       
  1896 
       
  1897 /*!
       
  1898     \property QTextEdit::tabStopWidth
       
  1899     \brief the tab stop width in pixels
       
  1900     \since 4.1
       
  1901 
       
  1902     By default, this property contains a value of 80.
       
  1903 */
       
  1904 
       
  1905 int QTextEdit::tabStopWidth() const
       
  1906 {
       
  1907     Q_D(const QTextEdit);
       
  1908     return qRound(d->control->document()->defaultTextOption().tabStop());
       
  1909 }
       
  1910 
       
  1911 void QTextEdit::setTabStopWidth(int width)
       
  1912 {
       
  1913     Q_D(QTextEdit);
       
  1914     QTextOption opt = d->control->document()->defaultTextOption();
       
  1915     if (opt.tabStop() == width || width < 0)
       
  1916         return;
       
  1917     opt.setTabStop(width);
       
  1918     d->control->document()->setDefaultTextOption(opt);
       
  1919 }
       
  1920 
       
  1921 /*!
       
  1922     \since 4.2
       
  1923     \property QTextEdit::cursorWidth
       
  1924 
       
  1925     This property specifies the width of the cursor in pixels. The default value is 1.
       
  1926 */
       
  1927 int QTextEdit::cursorWidth() const
       
  1928 {
       
  1929     Q_D(const QTextEdit);
       
  1930     return d->control->cursorWidth();
       
  1931 }
       
  1932 
       
  1933 void QTextEdit::setCursorWidth(int width)
       
  1934 {
       
  1935     Q_D(QTextEdit);
       
  1936     d->control->setCursorWidth(width);
       
  1937 }
       
  1938 
       
  1939 /*!
       
  1940     \property QTextEdit::acceptRichText
       
  1941     \brief whether the text edit accepts rich text insertions by the user
       
  1942     \since 4.1
       
  1943 
       
  1944     When this propery is set to false text edit will accept only
       
  1945     plain text input from the user. For example through clipboard or drag and drop.
       
  1946 
       
  1947     This property's default is true.
       
  1948 */
       
  1949 
       
  1950 bool QTextEdit::acceptRichText() const
       
  1951 {
       
  1952     Q_D(const QTextEdit);
       
  1953     return d->control->acceptRichText();
       
  1954 }
       
  1955 
       
  1956 void QTextEdit::setAcceptRichText(bool accept)
       
  1957 {
       
  1958     Q_D(QTextEdit);
       
  1959     d->control->setAcceptRichText(accept);
       
  1960 }
       
  1961 
       
  1962 /*!
       
  1963     \class QTextEdit::ExtraSelection
       
  1964     \since 4.2
       
  1965     \brief The QTextEdit::ExtraSelection structure provides a way of specifying a
       
  1966            character format for a given selection in a document
       
  1967 */
       
  1968 
       
  1969 /*!
       
  1970     \variable QTextEdit::ExtraSelection::cursor
       
  1971     A cursor that contains a selection in a QTextDocument
       
  1972 */
       
  1973 
       
  1974 /*!
       
  1975     \variable QTextEdit::ExtraSelection::format
       
  1976     A format that is used to specify a foreground or background brush/color
       
  1977     for the selection.
       
  1978 */
       
  1979 
       
  1980 /*!
       
  1981     \since 4.2
       
  1982     This function allows temporarily marking certain regions in the document
       
  1983     with a given color, specified as \a selections. This can be useful for
       
  1984     example in a programming editor to mark a whole line of text with a given
       
  1985     background color to indicate the existence of a breakpoint.
       
  1986 
       
  1987     \sa QTextEdit::ExtraSelection, extraSelections()
       
  1988 */
       
  1989 void QTextEdit::setExtraSelections(const QList<ExtraSelection> &selections)
       
  1990 {
       
  1991     Q_D(QTextEdit);
       
  1992     d->control->setExtraSelections(selections);
       
  1993 }
       
  1994 
       
  1995 /*!
       
  1996     \since 4.2
       
  1997     Returns previously set extra selections.
       
  1998 
       
  1999     \sa setExtraSelections()
       
  2000 */
       
  2001 QList<QTextEdit::ExtraSelection> QTextEdit::extraSelections() const
       
  2002 {
       
  2003     Q_D(const QTextEdit);
       
  2004     return d->control->extraSelections();
       
  2005 }
       
  2006 
       
  2007 /*!
       
  2008     This function returns a new MIME data object to represent the contents
       
  2009     of the text edit's current selection. It is called when the selection needs
       
  2010     to be encapsulated into a new QMimeData object; for example, when a drag
       
  2011     and drop operation is started, or when data is copyied to the clipboard.
       
  2012 
       
  2013     If you reimplement this function, note that the ownership of the returned
       
  2014     QMimeData object is passed to the caller. The selection can be retrieved
       
  2015     by using the textCursor() function.
       
  2016 */
       
  2017 QMimeData *QTextEdit::createMimeDataFromSelection() const
       
  2018 {
       
  2019     Q_D(const QTextEdit);
       
  2020     return d->control->QTextControl::createMimeDataFromSelection();
       
  2021 }
       
  2022 
       
  2023 /*!
       
  2024     This function returns true if the contents of the MIME data object, specified
       
  2025     by \a source, can be decoded and inserted into the document. It is called
       
  2026     for example when during a drag operation the mouse enters this widget and it
       
  2027     is necessary to determine whether it is possible to accept the drag and drop
       
  2028     operation.
       
  2029 
       
  2030     Reimplement this function to enable drag and drop support for additional MIME types.
       
  2031  */
       
  2032 bool QTextEdit::canInsertFromMimeData(const QMimeData *source) const
       
  2033 {
       
  2034     Q_D(const QTextEdit);
       
  2035     return d->control->QTextControl::canInsertFromMimeData(source);
       
  2036 }
       
  2037 
       
  2038 /*!
       
  2039     This function inserts the contents of the MIME data object, specified
       
  2040     by \a source, into the text edit at the current cursor position. It is
       
  2041     called whenever text is inserted as the result of a clipboard paste
       
  2042     operation, or when the text edit accepts data from a drag and drop
       
  2043     operation.
       
  2044 
       
  2045     Reimplement this function to enable drag and drop support for additional MIME types.
       
  2046  */
       
  2047 void QTextEdit::insertFromMimeData(const QMimeData *source)
       
  2048 {
       
  2049     Q_D(QTextEdit);
       
  2050     d->control->QTextControl::insertFromMimeData(source);
       
  2051 }
       
  2052 
       
  2053 /*!
       
  2054     \property QTextEdit::readOnly
       
  2055     \brief whether the text edit is read-only
       
  2056 
       
  2057     In a read-only text edit the user can only navigate through the
       
  2058     text and select text; modifying the text is not possible.
       
  2059 
       
  2060     This property's default is false.
       
  2061 */
       
  2062 
       
  2063 bool QTextEdit::isReadOnly() const
       
  2064 {
       
  2065     Q_D(const QTextEdit);
       
  2066     return !(d->control->textInteractionFlags() & Qt::TextEditable);
       
  2067 }
       
  2068 
       
  2069 void QTextEdit::setReadOnly(bool ro)
       
  2070 {
       
  2071     Q_D(QTextEdit);
       
  2072     Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
       
  2073     if (ro) {
       
  2074         flags = Qt::TextSelectableByMouse;
       
  2075 #ifndef QT_NO_TEXTBROWSER
       
  2076         if (qobject_cast<QTextBrowser *>(this))
       
  2077             flags |= Qt::TextBrowserInteraction;
       
  2078 #endif
       
  2079     } else {
       
  2080         flags = Qt::TextEditorInteraction;
       
  2081     }
       
  2082     d->control->setTextInteractionFlags(flags);
       
  2083     setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
       
  2084 }
       
  2085 
       
  2086 /*!
       
  2087     \property QTextEdit::textInteractionFlags
       
  2088     \since 4.2
       
  2089 
       
  2090     Specifies how the widget should interact with user input.
       
  2091 
       
  2092     The default value depends on whether the QTextEdit is read-only
       
  2093     or editable, and whether it is a QTextBrowser or not.
       
  2094 */
       
  2095 
       
  2096 void QTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
       
  2097 {
       
  2098     Q_D(QTextEdit);
       
  2099     d->control->setTextInteractionFlags(flags);
       
  2100 }
       
  2101 
       
  2102 Qt::TextInteractionFlags QTextEdit::textInteractionFlags() const
       
  2103 {
       
  2104     Q_D(const QTextEdit);
       
  2105     return d->control->textInteractionFlags();
       
  2106 }
       
  2107 
       
  2108 /*!
       
  2109     Merges the properties specified in \a modifier into the current character
       
  2110     format by calling QTextCursor::mergeCharFormat on the editor's cursor.
       
  2111     If the editor has a selection then the properties of \a modifier are
       
  2112     directly applied to the selection.
       
  2113 
       
  2114     \sa QTextCursor::mergeCharFormat()
       
  2115  */
       
  2116 void QTextEdit::mergeCurrentCharFormat(const QTextCharFormat &modifier)
       
  2117 {
       
  2118     Q_D(QTextEdit);
       
  2119     d->control->mergeCurrentCharFormat(modifier);
       
  2120 }
       
  2121 
       
  2122 /*!
       
  2123     Sets the char format that is be used when inserting new text to \a
       
  2124     format by calling QTextCursor::setCharFormat() on the editor's
       
  2125     cursor.  If the editor has a selection then the char format is
       
  2126     directly applied to the selection.
       
  2127  */
       
  2128 void QTextEdit::setCurrentCharFormat(const QTextCharFormat &format)
       
  2129 {
       
  2130     Q_D(QTextEdit);
       
  2131     d->control->setCurrentCharFormat(format);
       
  2132 }
       
  2133 
       
  2134 /*!
       
  2135     Returns the char format that is used when inserting new text.
       
  2136  */
       
  2137 QTextCharFormat QTextEdit::currentCharFormat() const
       
  2138 {
       
  2139     Q_D(const QTextEdit);
       
  2140     return d->control->currentCharFormat();
       
  2141 }
       
  2142 
       
  2143 /*!
       
  2144     \property QTextEdit::autoFormatting
       
  2145     \brief the enabled set of auto formatting features
       
  2146 
       
  2147     The value can be any combination of the values in the
       
  2148     AutoFormattingFlag enum.  The default is AutoNone. Choose
       
  2149     AutoAll to enable all automatic formatting.
       
  2150 
       
  2151     Currently, the only automatic formatting feature provided is
       
  2152     AutoBulletList; future versions of Qt may offer more.
       
  2153 */
       
  2154 
       
  2155 QTextEdit::AutoFormatting QTextEdit::autoFormatting() const
       
  2156 {
       
  2157     Q_D(const QTextEdit);
       
  2158     return d->autoFormatting;
       
  2159 }
       
  2160 
       
  2161 void QTextEdit::setAutoFormatting(AutoFormatting features)
       
  2162 {
       
  2163     Q_D(QTextEdit);
       
  2164     d->autoFormatting = features;
       
  2165 }
       
  2166 
       
  2167 /*!
       
  2168     Convenience slot that inserts \a text at the current
       
  2169     cursor position.
       
  2170 
       
  2171     It is equivalent to
       
  2172 
       
  2173     \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 1
       
  2174  */
       
  2175 void QTextEdit::insertPlainText(const QString &text)
       
  2176 {
       
  2177     Q_D(QTextEdit);
       
  2178     d->control->insertPlainText(text);
       
  2179 }
       
  2180 
       
  2181 /*!
       
  2182     Convenience slot that inserts \a text which is assumed to be of
       
  2183     html formatting at the current cursor position.
       
  2184 
       
  2185     It is equivalent to:
       
  2186 
       
  2187     \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 2
       
  2188 
       
  2189     \note When using this function with a style sheet, the style sheet will
       
  2190     only apply to the current block in the document. In order to apply a style
       
  2191     sheet throughout a document, use QTextDocument::setDefaultStyleSheet()
       
  2192     instead.
       
  2193  */
       
  2194 #ifndef QT_NO_TEXTHTMLPARSER
       
  2195 void QTextEdit::insertHtml(const QString &text)
       
  2196 {
       
  2197     Q_D(QTextEdit);
       
  2198     d->control->insertHtml(text);
       
  2199 }
       
  2200 #endif // QT_NO_TEXTHTMLPARSER
       
  2201 
       
  2202 /*!
       
  2203     Scrolls the text edit so that the anchor with the given \a name is
       
  2204     visible; does nothing if the \a name is empty, or is already
       
  2205     visible, or isn't found.
       
  2206 */
       
  2207 void QTextEdit::scrollToAnchor(const QString &name)
       
  2208 {
       
  2209     Q_D(QTextEdit);
       
  2210     if (name.isEmpty())
       
  2211         return;
       
  2212 
       
  2213     if (!isVisible()) {
       
  2214         d->anchorToScrollToWhenVisible = name;
       
  2215         return;
       
  2216     }
       
  2217 
       
  2218     QPointF p = d->control->anchorPosition(name);
       
  2219     const int newPosition = qRound(p.y());
       
  2220     if ( d->vbar->maximum() < newPosition )
       
  2221         d->_q_adjustScrollbars();
       
  2222     d->vbar->setValue(newPosition);
       
  2223 }
       
  2224 
       
  2225 /*!
       
  2226     \fn QTextEdit::zoomIn(int range)
       
  2227 
       
  2228     Zooms in on the text by making the base font size \a range
       
  2229     points larger and recalculating all font sizes to be the new size.
       
  2230     This does not change the size of any images.
       
  2231 
       
  2232     \sa zoomOut()
       
  2233 */
       
  2234 void QTextEdit::zoomIn(int range)
       
  2235 {
       
  2236     QFont f = font();
       
  2237     const int newSize = f.pointSize() + range;
       
  2238     if (newSize <= 0)
       
  2239         return;
       
  2240     f.setPointSize(newSize);
       
  2241     setFont(f);
       
  2242 }
       
  2243 
       
  2244 /*!
       
  2245     \fn QTextEdit::zoomOut(int range)
       
  2246 
       
  2247     \overload
       
  2248 
       
  2249     Zooms out on the text by making the base font size \a range points
       
  2250     smaller and recalculating all font sizes to be the new size. This
       
  2251     does not change the size of any images.
       
  2252 
       
  2253     \sa zoomIn()
       
  2254 */
       
  2255 void QTextEdit::zoomOut(int range)
       
  2256 {
       
  2257     zoomIn(-range);
       
  2258 }
       
  2259 
       
  2260 /*!
       
  2261     \since 4.2
       
  2262     Moves the cursor by performing the given \a operation.
       
  2263 
       
  2264     If \a mode is QTextCursor::KeepAnchor, the cursor selects the text it moves over.
       
  2265     This is the same effect that the user achieves when they hold down the Shift key
       
  2266     and move the cursor with the cursor keys.
       
  2267 
       
  2268     \sa QTextCursor::movePosition()
       
  2269 */
       
  2270 void QTextEdit::moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
       
  2271 {
       
  2272     Q_D(QTextEdit);
       
  2273     d->control->moveCursor(operation, mode);
       
  2274 }
       
  2275 
       
  2276 /*!
       
  2277     \since 4.2
       
  2278     Returns whether text can be pasted from the clipboard into the textedit.
       
  2279 */
       
  2280 bool QTextEdit::canPaste() const
       
  2281 {
       
  2282     Q_D(const QTextEdit);
       
  2283     return d->control->canPaste();
       
  2284 }
       
  2285 
       
  2286 #ifndef QT_NO_PRINTER
       
  2287 /*!
       
  2288     \since 4.3
       
  2289     Convenience function to print the text edit's document to the given \a printer. This
       
  2290     is equivalent to calling the print method on the document directly except that this
       
  2291     function also supports QPrinter::Selection as print range.
       
  2292 
       
  2293     \sa QTextDocument::print()
       
  2294 */
       
  2295 void QTextEdit::print(QPrinter *printer) const
       
  2296 {
       
  2297     Q_D(const QTextEdit);
       
  2298     d->control->print(printer);
       
  2299 }
       
  2300 #endif // QT _NO_PRINTER
       
  2301 
       
  2302 /*! \property QTextEdit::tabChangesFocus
       
  2303   \brief whether \gui Tab changes focus or is accepted as input
       
  2304 
       
  2305   In some occasions text edits should not allow the user to input
       
  2306   tabulators or change indentation using the \gui Tab key, as this breaks
       
  2307   the focus chain. The default is false.
       
  2308 
       
  2309 */
       
  2310 
       
  2311 bool QTextEdit::tabChangesFocus() const
       
  2312 {
       
  2313     Q_D(const QTextEdit);
       
  2314     return d->tabChangesFocus;
       
  2315 }
       
  2316 
       
  2317 void QTextEdit::setTabChangesFocus(bool b)
       
  2318 {
       
  2319     Q_D(QTextEdit);
       
  2320     d->tabChangesFocus = b;
       
  2321 }
       
  2322 
       
  2323 /*!
       
  2324     \property QTextEdit::documentTitle
       
  2325     \brief the title of the document parsed from the text.
       
  2326 
       
  2327     By default, for a newly-created, empty document, this property contains
       
  2328     an empty string.
       
  2329 */
       
  2330 
       
  2331 /*!
       
  2332     \property QTextEdit::lineWrapMode
       
  2333     \brief the line wrap mode
       
  2334 
       
  2335     The default mode is WidgetWidth which causes words to be
       
  2336     wrapped at the right edge of the text edit. Wrapping occurs at
       
  2337     whitespace, keeping whole words intact. If you want wrapping to
       
  2338     occur within words use setWordWrapMode(). If you set a wrap mode of
       
  2339     FixedPixelWidth or FixedColumnWidth you should also call
       
  2340     setLineWrapColumnOrWidth() with the width you want.
       
  2341 
       
  2342     \sa lineWrapColumnOrWidth
       
  2343 */
       
  2344 
       
  2345 QTextEdit::LineWrapMode QTextEdit::lineWrapMode() const
       
  2346 {
       
  2347     Q_D(const QTextEdit);
       
  2348     return d->lineWrap;
       
  2349 }
       
  2350 
       
  2351 void QTextEdit::setLineWrapMode(LineWrapMode wrap)
       
  2352 {
       
  2353     Q_D(QTextEdit);
       
  2354     if (d->lineWrap == wrap)
       
  2355         return;
       
  2356     d->lineWrap = wrap;
       
  2357     d->updateDefaultTextOption();
       
  2358     d->relayoutDocument();
       
  2359 }
       
  2360 
       
  2361 /*!
       
  2362     \property QTextEdit::lineWrapColumnOrWidth
       
  2363     \brief the position (in pixels or columns depending on the wrap mode) where text will be wrapped
       
  2364 
       
  2365     If the wrap mode is FixedPixelWidth, the value is the number of
       
  2366     pixels from the left edge of the text edit at which text should be
       
  2367     wrapped. If the wrap mode is FixedColumnWidth, the value is the
       
  2368     column number (in character columns) from the left edge of the
       
  2369     text edit at which text should be wrapped.
       
  2370 
       
  2371     By default, this property contains a value of 0.
       
  2372 
       
  2373     \sa lineWrapMode
       
  2374 */
       
  2375 
       
  2376 int QTextEdit::lineWrapColumnOrWidth() const
       
  2377 {
       
  2378     Q_D(const QTextEdit);
       
  2379     return d->lineWrapColumnOrWidth;
       
  2380 }
       
  2381 
       
  2382 void QTextEdit::setLineWrapColumnOrWidth(int w)
       
  2383 {
       
  2384     Q_D(QTextEdit);
       
  2385     d->lineWrapColumnOrWidth = w;
       
  2386     d->relayoutDocument();
       
  2387 }
       
  2388 
       
  2389 /*!
       
  2390     \property QTextEdit::wordWrapMode
       
  2391     \brief the mode QTextEdit will use when wrapping text by words
       
  2392 
       
  2393     By default, this property is set to QTextOption::WrapAtWordBoundaryOrAnywhere.
       
  2394 
       
  2395     \sa QTextOption::WrapMode
       
  2396 */
       
  2397 
       
  2398 QTextOption::WrapMode QTextEdit::wordWrapMode() const
       
  2399 {
       
  2400     Q_D(const QTextEdit);
       
  2401     return d->wordWrap;
       
  2402 }
       
  2403 
       
  2404 void QTextEdit::setWordWrapMode(QTextOption::WrapMode mode)
       
  2405 {
       
  2406     Q_D(QTextEdit);
       
  2407     if (mode == d->wordWrap)
       
  2408         return;
       
  2409     d->wordWrap = mode;
       
  2410     d->updateDefaultTextOption();
       
  2411 }
       
  2412 
       
  2413 /*!
       
  2414     Finds the next occurrence of the string, \a exp, using the given
       
  2415     \a options. Returns true if \a exp was found and changes the
       
  2416     cursor to select the match; otherwise returns false.
       
  2417 */
       
  2418 bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
       
  2419 {
       
  2420     Q_D(QTextEdit);
       
  2421     return d->control->find(exp, options);
       
  2422 }
       
  2423 
       
  2424 /*!
       
  2425     \fn void QTextEdit::copyAvailable(bool yes)
       
  2426 
       
  2427     This signal is emitted when text is selected or de-selected in the
       
  2428     text edit.
       
  2429 
       
  2430     When text is selected this signal will be emitted with \a yes set
       
  2431     to true. If no text has been selected or if the selected text is
       
  2432     de-selected this signal is emitted with \a yes set to false.
       
  2433 
       
  2434     If \a yes is true then copy() can be used to copy the selection to
       
  2435     the clipboard. If \a yes is false then copy() does nothing.
       
  2436 
       
  2437     \sa selectionChanged()
       
  2438 */
       
  2439 
       
  2440 /*!
       
  2441     \fn void QTextEdit::currentCharFormatChanged(const QTextCharFormat &f)
       
  2442 
       
  2443     This signal is emitted if the current character format has changed, for
       
  2444     example caused by a change of the cursor position.
       
  2445 
       
  2446     The new format is \a f.
       
  2447 
       
  2448     \sa setCurrentCharFormat()
       
  2449 */
       
  2450 
       
  2451 /*!
       
  2452     \fn void QTextEdit::selectionChanged()
       
  2453 
       
  2454     This signal is emitted whenever the selection changes.
       
  2455 
       
  2456     \sa copyAvailable()
       
  2457 */
       
  2458 
       
  2459 /*!
       
  2460     \fn void QTextEdit::cursorPositionChanged()
       
  2461 
       
  2462     This signal is emitted whenever the position of the
       
  2463     cursor changed.
       
  2464 */
       
  2465 
       
  2466 /*!
       
  2467     \since 4.2
       
  2468 
       
  2469     Sets the text edit's \a text. The text can be plain text or HTML
       
  2470     and the text edit will try to guess the right format.
       
  2471 
       
  2472     Use setHtml() or setPlainText() directly to avoid text edit's guessing.
       
  2473 */
       
  2474 void QTextEdit::setText(const QString &text)
       
  2475 {
       
  2476     Q_D(QTextEdit);
       
  2477     Qt::TextFormat format = d->textFormat;
       
  2478     if (d->textFormat == Qt::AutoText)
       
  2479         format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
       
  2480 #ifndef QT_NO_TEXTHTMLPARSER
       
  2481     if (format == Qt::RichText || format == Qt::LogText)
       
  2482         setHtml(text);
       
  2483     else
       
  2484 #endif
       
  2485         setPlainText(text);
       
  2486 }
       
  2487 
       
  2488 #ifdef QT3_SUPPORT
       
  2489 /*!
       
  2490     Use the QTextCursor class instead.
       
  2491 */
       
  2492 void QTextEdit::moveCursor(CursorAction action, QTextCursor::MoveMode mode)
       
  2493 {
       
  2494     Q_D(QTextEdit);
       
  2495     if (action == MovePageUp) {
       
  2496         d->pageUpDown(QTextCursor::Up, mode);
       
  2497         return;
       
  2498     } else if (action == MovePageDown) {
       
  2499         d->pageUpDown(QTextCursor::Down, mode);
       
  2500         return;
       
  2501     }
       
  2502 
       
  2503     QTextCursor cursor = d->control->textCursor();
       
  2504     QTextCursor::MoveOperation op = QTextCursor::NoMove;
       
  2505     switch (action) {
       
  2506         case MoveBackward: op = QTextCursor::Left; break;
       
  2507         case MoveForward: op = QTextCursor::Right; break;
       
  2508         case MoveWordBackward: op = QTextCursor::WordLeft; break;
       
  2509         case MoveWordForward: op = QTextCursor::WordRight; break;
       
  2510         case MoveUp: op = QTextCursor::Up; break;
       
  2511         case MoveDown: op = QTextCursor::Down; break;
       
  2512         case MoveLineStart: op = QTextCursor::StartOfLine; break;
       
  2513         case MoveLineEnd: op = QTextCursor::EndOfLine; break;
       
  2514         case MoveHome: op = QTextCursor::Start; break;
       
  2515         case MoveEnd: op = QTextCursor::End; break;
       
  2516         default: return;
       
  2517     }
       
  2518     cursor.movePosition(op, mode);
       
  2519     d->control->setTextCursor(cursor);
       
  2520 }
       
  2521 
       
  2522 /*!
       
  2523     Use the QTextCursor class instead.
       
  2524 */
       
  2525 void QTextEdit::moveCursor(CursorAction action, bool select)
       
  2526 {
       
  2527     moveCursor(action, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
       
  2528 }
       
  2529 
       
  2530 /*!
       
  2531     Executes keyboard action \a action.
       
  2532 
       
  2533     Use the QTextCursor class instead.
       
  2534 
       
  2535     \sa textCursor()
       
  2536 */
       
  2537 void QTextEdit::doKeyboardAction(KeyboardAction action)
       
  2538 {
       
  2539     Q_D(QTextEdit);
       
  2540     QTextCursor cursor = d->control->textCursor();
       
  2541     switch (action) {
       
  2542         case ActionBackspace: cursor.deletePreviousChar(); break;
       
  2543         case ActionDelete: cursor.deleteChar(); break;
       
  2544         case ActionReturn: cursor.insertBlock(); break;
       
  2545         case ActionKill: {
       
  2546                 QTextBlock block = cursor.block();
       
  2547                 if (cursor.position() == block.position() + block.length() - 2)
       
  2548                     cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
       
  2549                 else
       
  2550                     cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
       
  2551                 cursor.deleteChar();
       
  2552                 break;
       
  2553             }
       
  2554         case ActionWordBackspace:
       
  2555             cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
       
  2556             cursor.deletePreviousChar();
       
  2557             break;
       
  2558         case ActionWordDelete:
       
  2559             cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
       
  2560             cursor.deleteChar();
       
  2561             break;
       
  2562     }
       
  2563     d->control->setTextCursor(cursor);
       
  2564 }
       
  2565 
       
  2566 /*!
       
  2567     Returns all the text in the text edit as plain text.
       
  2568 */
       
  2569 QString QTextEdit::text() const
       
  2570 {
       
  2571     Q_D(const QTextEdit);
       
  2572     if (d->textFormat == Qt::RichText || d->textFormat == Qt::LogText || (d->textFormat == Qt::AutoText && d->preferRichText))
       
  2573         return d->control->toHtml();
       
  2574     else
       
  2575         return d->control->toPlainText();
       
  2576 }
       
  2577 
       
  2578 
       
  2579 /*!
       
  2580     Sets the text format to format \a f.
       
  2581 
       
  2582     \sa textFormat()
       
  2583 */
       
  2584 void QTextEdit::setTextFormat(Qt::TextFormat f)
       
  2585 {
       
  2586     Q_D(QTextEdit);
       
  2587     d->textFormat = f;
       
  2588 }
       
  2589 
       
  2590 /*!
       
  2591     Returns the text format.
       
  2592 
       
  2593     \sa setTextFormat()
       
  2594 */
       
  2595 Qt::TextFormat QTextEdit::textFormat() const
       
  2596 {
       
  2597     Q_D(const QTextEdit);
       
  2598     return d->textFormat;
       
  2599 }
       
  2600 
       
  2601 #endif // QT3_SUPPORT
       
  2602 
       
  2603 /*!
       
  2604     Appends a new paragraph with \a text to the end of the text edit.
       
  2605 
       
  2606     \note The new paragraph appended will have the same character format and
       
  2607     block format as the current paragraph, determined by the position of the cursor.
       
  2608 
       
  2609     \sa currentCharFormat(), QTextCursor::blockFormat()
       
  2610 */
       
  2611 
       
  2612 void QTextEdit::append(const QString &text)
       
  2613 {
       
  2614     Q_D(QTextEdit);
       
  2615     QTextBlock lastBlock = d->control->document()->lastBlock();
       
  2616     const bool atBottom = isReadOnly() ?  d->verticalOffset() >= d->vbar->maximum() :
       
  2617             d->control->textCursor().atEnd();
       
  2618     d->control->append(text);
       
  2619     if (atBottom)
       
  2620         d->vbar->setValue(d->vbar->maximum());
       
  2621 }
       
  2622 
       
  2623 /*!
       
  2624     Ensures that the cursor is visible by scrolling the text edit if
       
  2625     necessary.
       
  2626 */
       
  2627 void QTextEdit::ensureCursorVisible()
       
  2628 {
       
  2629     Q_D(QTextEdit);
       
  2630     d->control->ensureCursorVisible();
       
  2631 }
       
  2632 
       
  2633 /*!
       
  2634     \enum QTextEdit::KeyboardAction
       
  2635 
       
  2636     \compat
       
  2637 
       
  2638     \value ActionBackspace
       
  2639     \value ActionDelete
       
  2640     \value ActionReturn
       
  2641     \value ActionKill
       
  2642     \value ActionWordBackspace
       
  2643     \value ActionWordDelete
       
  2644 */
       
  2645 
       
  2646 /*!
       
  2647     \fn bool QTextEdit::find(const QString &exp, bool cs, bool wo)
       
  2648 
       
  2649     Use the find() overload that takes a QTextDocument::FindFlags
       
  2650     argument.
       
  2651 */
       
  2652 
       
  2653 /*!
       
  2654     \fn void QTextEdit::sync()
       
  2655 
       
  2656     Does nothing.
       
  2657 */
       
  2658 
       
  2659 /*!
       
  2660     \fn void QTextEdit::setBold(bool b)
       
  2661 
       
  2662     Use setFontWeight() instead.
       
  2663 */
       
  2664 
       
  2665 /*!
       
  2666     \fn void QTextEdit::setUnderline(bool b)
       
  2667 
       
  2668     Use setFontUnderline() instead.
       
  2669 */
       
  2670 
       
  2671 /*!
       
  2672     \fn void QTextEdit::setItalic(bool i)
       
  2673 
       
  2674     Use setFontItalic() instead.
       
  2675 */
       
  2676 
       
  2677 /*!
       
  2678     \fn void QTextEdit::setFamily(const QString &family)
       
  2679 
       
  2680     Use setFontFamily() instead.
       
  2681 */
       
  2682 
       
  2683 /*!
       
  2684     \fn void QTextEdit::setPointSize(int size)
       
  2685 
       
  2686     Use setFontPointSize() instead.
       
  2687 */
       
  2688 
       
  2689 /*!
       
  2690     \fn bool QTextEdit::italic() const
       
  2691 
       
  2692     Use fontItalic() instead.
       
  2693 */
       
  2694 
       
  2695 /*!
       
  2696     \fn bool QTextEdit::bold() const
       
  2697 
       
  2698     Use fontWeight() >= QFont::Bold instead.
       
  2699 */
       
  2700 
       
  2701 /*!
       
  2702     \fn bool QTextEdit::underline() const
       
  2703 
       
  2704     Use fontUnderline() instead.
       
  2705 */
       
  2706 
       
  2707 /*!
       
  2708     \fn QString QTextEdit::family() const
       
  2709 
       
  2710     Use fontFamily() instead.
       
  2711 */
       
  2712 
       
  2713 /*!
       
  2714     \fn int QTextEdit::pointSize() const
       
  2715 
       
  2716     Use int(fontPointSize()+0.5) instead.
       
  2717 */
       
  2718 
       
  2719 /*!
       
  2720     \fn bool QTextEdit::hasSelectedText() const
       
  2721 
       
  2722     Use textCursor().hasSelection() instead.
       
  2723 */
       
  2724 
       
  2725 /*!
       
  2726     \fn QString QTextEdit::selectedText() const
       
  2727 
       
  2728     Use textCursor().selectedText() instead.
       
  2729 */
       
  2730 
       
  2731 /*!
       
  2732     \fn bool QTextEdit::isUndoAvailable() const
       
  2733 
       
  2734     Use document()->isUndoAvailable() instead.
       
  2735 */
       
  2736 
       
  2737 /*!
       
  2738     \fn bool QTextEdit::isRedoAvailable() const
       
  2739 
       
  2740     Use document()->isRedoAvailable() instead.
       
  2741 */
       
  2742 
       
  2743 /*!
       
  2744     \fn void QTextEdit::insert(const QString &text)
       
  2745 
       
  2746     Use insertPlainText() instead.
       
  2747 */
       
  2748 
       
  2749 /*!
       
  2750     \fn bool QTextEdit::isModified() const
       
  2751 
       
  2752     Use document()->isModified() instead.
       
  2753 */
       
  2754 
       
  2755 /*!
       
  2756     \fn QColor QTextEdit::color() const
       
  2757 
       
  2758     Use textColor() instead.
       
  2759 */
       
  2760 
       
  2761 /*!
       
  2762     \fn void QTextEdit::textChanged()
       
  2763 
       
  2764     This signal is emitted whenever the document's content changes; for
       
  2765     example, when text is inserted or deleted, or when formatting is applied.
       
  2766 */
       
  2767 
       
  2768 /*!
       
  2769     \fn void QTextEdit::undoAvailable(bool available)
       
  2770 
       
  2771     This signal is emitted whenever undo operations become available
       
  2772     (\a available is true) or unavailable (\a available is false).
       
  2773 */
       
  2774 
       
  2775 /*!
       
  2776     \fn void QTextEdit::redoAvailable(bool available)
       
  2777 
       
  2778     This signal is emitted whenever redo operations become available
       
  2779     (\a available is true) or unavailable (\a available is false).
       
  2780 */
       
  2781 
       
  2782 /*!
       
  2783     \fn void QTextEdit::currentFontChanged(const QFont &font)
       
  2784 
       
  2785     Use currentCharFormatChanged() instead.
       
  2786 */
       
  2787 
       
  2788 /*!
       
  2789     \fn void QTextEdit::currentColorChanged(const QColor &color)
       
  2790 
       
  2791     Use currentCharFormatChanged() instead.
       
  2792 */
       
  2793 
       
  2794 /*!
       
  2795     \fn void QTextEdit::setModified(bool m)
       
  2796 
       
  2797     Use document->setModified() instead.
       
  2798 */
       
  2799 
       
  2800 /*!
       
  2801     \fn void QTextEdit::setColor(const QColor &color)
       
  2802 
       
  2803     Use setTextColor() instead.
       
  2804 */
       
  2805 #endif // QT_NO_TEXTEDIT
       
  2806 
       
  2807 QT_END_NAMESPACE
       
  2808 
       
  2809 #include "moc_qtextedit.cpp"