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