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);
1087bool QTextEdit::event(QEvent *e)
1090 switch (e->type()) {
1091 case QEvent::ShortcutOverride:
1092 case QEvent::ToolTip:
1093 d->sendControlEvent(e);
1095 case QEvent::WindowActivate:
1096 case QEvent::WindowDeactivate:
1097 d->control->setPalette(palette());
1099#ifndef QT_NO_CONTEXTMENU
1100 case QEvent::ContextMenu:
1101 if (
static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
1102 ensureCursorVisible();
1103 const QPoint cursorPos = cursorRect().center();
1104 QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
1105 ce.setAccepted(e->isAccepted());
1106 const bool result = QAbstractScrollArea::event(&ce);
1107 e->setAccepted(ce.isAccepted());
1115 return QAbstractScrollArea::event(e);
1121void QTextEdit::timerEvent(QTimerEvent *e)
1124 if (e->timerId() == d->autoScrollTimer.timerId()) {
1125 QRect visible = d->viewport->rect();
1128 pos = d->autoScrollDragPos;
1129 visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
1130 -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
1132 const QPoint globalPos = QCursor::pos();
1133 pos = d->viewport->mapFromGlobal(globalPos);
1134 QMouseEvent ev(QEvent::MouseMove, pos, mapTo(topLevelWidget(), pos), globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
1135 mouseMoveEvent(&ev);
1137 int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
1138 int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
1139 int delta = qMax(deltaX, deltaY);
1143 int timeout = 4900 / (delta * delta);
1144 d->autoScrollTimer.start(timeout,
this);
1147 d->vbar->triggerAction(pos.y() < visible.center().y() ?
1148 QAbstractSlider::SliderSingleStepSub
1149 : QAbstractSlider::SliderSingleStepAdd);
1151 d->hbar->triggerAction(pos.x() < visible.center().x() ?
1152 QAbstractSlider::SliderSingleStepSub
1153 : QAbstractSlider::SliderSingleStepAdd);
1284void QTextEdit::keyPressEvent(QKeyEvent *e)
1288#ifndef QT_NO_SHORTCUT
1290 Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
1292 if (tif & Qt::TextSelectableByKeyboard){
1293 if (e == QKeySequence::SelectPreviousPage) {
1295 d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
1297 }
else if (e ==QKeySequence::SelectNextPage) {
1299 d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
1303 if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
1304 if (e == QKeySequence::MoveToPreviousPage) {
1306 d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
1308 }
else if (e == QKeySequence::MoveToNextPage) {
1310 d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
1315 if (!(tif & Qt::TextEditable)) {
1319 if (e->modifiers() & Qt::ShiftModifier)
1320 d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
1322 d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
1325 d->sendControlEvent(e);
1326 if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
1327 if (e->key() == Qt::Key_Home) {
1328 d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
1330 }
else if (e->key() == Qt::Key_End) {
1331 d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
1335 if (!e->isAccepted()) {
1336 QAbstractScrollArea::keyPressEvent(e);
1344 QTextCursor cursor = d->control->textCursor();
1345 const QString text = e->text();
1346 if (cursor.atBlockStart()
1347 && (d->autoFormatting & AutoBulletList)
1348 && (text.size() == 1)
1349 && (text.at(0) == u'-' || text.at(0) == u'*')
1350 && (!cursor.currentList())) {
1352 d->createAutoBulletList();
1358 d->sendControlEvent(e);
1413 QTextDocument *doc = control->document();
1414 QAbstractTextDocumentLayout *layout = doc->documentLayout();
1416 if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
1417 if (lineWrap == QTextEdit::FixedColumnWidth)
1418 tlayout->setFixedColumnWidth(lineWrapColumnOrWidth);
1420 tlayout->setFixedColumnWidth(-1);
1423 QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout);
1426 lastUsedSize = tlayout->dynamicDocumentSize().toSize();
1428 lastUsedSize = layout->documentSize().toSize();
1433 const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
1434 ignoreAutomaticScrollbarAdjustment =
true;
1436 int width = viewport->width();
1437 if (lineWrap == QTextEdit::FixedPixelWidth)
1439 else if (lineWrap == QTextEdit::NoWrap) {
1440 QVariant alignmentProperty = doc->documentLayout()->property(
"contentHasAlignment");
1441 if (alignmentProperty.userType() == QMetaType::Bool && !alignmentProperty.toBool()) {
1447 doc->setPageSize(QSize(width, -1));
1451 ignoreAutomaticScrollbarAdjustment = oldIgnoreScrollbarAdjustment;
1455 usedSize = tlayout->dynamicDocumentSize().toSize();
1457 usedSize = layout->documentSize().toSize();
1475 if (lastUsedSize.isValid()
1476 && !vbar->isHidden()
1477 && viewport->width() < lastUsedSize.width()
1478 && usedSize.height() < lastUsedSize.height()
1479 && usedSize.height() <= viewport->height())
1490 QRect r = e->rect();
1491 p->translate(-xOffset, -yOffset);
1492 r.translate(xOffset, yOffset);
1494 QTextDocument *doc = control->document();
1495 QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
1500 layout->setViewport(viewport->rect());
1502 control->drawContents(p, r, q_func());
1505 layout->setViewport(QRect());
1507 if (!placeholderText.isEmpty() && doc->isEmpty() && !control->isPreediting()) {
1508 const QColor col = control->palette().placeholderText().color();
1510 const int margin =
int(doc->documentMargin());
1511 QRectF boundingRect = layout ? layout->frameBoundingRect(doc->rootFrame()) : viewport->rect();
1512 p->drawText(boundingRect.adjusted(margin, margin, -margin, -margin),
1513 Qt::AlignTop | Qt::TextWordWrap,
1710QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument)
const
1712 Q_D(
const QTextEdit);
1715 return isEnabled() && !isReadOnly();
1717 case Qt::ImInputItemClipRectangle:
1718 return QWidget::inputMethodQuery(query);
1719 case Qt::ImReadOnly:
1720 return isReadOnly();
1725 const QPointF offset(-d->horizontalOffset(), -d->verticalOffset());
1726 switch (argument.userType()) {
1727 case QMetaType::QRectF:
1728 argument = argument.toRectF().translated(-offset);
1730 case QMetaType::QPointF:
1731 argument = argument.toPointF() - offset;
1733 case QMetaType::QRect:
1734 argument = argument.toRect().translated(-offset.toPoint());
1736 case QMetaType::QPoint:
1737 argument = argument.toPoint() - offset;
1743 const QVariant v = d->control->inputMethodQuery(query, argument);
1744 switch (v.userType()) {
1745 case QMetaType::QRectF:
1746 return v.toRectF().translated(offset);
1747 case QMetaType::QPointF:
1748 return v.toPointF() + offset;
1749 case QMetaType::QRect:
1750 return v.toRect().translated(offset.toPoint());
1751 case QMetaType::QPoint:
1752 return v.toPoint() + offset.toPoint();
1797void QTextEdit::changeEvent(QEvent *e)
1800 QAbstractScrollArea::changeEvent(e);
1801 if (e->type() == QEvent::ApplicationFontChange
1802 || e->type() == QEvent::FontChange) {
1803 d->control->document()->setDefaultFont(font());
1804 }
else if (e->type() == QEvent::ActivationChange) {
1805 if (!isActiveWindow())
1806 d->autoScrollTimer.stop();
1807 }
else if (e->type() == QEvent::EnabledChange) {
1808 e->setAccepted(isEnabled());
1809 d->control->setPalette(palette());
1810 d->sendControlEvent(e);
1811 }
else if (e->type() == QEvent::PaletteChange) {
1812 d->control->setPalette(palette());
1813 }
else if (e->type() == QEvent::LayoutDirectionChange) {
1814 d->sendControlEvent(e);
2123void QTextEdit::setReadOnly(
bool ro)
2126 Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
2128 flags = Qt::TextSelectableByMouse;
2129#if QT_CONFIG(textbrowser)
2130 if (qobject_cast<QTextBrowser *>(
this))
2131 flags |= Qt::TextBrowserInteraction;
2134 flags = Qt::TextEditorInteraction;
2136 d->control->setTextInteractionFlags(flags);
2137 setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(
this));
2138 QEvent event(QEvent::ReadOnlyChange);
2139 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)