8#if QT_CONFIG(textbrowser)
9#include "qtextbrowser.h"
16#if QT_CONFIG(draganddrop)
19#include <qclipboard.h>
24#if QT_CONFIG(accessibility)
25#include <qaccessible.h>
27#include "private/qtextdocumentlayout_p.h"
29#include "private/qtextdocument_p.h"
31#include "private/qwidgettextcontrol_p.h"
33#include <qtextformat.h>
35#include <qapplication.h>
36#include <private/qapplication_p.h>
38#include <qtextobject.h>
39#include <qtexttable.h>
46#if defined (Q_OS_ANDROID)
47 return !textedit->isReadOnly() || (textedit->textInteractionFlags() & Qt::TextSelectableByMouse);
49 return !textedit->isReadOnly();
59 QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
61 return QWidgetTextControl::createMimeDataFromSelection();
62 return ed->createMimeDataFromSelection();
65 QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
67 return QWidgetTextControl::canInsertFromMimeData(source);
68 return ed->canInsertFromMimeData(source);
71 QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
73 QWidgetTextControl::insertFromMimeData(source);
75 ed->insertFromMimeData(source);
78 auto *ed = qobject_cast<QTextEdit *>(parent());
80 return QWidgetTextControl::loadResource(type, name);
82 QUrl resolvedName = ed->d_func()->resolveUrl(name);
83 return ed->loadResource(type, resolvedName);
91 wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0)
93 ignoreAutomaticScrollbarAdjustment =
false;
94 preferRichText =
false;
95 showCursorOnInitialShow =
true;
101 for (
const QMetaObject::Connection &connection : connections)
102 QObject::disconnect(connection);
107 QTextCursor cursor = control->textCursor();
108 cursor.beginEditBlock();
110 QTextBlockFormat blockFmt = cursor.blockFormat();
112 QTextListFormat listFmt;
113 listFmt.setStyle(QTextListFormat::ListDisc);
114 listFmt.setIndent(blockFmt.indent() + 1);
116 blockFmt.setIndent(0);
117 cursor.setBlockFormat(blockFmt);
119 cursor.createList(listFmt);
121 cursor.endEditBlock();
122 control->setTextCursor(cursor);
128 control =
new QTextEditControl(q);
129 control->setPalette(q->palette());
132 QObjectPrivate::connect(control, &QTextEditControl::documentSizeChanged,
133 this, &QTextEditPrivate::adjustScrollbars),
134 QObjectPrivate::connect(control, &QTextEditControl::updateRequest,
135 this, &QTextEditPrivate::repaintContents),
136 QObjectPrivate::connect(control, &QTextEditControl::visibilityRequest,
137 this, &QTextEditPrivate::ensureVisible),
138 QObjectPrivate::connect(control, &QTextEditControl::blockMarkerHovered,
139 this, &QTextEditPrivate::hoveredBlockWithMarkerChanged),
140 QObjectPrivate::connect(control, &QTextEditControl::cursorPositionChanged,
141 this, &QTextEditPrivate::cursorPositionChanged),
142 QObject::connect(control, &QTextEditControl::microFocusChanged,
143 q, [q]() { q->updateMicroFocus(); }),
144 QObject::connect(control, &QTextEditControl::currentCharFormatChanged,
145 q, &QTextEdit::currentCharFormatChanged),
146 QObject::connect(control, &QTextEditControl::textChanged,
147 q, &QTextEdit::textChanged),
148 QObject::connect(control, &QTextEditControl::undoAvailable,
149 q, &QTextEdit::undoAvailable),
150 QObject::connect(control, &QTextEditControl::redoAvailable,
151 q, &QTextEdit::redoAvailable),
152 QObject::connect(control, &QTextEditControl::copyAvailable,
153 q, &QTextEdit::copyAvailable),
154 QObject::connect(control, &QTextEditControl::selectionChanged,
155 q, &QTextEdit::selectionChanged),
156 QObject::connect(control, &QTextEditControl::textChanged,
157 q, [q]() { q->updateMicroFocus(); }),
160 QTextDocument *doc = control->document();
164 doc->setPageSize(QSize(0, 0));
165 doc->documentLayout()->setPaintDevice(viewport);
166 doc->setDefaultFont(q->font());
167 doc->setUndoRedoEnabled(
false);
168 doc->setUndoRedoEnabled(
true);
171 control->setHtml(html);
173 hbar->setSingleStep(20);
174 vbar->setSingleStep(20);
176 viewport->setBackgroundRole(QPalette::Base);
177 q->setMouseTracking(
true);
178 q->setAcceptDrops(
true);
179 q->setFocusPolicy(Qt::StrongFocus);
180 q->setAttribute(Qt::WA_KeyCompression);
181 q->setAttribute(Qt::WA_InputMethodEnabled);
182 q->setInputMethodHints(Qt::ImhMultiLine);
184 viewport->setCursor(Qt::IBeamCursor);
190 if (!contentsRect.isValid()) {
196 const QRectF visibleRect(xOffset, yOffset, viewport->width(), viewport->height());
198 QRect r = contentsRect.intersected(visibleRect).toAlignedRect();
202 r.translate(-xOffset, -yOffset);
209 emit q->cursorPositionChanged();
210#if QT_CONFIG(accessibility)
211 QAccessibleTextCursorEvent event(q, q->textCursor().position());
212 QAccessible::updateAccessibility(&event);
220 Qt::CursorShape cursor = cursorToRestoreAfterHover;
221 if (block.isValid() && !q->isReadOnly()) {
222 QTextBlockFormat::MarkerType marker = block.blockFormat().marker();
223 if (marker != QTextBlockFormat::MarkerType::NoMarker) {
224 if (viewport->cursor().shape() != Qt::PointingHandCursor)
225 cursorToRestoreAfterHover = viewport->cursor().shape();
226 cursor = Qt::PointingHandCursor;
229 viewport->setCursor(cursor);
235 QTextCursor cursor = control->textCursor();
237 qreal lastY = control->cursorRect(cursor).top();
241 qreal y = control->cursorRect(cursor).top();
242 distance += qAbs(y - lastY);
244 moved = cursor.movePosition(op, moveMode);
245 }
while (moved && distance < viewport->height());
248 if (op == QTextCursor::Up) {
249 cursor.movePosition(QTextCursor::Down, moveMode);
250 vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
252 cursor.movePosition(QTextCursor::Up, moveMode);
253 vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
256 control->setTextCursor(cursor, moveMode == QTextCursor::KeepAnchor);
259#if QT_CONFIG(scrollbar)
260static QSize documentSize(QWidgetTextControl *control)
262 QTextDocument *doc = control->document();
263 QAbstractTextDocumentLayout *layout = doc->documentLayout();
267 if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
268 docSize = tlayout->dynamicDocumentSize().toSize();
269 int percentageDone = tlayout->layoutStatus();
271 if (percentageDone > 0)
272 docSize.setHeight(docSize.height() * 100 / percentageDone);
274 docSize = layout->documentSize().toSize();
280void QTextEditPrivate::adjustScrollbars()
282 if (ignoreAutomaticScrollbarAdjustment)
284 ignoreAutomaticScrollbarAdjustment =
true;
286 QSize viewportSize = viewport->size();
287 QSize docSize = documentSize(control);
295 for (
int i = 0; i < 4; ++i) {
296 hbar->setRange(0, docSize.width() - viewportSize.width());
297 hbar->setPageStep(viewportSize.width());
299 vbar->setRange(0, docSize.height() - viewportSize.height());
300 vbar->setPageStep(viewportSize.height());
308 if (q_func()->isRightToLeft())
311 _q_showOrHideScrollBars();
313 const QSize oldViewportSize = viewportSize;
314 const QSize oldDocSize = docSize;
317 viewportSize = viewport->size();
318 if (viewportSize.width() != oldViewportSize.width())
321 docSize = documentSize(control);
322 if (viewportSize == oldViewportSize && docSize == oldDocSize)
325 ignoreAutomaticScrollbarAdjustment =
false;
332 const QRect rect = _rect.toRect();
333 if ((vbar->isVisible() && vbar->maximum() < rect.bottom())
334 || (hbar->isVisible() && hbar->maximum() < rect.right()))
336 const int visibleWidth = viewport->width();
337 const int visibleHeight = viewport->height();
338 const bool rtl = q_func()->isRightToLeft();
342 hbar->setValue(hbar->maximum() - rect.x());
344 hbar->setValue(rect.x());
347 hbar->setValue(hbar->maximum() - (rect.x() + rect.width() - visibleWidth));
349 hbar->setValue(rect.x() + rect.width() - visibleWidth);
352 if (rect.y() < verticalOffset())
353 vbar->setValue(rect.y());
354 else if (rect.y() + rect.height() > verticalOffset() + visibleHeight)
355 vbar->setValue(rect.y() + rect.height() - visibleHeight);
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
582
583
584
585
586
587
590
591
592
593
594
595
596
599
600
601
602
603
604
605
606
607
611
612
613
614QTextEdit::QTextEdit(QWidget *parent)
615 : QAbstractScrollArea(*
new QTextEditPrivate, parent)
622
623
624QTextEdit::QTextEdit(QTextEditPrivate &dd, QWidget *parent)
625 : QAbstractScrollArea(dd, parent)
632
633
634
635QTextEdit::QTextEdit(
const QString &text, QWidget *parent)
636 : QAbstractScrollArea(*
new QTextEditPrivate, parent)
645
646
647QTextEdit::~QTextEdit()
652
653
654
655
656qreal QTextEdit::fontPointSize()
const
658 Q_D(
const QTextEdit);
659 return d->control->textCursor().charFormat().fontPointSize();
663
664
665
666
667QString QTextEdit::fontFamily()
const
669 Q_D(
const QTextEdit);
670 return d->control->textCursor().charFormat().fontFamilies().toStringList().value(0, QString());
674
675
676
677
678int QTextEdit::fontWeight()
const
680 Q_D(
const QTextEdit);
681 return d->control->textCursor().charFormat().fontWeight();
685
686
687
688
689
690bool QTextEdit::fontUnderline()
const
692 Q_D(
const QTextEdit);
693 return d->control->textCursor().charFormat().fontUnderline();
697
698
699
700
701
702bool QTextEdit::fontItalic()
const
704 Q_D(
const QTextEdit);
705 return d->control->textCursor().charFormat().fontItalic();
709
710
711
712
713QColor QTextEdit::textColor()
const
715 Q_D(
const QTextEdit);
717 const auto fg = d->control->textCursor().charFormat().foreground();
718 if (fg.style() == Qt::NoBrush) {
719 const auto context = d->control->getPaintContext(
const_cast<QTextEdit *>(
this));
720 return context.palette.color(QPalette::Text);
727
728
729
730
731
732
733QColor QTextEdit::textBackgroundColor()
const
735 Q_D(
const QTextEdit);
736 const QBrush &brush = d->control->textCursor().charFormat().background();
737 return brush.style() == Qt::NoBrush ? Qt::transparent : brush.color();
741
742
743
744
745QFont QTextEdit::currentFont()
const
747 Q_D(
const QTextEdit);
748 return d->control->textCursor().charFormat().font();
752
753
754
755
756
757void QTextEdit::setAlignment(Qt::Alignment a)
760 QTextBlockFormat fmt;
762 QTextCursor cursor = d->control->textCursor();
763 cursor.mergeBlockFormat(fmt);
764 d->control->setTextCursor(cursor);
765 d->relayoutDocument();
769
770
771
772
773Qt::Alignment QTextEdit::alignment()
const
775 Q_D(
const QTextEdit);
776 return d->control->textCursor().blockFormat().alignment();
780
781
782
783
784
785
786
787
788void QTextEdit::setDocument(QTextDocument *document)
791 d->control->setDocument(document);
792 d->updateDefaultTextOption();
793 d->relayoutDocument();
796QTextDocument *QTextEdit::document()
const
798 Q_D(
const QTextEdit);
799 return d->control->document();
803
804
805
806
807
808
809
810
811
812
813
814
815QString QTextEdit::placeholderText()
const
817 Q_D(
const QTextEdit);
818 return d->placeholderText;
821void QTextEdit::setPlaceholderText(
const QString &placeholderText)
824 if (d->placeholderText != placeholderText) {
825 d->placeholderText = placeholderText;
826 if (d->control->document()->isEmpty())
827 d->viewport->update();
832
833
834void QTextEdit::setTextCursor(
const QTextCursor &cursor)
836 doSetTextCursor(cursor);
840
841
842
843
845void QTextEdit::doSetTextCursor(
const QTextCursor &cursor)
848 d->control->setTextCursor(cursor);
852
853
854
855
856QTextCursor QTextEdit::textCursor()
const
858 Q_D(
const QTextEdit);
859 return d->control->textCursor();
863
864
865
866
867void QTextEdit::setFontFamily(
const QString &fontFamily)
870 fmt.setFontFamilies({fontFamily});
871 mergeCurrentCharFormat(fmt);
875
876
877
878
879
880
881
882void QTextEdit::setFontPointSize(qreal s)
885 fmt.setFontPointSize(s);
886 mergeCurrentCharFormat(fmt);
890
891
892
893
894
895
896
897
898void QTextEdit::setFontWeight(
int w)
901 fmt.setFontWeight(w);
902 mergeCurrentCharFormat(fmt);
906
907
908
909
910
911void QTextEdit::setFontUnderline(
bool underline)
914 fmt.setFontUnderline(underline);
915 mergeCurrentCharFormat(fmt);
919
920
921
922
923
924void QTextEdit::setFontItalic(
bool italic)
927 fmt.setFontItalic(italic);
928 mergeCurrentCharFormat(fmt);
932
933
934
935
936void QTextEdit::setTextColor(
const QColor &c)
939 fmt.setForeground(QBrush(c));
940 mergeCurrentCharFormat(fmt);
944
945
946
947
948
949
950void QTextEdit::setTextBackgroundColor(
const QColor &c)
953 fmt.setBackground(QBrush(c));
954 mergeCurrentCharFormat(fmt);
958
959
960
961
962void QTextEdit::setCurrentFont(
const QFont &f)
966 mergeCurrentCharFormat(fmt);
970
971
972
973
974
975
976
977
978
979void QTextEdit::undo()
985void QTextEdit::redo()
992
993
994
995
996
997
998
999
1000
1001
1003#ifndef QT_NO_CLIPBOARD
1005
1006
1007
1008
1009
1010
1011
1013void QTextEdit::cut()
1020
1021
1022
1023
1025void QTextEdit::copy()
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1045void QTextEdit::paste()
1048 d->control->paste();
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064void QTextEdit::clear()
1068 d->control->clear();
1073
1074
1075
1076
1077void QTextEdit::selectAll()
1080 d->control->selectAll();
1084
1085bool QTextEdit::event(QEvent *e)
1088 switch (e->type()) {
1089 case QEvent::ShortcutOverride:
1090 case QEvent::ToolTip:
1091 d->sendControlEvent(e);
1093 case QEvent::WindowActivate:
1094 case QEvent::WindowDeactivate:
1095 d->control->setPalette(palette());
1097#ifndef QT_NO_CONTEXTMENU
1098 case QEvent::ContextMenu:
1099 if (
static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
1100 ensureCursorVisible();
1101 const QPoint cursorPos = cursorRect().center();
1102 QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
1103 ce.setAccepted(e->isAccepted());
1104 const bool result = QAbstractScrollArea::event(&ce);
1105 e->setAccepted(ce.isAccepted());
1110#ifdef QT_KEYPAD_NAVIGATION
1111 case QEvent::EnterEditFocus:
1112 case QEvent::LeaveEditFocus:
1113 if (QApplicationPrivate::keypadNavigationEnabled())
1114 d->sendControlEvent(e);
1120 return QAbstractScrollArea::event(e);
1124
1126void QTextEdit::timerEvent(QTimerEvent *e)
1129 if (e->timerId() == d->autoScrollTimer.timerId()) {
1130 QRect visible = d->viewport->rect();
1133 pos = d->autoScrollDragPos;
1134 visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
1135 -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
1137 const QPoint globalPos = QCursor::pos();
1138 pos = d->viewport->mapFromGlobal(globalPos);
1139 QMouseEvent ev(QEvent::MouseMove, pos, mapTo(topLevelWidget(), pos), globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
1140 mouseMoveEvent(&ev);
1142 int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
1143 int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
1144 int delta = qMax(deltaX, deltaY);
1148 int timeout = 4900 / (delta * delta);
1149 d->autoScrollTimer.start(timeout,
this);
1152 d->vbar->triggerAction(pos.y() < visible.center().y() ?
1153 QAbstractSlider::SliderSingleStepSub
1154 : QAbstractSlider::SliderSingleStepAdd);
1156 d->hbar->triggerAction(pos.x() < visible.center().x() ?
1157 QAbstractSlider::SliderSingleStepSub
1158 : QAbstractSlider::SliderSingleStepAdd);
1161#ifdef QT_KEYPAD_NAVIGATION
1162 else if (e->timerId() == d->deleteAllTimer.timerId()) {
1163 d->deleteAllTimer.stop();
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1184void QTextEdit::setPlainText(
const QString &text)
1187 d->control->setPlainText(text);
1188 d->preferRichText =
false;
1192
1193
1194
1195
1196
1197
1198QString QTextEdit::toPlainText()
const
1200 Q_D(
const QTextEdit);
1201 return d->control->toPlainText();
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1226#ifndef QT_NO_TEXTHTMLPARSER
1227void QTextEdit::setHtml(
const QString &text)
1230 d->control->setHtml(text);
1231 d->preferRichText =
true;
1234QString QTextEdit::toHtml()
const
1236 Q_D(
const QTextEdit);
1237 return d->control->toHtml();
1241#if QT_CONFIG(textmarkdownreader) && QT_CONFIG(textmarkdownwriter)
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1277#if QT_CONFIG(textmarkdownreader)
1278void QTextEdit::setMarkdown(
const QString &markdown)
1280 Q_D(
const QTextEdit);
1281 d->control->setMarkdown(markdown);
1285#if QT_CONFIG(textmarkdownwriter)
1286QString QTextEdit::toMarkdown(QTextDocument::MarkdownFeatures features)
const
1288 Q_D(
const QTextEdit);
1289 return d->control->toMarkdown(features);
1294
1295void QTextEdit::keyPressEvent(QKeyEvent *e)
1299#ifdef QT_KEYPAD_NAVIGATION
1301 case Qt::Key_Select:
1302 if (QApplicationPrivate::keypadNavigationEnabled()) {
1304 if (d->control->textInteractionFlags() & Qt::TextEditable) {
1305 setEditFocus(!hasEditFocus());
1307 if (!hasEditFocus())
1310 QTextCursor cursor = d->control->textCursor();
1311 QTextCharFormat charFmt = cursor.charFormat();
1312 if (!(d->control->textInteractionFlags() & Qt::LinksAccessibleByKeyboard)
1313 || !cursor.hasSelection() || charFmt.anchorHref().isEmpty()) {
1323 if (!QApplicationPrivate::keypadNavigationEnabled() || !hasEditFocus()) {
1329 if (QApplicationPrivate::keypadNavigationEnabled()) {
1330 if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
1331 if (e->text()[0].isPrint())
1342#ifndef QT_NO_SHORTCUT
1344 Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
1346 if (tif & Qt::TextSelectableByKeyboard){
1347 if (e == QKeySequence::SelectPreviousPage) {
1349 d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
1351 }
else if (e ==QKeySequence::SelectNextPage) {
1353 d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
1357 if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
1358 if (e == QKeySequence::MoveToPreviousPage) {
1360 d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
1362 }
else if (e == QKeySequence::MoveToNextPage) {
1364 d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
1369 if (!(tif & Qt::TextEditable)) {
1373 if (e->modifiers() & Qt::ShiftModifier)
1374 d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
1376 d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
1379 d->sendControlEvent(e);
1380 if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
1381 if (e->key() == Qt::Key_Home) {
1382 d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
1384 }
else if (e->key() == Qt::Key_End) {
1385 d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
1389 if (!e->isAccepted()) {
1390 QAbstractScrollArea::keyPressEvent(e);
1398 QTextCursor cursor = d->control->textCursor();
1399 const QString text = e->text();
1400 if (cursor.atBlockStart()
1401 && (d->autoFormatting & AutoBulletList)
1402 && (text.size() == 1)
1403 && (text.at(0) == u'-' || text.at(0) == u'*')
1404 && (!cursor.currentList())) {
1406 d->createAutoBulletList();
1412 d->sendControlEvent(e);
1413#ifdef QT_KEYPAD_NAVIGATION
1414 if (!e->isAccepted()) {
1418 if (QApplicationPrivate::keypadNavigationEnabled()) {
1426 if (!e->isAutoRepeat()) {
1427 if (QApplicationPrivate::keypadNavigationEnabled()) {
1428 if (document()->isEmpty() || !(d->control->textInteractionFlags() & Qt::TextEditable)) {
1429 setEditFocus(
false);
1431 }
else if (!d->deleteAllTimer.isActive()) {
1433 d->deleteAllTimer.start(750,
this);
1448
1449void QTextEdit::keyReleaseEvent(QKeyEvent *e)
1453 d->handleSoftwareInputPanel();
1454#ifdef QT_KEYPAD_NAVIGATION
1455 if (QApplicationPrivate::keypadNavigationEnabled()) {
1456 if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
1457 && d->deleteAllTimer.isActive()) {
1458 d->deleteAllTimer.stop();
1459 QTextCursor cursor = d->control->textCursor();
1460 QTextBlockFormat blockFmt = cursor.blockFormat();
1462 QTextList *list = cursor.currentList();
1463 if (list && cursor.atBlockStart()) {
1464 list->remove(cursor.block());
1465 }
else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
1466 blockFmt.setIndent(blockFmt.indent() - 1);
1467 cursor.setBlockFormat(blockFmt);
1469 cursor.deletePreviousChar();
1471 setTextCursor(cursor);
1481
1482
1483
1484
1485
1486
1487QVariant QTextEdit::loadResource(
int type,
const QUrl &name)
1495
1496void QTextEdit::resizeEvent(QResizeEvent *e)
1500 if (d->lineWrap == NoWrap) {
1501 QTextDocument *doc = d->control->document();
1502 QVariant alignmentProperty = doc->documentLayout()->property(
"contentHasAlignment");
1504 if (!doc->pageSize().isNull()
1505 && alignmentProperty.userType() == QMetaType::Bool
1506 && !alignmentProperty.toBool()) {
1508 d->adjustScrollbars();
1513 if (d->lineWrap != FixedPixelWidth
1514 && e->oldSize().width() != e->size().width())
1515 d->relayoutDocument();
1517 d->adjustScrollbars();
1522 QTextDocument *doc = control->document();
1523 QAbstractTextDocumentLayout *layout = doc->documentLayout();
1525 if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
1526 if (lineWrap == QTextEdit::FixedColumnWidth)
1527 tlayout->setFixedColumnWidth(lineWrapColumnOrWidth);
1529 tlayout->setFixedColumnWidth(-1);
1532 QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout);
1535 lastUsedSize = tlayout->dynamicDocumentSize().toSize();
1537 lastUsedSize = layout->documentSize().toSize();
1542 const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
1543 ignoreAutomaticScrollbarAdjustment =
true;
1545 int width = viewport->width();
1546 if (lineWrap == QTextEdit::FixedPixelWidth)
1548 else if (lineWrap == QTextEdit::NoWrap) {
1549 QVariant alignmentProperty = doc->documentLayout()->property(
"contentHasAlignment");
1550 if (alignmentProperty.userType() == QMetaType::Bool && !alignmentProperty.toBool()) {
1556 doc->setPageSize(QSize(width, -1));
1560 ignoreAutomaticScrollbarAdjustment = oldIgnoreScrollbarAdjustment;
1564 usedSize = tlayout->dynamicDocumentSize().toSize();
1566 usedSize = layout->documentSize().toSize();
1584 if (lastUsedSize.isValid()
1585 && !vbar->isHidden()
1586 && viewport->width() < lastUsedSize.width()
1587 && usedSize.height() < lastUsedSize.height()
1588 && usedSize.height() <= viewport->height())
1599 QRect r = e->rect();
1600 p->translate(-xOffset, -yOffset);
1601 r.translate(xOffset, yOffset);
1603 QTextDocument *doc = control->document();
1604 QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
1609 layout->setViewport(viewport->rect());
1611 control->drawContents(p, r, q_func());
1614 layout->setViewport(QRect());
1616 if (!placeholderText.isEmpty() && doc->isEmpty() && !control->isPreediting()) {
1617 const QColor col = control->palette().placeholderText().color();
1619 const int margin =
int(doc->documentMargin());
1620 QRectF boundingRect = layout ? layout->frameBoundingRect(doc->rootFrame()) : viewport->rect();
1621 p->drawText(boundingRect.adjusted(margin, margin, -margin, -margin),
1622 Qt::AlignTop | Qt::TextWordWrap,
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637void QTextEdit::paintEvent(QPaintEvent *e)
1640 QPainter p(d->viewport);
1646 QTextDocument *doc = control->document();
1648 QTextOption opt = doc->defaultTextOption();
1649 QTextOption::WrapMode oldWrapMode = opt.wrapMode();
1651 if (lineWrap == QTextEdit::NoWrap)
1652 opt.setWrapMode(QTextOption::NoWrap);
1654 opt.setWrapMode(wordWrap);
1656 if (opt.wrapMode() != oldWrapMode)
1657 doc->setDefaultTextOption(opt);
1661
1662void QTextEdit::mousePressEvent(QMouseEvent *e)
1665#ifdef QT_KEYPAD_NAVIGATION
1666 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
1669 d->sendControlEvent(e);
1673
1674void QTextEdit::mouseMoveEvent(QMouseEvent *e)
1678 const QPoint pos = e->position().toPoint();
1679 d->sendControlEvent(e);
1680 if (!(e->buttons() & Qt::LeftButton))
1682 if (e->source() == Qt::MouseEventNotSynthesized) {
1683 const QRect visible = d->viewport->rect();
1684 if (visible.contains(pos))
1685 d->autoScrollTimer.stop();
1686 else if (!d->autoScrollTimer.isActive())
1687 d->autoScrollTimer.start(100,
this);
1692
1693void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
1696 d->sendControlEvent(e);
1697 if (e->source() == Qt::MouseEventNotSynthesized && d->autoScrollTimer.isActive()) {
1698 d->autoScrollTimer.stop();
1699 ensureCursorVisible();
1701 if (!isReadOnly() && rect().contains(e->position().toPoint()))
1702 d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
1703 d->clickCausedFocus = 0;
1707
1708void QTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
1711 d->sendControlEvent(e);
1715
1716bool QTextEdit::focusNextPrevChild(
bool next)
1718 Q_D(
const QTextEdit);
1719 if (!d->tabChangesFocus && d->control->textInteractionFlags() & Qt::TextEditable)
1721 return QAbstractScrollArea::focusNextPrevChild(next);
1724#ifndef QT_NO_CONTEXTMENU
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740void QTextEdit::contextMenuEvent(QContextMenuEvent *e)
1743 d->sendControlEvent(e);
1747#if QT_CONFIG(draganddrop)
1749
1750void QTextEdit::dragEnterEvent(QDragEnterEvent *e)
1754 d->sendControlEvent(e);
1758
1759void QTextEdit::dragLeaveEvent(QDragLeaveEvent *e)
1763 d->autoScrollTimer.stop();
1764 d->sendControlEvent(e);
1768
1769void QTextEdit::dragMoveEvent(QDragMoveEvent *e)
1772 d->autoScrollDragPos = e->position().toPoint();
1773 if (!d->autoScrollTimer.isActive())
1774 d->autoScrollTimer.start(100,
this);
1775 d->sendControlEvent(e);
1779
1780void QTextEdit::dropEvent(QDropEvent *e)
1784 d->autoScrollTimer.stop();
1785 d->sendControlEvent(e);
1791
1792void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
1795#ifdef QT_KEYPAD_NAVIGATION
1796 if (d->control->textInteractionFlags() & Qt::TextEditable
1797 && QApplicationPrivate::keypadNavigationEnabled()
1801 d->sendControlEvent(e);
1802 const bool emptyEvent = e->preeditString().isEmpty() && e->commitString().isEmpty()
1803 && e->attributes().isEmpty();
1806 ensureCursorVisible();
1810
1811void QTextEdit::scrollContentsBy(
int dx,
int dy)
1814 if (isRightToLeft())
1816 d->viewport->scroll(dx, dy);
1817 QGuiApplication::inputMethod()->update(Qt::ImCursorRectangle | Qt::ImAnchorRectangle);
1821
1822QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property)
const
1824 return inputMethodQuery(property, QVariant());
1828
1829QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument)
const
1831 Q_D(
const QTextEdit);
1834 return isEnabled() && !isReadOnly();
1836 case Qt::ImInputItemClipRectangle:
1837 return QWidget::inputMethodQuery(query);
1838 case Qt::ImReadOnly:
1839 return isReadOnly();
1844 const QPointF offset(-d->horizontalOffset(), -d->verticalOffset());
1845 switch (argument.userType()) {
1846 case QMetaType::QRectF:
1847 argument = argument.toRectF().translated(-offset);
1849 case QMetaType::QPointF:
1850 argument = argument.toPointF() - offset;
1852 case QMetaType::QRect:
1853 argument = argument.toRect().translated(-offset.toPoint());
1855 case QMetaType::QPoint:
1856 argument = argument.toPoint() - offset;
1862 const QVariant v = d->control->inputMethodQuery(query, argument);
1863 switch (v.userType()) {
1864 case QMetaType::QRectF:
1865 return v.toRectF().translated(offset);
1866 case QMetaType::QPointF:
1867 return v.toPointF() + offset;
1868 case QMetaType::QRect:
1869 return v.toRect().translated(offset.toPoint());
1870 case QMetaType::QPoint:
1871 return v.toPoint() + offset.toPoint();
1879
1880void QTextEdit::focusInEvent(QFocusEvent *e)
1883 if (e->reason() == Qt::MouseFocusReason) {
1884 d->clickCausedFocus = 1;
1886 QAbstractScrollArea::focusInEvent(e);
1887 d->sendControlEvent(e);
1891
1892void QTextEdit::focusOutEvent(QFocusEvent *e)
1895 QAbstractScrollArea::focusOutEvent(e);
1896 d->sendControlEvent(e);
1900
1901void QTextEdit::showEvent(QShowEvent *)
1904 if (!d->anchorToScrollToWhenVisible.isEmpty()) {
1905 scrollToAnchor(d->anchorToScrollToWhenVisible);
1906 d->anchorToScrollToWhenVisible.clear();
1907 d->showCursorOnInitialShow =
false;
1908 }
else if (d->showCursorOnInitialShow) {
1909 d->showCursorOnInitialShow =
false;
1910 ensureCursorVisible();
1915
1916void QTextEdit::changeEvent(QEvent *e)
1919 QAbstractScrollArea::changeEvent(e);
1920 if (e->type() == QEvent::ApplicationFontChange
1921 || e->type() == QEvent::FontChange) {
1922 d->control->document()->setDefaultFont(font());
1923 }
else if (e->type() == QEvent::ActivationChange) {
1924 if (!isActiveWindow())
1925 d->autoScrollTimer.stop();
1926 }
else if (e->type() == QEvent::EnabledChange) {
1927 e->setAccepted(isEnabled());
1928 d->control->setPalette(palette());
1929 d->sendControlEvent(e);
1930 }
else if (e->type() == QEvent::PaletteChange) {
1931 d->control->setPalette(palette());
1932 }
else if (e->type() == QEvent::LayoutDirectionChange) {
1933 d->sendControlEvent(e);
1938
1939#if QT_CONFIG(wheelevent)
1940void QTextEdit::wheelEvent(QWheelEvent *e)
1943 if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
1944 if (e->modifiers() & Qt::ControlModifier) {
1945 float delta = e->angleDelta().y() / 120.f;
1950 QAbstractScrollArea::wheelEvent(e);
1955#ifndef QT_NO_CONTEXTMENU
1957
1958
1959
1960
1961
1962
1963
1965QMenu *QTextEdit::createStandardContextMenu()
1968 return d->control->createStandardContextMenu(QPointF(),
this);
1972
1973
1974
1975
1976
1977
1978
1979
1981QMenu *QTextEdit::createStandardContextMenu(
const QPoint &position)
1984 return d->control->createStandardContextMenu(position,
this);
1989
1990
1991QTextCursor QTextEdit::cursorForPosition(
const QPoint &pos)
const
1993 Q_D(
const QTextEdit);
1994 return d->control->cursorForPosition(d->mapToContents(pos));
1998
1999
2000
2001QRect QTextEdit::cursorRect(
const QTextCursor &cursor)
const
2003 Q_D(
const QTextEdit);
2004 if (cursor.isNull())
2007 QRect r = d->control->cursorRect(cursor).toRect();
2008 r.translate(-d->horizontalOffset(),-d->verticalOffset());
2013
2014
2015
2016QRect QTextEdit::cursorRect()
const
2018 Q_D(
const QTextEdit);
2019 QRect r = d->control->cursorRect().toRect();
2020 r.translate(-d->horizontalOffset(),-d->verticalOffset());
2026
2027
2028
2029QString QTextEdit::anchorAt(
const QPoint& pos)
const
2031 Q_D(
const QTextEdit);
2032 return d->control->anchorAt(d->mapToContents(pos));
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2050bool QTextEdit::overwriteMode()
const
2052 Q_D(
const QTextEdit);
2053 return d->control->overwriteMode();
2056void QTextEdit::setOverwriteMode(
bool overwrite)
2059 d->control->setOverwriteMode(overwrite);
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2076qreal QTextEdit::tabStopDistance()
const
2078 Q_D(
const QTextEdit);
2079 return d->control->document()->defaultTextOption().tabStopDistance();
2082void QTextEdit::setTabStopDistance(qreal distance)
2085 QTextOption opt = d->control->document()->defaultTextOption();
2086 if (opt.tabStopDistance() == distance || distance < 0)
2088 opt.setTabStopDistance(distance);
2089 d->control->document()->setDefaultTextOption(opt);
2093
2094
2095
2096
2097
2098int QTextEdit::cursorWidth()
const
2100 Q_D(
const QTextEdit);
2101 return d->control->cursorWidth();
2104void QTextEdit::setCursorWidth(
int width)
2107 d->control->setCursorWidth(width);
2111
2112
2113
2114
2115
2116
2117
2118
2119
2121bool QTextEdit::acceptRichText()
const
2123 Q_D(
const QTextEdit);
2124 return d->control->acceptRichText();
2127void QTextEdit::setAcceptRichText(
bool accept)
2130 d->control->setAcceptRichText(accept);
2134
2135
2136
2137
2138
2139
2140
2143
2144
2145
2148
2149
2150
2151
2154
2155
2156
2157
2158
2159
2160
2161
2162void QTextEdit::setExtraSelections(
const QList<ExtraSelection> &selections)
2165 d->control->setExtraSelections(selections);
2169
2170
2171
2172
2173
2174QList<QTextEdit::ExtraSelection> QTextEdit::extraSelections()
const
2176 Q_D(
const QTextEdit);
2177 return d->control->extraSelections();
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190QMimeData *QTextEdit::createMimeDataFromSelection()
const
2192 Q_D(
const QTextEdit);
2193 return d->control->QWidgetTextControl::createMimeDataFromSelection();
2197
2198
2199
2200
2201
2202
2203
2204
2205bool QTextEdit::canInsertFromMimeData(
const QMimeData *source)
const
2207 Q_D(
const QTextEdit);
2208 return d->control->QWidgetTextControl::canInsertFromMimeData(source);
2212
2213
2214
2215
2216
2217
2218
2219
2220void QTextEdit::insertFromMimeData(
const QMimeData *source)
2223 d->control->QWidgetTextControl::insertFromMimeData(source);
2227
2228
2229
2230
2231
2232
2233
2234
2236bool QTextEdit::isReadOnly()
const
2238 Q_D(
const QTextEdit);
2239 return !d->control || !(d->control->textInteractionFlags() & Qt::TextEditable);
2242void QTextEdit::setReadOnly(
bool ro)
2245 Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
2247 flags = Qt::TextSelectableByMouse;
2248#if QT_CONFIG(textbrowser)
2249 if (qobject_cast<QTextBrowser *>(
this))
2250 flags |= Qt::TextBrowserInteraction;
2253 flags = Qt::TextEditorInteraction;
2255 d->control->setTextInteractionFlags(flags);
2256 setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(
this));
2257 QEvent event(QEvent::ReadOnlyChange);
2258 QCoreApplication::sendEvent(
this, &event);
2262
2263
2264
2265
2266
2267
2268
2269
2271void QTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
2274 d->control->setTextInteractionFlags(flags);
2277Qt::TextInteractionFlags QTextEdit::textInteractionFlags()
const
2279 Q_D(
const QTextEdit);
2280 return d->control->textInteractionFlags();
2284
2285
2286
2287
2288
2289
2290
2291void QTextEdit::mergeCurrentCharFormat(
const QTextCharFormat &modifier)
2294 d->control->mergeCurrentCharFormat(modifier);
2298
2299
2300
2301
2302
2303void QTextEdit::setCurrentCharFormat(
const QTextCharFormat &format)
2306 d->control->setCurrentCharFormat(format);
2310
2311
2312QTextCharFormat QTextEdit::currentCharFormat()
const
2314 Q_D(
const QTextEdit);
2315 return d->control->currentCharFormat();
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2330QTextEdit::AutoFormatting QTextEdit::autoFormatting()
const
2332 Q_D(
const QTextEdit);
2333 return d->autoFormatting;
2336void QTextEdit::setAutoFormatting(AutoFormatting features)
2339 d->autoFormatting = features;
2343
2344
2345
2346
2347
2348
2349
2350void QTextEdit::insertPlainText(
const QString &text)
2353 d->control->insertPlainText(text);
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369#ifndef QT_NO_TEXTHTMLPARSER
2370void QTextEdit::insertHtml(
const QString &text)
2373 d->control->insertHtml(text);
2378
2379
2380
2381
2382void QTextEdit::scrollToAnchor(
const QString &name)
2389 d->anchorToScrollToWhenVisible = name;
2393 QPointF p = d->control->anchorPosition(name);
2394 const int newPosition = qRound(p.y());
2395 if ( d->vbar->maximum() < newPosition )
2396 d->adjustScrollbars();
2397 d->vbar->setValue(newPosition);
2401
2402
2403
2404
2405
2406
2407void QTextEdit::zoomIn(
int range)
2413
2414
2415
2416
2417
2418
2419void QTextEdit::zoomOut(
int range)
2425
2426
2427void QTextEdit::zoomInF(
float range)
2432 const float newSize = f.pointSizeF() + range;
2435 f.setPointSizeF(newSize);
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449void QTextEdit::moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
2452 d->control->moveCursor(operation, mode);
2456
2457
2458
2459bool QTextEdit::canPaste()
const
2461 Q_D(
const QTextEdit);
2462 return d->control->canPaste();
2466
2467
2468
2469
2470
2471
2472
2473#ifndef QT_NO_PRINTER
2474void QTextEdit::print(QPagedPaintDevice *printer)
const
2476 Q_D(
const QTextEdit);
2477 d->control->print(printer);
2482
2483
2484
2485
2486
2487
2488
2490bool QTextEdit::tabChangesFocus()
const
2492 Q_D(
const QTextEdit);
2493 return d->tabChangesFocus;
2496void QTextEdit::setTabChangesFocus(
bool b)
2499 d->tabChangesFocus = b;
2503
2504
2505
2506
2507
2508
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2524QTextEdit::LineWrapMode QTextEdit::lineWrapMode()
const
2526 Q_D(
const QTextEdit);
2530void QTextEdit::setLineWrapMode(LineWrapMode wrap)
2533 if (d->lineWrap == wrap)
2536 d->updateDefaultTextOption();
2537 d->relayoutDocument();
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2555int QTextEdit::lineWrapColumnOrWidth()
const
2557 Q_D(
const QTextEdit);
2558 return d->lineWrapColumnOrWidth;
2561void QTextEdit::setLineWrapColumnOrWidth(
int w)
2564 d->lineWrapColumnOrWidth = w;
2565 d->relayoutDocument();
2569
2570
2571
2572
2573
2574
2575
2577QTextOption::WrapMode QTextEdit::wordWrapMode()
const
2579 Q_D(
const QTextEdit);
2583void QTextEdit::setWordWrapMode(QTextOption::WrapMode mode)
2586 if (mode == d->wordWrap)
2589 d->updateDefaultTextOption();
2593
2594
2595
2596
2597bool QTextEdit::find(
const QString &exp, QTextDocument::FindFlags options)
2600 return d->control->find(exp, options);
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619#if QT_CONFIG(regularexpression)
2620bool QTextEdit::find(
const QRegularExpression &exp, QTextDocument::FindFlags options)
2623 return d->control->find(exp, options);
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2644
2645
2646
2647
2648
2649
2650
2651
2652
2655
2656
2657
2658
2659
2660
2663
2664
2665
2666
2667
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679void QTextEdit::setText(
const QString &text)
2681 Qt::TextFormat format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
2682#ifndef QT_NO_TEXTHTMLPARSER
2683 if (format == Qt::RichText)
2694
2695
2696
2697
2698
2699
2700
2702void QTextEdit::append(
const QString &text)
2705 const bool atBottom = isReadOnly() ? d->verticalOffset() >= d->vbar->maximum() :
2706 d->control->textCursor().atEnd();
2707 d->control->append(text);
2709 d->vbar->setValue(d->vbar->maximum());
2713
2714
2715
2716void QTextEdit::ensureCursorVisible()
2719 d->control->ensureCursorVisible();
2723
2724
2725
2726
2727
2730
2731
2732
2733
2734
2737
2738
2739
2740
2741
2745#include "moc_qtextedit.cpp"
QRect viewport() const
Returns the viewport rectangle.
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
QTextEditControl(QObject *parent)
void pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
int horizontalOffset() const
int lineWrapColumnOrWidth
int verticalOffset() const
void createAutoBulletList()
void cursorPositionChanged()
void updateDefaultTextOption()
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
Combined button and popup list for selecting options.
static QT_BEGIN_NAMESPACE bool shouldEnableInputMethod(QTextEdit *textedit)