summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qtextedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qtextedit.cpp')
-rw-r--r--src/widgets/widgets/qtextedit.cpp156
1 files changed, 88 insertions, 68 deletions
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index f3d1d3e511..90884dd438 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -88,8 +88,7 @@ QTextEditPrivate::QTextEditPrivate()
: control(nullptr),
autoFormatting(QTextEdit::AutoNone), tabChangesFocus(false),
lineWrap(QTextEdit::WidgetWidth), lineWrapColumnOrWidth(0),
- wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0),
- textFormat(Qt::AutoText)
+ wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0)
{
ignoreAutomaticScrollbarAdjustment = false;
preferRichText = false;
@@ -97,6 +96,12 @@ QTextEditPrivate::QTextEditPrivate()
inDrag = false;
}
+QTextEditPrivate::~QTextEditPrivate()
+{
+ for (const QMetaObject::Connection &connection : connections)
+ QObject::disconnect(connection);
+}
+
void QTextEditPrivate::createAutoBulletList()
{
QTextCursor cursor = control->textCursor();
@@ -123,24 +128,34 @@ void QTextEditPrivate::init(const QString &html)
control = new QTextEditControl(q);
control->setPalette(q->palette());
- QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
- QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
- QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
- QObject::connect(control, SIGNAL(visibilityRequest(QRectF)), q, SLOT(_q_ensureVisible(QRectF)));
- QObject::connect(control, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
- q, SLOT(_q_currentCharFormatChanged(QTextCharFormat)));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
- QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
- QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
- QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
- QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
-#if QT_CONFIG(cursor)
- QObject::connect(control, SIGNAL(blockMarkerHovered(QTextBlock)), q, SLOT(_q_hoveredBlockWithMarkerChanged(QTextBlock)));
-#endif
-
- QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
+ connections = {
+ QObjectPrivate::connect(control, &QTextEditControl::documentSizeChanged,
+ this, &QTextEditPrivate::adjustScrollbars),
+ QObjectPrivate::connect(control, &QTextEditControl::updateRequest,
+ this, &QTextEditPrivate::repaintContents),
+ QObjectPrivate::connect(control, &QTextEditControl::visibilityRequest,
+ this, &QTextEditPrivate::ensureVisible),
+ QObjectPrivate::connect(control, &QTextEditControl::blockMarkerHovered,
+ this, &QTextEditPrivate::hoveredBlockWithMarkerChanged),
+ QObjectPrivate::connect(control, &QTextEditControl::cursorPositionChanged,
+ this, &QTextEditPrivate::cursorPositionChanged),
+ QObject::connect(control, &QTextEditControl::microFocusChanged,
+ q, [q]() { q->updateMicroFocus(); }),
+ QObject::connect(control, &QTextEditControl::currentCharFormatChanged,
+ q, &QTextEdit::currentCharFormatChanged),
+ QObject::connect(control, &QTextEditControl::textChanged,
+ q, &QTextEdit::textChanged),
+ QObject::connect(control, &QTextEditControl::undoAvailable,
+ q, &QTextEdit::undoAvailable),
+ QObject::connect(control, &QTextEditControl::redoAvailable,
+ q, &QTextEdit::redoAvailable),
+ QObject::connect(control, &QTextEditControl::copyAvailable,
+ q, &QTextEdit::copyAvailable),
+ QObject::connect(control, &QTextEditControl::selectionChanged,
+ q, &QTextEdit::selectionChanged),
+ QObject::connect(control, &QTextEditControl::textChanged,
+ q, [q]() { q->updateMicroFocus(); }),
+ };
QTextDocument *doc = control->document();
// set a null page size initially to avoid any relayouting until the textedit
@@ -170,7 +185,7 @@ void QTextEditPrivate::init(const QString &html)
#endif
}
-void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
+void QTextEditPrivate::repaintContents(const QRectF &contentsRect)
{
if (!contentsRect.isValid()) {
viewport->update();
@@ -188,7 +203,7 @@ void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
viewport->update(r);
}
-void QTextEditPrivate::_q_cursorPositionChanged()
+void QTextEditPrivate::cursorPositionChanged()
{
Q_Q(QTextEdit);
emit q->cursorPositionChanged();
@@ -198,9 +213,9 @@ void QTextEditPrivate::_q_cursorPositionChanged()
#endif
}
-#if QT_CONFIG(cursor)
-void QTextEditPrivate::_q_hoveredBlockWithMarkerChanged(const QTextBlock &block)
+void QTextEditPrivate::hoveredBlockWithMarkerChanged(const QTextBlock &block)
{
+#if QT_CONFIG(cursor)
Q_Q(QTextEdit);
Qt::CursorShape cursor = cursorToRestoreAfterHover;
if (block.isValid() && !q->isReadOnly()) {
@@ -212,8 +227,8 @@ void QTextEditPrivate::_q_hoveredBlockWithMarkerChanged(const QTextBlock &block)
}
}
viewport->setCursor(cursor);
-}
#endif
+}
void QTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
{
@@ -262,7 +277,7 @@ static QSize documentSize(QWidgetTextControl *control)
return docSize;
}
-void QTextEditPrivate::_q_adjustScrollbars()
+void QTextEditPrivate::adjustScrollbars()
{
if (ignoreAutomaticScrollbarAdjustment)
return;
@@ -312,12 +327,12 @@ void QTextEditPrivate::_q_adjustScrollbars()
#endif
// rect is in content coordinates
-void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
+void QTextEditPrivate::ensureVisible(const QRectF &_rect)
{
const QRect rect = _rect.toRect();
if ((vbar->isVisible() && vbar->maximum() < rect.bottom())
|| (hbar->isVisible() && hbar->maximum() < rect.right()))
- _q_adjustScrollbars();
+ adjustScrollbars();
const int visibleWidth = viewport->width();
const int visibleHeight = viewport->height();
const bool rtl = q_func()->isRightToLeft();
@@ -540,7 +555,7 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
of the movement keystrokes, for example, \e{Shift+Right}
will select the character to the right, and \e{Shift+Ctrl+Right} will select the word to the right, etc.
- \sa QTextDocument, QTextCursor, {Qt Widgets - Application Example},
+ \sa QTextDocument, QTextCursor,
{Syntax Highlighter Example}, {Rich Text Processing}
*/
@@ -713,7 +728,8 @@ QColor QTextEdit::textColor() const
QColor QTextEdit::textBackgroundColor() const
{
Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().background().color();
+ const QBrush &brush = d->control->textCursor().charFormat().background();
+ return brush.style() == Qt::NoBrush ? Qt::transparent : brush.color();
}
/*!
@@ -1064,30 +1080,38 @@ void QTextEdit::selectAll()
bool QTextEdit::event(QEvent *e)
{
Q_D(QTextEdit);
-#ifndef QT_NO_CONTEXTMENU
- if (e->type() == QEvent::ContextMenu
- && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
- Q_D(QTextEdit);
- ensureCursorVisible();
- const QPoint cursorPos = cursorRect().center();
- QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
- ce.setAccepted(e->isAccepted());
- const bool result = QAbstractScrollArea::event(&ce);
- e->setAccepted(ce.isAccepted());
- return result;
- } else if (e->type() == QEvent::ShortcutOverride
- || e->type() == QEvent::ToolTip) {
+ switch (e->type()) {
+ case QEvent::ShortcutOverride:
+ case QEvent::ToolTip:
d->sendControlEvent(e);
- }
-#else
- Q_UNUSED(d);
+ break;
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ d->control->setPalette(palette());
+ break;
+#ifndef QT_NO_CONTEXTMENU
+ case QEvent::ContextMenu:
+ if (static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
+ ensureCursorVisible();
+ const QPoint cursorPos = cursorRect().center();
+ QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
+ ce.setAccepted(e->isAccepted());
+ const bool result = QAbstractScrollArea::event(&ce);
+ e->setAccepted(ce.isAccepted());
+ return result;
+ }
+ break;
#endif // QT_NO_CONTEXTMENU
#ifdef QT_KEYPAD_NAVIGATION
- if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
+ case QEvent::EnterEditFocus:
+ case QEvent::LeaveEditFocus:
if (QApplicationPrivate::keypadNavigationEnabled())
d->sendControlEvent(e);
- }
+ break;
#endif
+ default:
+ break;
+ }
return QAbstractScrollArea::event(e);
}
@@ -1477,7 +1501,7 @@ void QTextEdit::resizeEvent(QResizeEvent *e)
&& alignmentProperty.userType() == QMetaType::Bool
&& !alignmentProperty.toBool()) {
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
return;
}
}
@@ -1486,7 +1510,7 @@ void QTextEdit::resizeEvent(QResizeEvent *e)
&& e->oldSize().width() != e->size().width())
d->relayoutDocument();
else
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
}
void QTextEditPrivate::relayoutDocument()
@@ -1508,7 +1532,7 @@ void QTextEditPrivate::relayoutDocument()
else
lastUsedSize = layout->documentSize().toSize();
- // ignore calls to _q_adjustScrollbars caused by an emission of the
+ // ignore calls to adjustScrollbars caused by an emission of the
// usedSizeChanged() signal in the layout, as we're calling it
// later on our own anyway (or deliberately not) .
const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
@@ -1547,7 +1571,7 @@ void QTextEditPrivate::relayoutDocument()
// its size. So a layout with less width _can_ take up less vertical space, too.
// If the wider case causes a vertical scroll bar to appear and the narrower one
// (narrower because the vertical scroll bar takes up horizontal space)) to disappear
- // again then we have an endless loop, as _q_adjustScrollBars sets new ranges on the
+ // again then we have an endless loop, as adjustScrollbars sets new ranges on the
// scroll bars, the QAbstractScrollArea will find out about it and try to show/hide
// the scroll bars again. That's why we try to detect this case here and break out.
//
@@ -1560,7 +1584,7 @@ void QTextEditPrivate::relayoutDocument()
&& usedSize.height() <= viewport->height())
return;
- _q_adjustScrollbars();
+ adjustScrollbars();
}
void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
@@ -1598,6 +1622,8 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
This event handler can be reimplemented in a subclass to receive paint events passed in \a event.
It is usually unnecessary to reimplement this function in a subclass of QTextEdit.
+\note If you create a QPainter, it must operate on the \l{QAbstractScrollArea::}{viewport()}.
+
\warning The underlying text document must not be modified from within a reimplementation
of this function.
*/
@@ -1608,12 +1634,6 @@ void QTextEdit::paintEvent(QPaintEvent *e)
d->paint(&p, e);
}
-void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
-{
- Q_Q(QTextEdit);
- emit q->currentCharFormatChanged(fmt);
-}
-
void QTextEditPrivate::updateDefaultTextOption()
{
QTextDocument *doc = control->document();
@@ -1804,7 +1824,7 @@ QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argume
Q_D(const QTextEdit);
switch (query) {
case Qt::ImEnabled:
- return isEnabled();
+ return isEnabled() && !isReadOnly();
case Qt::ImHints:
case Qt::ImInputItemClipRectangle:
return QWidget::inputMethodQuery(query);
@@ -2209,7 +2229,7 @@ void QTextEdit::insertFromMimeData(const QMimeData *source)
bool QTextEdit::isReadOnly() const
{
Q_D(const QTextEdit);
- return !(d->control->textInteractionFlags() & Qt::TextEditable);
+ return !d->control || !(d->control->textInteractionFlags() & Qt::TextEditable);
}
void QTextEdit::setReadOnly(bool ro)
@@ -2366,7 +2386,7 @@ void QTextEdit::scrollToAnchor(const QString &name)
QPointF p = d->control->anchorPosition(name);
const int newPosition = qRound(p.y());
if ( d->vbar->maximum() < newPosition )
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
d->vbar->setValue(newPosition);
}
@@ -2580,11 +2600,14 @@ bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
\overload
Finds the next occurrence, matching the regular expression, \a exp, using the given
- \a options. The QTextDocument::FindCaseSensitively option is ignored for this overload,
- use QRegularExpression::CaseInsensitiveOption instead.
+ \a options.
Returns \c true if a match was found and changes the cursor to select the match;
otherwise returns \c false.
+
+ \warning For historical reasons, the case sensitivity option set on
+ \a exp is ignored. Instead, the \a options are used to determine
+ if the search is case sensitive or not.
*/
#if QT_CONFIG(regularexpression)
bool QTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
@@ -2648,10 +2671,7 @@ bool QTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags opt
*/
void QTextEdit::setText(const QString &text)
{
- Q_D(QTextEdit);
- Qt::TextFormat format = d->textFormat;
- if (d->textFormat == Qt::AutoText)
- format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
+ Qt::TextFormat format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
#ifndef QT_NO_TEXTHTMLPARSER
if (format == Qt::RichText)
setHtml(text);