diff options
Diffstat (limited to 'src/widgets/widgets/qwidgettextcontrol.cpp')
-rw-r--r-- | src/widgets/widgets/qwidgettextcontrol.cpp | 93 |
1 files changed, 63 insertions, 30 deletions
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index e73975f9e2..6dcaeee0c8 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -24,6 +24,7 @@ #endif #include "qtextdocument.h" #include "private/qtextdocument_p.h" +#include "private/qtextdocumentfragment_p.h" #include "qtextlist.h" #include "private/qwidgettextcontrol_p.h" #if QT_CONFIG(style_stylesheet) @@ -578,7 +579,7 @@ void QWidgetTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged Q_Q(QWidgetTextControl); if (forceEmitSelectionChanged) { emit q->selectionChanged(); -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) if (q->parent() && q->parent()->isWidgetType()) { QAccessibleTextSelectionEvent ev(q->parent(), cursor.anchor(), cursor.position()); QAccessible::updateAccessibility(&ev); @@ -601,7 +602,7 @@ void QWidgetTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged && (cursor.position() != lastSelectionPosition || cursor.anchor() != lastSelectionAnchor)))) { emit q->selectionChanged(); -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) if (q->parent() && q->parent()->isWidgetType()) { QAccessibleTextSelectionEvent ev(q->parent(), cursor.anchor(), cursor.position()); QAccessible::updateAccessibility(&ev); @@ -642,7 +643,7 @@ void QWidgetTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someC void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, int charsAdded) { -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) Q_Q(QWidgetTextControl); if (QAccessible::isActive() && q->parent() && q->parent()->isWidgetType()) { @@ -966,9 +967,12 @@ void QWidgetTextControl::selectAll() { Q_D(QWidgetTextControl); const int selectionLength = qAbs(d->cursor.position() - d->cursor.anchor()); + const int oldCursorPos = d->cursor.position(); d->cursor.select(QTextCursor::Document); d->selectionChanged(selectionLength != qAbs(d->cursor.position() - d->cursor.anchor())); d->cursorIsFocusIndicator = false; + if (d->cursor.position() != oldCursorPos) + emit cursorPositionChanged(); emit updateRequest(); } @@ -1402,7 +1406,7 @@ QRectF QWidgetTextControlPrivate::rectForPosition(int position) const if (relativePos == preeditPos) relativePos += preeditCursor; else if (relativePos > preeditPos) - relativePos += layout->preeditAreaText().length(); + relativePos += layout->preeditAreaText().size(); } QTextLine line = layout->lineForTextPosition(relativePos); @@ -1817,25 +1821,36 @@ void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton but } if (interactionFlags & Qt::LinksAccessibleByMouse) { - if (!(button & Qt::LeftButton)) + + // Ignore event unless left button has been pressed + if (!(button & Qt::LeftButton)) { + e->ignore(); return; + } const QString anchor = q->anchorAt(pos); - if (anchor.isEmpty()) + // Ignore event without selection anchor + if (anchor.isEmpty()) { + e->ignore(); return; + } if (!cursor.hasSelection() || (anchor == anchorOnMousePress && hadSelectionOnMousePress)) { const int anchorPos = q->hitTest(pos, Qt::ExactHit); - if (anchorPos != -1) { - cursor.setPosition(anchorPos); - QString anchor = anchorOnMousePress; - anchorOnMousePress = QString(); - activateLinkUnderCursor(anchor); + // Ignore event without valid anchor position + if (anchorPos < 0) { + e->ignore(); + return; } + + cursor.setPosition(anchorPos); + QString anchor = anchorOnMousePress; + anchorOnMousePress = QString(); + activateLinkUnderCursor(anchor); } } } @@ -1899,7 +1914,7 @@ bool QWidgetTextControlPrivate::sendMouseEventToInputContext( QTextLayout *layout = cursor.block().layout(); int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position(); - if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) + if (cursorPos < 0 || cursorPos > layout->preeditAreaText().size()) cursorPos = -1; if (cursorPos >= 0) { @@ -2020,6 +2035,11 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) || e->preeditString() != cursor.block().layout()->preeditAreaText() || e->replacementLength() > 0; + if (!isGettingInput && e->attributes().isEmpty()) { + e->ignore(); + return; + } + int oldCursorPos = cursor.position(); cursor.beginEditBlock(); @@ -2059,7 +2079,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) QList<QTextLayout::FormatRange> overrides; overrides.reserve(e->attributes().size()); const int oldPreeditCursor = preeditCursor; - preeditCursor = e->preeditString().length(); + preeditCursor = e->preeditString().size(); hideCursor = false; for (int i = 0; i < e->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = e->attributes().at(i); @@ -2094,7 +2114,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) if (cursor.charFormat().isValid()) { int start = cursor.position() - block.position(); - int end = start + e->preeditString().length(); + int end = start + e->preeditString().size(); QList<QTextLayout::FormatRange>::iterator it = overrides.begin(); while (it != overrides.end()) { @@ -2167,7 +2187,7 @@ QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVa QTextCursor tmpCursor = d->cursor; int localPos = d->cursor.position() - block.position(); QString result = block.text().mid(localPos); - while (result.length() < maxLength) { + while (result.size() < maxLength) { int currentBlock = tmpCursor.blockNumber(); tmpCursor.movePosition(QTextCursor::NextBlock); if (tmpCursor.blockNumber() == currentBlock) @@ -2284,7 +2304,7 @@ void QWidgetTextControlPrivate::editFocusEvent(QEvent *e) #endif #ifndef QT_NO_CONTEXTMENU -static inline void setActionIcon(QAction *action, const QString &name) +void setActionIcon(QAction *action, const QString &name) { const QIcon icon = QIcon::fromTheme(name); if (!icon.isNull()) @@ -2450,7 +2470,7 @@ void QWidgetTextControl::setCursorWidth(int width) { Q_D(QWidgetTextControl); if (width == -1) - width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth, nullptr); + width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth, nullptr, qobject_cast<QWidget *>(parent())); d->doc->documentLayout()->setProperty("cursorWidth", width); d->repaintCursor(); } @@ -2474,12 +2494,12 @@ void QWidgetTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelectio Q_D(QWidgetTextControl); QMultiHash<int, int> hash; - for (int i = 0; i < d->extraSelections.count(); ++i) { + for (int i = 0; i < d->extraSelections.size(); ++i) { const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(i); hash.insert(esel.cursor.anchor(), i); } - for (int i = 0; i < selections.count(); ++i) { + for (int i = 0; i < selections.size(); ++i) { const QTextEdit::ExtraSelection &sel = selections.at(i); const auto it = hash.constFind(sel.cursor.anchor()); if (it != hash.cend()) { @@ -2508,8 +2528,8 @@ void QWidgetTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelectio emit updateRequest(r); } - d->extraSelections.resize(selections.count()); - for (int i = 0; i < selections.count(); ++i) { + d->extraSelections.resize(selections.size()); + for (int i = 0; i < selections.size(); ++i) { d->extraSelections[i].cursor = selections.at(i).cursor; d->extraSelections[i].format = selections.at(i).format; } @@ -2519,7 +2539,7 @@ QList<QTextEdit::ExtraSelection> QWidgetTextControl::extraSelections() const { Q_D(const QWidgetTextControl); QList<QTextEdit::ExtraSelection> selections; - const int numExtraSelections = d->extraSelections.count(); + const int numExtraSelections = d->extraSelections.size(); selections.reserve(numExtraSelections); for (int i = 0; i < numExtraSelections; ++i) { QTextEdit::ExtraSelection sel; @@ -2697,6 +2717,14 @@ void QWidgetTextControl::insertFromMimeData(const QMimeData *source) bool hasData = false; QTextDocumentFragment fragment; +#if QT_CONFIG(textmarkdownreader) + const auto formats = source->formats(); + if (formats.size() && formats.first() == "text/markdown"_L1) { + auto s = QString::fromUtf8(source->data("text/markdown"_L1)); + fragment = QTextDocumentFragment::fromMarkdown(s); + hasData = true; + } else +#endif #ifndef QT_NO_TEXTHTMLPARSER if (source->hasFormat("application/x-qrichtext"_L1) && d->acceptRichText) { // x-qrichtext is always UTF-8 (taken from Qt3 since we don't use it anymore). @@ -2707,16 +2735,15 @@ void QWidgetTextControl::insertFromMimeData(const QMimeData *source) } else if (source->hasHtml() && d->acceptRichText) { fragment = QTextDocumentFragment::fromHtml(source->html(), d->doc); hasData = true; - } else { - QString text = source->text(); + } +#endif // QT_NO_TEXTHTMLPARSER + if (!hasData) { + const QString text = source->text(); if (!text.isNull()) { fragment = QTextDocumentFragment::fromPlainText(text); hasData = true; } } -#else - fragment = QTextDocumentFragment::fromPlainText(source->text()); -#endif // QT_NO_TEXTHTMLPARSER if (hasData) d->cursor.insertFragment(fragment); @@ -3433,9 +3460,12 @@ void QUnicodeControlCharacterMenu::menuActionTriggered() QStringList QTextEditMimeData::formats() const { if (!fragment.isEmpty()) - return QStringList() << QString::fromLatin1("text/plain") << QString::fromLatin1("text/html") + return QStringList() << u"text/plain"_s << u"text/html"_s +#if QT_CONFIG(textmarkdownwriter) + << u"text/markdown"_s +#endif #ifndef QT_NO_TEXTODFWRITER - << QString::fromLatin1("application/vnd.oasis.opendocument.text") + << u"application/vnd.oasis.opendocument.text"_s #endif ; else @@ -3455,6 +3485,9 @@ void QTextEditMimeData::setup() const #ifndef QT_NO_TEXTHTMLPARSER that->setData("text/html"_L1, fragment.toHtml().toUtf8()); #endif +#if QT_CONFIG(textmarkdownwriter) + that->setData("text/markdown"_L1, fragment.toMarkdown().toUtf8()); +#endif #ifndef QT_NO_TEXTODFWRITER { QBuffer buffer; @@ -3464,7 +3497,7 @@ void QTextEditMimeData::setup() const that->setData("application/vnd.oasis.opendocument.text"_L1, buffer.data()); } #endif - that->setText(fragment.toRawText()); + that->setText(fragment.toPlainText()); fragment = QTextDocumentFragment(); } |