diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-12-19 21:45:21 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-05-29 13:46:44 +0200 |
commit | 8f62f07bbc59ee3d97cd3d7d54b60b47c979a3cc (patch) | |
tree | 191b8c84f38fd25bad90103716a5d6c06445ba5c /src | |
parent | c8827b444c23656f67feee2e3ebd4f2868ab3db7 (diff) |
Add Markdown support to TextEdit
- textFormat can be set to MarkdownText, and markdown can be
loaded into the text property
- markdown text can be pulled out of the text property
- if there are lists with checkboxes, you can click them to
change the checkbox state
Change-Id: I450115c732d737446ae71806e4abb18e8cc639f3
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquicktextcontrol.cpp | 44 | ||||
-rw-r--r-- | src/quick/items/qquicktextcontrol_p.h | 7 | ||||
-rw-r--r-- | src/quick/items/qquicktextcontrol_p_p.h | 3 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit.cpp | 31 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit_p.h | 4 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit_p_p.h | 3 |
6 files changed, 87 insertions, 5 deletions
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index ac8093e10b..5c4ecd60aa 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -113,6 +113,7 @@ QQuickTextControlPrivate::QQuickTextControlPrivate() wordSelectionEnabled(false), hasImState(false), cursorRectangleChanged(false), + hoveredMarker(false), lastSelectionStart(-1), lastSelectionEnd(-1) {} @@ -321,6 +322,9 @@ void QQuickTextControlPrivate::setContent(Qt::TextFormat format, const QString & formatCursor.select(QTextCursor::Document); formatCursor.setCharFormat(charFormatForInsertion); formatCursor.endEditBlock(); + } else if (format == Qt::MarkdownText) { + doc->setBaseUrl(doc->baseUrl().adjusted(QUrl::RemoveFilename)); + doc->setMarkdown(text); } else { #if QT_CONFIG(texthtmlparser) doc->setHtml(text); @@ -801,6 +805,12 @@ void QQuickTextControl::setPlainText(const QString &text) d->setContent(Qt::PlainText, text); } +void QQuickTextControl::setMarkdownText(const QString &text) +{ + Q_D(QQuickTextControl); + d->setContent(Qt::MarkdownText, text); +} + void QQuickTextControl::setHtml(const QString &text) { Q_D(QQuickTextControl); @@ -1027,6 +1037,8 @@ void QQuickTextControlPrivate::mousePressEvent(QMouseEvent *e, const QPointF &po cursor.clearSelection(); } } + if (interactionFlags & Qt::TextEditable) + blockWithMarkerUnderMousePress = q->blockWithMarkerAt(pos); if (e->button() & Qt::MiddleButton) { return; } else if (!(e->button() & Qt::LeftButton)) { @@ -1198,6 +1210,16 @@ void QQuickTextControlPrivate::mouseReleaseEvent(QMouseEvent *e, const QPointF & q->updateCursorRectangle(true); } + if ((interactionFlags & Qt::TextEditable) && (e->button() & Qt::LeftButton) && blockWithMarkerUnderMousePress.isValid()) { + QTextBlock block = q->blockWithMarkerAt(pos); + if (block == blockWithMarkerUnderMousePress) { + auto fmt = block.blockFormat(); + fmt.setMarker(fmt.marker() == QTextBlockFormat::Unchecked ? + QTextBlockFormat::Checked : QTextBlockFormat::Unchecked); + cursor.setBlockFormat(fmt); + } + } + if (interactionFlags & Qt::LinksAccessibleByMouse) { if (!(e->button() & Qt::LeftButton)) return; @@ -1480,8 +1502,15 @@ void QQuickTextControlPrivate::hoverEvent(QHoverEvent *e, const QPointF &pos) if (hoveredLink != link) { hoveredLink = link; emit q->linkHovered(link); + qCDebug(DBG_HOVER_TRACE) << q << e->type() << pos << "hoveredLink" << hoveredLink; + } else { + QTextBlock block = q->blockWithMarkerAt(pos); + if (block.isValid() != hoveredMarker) + emit q->markerHovered(block.isValid()); + hoveredMarker = block.isValid(); + if (hoveredMarker) + qCDebug(DBG_HOVER_TRACE) << q << e->type() << pos << "hovered marker" << block.blockFormat().marker() << block.text(); } - qCDebug(DBG_HOVER_TRACE) << q << e->type() << pos << "hoveredLink" << hoveredLink; } bool QQuickTextControl::hasImState() const @@ -1557,6 +1586,12 @@ QString QQuickTextControl::anchorAt(const QPointF &pos) const return d->doc->documentLayout()->anchorAt(pos); } +QTextBlock QQuickTextControl::blockWithMarkerAt(const QPointF &pos) const +{ + Q_D(const QQuickTextControl); + return d->doc->documentLayout()->blockWithMarkerAt(pos); +} + void QQuickTextControl::setAcceptRichText(bool accept) { Q_D(QQuickTextControl); @@ -1786,6 +1821,13 @@ QString QQuickTextControl::toHtml() const } #endif +#if QT_CONFIG(textmarkdownwriter) +QString QQuickTextControl::toMarkdown() const +{ + return document()->toMarkdown(); +} +#endif + bool QQuickTextControl::cursorOn() const { Q_D(const QQuickTextControl); diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h index c99736a874..3c7d48f918 100644 --- a/src/quick/items/qquicktextcontrol_p.h +++ b/src/quick/items/qquicktextcontrol_p.h @@ -93,6 +93,9 @@ public: #if QT_CONFIG(texthtmlparser) QString toHtml() const; #endif +#if QT_CONFIG(textmarkdownwriter) + QString toMarkdown() const; +#endif bool hasImState() const; bool overwriteMode() const; @@ -107,6 +110,7 @@ public: QString hoveredLink() const; QString anchorAt(const QPointF &pos) const; + QTextBlock blockWithMarkerAt(const QPointF &pos) const; void setCursorWidth(int width); @@ -128,6 +132,7 @@ public: public Q_SLOTS: void setPlainText(const QString &text); + void setMarkdownText(const QString &text); void setHtml(const QString &text); #if QT_CONFIG(clipboard) @@ -160,6 +165,8 @@ Q_SIGNALS: void cursorRectangleChanged(); void linkActivated(const QString &link); void linkHovered(const QString &link); + void markerClicked(); + void markerHovered(bool marker); public: virtual void processEvent(QEvent *e, const QMatrix &matrix); diff --git a/src/quick/items/qquicktextcontrol_p_p.h b/src/quick/items/qquicktextcontrol_p_p.h index 0582e6d113..5648c31e21 100644 --- a/src/quick/items/qquicktextcontrol_p_p.h +++ b/src/quick/items/qquicktextcontrol_p_p.h @@ -54,6 +54,7 @@ #include "QtGui/qtextdocumentfragment.h" #include "QtGui/qtextcursor.h" #include "QtGui/qtextformat.h" +#include "QtGui/qtextobject.h" #include "QtGui/qabstracttextdocumentlayout.h" #include "QtCore/qbasictimer.h" #include "QtCore/qpointer.h" @@ -139,6 +140,7 @@ public: QString anchorOnMousePress; QString linkToCopy; QString hoveredLink; + QTextBlock blockWithMarkerUnderMousePress; QBasicTimer cursorBlinkTimer; QBasicTimer tripleClickTimer; @@ -163,6 +165,7 @@ public: bool wordSelectionEnabled : 1; bool hasImState : 1; bool cursorRectangleChanged : 1; + bool hoveredMarker: 1; int lastSelectionStart; int lastSelectionEnd; diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index b299e7c92f..7414d7fd6a 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -194,6 +194,11 @@ QString QQuickTextEdit::text() const d->text = d->control->toHtml(); else #endif +#if QT_CONFIG(textmarkdownwriter) + if (d->markdownText) + d->text = d->control->toMarkdown(); + else +#endif d->text = d->control->toPlainText(); d->textCached = true; } @@ -407,6 +412,7 @@ void QQuickTextEdit::setText(const QString &text) d->document->clearResources(); d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text)); + d->markdownText = d->format == MarkdownText; if (!isComponentComplete()) { d->text = text; } else if (d->richText) { @@ -415,6 +421,8 @@ void QQuickTextEdit::setText(const QString &text) #else d->control->setPlainText(text); #endif + } else if (d->markdownText) { + d->control->setMarkdownText(text); } else { d->control->setPlainText(text); } @@ -486,6 +494,7 @@ void QQuickTextEdit::setTextFormat(TextFormat format) bool wasRich = d->richText; d->richText = format == RichText || (format == AutoText && (wasRich || Qt::mightBeRichText(text()))); + d->markdownText = format == MarkdownText; #if QT_CONFIG(texthtmlparser) if (isComponentComplete()) { @@ -1463,8 +1472,12 @@ void QQuickTextEdit::componentComplete() d->control->setHtml(d->text); else #endif - if (!d->text.isEmpty()) - d->control->setPlainText(d->text); + if (!d->text.isEmpty()) { + if (d->markdownText) + d->control->setMarkdownText(d->text); + else + d->control->setPlainText(d->text); + } if (d->dirty) { d->determineHorizontalAlignment(); @@ -2310,6 +2323,7 @@ void QQuickTextEditPrivate::init() QObject::connect(document, &QQuickTextDocumentWithImageResources::contentsChange, q, &QQuickTextEdit::q_contentsChange); QObject::connect(document->documentLayout(), &QAbstractTextDocumentLayout::updateBlock, q, &QQuickTextEdit::invalidateBlock); QObject::connect(control, &QQuickTextControl::linkHovered, q, &QQuickTextEdit::q_linkHovered); + QObject::connect(control, &QQuickTextControl::markerHovered, q, &QQuickTextEdit::q_markerHovered); document->setDefaultFont(font); document->setDocumentMargin(textMargin); @@ -2601,6 +2615,19 @@ void QQuickTextEdit::q_linkHovered(const QString &link) #endif } +void QQuickTextEdit::q_markerHovered(bool hovered) +{ + Q_D(QQuickTextEdit); +#if QT_CONFIG(cursor) + if (!hovered) { + setCursor(d->cursorToRestoreAfterHover); + } else if (cursor().shape() != Qt::PointingHandCursor) { + d->cursorToRestoreAfterHover = cursor().shape(); + setCursor(Qt::PointingHandCursor); + } +#endif +} + void QQuickTextEdit::q_updateAlignment() { Q_D(QQuickTextEdit); diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 259a614d6b..2d1b6c7f9c 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -134,7 +134,8 @@ public: enum TextFormat { PlainText = Qt::PlainText, RichText = Qt::RichText, - AutoText = Qt::AutoText + AutoText = Qt::AutoText, + MarkdownText = Qt::MarkdownText }; Q_ENUM(TextFormat) @@ -375,6 +376,7 @@ private Q_SLOTS: void invalidateBlock(const QTextBlock &block); void updateCursor(); void q_linkHovered(const QString &link); + void q_markerHovered(bool hovered); void q_updateAlignment(); void updateSize(); void triggerPreprocess(); diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index 389ce3175c..be555d44fd 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -127,7 +127,7 @@ public: , focusOnPress(true), persistentSelection(false), requireImplicitWidth(false) , selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true) , textCached(true), inLayout(false), selectByKeyboard(false), selectByKeyboardSet(false) - , hadSelection(false) + , hadSelection(false), markdownText(false) { } @@ -225,6 +225,7 @@ public: bool selectByKeyboard:1; bool selectByKeyboardSet:1; bool hadSelection : 1; + bool markdownText : 1; }; QT_END_NAMESPACE |