129 control =
new QTextEditControl(q);
130 control->setPalette(q->palette());
133 QObjectPrivate::connect(control, &QTextEditControl::documentSizeChanged,
134 this, &QTextEditPrivate::adjustScrollbars),
135 QObjectPrivate::connect(control, &QTextEditControl::updateRequest,
136 this, &QTextEditPrivate::repaintContents),
137 QObjectPrivate::connect(control, &QTextEditControl::visibilityRequest,
138 this, &QTextEditPrivate::ensureVisible),
139 QObjectPrivate::connect(control, &QTextEditControl::blockMarkerHovered,
140 this, &QTextEditPrivate::hoveredBlockWithMarkerChanged),
141 QObjectPrivate::connect(control, &QTextEditControl::cursorPositionChanged,
142 this, &QTextEditPrivate::cursorPositionChanged),
143 QObject::connect(control, &QTextEditControl::microFocusChanged,
144 q, [q]() { q->updateMicroFocus(); }),
145 QObject::connect(control, &QTextEditControl::currentCharFormatChanged,
146 q, &QTextEdit::currentCharFormatChanged),
147 QObject::connect(control, &QTextEditControl::textChanged,
148 q, &QTextEdit::textChanged),
149 QObject::connect(control, &QTextEditControl::undoAvailable,
150 q, &QTextEdit::undoAvailable),
151 QObject::connect(control, &QTextEditControl::redoAvailable,
152 q, &QTextEdit::redoAvailable),
153 QObject::connect(control, &QTextEditControl::copyAvailable,
154 q, &QTextEdit::copyAvailable),
155 QObject::connect(control, &QTextEditControl::selectionChanged,
156 q, &QTextEdit::selectionChanged),
157 QObject::connect(control, &QTextEditControl::textChanged,
158 q, [q]() { q->updateMicroFocus(); }),
161 QTextDocument *doc = control->document();
165 doc->setPageSize(QSize(0, 0));
166 doc->documentLayout()->setPaintDevice(viewport);
167 doc->setDefaultFont(q->font());
168 doc->setUndoRedoEnabled(
false);
169 doc->setUndoRedoEnabled(
true);
172 control->setHtml(html);
174 const auto singleStep = defaultSingleStep();
175 hbar->setSingleStep(singleStep);
176 vbar->setSingleStep(singleStep);
178 viewport->setBackgroundRole(QPalette::Base);
179 q->setMouseTracking(
true);
180 q->setAcceptDrops(
true);
181 q->setFocusPolicy(Qt::StrongFocus);
182 q->setAttribute(Qt::WA_KeyCompression);
183 q->setAttribute(Qt::WA_InputMethodEnabled);
184 q->setInputMethodHints(Qt::ImhMultiLine);
186 viewport->setCursor(Qt::IBeamCursor);
237 QTextCursor cursor = control->textCursor();
239 qreal lastY = control->cursorRect(cursor).top();
243 qreal y = control->cursorRect(cursor).top();
244 distance += qAbs(y - lastY);
246 moved = cursor.movePosition(op, moveMode);
247 }
while (moved && distance < viewport->height());
250 if (op == QTextCursor::Up) {
251 cursor.movePosition(QTextCursor::Down, moveMode);
252 vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
254 cursor.movePosition(QTextCursor::Up, moveMode);
255 vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
258 control->setTextCursor(cursor, moveMode == QTextCursor::KeepAnchor);
334 const QRect rect = _rect.toRect();
335 if ((vbar->isVisible() && vbar->maximum() < rect.bottom())
336 || (hbar->isVisible() && hbar->maximum() < rect.right()))
338 const int visibleWidth = viewport->width();
339 const int visibleHeight = viewport->height();
340 const bool rtl = q_func()->isRightToLeft();
344 hbar->setValue(hbar->maximum() - rect.x());
346 hbar->setValue(rect.x());
349 hbar->setValue(hbar->maximum() - (rect.x() + rect.width() - visibleWidth));
351 hbar->setValue(rect.x() + rect.width() - visibleWidth);
354 if (rect.y() < verticalOffset())
355 vbar->setValue(rect.y());
356 else if (rect.y() + rect.height() > verticalOffset() + visibleHeight)
357 vbar->setValue(rect.y() + rect.height() - visibleHeight);
1088bool QTextEdit::event(QEvent *e)
1091 switch (e->type()) {
1092 case QEvent::ShortcutOverride:
1093 case QEvent::ToolTip:
1094 d->sendControlEvent(e);
1096 case QEvent::WindowActivate:
1097 case QEvent::WindowDeactivate:
1098 d->control->setPalette(palette());
1100#ifndef QT_NO_CONTEXTMENU
1101 case QEvent::ContextMenu:
1102 if (
static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
1103 ensureCursorVisible();
1104 const QPoint cursorPos = cursorRect().center();
1105 QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
1106 ce.setAccepted(e->isAccepted());
1107 const bool result = QAbstractScrollArea::event(&ce);
1108 e->setAccepted(ce.isAccepted());
1116 return QAbstractScrollArea::event(e);
1122void QTextEdit::timerEvent(QTimerEvent *e)
1125 if (e->timerId() == d->autoScrollTimer.timerId()) {
1126 QRect visible = d->viewport->rect();
1129 pos = d->autoScrollDragPos;
1130 visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
1131 -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
1133 const QPoint globalPos = QCursor::pos();
1134 pos = d->viewport->mapFromGlobal(globalPos);
1135 QMouseEvent ev(QEvent::MouseMove, pos, mapTo(topLevelWidget(), pos), globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
1136 mouseMoveEvent(&ev);
1138 int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
1139 int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
1140 int delta = qMax(deltaX, deltaY);
1144 int timeout = 4900 / (delta * delta);
1145 d->autoScrollTimer.start(timeout,
this);
1148 d->vbar->triggerAction(pos.y() < visible.center().y() ?
1149 QAbstractSlider::SliderSingleStepSub
1150 : QAbstractSlider::SliderSingleStepAdd);
1152 d->hbar->triggerAction(pos.x() < visible.center().x() ?
1153 QAbstractSlider::SliderSingleStepSub
1154 : QAbstractSlider::SliderSingleStepAdd);
1285void QTextEdit::keyPressEvent(QKeyEvent *e)
1289#ifndef QT_NO_SHORTCUT
1291 Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
1293 if (tif & Qt::TextSelectableByKeyboard){
1294 if (e == QKeySequence::SelectPreviousPage) {
1296 d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
1298 }
else if (e ==QKeySequence::SelectNextPage) {
1300 d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
1304 if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
1305 if (e == QKeySequence::MoveToPreviousPage) {
1307 d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
1309 }
else if (e == QKeySequence::MoveToNextPage) {
1311 d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
1316 if (!(tif & Qt::TextEditable)) {
1320 if (e->modifiers() & Qt::ShiftModifier)
1321 d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
1323 d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
1326 d->sendControlEvent(e);
1327 if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
1328 if (e->key() == Qt::Key_Home) {
1329 d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
1331 }
else if (e->key() == Qt::Key_End) {
1332 d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
1336 if (!e->isAccepted()) {
1337 QAbstractScrollArea::keyPressEvent(e);
1345 QTextCursor cursor = d->control->textCursor();
1346 const QString text = e->text();
1347 if (cursor.atBlockStart()
1348 && (d->autoFormatting & AutoBulletList)
1349 && (text.size() == 1)
1350 && (text.at(0) == u'-' || text.at(0) == u'*')
1351 && (!cursor.currentList())) {
1353 d->createAutoBulletList();
1359 d->sendControlEvent(e);
1414 QTextDocument *doc = control->document();
1415 QAbstractTextDocumentLayout *layout = doc->documentLayout();
1417 if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
1418 if (lineWrap == QTextEdit::FixedColumnWidth)
1419 tlayout->setFixedColumnWidth(lineWrapColumnOrWidth);
1421 tlayout->setFixedColumnWidth(-1);
1424 QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout);
1427 lastUsedSize = tlayout->dynamicDocumentSize().toSize();
1429 lastUsedSize = layout->documentSize().toSize();
1434 const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
1435 ignoreAutomaticScrollbarAdjustment =
true;
1437 int width = viewport->width();
1438 if (lineWrap == QTextEdit::FixedPixelWidth)
1440 else if (lineWrap == QTextEdit::NoWrap) {
1441 QVariant alignmentProperty = doc->documentLayout()->property(
"contentHasAlignment");
1442 if (alignmentProperty.userType() == QMetaType::Bool && !alignmentProperty.toBool()) {
1448 doc->setPageSize(QSize(width, -1));
1452 ignoreAutomaticScrollbarAdjustment = oldIgnoreScrollbarAdjustment;
1456 usedSize = tlayout->dynamicDocumentSize().toSize();
1458 usedSize = layout->documentSize().toSize();
1476 if (lastUsedSize.isValid()
1477 && !vbar->isHidden()
1478 && viewport->width() < lastUsedSize.width()
1479 && usedSize.height() < lastUsedSize.height()
1480 && usedSize.height() <= viewport->height())
1491 QRect r = e->rect();
1492 p->translate(-xOffset, -yOffset);
1493 r.translate(xOffset, yOffset);
1495 QTextDocument *doc = control->document();
1496 QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
1501 layout->setViewport(viewport->rect());
1503 control->drawContents(p, r, q_func());
1506 layout->setViewport(QRect());
1508 if (!placeholderText.isEmpty() && doc->isEmpty() && !control->isPreediting()) {
1509 const QColor col = control->palette().placeholderText().color();
1511 const int margin =
int(doc->documentMargin());
1512 QRectF boundingRect = layout ? layout->frameBoundingRect(doc->rootFrame()) : viewport->rect();
1513 p->drawText(boundingRect.adjusted(margin, margin, -margin, -margin),
1514 Qt::AlignTop | Qt::TextWordWrap,
1711QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument)
const
1713 Q_D(
const QTextEdit);
1716 return isEnabled() && !isReadOnly();
1718 case Qt::ImInputItemClipRectangle:
1719 return QWidget::inputMethodQuery(query);
1720 case Qt::ImReadOnly:
1721 return isReadOnly();
1726 const QPointF offset(-d->horizontalOffset(), -d->verticalOffset());
1727 switch (argument.userType()) {
1728 case QMetaType::QRectF:
1729 argument = argument.toRectF().translated(-offset);
1731 case QMetaType::QPointF:
1732 argument = argument.toPointF() - offset;
1734 case QMetaType::QRect:
1735 argument = argument.toRect().translated(-offset.toPoint());
1737 case QMetaType::QPoint:
1738 argument = argument.toPoint() - offset;
1744 const QVariant v = d->control->inputMethodQuery(query, argument);
1745 switch (v.userType()) {
1746 case QMetaType::QRectF:
1747 return v.toRectF().translated(offset);
1748 case QMetaType::QPointF:
1749 return v.toPointF() + offset;
1750 case QMetaType::QRect:
1751 return v.toRect().translated(offset.toPoint());
1752 case QMetaType::QPoint:
1753 return v.toPoint() + offset.toPoint();
1798void QTextEdit::changeEvent(QEvent *e)
1801 QAbstractScrollArea::changeEvent(e);
1802 if (e->type() == QEvent::ApplicationFontChange
1803 || e->type() == QEvent::FontChange) {
1804 d->control->document()->setDefaultFont(font());
1805 }
else if (e->type() == QEvent::ActivationChange) {
1806 if (!isActiveWindow())
1807 d->autoScrollTimer.stop();
1808 }
else if (e->type() == QEvent::EnabledChange) {
1809 e->setAccepted(isEnabled());
1810 d->control->setPalette(palette());
1811 d->sendControlEvent(e);
1812 }
else if (e->type() == QEvent::PaletteChange) {
1813 d->control->setPalette(palette());
1814 }
else if (e->type() == QEvent::LayoutDirectionChange) {
1815 d->sendControlEvent(e);
2124void QTextEdit::setReadOnly(
bool ro)
2127 Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
2129 flags = Qt::TextSelectableByMouse;
2130#if QT_CONFIG(textbrowser)
2131 if (qobject_cast<QTextBrowser *>(
this))
2132 flags |= Qt::TextBrowserInteraction;
2135 flags = Qt::TextEditorInteraction;
2137 d->control->setTextInteractionFlags(flags);
2138 setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(
this));
2139 QEvent event(QEvent::ReadOnlyChange);
2140 QCoreApplication::sendEvent(
this, &event);
virtual void insertFromMimeData(const QMimeData *source) override
virtual QMimeData * createMimeDataFromSelection() const override
QVariant loadResource(int type, const QUrl &name) override
virtual bool canInsertFromMimeData(const QMimeData *source) const override
void pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
static QT_BEGIN_NAMESPACE bool shouldEnableInputMethod(QTextEdit *textedit)