00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00157
00158
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
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;
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
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
00254
00255
00256
00257
00258
00259 if (q_func()->isRightToLeft())
00260 viewport->update();
00261
00262 _q_showOrHideScrollBars();
00263 ignoreAutomaticScrollbarAdjustment = false;
00264 }
00265 #endif
00266
00267
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
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
01134
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
01240
01241
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
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
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
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"