src/gui/widgets/qtextedit.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qtextedit_p.h"
00025 #include "qlineedit.h"
00026 #include "qtextbrowser.h"
00027 
00028 QStringList QTextEditMimeData::formats() const
00029 {
00030     if (!fragment.isEmpty())
00031         return QStringList() << QString::fromLatin1("text/plain") << QString::fromLatin1("text/html");
00032     else
00033         return QMimeData::formats();
00034 }
00035 
00036 QVariant QTextEditMimeData::retrieveData(const QString &mimeType, QVariant::Type type) const
00037 {
00038     if (!fragment.isEmpty())
00039         setup();
00040     return QMimeData::retrieveData(mimeType, type);
00041 }
00042 
00043 void QTextEditMimeData::setup() const
00044 {
00045     QTextEditMimeData *that = const_cast<QTextEditMimeData *>(this);
00046     that->setData(QLatin1String("text/html"), fragment.toHtml("utf-8").toUtf8());
00047     that->setText(fragment.toPlainText());
00048     fragment = QTextDocumentFragment();
00049 }
00050 
00051 #ifndef QT_NO_TEXTEDIT
00052 
00053 #include <qfont.h>
00054 #include <qpainter.h>
00055 #include <qevent.h>
00056 #include <qdebug.h>
00057 #include <qmime.h>
00058 #include <qdrag.h>
00059 #include <qclipboard.h>
00060 #include <qmenu.h>
00061 #include <qstyle.h>
00062 #include <qtimer.h>
00063 #include "private/qtextdocumentlayout_p.h"
00064 #include "qtextdocument.h"
00065 #include "private/qtextdocument_p.h"
00066 #include "qtextlist.h"
00067 #include "private/qtextcontrol_p.h"
00068 
00069 #include <qtextformat.h>
00070 #include <qdatetime.h>
00071 #include <qapplication.h>
00072 #include <limits.h>
00073 #include <qtexttable.h>
00074 #include <qvariant.h>
00075 
00076 #include <qinputcontext.h>
00077 
00078 class QTextEditControl : public QTextControl
00079 {
00080 public:
00081     inline QTextEditControl(QObject *parent) : QTextControl(parent) {}
00082 
00083     virtual QMimeData *createMimeDataFromSelection() const {
00084         QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
00085         if (!ed)
00086             return QTextControl::createMimeDataFromSelection();
00087         return ed->createMimeDataFromSelection();
00088     }
00089     virtual bool canInsertFromMimeData(const QMimeData *source) const {
00090         QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
00091         if (!ed)
00092             return QTextControl::canInsertFromMimeData(source);
00093         return ed->canInsertFromMimeData(source);
00094     }
00095     virtual void insertFromMimeData(const QMimeData *source) {
00096         QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
00097         if (!ed)
00098             QTextControl::insertFromMimeData(source);
00099         else
00100             ed->insertFromMimeData(source);
00101     }
00102 };
00103 
00104 QTextEditPrivate::QTextEditPrivate()
00105     : control(0),
00106       autoFormatting(QTextEdit::AutoNone), tabChangesFocus(false),
00107       lineWrap(QTextEdit::WidgetWidth), lineWrapColumnOrWidth(0),
00108       textFormat(Qt::AutoText)
00109 {
00110     ignoreAutomaticScrollbarAdjustment = false;
00111     preferRichText = false;
00112     showCursorOnInitialShow = true;
00113 }
00114 
00115 void QTextEditPrivate::createAutoBulletList()
00116 {
00117     QTextCursor cursor = control->textCursor();
00118     cursor.beginEditBlock();
00119 
00120     QTextBlockFormat blockFmt = cursor.blockFormat();
00121 
00122     QTextListFormat listFmt;
00123     listFmt.setStyle(QTextListFormat::ListDisc);
00124     listFmt.setIndent(blockFmt.indent() + 1);
00125 
00126     blockFmt.setIndent(0);
00127     cursor.setBlockFormat(blockFmt);
00128 
00129     cursor.createList(listFmt);
00130 
00131     cursor.endEditBlock();
00132     control->setTextCursor(cursor);
00133 }
00134 
00135 void QTextEditPrivate::init(const QString &html)
00136 {
00137     Q_Q(QTextEdit);
00138     control = new QTextEditControl(q);
00139     control->setPalette(q->palette());
00140 
00141     QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
00142     QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
00143     QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
00144     QObject::connect(control, SIGNAL(visibilityRequest(QRectF)), q, SLOT(_q_ensureVisible(QRectF)));
00145     QObject::connect(control, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
00146                      q, SLOT(_q_currentCharFormatChanged(QTextCharFormat)));
00147 
00148     QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
00149     QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
00150     QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
00151     QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
00152     QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
00153     QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
00154 
00155     QTextDocument *doc = control->document();
00156     // set a null page size initially to avoid any relayouting until the textedit
00157     // is shown. relayoutDocument() will take care of setting the page size to the
00158     // viewport dimensions later.
00159     doc->setPageSize(QSize(0, 0));
00160     doc->documentLayout()->setPaintDevice(viewport);
00161     doc->setDefaultFont(q->font());
00162 
00163     if (!html.isEmpty())
00164         control->setHtml(html);
00165 
00166     hbar->setSingleStep(20);
00167     vbar->setSingleStep(20);
00168 
00169     viewport->setBackgroundRole(QPalette::Base);
00170     q->setAcceptDrops(true);
00171     q->setFocusPolicy(Qt::WheelFocus);
00172     q->setAttribute(Qt::WA_KeyCompression);
00173     q->setAttribute(Qt::WA_InputMethodEnabled);
00174 
00175 #ifndef QT_NO_CURSOR
00176     viewport->setCursor(Qt::IBeamCursor);
00177 #endif
00178 }
00179 
00180 void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
00181 {
00182     if (!contentsRect.isValid()) {
00183         viewport->update();
00184         return;
00185     }
00186     const int xOffset = horizontalOffset();
00187     const int yOffset = verticalOffset();
00188     const QRectF visibleRect(xOffset, yOffset, viewport->width(), viewport->height());
00189 
00190     QRect r = contentsRect.intersected(visibleRect).toRect();
00191     if (r.isEmpty())
00192         return;
00193 
00194     r.translate(-xOffset, -yOffset);
00195     viewport->update(r);
00196 }
00197 
00198 void QTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
00199 {
00200     QTextCursor cursor = control->textCursor();
00201     bool moved = false;
00202     qreal lastY = control->cursorRect(cursor).top();
00203     qreal distance = 0;
00204     // move using movePosition to keep the cursor's x
00205     do {
00206         qreal y = control->cursorRect(cursor).top();
00207         distance += qAbs(y - lastY);
00208         lastY = y;
00209         moved = cursor.movePosition(op, moveMode);
00210     } while (moved && distance < viewport->height());
00211 
00212     if (moved) {
00213         if (op == QTextCursor::Up) {
00214             cursor.movePosition(QTextCursor::Down, moveMode);
00215             vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
00216         } else {
00217             cursor.movePosition(QTextCursor::Up, moveMode);
00218             vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
00219         }
00220     }
00221     control->setTextCursor(cursor);
00222 }
00223 
00224 #ifndef QT_NO_SCROLLBAR
00225 void QTextEditPrivate::_q_adjustScrollbars()
00226 {
00227     if (ignoreAutomaticScrollbarAdjustment)
00228         return;
00229     ignoreAutomaticScrollbarAdjustment = true; // avoid recursion, #106108
00230 
00231     QTextDocument *doc = control->document();
00232     QAbstractTextDocumentLayout *layout = doc->documentLayout();
00233 
00234     const QSize viewportSize = viewport->size();
00235     QSize docSize;
00236 
00237     if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
00238         docSize = tlayout->dynamicDocumentSize().toSize();
00239         int percentageDone = tlayout->layoutStatus();
00240         // extrapolate height
00241         if (percentageDone > 0)
00242             docSize.setHeight(docSize.height() * 100 / percentageDone);
00243     } else {
00244         docSize = layout->documentSize().toSize();
00245     }
00246 
00247     hbar->setRange(0, docSize.width() - viewportSize.width());
00248     hbar->setPageStep(viewportSize.width());
00249 
00250     vbar->setRange(0, docSize.height() - viewportSize.height());
00251     vbar->setPageStep(viewportSize.height());
00252 
00253     // if we are in left-to-right mode widening the document due to
00254     // lazy layouting does not require a repaint. If in right-to-left
00255     // the scrollbar has the value zero and it visually has the maximum
00256     // value (it is visually at the right), then widening the document
00257     // keeps it at value zero but visually adjusts it to the new maximum
00258     // on the right, hence we need an update.
00259     if (q_func()->isRightToLeft())
00260         viewport->update();
00261 
00262     _q_showOrHideScrollBars();
00263     ignoreAutomaticScrollbarAdjustment = false;
00264 }
00265 #endif
00266 
00267 // rect is in content coordinates
00268 void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
00269 {
00270     const QRect rect = _rect.toRect();
00271     const int visibleWidth = viewport->width();
00272     const int visibleHeight = viewport->height();
00273     const bool rtl = q_func()->isRightToLeft();
00274 
00275     if (rect.x() < horizontalOffset()) {
00276         if (rtl)
00277             hbar->setValue(hbar->maximum() - rect.x());
00278         else
00279             hbar->setValue(rect.x());
00280     } else if (rect.x() + rect.width() > horizontalOffset() + visibleWidth) {
00281         if (rtl)
00282             hbar->setValue(hbar->maximum() - (rect.x() + rect.width() - visibleWidth));
00283         else
00284             hbar->setValue(rect.x() + rect.width() - visibleWidth);
00285     }
00286 
00287     if (rect.y() < verticalOffset())
00288         vbar->setValue(rect.y());
00289     else if (rect.y() + rect.height() > verticalOffset() + visibleHeight)
00290         vbar->setValue(rect.y() + rect.height() - visibleHeight);
00291 }
00292 
00293 void QTextEditPrivate::ensureViewportLayouted()
00294 {
00295     QAbstractTextDocumentLayout *layout = control->document()->documentLayout();
00296     if (!layout)
00297         return;
00298     if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout))
00299         tlayout->ensureLayouted(verticalOffset() + viewport->height());
00300 }
00301 
00499 #ifdef QT3_SUPPORT
00500 
00519 #endif
00520 
00525 QTextEdit::QTextEdit(QWidget *parent)
00526     : QAbstractScrollArea(*new QTextEditPrivate, parent)
00527 {
00528     Q_D(QTextEdit);
00529     d->init();
00530 }
00531 
00535 QTextEdit::QTextEdit(QTextEditPrivate &dd, QWidget *parent)
00536     : QAbstractScrollArea(dd, parent)
00537 {
00538     Q_D(QTextEdit);
00539     d->init();
00540 }
00541 
00546 QTextEdit::QTextEdit(const QString &text, QWidget *parent)
00547     : QAbstractScrollArea(*new QTextEditPrivate, parent)
00548 {
00549     Q_D(QTextEdit);
00550     d->init(text);
00551 }
00552 
00553 #ifdef QT3_SUPPORT
00554 
00558 QTextEdit::QTextEdit(QWidget *parent, const char *name)
00559     : QAbstractScrollArea(*new QTextEditPrivate, parent)
00560 {
00561     Q_D(QTextEdit);
00562     d->init();
00563     setObjectName(QString::fromAscii(name));
00564 }
00565 #endif
00566 
00567 
00571 QTextEdit::~QTextEdit()
00572 {
00573 }
00574 
00580 qreal QTextEdit::fontPointSize() const
00581 {
00582     Q_D(const QTextEdit);
00583     return d->control->textCursor().charFormat().fontPointSize();
00584 }
00585 
00591 QString QTextEdit::fontFamily() const
00592 {
00593     Q_D(const QTextEdit);
00594     return d->control->textCursor().charFormat().fontFamily();
00595 }
00596 
00602 int QTextEdit::fontWeight() const
00603 {
00604     Q_D(const QTextEdit);
00605     return d->control->textCursor().charFormat().fontWeight();
00606 }
00607 
00614 bool QTextEdit::fontUnderline() const
00615 {
00616     Q_D(const QTextEdit);
00617     return d->control->textCursor().charFormat().fontUnderline();
00618 }
00619 
00626 bool QTextEdit::fontItalic() const
00627 {
00628     Q_D(const QTextEdit);
00629     return d->control->textCursor().charFormat().fontItalic();
00630 }
00631 
00637 QColor QTextEdit::textColor() const
00638 {
00639     Q_D(const QTextEdit);
00640     return d->control->textCursor().charFormat().foreground().color();
00641 }
00642 
00648 QFont QTextEdit::currentFont() const
00649 {
00650     Q_D(const QTextEdit);
00651     return d->control->textCursor().charFormat().font();
00652 }
00653 
00660 void QTextEdit::setAlignment(Qt::Alignment a)
00661 {
00662     Q_D(QTextEdit);
00663     QTextBlockFormat fmt;
00664     fmt.setAlignment(a);
00665     QTextCursor cursor = d->control->textCursor();
00666     cursor.mergeBlockFormat(fmt);
00667     d->control->setTextCursor(cursor);
00668 }
00669 
00675 Qt::Alignment QTextEdit::alignment() const
00676 {
00677     Q_D(const QTextEdit);
00678     return d->control->textCursor().blockFormat().alignment();
00679 }
00680 
00690 void QTextEdit::setDocument(QTextDocument *document)
00691 {
00692     Q_D(QTextEdit);
00693     d->control->setDocument(document);
00694     d->relayoutDocument();
00695 }
00696 
00702 QTextDocument *QTextEdit::document() const
00703 {
00704     Q_D(const QTextEdit);
00705     return d->control->document();
00706 }
00707 
00711 void QTextEdit::setTextCursor(const QTextCursor &cursor)
00712 {
00713     Q_D(QTextEdit);
00714     d->control->setTextCursor(cursor);
00715 }
00716 
00722 QTextCursor QTextEdit::textCursor() const
00723 {
00724     Q_D(const QTextEdit);
00725     return d->control->textCursor();
00726 }
00727 
00733 void QTextEdit::setFontFamily(const QString &fontFamily)
00734 {
00735     QTextCharFormat fmt;
00736     fmt.setFontFamily(fontFamily);
00737     mergeCurrentCharFormat(fmt);
00738 }
00739 
00748 void QTextEdit::setFontPointSize(qreal s)
00749 {
00750     QTextCharFormat fmt;
00751     fmt.setFontPointSize(s);
00752     mergeCurrentCharFormat(fmt);
00753 }
00754 
00764 void QTextEdit::setFontWeight(int w)
00765 {
00766     QTextCharFormat fmt;
00767     fmt.setFontWeight(w);
00768     mergeCurrentCharFormat(fmt);
00769 }
00770 
00777 void QTextEdit::setFontUnderline(bool underline)
00778 {
00779     QTextCharFormat fmt;
00780     fmt.setFontUnderline(underline);
00781     mergeCurrentCharFormat(fmt);
00782 }
00783 
00790 void QTextEdit::setFontItalic(bool italic)
00791 {
00792     QTextCharFormat fmt;
00793     fmt.setFontItalic(italic);
00794     mergeCurrentCharFormat(fmt);
00795 }
00796 
00802 void QTextEdit::setTextColor(const QColor &c)
00803 {
00804     QTextCharFormat fmt;
00805     fmt.setForeground(QBrush(c));
00806     mergeCurrentCharFormat(fmt);
00807 }
00808 
00814 void QTextEdit::setCurrentFont(const QFont &f)
00815 {
00816     QTextCharFormat fmt;
00817     fmt.setFont(f);
00818     mergeCurrentCharFormat(fmt);
00819 }
00820 
00831 void QTextEdit::undo()
00832 {
00833     Q_D(QTextEdit);
00834     d->control->undo();
00835 }
00836 
00837 void QTextEdit::redo()
00838 {
00839     Q_D(QTextEdit);
00840     d->control->redo();
00841 }
00842 
00863 #ifndef QT_NO_CLIPBOARD
00864 
00873 void QTextEdit::cut()
00874 {
00875     Q_D(QTextEdit);
00876     d->control->cut();
00877 }
00878 
00885 void QTextEdit::copy()
00886 {
00887     Q_D(QTextEdit);
00888     d->control->copy();
00889 }
00890 
00905 void QTextEdit::paste()
00906 {
00907     Q_D(QTextEdit);
00908     d->control->paste();
00909 }
00910 #endif
00911 
00919 void QTextEdit::clear()
00920 {
00921     Q_D(QTextEdit);
00922     // clears and sets empty content
00923     d->control->clear();
00924 }
00925 
00926 
00932 void QTextEdit::selectAll()
00933 {
00934     Q_D(QTextEdit);
00935     d->control->selectAll();
00936 }
00937 
00940 bool QTextEdit::event(QEvent *e)
00941 {
00942     Q_D(QTextEdit);
00943     if (e->type() == QEvent::ContextMenu
00944         && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
00945         Q_D(QTextEdit);
00946         ensureCursorVisible();
00947         const QPoint cursorPos = cursorRect().center();
00948         QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
00949         ce.setAccepted(e->isAccepted());
00950         const bool result = QAbstractScrollArea::event(&ce);
00951         e->setAccepted(ce.isAccepted());
00952         return result;
00953     } else if (e->type() == QEvent::ShortcutOverride) {
00954         d->sendControlEvent(e);
00955     }
00956     return QAbstractScrollArea::event(e);
00957 }
00958 
00962 void QTextEdit::timerEvent(QTimerEvent *e)
00963 {
00964     Q_D(QTextEdit);
00965     if (e->timerId() == d->autoScrollTimer.timerId()) {
00966         const QPoint globalPos = QCursor::pos();
00967         const QPoint pos = d->viewport->mapFromGlobal(globalPos);
00968         QMouseEvent ev(QEvent::MouseMove, pos, globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
00969         mouseMoveEvent(&ev);
00970     }
00971 #ifdef QT_KEYPAD_NAVIGATION
00972     else if (e->timerId() == d->deleteAllTimer.timerId()) {
00973         d->deleteAllTimer.stop();
00974         clear();
00975     }
00976 #endif
00977 }
00978 
00990 void QTextEdit::setPlainText(const QString &text)
00991 {
00992     Q_D(QTextEdit);
00993     d->control->setPlainText(text);
00994     d->preferRichText = false;
00995 }
00996 
01021 void QTextEdit::setHtml(const QString &text)
01022 {
01023     Q_D(QTextEdit);
01024     d->control->setHtml(text);
01025     d->preferRichText = true;
01026 }
01027 
01030 void QTextEdit::keyPressEvent(QKeyEvent *e)
01031 {
01032     Q_D(QTextEdit);
01033 
01034 #ifdef QT_KEYPAD_NAVIGATION
01035     switch (e->key()) {
01036         case Qt::Key_Select:
01037             if (QApplication::keypadNavigationEnabled())
01038                 setEditFocus(!hasEditFocus());
01039             break;
01040         case Qt::Key_Back:
01041         case Qt::Key_No:
01042             if (!QApplication::keypadNavigationEnabled()
01043                     || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) {
01044                 e->ignore();
01045                 return;
01046             }
01047             break;
01048         default:
01049             if (QApplication::keypadNavigationEnabled()) {
01050                 if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
01051                     if (e->text()[0].isPrint()) {
01052                         setEditFocus(true);
01053                         clear();
01054                     } else {
01055                         e->ignore();
01056                         return;
01057                     }
01058                 }
01059             }
01060             break;
01061     }
01062 #endif
01063 
01064     if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
01065         switch (e->key()) {
01066             case Qt::Key_Space:
01067                 e->accept();
01068                 if (e->modifiers() & Qt::ShiftModifier)
01069                     d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
01070                 else
01071                     d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
01072                 break;
01073             default:
01074                 d->sendControlEvent(e);
01075                 if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
01076                     if (e->key() == Qt::Key_Home) {
01077                         d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
01078                         e->accept();
01079                     } else if (e->key() == Qt::Key_End) {
01080                         d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
01081                         e->accept();
01082                     }
01083                 }
01084                 if (!e->isAccepted()) {
01085                     QAbstractScrollArea::keyPressEvent(e);
01086                 }
01087         }
01088         return;
01089     }
01090 
01091 #ifndef QT_NO_SHORTCUT
01092     if (e == QKeySequence::MoveToPreviousPage) {
01093             e->accept();
01094             d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
01095             return;
01096     } else if (e == QKeySequence::MoveToNextPage) {
01097             e->accept();
01098             d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
01099             return;
01100     } else if (e == QKeySequence::SelectPreviousPage) {
01101             e->accept();
01102             d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
01103             return;
01104     } else if (e ==QKeySequence::SelectNextPage) {
01105             e->accept();
01106             d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
01107             return;
01108     }
01109 #endif // QT_NO_SHORTCUT
01110 
01111     {
01112         QTextCursor cursor = d->control->textCursor();
01113         const QString text = e->text();
01114         if (cursor.atBlockStart()
01115             && (d->autoFormatting & AutoBulletList)
01116             && (text.length() == 1)
01117             && (text.at(0) == QLatin1Char('-') || text.at(0) == QLatin1Char('*'))
01118             && (!cursor.currentList())) {
01119 
01120             d->createAutoBulletList();
01121             e->accept();
01122             return;
01123         }
01124     }
01125 
01126     d->sendControlEvent(e);
01127 #ifdef QT_KEYPAD_NAVIGATION
01128     if (!e->isAccepted()) {
01129         switch (e->key()) {
01130             case Qt::Key_Up:
01131             case Qt::Key_Down:
01132                 if (QApplication::keypadNavigationEnabled()) {
01133                     // Cursor position didn't change, so we want to leave
01134                     // these keys to change focus.
01135                     e->ignore();
01136                     return;
01137                 }
01138                 break;
01139             case Qt::Key_Back:
01140                 if (!e->isAutoRepeat()) {
01141                     if (QApplication::keypadNavigationEnabled()) {
01142                         if (document()->isEmpty()) {
01143                             setEditFocus(false);
01144                         } else if (!d->deleteAllTimer.isActive()) {
01145                             e->accept();
01146                             d->deleteAllTimer.start(750, this);
01147                         }
01148                     } else {
01149                         e->ignore();
01150                         return;
01151                     }
01152                 }
01153                 break;
01154             default: break;
01155         }
01156     }
01157 #endif
01158 }
01159 
01162 void QTextEdit::keyReleaseEvent(QKeyEvent *e)
01163 {
01164 #ifdef QT_KEYPAD_NAVIGATION
01165     Q_D(QTextEdit);
01166     if (QApplication::keypadNavigationEnabled()) {
01167         if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
01168             && d->deleteAllTimer.isActive()) {
01169             d->deleteAllTimer.stop();
01170             QTextCursor cursor = d->control->textCursor();
01171             QTextBlockFormat blockFmt = cursor.blockFormat();
01172 
01173             QTextList *list = cursor.currentList();
01174             if (list && cursor.atBlockStart()) {
01175                 list->remove(cursor.block());
01176             } else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
01177                 blockFmt.setIndent(blockFmt.indent() - 1);
01178                 cursor.setBlockFormat(blockFmt);
01179             } else {
01180                 cursor.deletePreviousChar();
01181             }
01182             setTextCursor(cursor);
01183         }
01184     }
01185 #else
01186     Q_UNUSED(e);
01187 #endif
01188 }
01189 
01197 QVariant QTextEdit::loadResource(int type, const QUrl &name)
01198 {
01199     Q_UNUSED(type);
01200     Q_UNUSED(name);
01201     return QVariant();
01202 }
01203 
01206 void QTextEdit::resizeEvent(QResizeEvent *e)
01207 {
01208     Q_D(QTextEdit);
01209     if (d->lineWrap == WidgetWidth) {
01210         if (e->oldSize().width() == e->size().width()
01211             && e->oldSize().height() != e->size().height())
01212             d->_q_adjustScrollbars();
01213         else
01214             d->relayoutDocument();
01215     } else {
01216         d->_q_adjustScrollbars();
01217     }
01218 }
01219 
01220 void QTextEditPrivate::relayoutDocument()
01221 {
01222     QTextDocument *doc = control->document();
01223     QAbstractTextDocumentLayout *layout = doc->documentLayout();
01224 
01225     if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
01226         if (lineWrap == QTextEdit::FixedColumnWidth)
01227             tlayout->setFixedColumnWidth(lineWrapColumnOrWidth);
01228         else
01229             tlayout->setFixedColumnWidth(-1);
01230     }
01231 
01232     QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout);
01233     QSize lastUsedSize;
01234     if (tlayout)
01235         lastUsedSize = tlayout->dynamicDocumentSize().toSize();
01236     else
01237         lastUsedSize = layout->documentSize().toSize();
01238 
01239     // ignore calls to _q_adjustScrollbars caused by an emission of the
01240     // usedSizeChanged() signal in the layout, as we're calling it
01241     // later on our own anyway (or deliberately not) .
01242     const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
01243     ignoreAutomaticScrollbarAdjustment = true;
01244 
01245     int width = 0;
01246     switch (lineWrap) {
01247         case QTextEdit::NoWrap:
01248             width = -1;
01249             break;
01250         case QTextEdit::WidgetWidth:
01251             width = viewport->width();
01252             break;
01253         case QTextEdit::FixedPixelWidth:
01254             width = lineWrapColumnOrWidth;
01255             break;
01256         case QTextEdit::FixedColumnWidth:
01257             width = 0;
01258             break;
01259     }
01260 
01261     doc->setPageSize(QSize(width, INT_MAX));
01262     if (tlayout)
01263         tlayout->ensureLayouted(verticalOffset() + viewport->height());
01264 
01265     ignoreAutomaticScrollbarAdjustment = oldIgnoreScrollbarAdjustment;
01266 
01267     QSize usedSize;
01268     if (tlayout)
01269         usedSize = tlayout->dynamicDocumentSize().toSize();
01270     else
01271         usedSize = layout->documentSize().toSize();
01272 
01273     // this is an obscure situation in the layout that can happen:
01274     // if a character at the end of a line is the tallest one and therefore
01275     // influencing the total height of the line and the line right below it
01276     // is always taller though, then it can happen that if due to line breaking
01277     // that tall character wraps into the lower line the document not only shrinks
01278     // horizontally (causing the character to wrap in the first place) but also
01279     // vertically, because the original line is now smaller and the one below kept
01280     // its size. So a layout with less width _can_ take up less vertical space, too.
01281     // If the wider case causes a vertical scrollbar to appear and the narrower one
01282     // (narrower because the vertical scrollbar takes up horizontal space)) to disappear
01283     // again then we have an endless loop, as _q_adjustScrollBars sets new ranges on the
01284     // scrollbars, the QAbstractScrollArea will find out about it and try to show/hide the scrollbars
01285     // again. That's why we try to detect this case here and break out.
01286     //
01287     // (if you change this please also check the layoutingLoop() testcase in
01288     // QTextEdit's autotests)
01289     if (lastUsedSize.isValid()
01290         && !vbar->isHidden()
01291         && viewport->width() < lastUsedSize.width()
01292         && usedSize.height() < lastUsedSize.height()
01293         && usedSize.height() <= viewport->height())
01294         return;
01295 
01296     _q_adjustScrollbars();
01297 }
01298 
01299 void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
01300 {
01301     const int xOffset = horizontalOffset();
01302     const int yOffset = verticalOffset();
01303 
01304     QRect r = e->rect();
01305     p->translate(-xOffset, -yOffset);
01306     r.translate(xOffset, yOffset);
01307 
01308     control->drawContents(p, r);
01309 }
01310 
01313 void QTextEdit::paintEvent(QPaintEvent *e)
01314 {
01315     Q_D(QTextEdit);
01316     QPainter p(d->viewport);
01317     d->paint(&p, e);
01318 }
01319 
01320 void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
01321 {
01322     Q_Q(QTextEdit);
01323     emit q->currentCharFormatChanged(fmt);
01324 #ifdef QT3_SUPPORT
01325     // compat signals
01326     emit q->currentFontChanged(fmt.font());
01327     emit q->currentColorChanged(fmt.foreground().color());
01328 #endif
01329 }
01330 
01333 void QTextEdit::mousePressEvent(QMouseEvent *e)
01334 {
01335     Q_D(QTextEdit);
01336     d->sendControlEvent(e);
01337 }
01338 
01341 void QTextEdit::mouseMoveEvent(QMouseEvent *e)
01342 {
01343     Q_D(QTextEdit);
01344     const QPoint pos = e->pos();
01345     d->sendControlEvent(e);
01346     if (!(e->buttons() & Qt::LeftButton))
01347         return;
01348     if (d->autoScrollTimer.isActive()) {
01349         if (d->viewport->rect().contains(pos))
01350             d->autoScrollTimer.stop();
01351     } else {
01352         if (!d->viewport->rect().contains(pos))
01353             d->autoScrollTimer.start(100, this);
01354     }
01355 }
01356 
01359 void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
01360 {
01361     Q_D(QTextEdit);
01362     d->autoScrollTimer.stop();
01363     d->sendControlEvent(e);
01364 }
01365 
01368 void QTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
01369 {
01370     Q_D(QTextEdit);
01371     d->sendControlEvent(e);
01372 }
01373 
01376 bool QTextEdit::focusNextPrevChild(bool next)
01377 {
01378     Q_D(const QTextEdit);
01379     if (!d->tabChangesFocus && d->control->textInteractionFlags() & Qt::TextEditable)
01380         return false;
01381     return QAbstractScrollArea::focusNextPrevChild(next);
01382 }
01383 
01405 void QTextEdit::contextMenuEvent(QContextMenuEvent *e)
01406 {
01407     Q_D(QTextEdit);
01408     d->sendControlEvent(e);
01409 }
01410 
01411 #ifndef QT_NO_DRAGANDDROP
01412 
01414 void QTextEdit::dragEnterEvent(QDragEnterEvent *e)
01415 {
01416     Q_D(QTextEdit);
01417     d->sendControlEvent(e);
01418 }
01419 
01422 void QTextEdit::dragLeaveEvent(QDragLeaveEvent *e)
01423 {
01424     Q_D(QTextEdit);
01425     d->sendControlEvent(e);
01426 }
01427 
01430 void QTextEdit::dragMoveEvent(QDragMoveEvent *e)
01431 {
01432     Q_D(QTextEdit);
01433     d->sendControlEvent(e);
01434 }
01435 
01438 void QTextEdit::dropEvent(QDropEvent *e)
01439 {
01440     Q_D(QTextEdit);
01441     d->sendControlEvent(e);
01442 }
01443 
01444 #endif // QT_NO_DRAGANDDROP
01445 
01448 void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
01449 {
01450     Q_D(QTextEdit);
01451 #ifdef QT_KEYPAD_NAVIGATION
01452     if (d->control->textInteractionFlags() & Qt::TextEditable
01453         && QApplication::keypadNavigationEnabled()
01454         && !hasEditFocus())
01455         setEditFocus(true);
01456 #endif
01457     d->sendControlEvent(e);
01458 }
01459 
01462 void QTextEdit::scrollContentsBy(int dx, int dy)
01463 {
01464     Q_D(QTextEdit);
01465     if (isRightToLeft())
01466         dx = -dx;
01467     d->viewport->scroll(dx, dy);
01468 }
01469 
01472 QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
01473 {
01474     Q_D(const QTextEdit);
01475     QVariant v = d->control->inputMethodQuery(property);
01476     const QPoint offset(-d->horizontalOffset(), -d->verticalOffset());
01477     if (v.type() == QVariant::RectF)
01478         v = v.toRectF().toRect().translated(offset);
01479     else if (v.type() == QVariant::PointF)
01480         v = v.toPointF().toPoint() + offset;
01481     else if (v.type() == QVariant::Rect)
01482         v = v.toRect().translated(offset);
01483     else if (v.type() == QVariant::Point)
01484         v = v.toPoint() + offset;
01485     return v;
01486 }
01487 
01490 void QTextEdit::focusInEvent(QFocusEvent *e)
01491 {
01492     Q_D(QTextEdit);
01493     QAbstractScrollArea::focusInEvent(e);
01494     d->sendControlEvent(e);
01495 }
01496 
01499 void QTextEdit::focusOutEvent(QFocusEvent *e)
01500 {
01501     Q_D(QTextEdit);
01502     QAbstractScrollArea::focusOutEvent(e);
01503     d->sendControlEvent(e);
01504 }
01505 
01508 void QTextEdit::showEvent(QShowEvent *)
01509 {
01510     Q_D(QTextEdit);
01511     if (!d->anchorToScrollToWhenVisible.isEmpty()) {
01512         scrollToAnchor(d->anchorToScrollToWhenVisible);
01513         d->anchorToScrollToWhenVisible.clear();
01514         d->showCursorOnInitialShow = false;
01515     } else if (d->showCursorOnInitialShow) {
01516         d->showCursorOnInitialShow = false;
01517         ensureCursorVisible();
01518     }
01519 }
01520 
01523 void QTextEdit::changeEvent(QEvent *e)
01524 {
01525     Q_D(QTextEdit);
01526     QAbstractScrollArea::changeEvent(e);
01527     if (e->type() == QEvent::ApplicationFontChange
01528         || e->type() == QEvent::FontChange) {
01529         d->control->document()->setDefaultFont(font());
01530     }  else if(e->type() == QEvent::ActivationChange) {
01531         if (!isActiveWindow())
01532             d->autoScrollTimer.stop();
01533     } else if (e->type() == QEvent::EnabledChange) {
01534         e->setAccepted(isEnabled());
01535         d->sendControlEvent(e);
01536     } else if (e->type() == QEvent::PaletteChange) {
01537         d->control->setPalette(palette());
01538     }
01539 }
01540 
01543 #ifndef QT_NO_WHEELEVENT
01544 void QTextEdit::wheelEvent(QWheelEvent *e)
01545 {
01546     Q_D(QTextEdit);
01547     if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
01548         if (e->modifiers() & Qt::ControlModifier) {
01549             const int delta = e->delta();
01550             if (delta > 0)
01551                 zoomOut();
01552             else if (delta < 0)
01553                 zoomIn();
01554             return;
01555         }
01556     }
01557     QAbstractScrollArea::wheelEvent(e);
01558     updateMicroFocus();
01559 }
01560 #endif
01561 
01562 #ifndef QT_NO_CONTEXTMENU
01563 
01569 QMenu *QTextEdit::createStandardContextMenu()
01570 {
01571     Q_D(QTextEdit);
01572     return d->control->createStandardContextMenu(QPointF(), this);
01573 }
01574 #endif // QT_NO_CONTEXTMENU
01575 
01579 QTextCursor QTextEdit::cursorForPosition(const QPoint &pos) const
01580 {
01581     Q_D(const QTextEdit);
01582     return d->control->cursorForPosition(d->mapToContents(pos));
01583 }
01584 
01589 QRect QTextEdit::cursorRect(const QTextCursor &cursor) const
01590 {
01591     Q_D(const QTextEdit);
01592     if (cursor.isNull())
01593         return QRect();
01594 
01595     QRect r = d->control->cursorRect(cursor).toRect();
01596     r.translate(-d->horizontalOffset(),-d->verticalOffset());
01597     return r;
01598 }
01599 
01604 QRect QTextEdit::cursorRect() const
01605 {
01606     Q_D(const QTextEdit);
01607     QRect r = d->control->cursorRect().toRect();
01608     r.translate(-d->horizontalOffset(),-d->verticalOffset());
01609     return r;
01610 }
01611 
01612 
01617 QString QTextEdit::anchorAt(const QPoint& pos) const
01618 {
01619     Q_D(const QTextEdit);
01620     return d->control->anchorAt(d->mapToContents(pos));
01621 }
01622 
01628 bool QTextEdit::overwriteMode() const
01629 {
01630     Q_D(const QTextEdit);
01631     return d->control->overwriteMode();
01632 }
01633 
01634 void QTextEdit::setOverwriteMode(bool overwrite)
01635 {
01636     Q_D(QTextEdit);
01637     d->control->setOverwriteMode(overwrite);
01638 }
01639 
01646 int QTextEdit::tabStopWidth() const
01647 {
01648     Q_D(const QTextEdit);
01649     return d->control->tabStopWidth();
01650 }
01651 
01652 void QTextEdit::setTabStopWidth(int width)
01653 {
01654     Q_D(QTextEdit);
01655     d->control->setTabStopWidth(width);
01656 }
01657 
01664 int QTextEdit::cursorWidth() const
01665 {
01666     Q_D(const QTextEdit);
01667     return d->control->cursorWidth();
01668 }
01669 
01670 void QTextEdit::setCursorWidth(int width)
01671 {
01672     Q_D(QTextEdit);
01673     d->control->setCursorWidth(width);
01674 }
01675 
01687 bool QTextEdit::acceptRichText() const
01688 {
01689     Q_D(const QTextEdit);
01690     return d->control->acceptRichText();
01691 }
01692 
01693 void QTextEdit::setAcceptRichText(bool accept)
01694 {
01695     Q_D(QTextEdit);
01696     d->control->setAcceptRichText(accept);
01697 }
01698 
01726 void QTextEdit::setExtraSelections(const QList<ExtraSelection> &selections)
01727 {
01728     Q_D(QTextEdit);
01729     d->control->setExtraSelections(selections);
01730 }
01731 
01738 QList<QTextEdit::ExtraSelection> QTextEdit::extraSelections() const
01739 {
01740     Q_D(const QTextEdit);
01741     return d->control->extraSelections();
01742 }
01743 
01754 QMimeData *QTextEdit::createMimeDataFromSelection() const
01755 {
01756     Q_D(const QTextEdit);
01757     return d->control->QTextControl::createMimeDataFromSelection();
01758 }
01759 
01766 bool QTextEdit::canInsertFromMimeData(const QMimeData *source) const
01767 {
01768     Q_D(const QTextEdit);
01769     return d->control->QTextControl::canInsertFromMimeData(source);
01770 }
01771 
01779 void QTextEdit::insertFromMimeData(const QMimeData *source)
01780 {
01781     Q_D(QTextEdit);
01782     d->control->QTextControl::insertFromMimeData(source);
01783 }
01784 
01795 bool QTextEdit::isReadOnly() const
01796 {
01797     Q_D(const QTextEdit);
01798     return !(d->control->textInteractionFlags() & Qt::TextEditable);
01799 }
01800 
01801 void QTextEdit::setReadOnly(bool ro)
01802 {
01803     Q_D(QTextEdit);
01804     Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
01805     if (ro) {
01806         flags = Qt::TextSelectableByMouse;
01807 #ifndef QT_NO_TEXTBROWSER
01808         if (qobject_cast<QTextBrowser *>(this))
01809             flags |= Qt::TextBrowserInteraction;
01810 #endif
01811     } else {
01812         flags = Qt::TextEditorInteraction;
01813     }
01814     d->control->setTextInteractionFlags(flags);
01815 }
01816 
01830 void QTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
01831 {
01832     Q_D(QTextEdit);
01833     d->control->setTextInteractionFlags(flags);
01834 }
01835 
01836 Qt::TextInteractionFlags QTextEdit::textInteractionFlags() const
01837 {
01838     Q_D(const QTextEdit);
01839     return d->control->textInteractionFlags();
01840 }
01841 
01850 void QTextEdit::mergeCurrentCharFormat(const QTextCharFormat &modifier)
01851 {
01852     Q_D(QTextEdit);
01853     d->control->mergeCurrentCharFormat(modifier);
01854 }
01855 
01862 void QTextEdit::setCurrentCharFormat(const QTextCharFormat &format)
01863 {
01864     Q_D(QTextEdit);
01865     d->control->setCurrentCharFormat(format);
01866 }
01867 
01871 QTextCharFormat QTextEdit::currentCharFormat() const
01872 {
01873     Q_D(const QTextEdit);
01874     return d->control->currentCharFormat();
01875 }
01876 
01889 QTextEdit::AutoFormatting QTextEdit::autoFormatting() const
01890 {
01891     Q_D(const QTextEdit);
01892     return d->autoFormatting;
01893 }
01894 
01895 void QTextEdit::setAutoFormatting(AutoFormatting features)
01896 {
01897     Q_D(QTextEdit);
01898     d->autoFormatting = features;
01899 }
01900 
01911 void QTextEdit::insertPlainText(const QString &text)
01912 {
01913     Q_D(QTextEdit);
01914     d->control->insertPlainText(text);
01915 }
01916 
01927 void QTextEdit::insertHtml(const QString &text)
01928 {
01929     Q_D(QTextEdit);
01930     d->control->insertHtml(text);
01931 }
01932 
01938 void QTextEdit::scrollToAnchor(const QString &name)
01939 {
01940     Q_D(QTextEdit);
01941     if (name.isEmpty())
01942         return;
01943 
01944     if (!isVisible()) {
01945         d->anchorToScrollToWhenVisible = name;
01946         return;
01947     }
01948 
01949     QPointF p = d->control->anchorPosition(name);
01950     d->vbar->setValue(qRound(p.y()));
01951 }
01952 
01962 void QTextEdit::zoomIn(int range)
01963 {
01964     QFont f = font();
01965     const int newSize = f.pointSize() + range;
01966     if (newSize <= 0)
01967         return;
01968     f.setPointSize(newSize);
01969     setFont(f);
01970 }
01971 
01983 void QTextEdit::zoomOut(int range)
01984 {
01985     zoomIn(-range);
01986 }
01987 
01998 void QTextEdit::moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
01999 {
02000     Q_D(QTextEdit);
02001     d->control->moveCursor(operation, mode);
02002 }
02003 
02008 bool QTextEdit::canPaste() const
02009 {
02010     Q_D(const QTextEdit);
02011     return d->control->canPaste();
02012 }
02013 
02023 bool QTextEdit::tabChangesFocus() const
02024 {
02025     Q_D(const QTextEdit);
02026     return d->tabChangesFocus;
02027 }
02028 
02029 void QTextEdit::setTabChangesFocus(bool b)
02030 {
02031     Q_D(QTextEdit);
02032     d->tabChangesFocus = b;
02033 }
02034 
02054 QTextEdit::LineWrapMode QTextEdit::lineWrapMode() const
02055 {
02056     Q_D(const QTextEdit);
02057     return d->lineWrap;
02058 }
02059 
02060 void QTextEdit::setLineWrapMode(LineWrapMode wrap)
02061 {
02062     Q_D(QTextEdit);
02063     if (d->lineWrap == wrap)
02064         return;
02065     d->lineWrap = wrap;
02066     d->relayoutDocument();
02067 }
02068 
02082 int QTextEdit::lineWrapColumnOrWidth() const
02083 {
02084     Q_D(const QTextEdit);
02085     return d->lineWrapColumnOrWidth;
02086 }
02087 
02088 void QTextEdit::setLineWrapColumnOrWidth(int w)
02089 {
02090     Q_D(QTextEdit);
02091     d->lineWrapColumnOrWidth = w;
02092     d->relayoutDocument();
02093 }
02094 
02102 QTextOption::WrapMode QTextEdit::wordWrapMode() const
02103 {
02104     Q_D(const QTextEdit);
02105     return d->control->wordWrapMode();
02106 }
02107 
02108 void QTextEdit::setWordWrapMode(QTextOption::WrapMode mode)
02109 {
02110     Q_D(QTextEdit);
02111     d->control->setWordWrapMode(mode);
02112 }
02113 
02119 bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
02120 {
02121     Q_D(QTextEdit);
02122     return d->control->find(exp, options);
02123 }
02124 
02175 void QTextEdit::setText(const QString &text)
02176 {
02177     Q_D(QTextEdit);
02178     if (d->textFormat == Qt::AutoText)
02179         d->textFormat = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
02180     if (d->textFormat == Qt::RichText || d->textFormat == Qt::LogText)
02181         setHtml(text);
02182     else
02183         setPlainText(text);
02184 }
02185 
02186 #ifdef QT3_SUPPORT
02187 
02190 void QTextEdit::moveCursor(CursorAction action, QTextCursor::MoveMode mode)
02191 {
02192     Q_D(QTextEdit);
02193     if (action == MovePageUp) {
02194         d->pageUpDown(QTextCursor::Up, mode);
02195         return;
02196     } else if (action == MovePageDown) {
02197         d->pageUpDown(QTextCursor::Down, mode);
02198         return;
02199     }
02200 
02201     QTextCursor cursor = d->control->textCursor();
02202     QTextCursor::MoveOperation op = QTextCursor::NoMove;
02203     switch (action) {
02204         case MoveBackward: op = QTextCursor::Left; break;
02205         case MoveForward: op = QTextCursor::Right; break;
02206         case MoveWordBackward: op = QTextCursor::WordLeft; break;
02207         case MoveWordForward: op = QTextCursor::WordRight; break;
02208         case MoveUp: op = QTextCursor::Up; break;
02209         case MoveDown: op = QTextCursor::Down; break;
02210         case MoveLineStart: op = QTextCursor::StartOfLine; break;
02211         case MoveLineEnd: op = QTextCursor::EndOfLine; break;
02212         case MoveHome: op = QTextCursor::Start; break;
02213         case MoveEnd: op = QTextCursor::End; break;
02214         default: return;
02215     }
02216     cursor.movePosition(op, mode);
02217     d->control->setTextCursor(cursor);
02218 }
02219 
02223 void QTextEdit::moveCursor(CursorAction action, bool select)
02224 {
02225     moveCursor(action, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
02226 }
02227 
02235 void QTextEdit::doKeyboardAction(KeyboardAction action)
02236 {
02237     Q_D(QTextEdit);
02238     QTextCursor cursor = d->control->textCursor();
02239     switch (action) {
02240         case ActionBackspace: cursor.deletePreviousChar(); break;
02241         case ActionDelete: cursor.deleteChar(); break;
02242         case ActionReturn: cursor.insertBlock(); break;
02243         case ActionKill: {
02244                 QTextBlock block = cursor.block();
02245                 if (cursor.position() == block.position() + block.length() - 2)
02246                     cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
02247                 else
02248                     cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
02249                 cursor.deleteChar();
02250                 break;
02251             }
02252         case ActionWordBackspace:
02253             cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
02254             cursor.deletePreviousChar();
02255             break;
02256         case ActionWordDelete:
02257             cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
02258             cursor.deleteChar();
02259             break;
02260     }
02261     d->control->setTextCursor(cursor);
02262 }
02263 
02267 QString QTextEdit::text() const
02268 {
02269     Q_D(const QTextEdit);
02270     if (d->textFormat == Qt::RichText || d->textFormat == Qt::LogText || (d->textFormat == Qt::AutoText && d->preferRichText))
02271         return d->control->toHtml();
02272     else
02273         return d->control->toPlainText();
02274 }
02275 
02276 
02282 void QTextEdit::setTextFormat(Qt::TextFormat f)
02283 {
02284     Q_D(QTextEdit);
02285     d->textFormat = f;
02286 }
02287 
02293 Qt::TextFormat QTextEdit::textFormat() const
02294 {
02295     Q_D(const QTextEdit);
02296     return d->textFormat;
02297 }
02298 
02299 #endif // QT3_SUPPORT
02300 
02301 
02305 void QTextEdit::append(const QString &text)
02306 {
02307     Q_D(QTextEdit);
02308     const bool atBottom = d->verticalOffset() >= d->vbar->maximum();
02309     d->control->append(text);
02310     if (atBottom)
02311         d->vbar->setValue(d->vbar->maximum());
02312 }
02313 
02318 void QTextEdit::ensureCursorVisible()
02319 {
02320     Q_D(QTextEdit);
02321     d->control->ensureCursorVisible();
02322 }
02323 
02324 
02497 #endif // QT_NO_TEXTEDIT
02498 
02499 #ifndef QT_NO_CONTEXTMENU
02500 #define NUM_CONTROL_CHARACTERS 10
02501 const struct QUnicodeControlCharacter {
02502     const char *text;
02503     ushort character;
02504 } qt_controlCharacters[NUM_CONTROL_CHARACTERS] = {
02505     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRM Left-to-right mark"), 0x200e },
02506     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLM Right-to-left mark"), 0x200f },
02507     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWJ Zero width joiner"), 0x200d },
02508     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWNJ Zero width non-joiner"), 0x200c },
02509     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWSP Zero width space"), 0x200b },
02510     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRE Start of left-to-right embedding"), 0x202a },
02511     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLE Start of right-to-left embedding"), 0x202b },
02512     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRO Start of left-to-right override"), 0x202d },
02513     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLO Start of right-to-left override"), 0x202e },
02514     { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "PDF Pop directional formatting"), 0x202c },
02515 };
02516 
02517 QUnicodeControlCharacterMenu::QUnicodeControlCharacterMenu(QObject *_editWidget, QWidget *parent)
02518     : QMenu(parent), editWidget(_editWidget)
02519 {
02520     setTitle(tr("Insert Unicode control character"));
02521     for (int i = 0; i < NUM_CONTROL_CHARACTERS; ++i) {
02522         addAction(tr(qt_controlCharacters[i].text), this, SLOT(menuActionTriggered()));
02523     }
02524 }
02525 
02526 void QUnicodeControlCharacterMenu::menuActionTriggered()
02527 {
02528     QAction *a = qobject_cast<QAction *>(sender());
02529     int idx = actions().indexOf(a);
02530     if (idx < 0 || idx >= NUM_CONTROL_CHARACTERS)
02531         return;
02532     QChar c(qt_controlCharacters[idx].character);
02533     QString str(c);
02534 
02535 #ifndef QT_NO_TEXTEDIT
02536     if (QTextEdit *edit = qobject_cast<QTextEdit *>(editWidget)) {
02537         edit->insertPlainText(str);
02538         return;
02539     }
02540 #endif
02541     if (QTextControl *control = qobject_cast<QTextControl *>(editWidget)) {
02542         control->insertPlainText(str);
02543     }
02544 #ifndef QT_NO_LINEEDIT
02545     if (QLineEdit *edit = qobject_cast<QLineEdit *>(editWidget)) {
02546         edit->insert(str);
02547         return;
02548     }
02549 #endif
02550 }
02551 #endif // QT_NO_CONTEXTMENU
02552 
02553 #include "moc_qtextedit.cpp"
02554 #include "moc_qtextedit_p.cpp"

Generated on Thu Mar 15 11:57:08 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1