From 2c8fa9700cb1eb5f1587bec46b7060ec93c6b1d2 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 10 May 2019 20:20:00 +0200 Subject: Support clicking to toggle checkboxes in QTextEdit Add QAbstractTextDocumentLayout::markerAt(pos) for hit testing. (Qt Quick TextEdit needs it too.) Finds out whether the position corresponds to a marker on a paragraph. I.e. it finds checkboxes in GitHub-flavored markdown. This enables editor classes to toggle checkboxes by clicking them. Use it in QTextEdit to add the checkbox toggling feature. Also show the "pointing finger" cursor when hovering a toggleable checkbox. Change-Id: I036c967ab45e14c836272eac2cc7c7d652543c89 Reviewed-by: Gatis Paeglis --- src/gui/text/qabstracttextdocumentlayout.cpp | 31 ++++++++++++++++++++++++++++ src/gui/text/qabstracttextdocumentlayout.h | 1 + 2 files changed, 32 insertions(+) (limited to 'src/gui/text') diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp index 2278378613..5263ece87c 100644 --- a/src/gui/text/qabstracttextdocumentlayout.cpp +++ b/src/gui/text/qabstracttextdocumentlayout.cpp @@ -41,6 +41,7 @@ #include #include "qtextdocument_p.h" #include "qtextengine_p.h" +#include "qtextlist.h" #include "qabstracttextdocumentlayout_p.h" @@ -649,6 +650,36 @@ QTextFormat QAbstractTextDocumentLayout::formatAt(const QPointF &pos) const return pieceTable->formatCollection()->format(it->format); } +/*! + \since 5.14 + + Returns the block (probably a list item) whose \l{QTextBlockFormat::marker()}{marker} + is found at the given position \a pos. +*/ +QTextBlock QAbstractTextDocumentLayout::blockWithMarkerAt(const QPointF &pos) const +{ + QTextBlock block = document()->firstBlock(); + while (block.isValid()) { + if (block.blockFormat().marker() != QTextBlockFormat::NoMarker) { + QRectF blockBr = blockBoundingRect(block); + QTextBlockFormat blockFmt = block.blockFormat(); + QFontMetrics fm(block.charFormat().font()); + qreal totalIndent = blockFmt.indent() + blockFmt.leftMargin() + blockFmt.textIndent(); + if (block.textList()) + totalIndent += block.textList()->format().indent() * 40; + QRectF adjustedBr = blockBr.adjusted(totalIndent - fm.height(), 0, totalIndent - blockBr.width(), fm.height() - blockBr.height()); + if (adjustedBr.contains(pos)) { + //qDebug() << "hit block" << block.text() << blockBr << adjustedBr << "marker" << block.blockFormat().marker() + // << "font" << block.charFormat().font() << "adj" << lineHeight << totalIndent; + if (block.blockFormat().hasProperty(QTextFormat::BlockMarker)) + return block; + } + } + block = block.next(); + } + return QTextBlock(); +} + /*! \fn QRectF QAbstractTextDocumentLayout::frameBoundingRect(QTextFrame *frame) const diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h index 3371401420..397dcd37d4 100644 --- a/src/gui/text/qabstracttextdocumentlayout.h +++ b/src/gui/text/qabstracttextdocumentlayout.h @@ -87,6 +87,7 @@ public: QString anchorAt(const QPointF& pos) const; QString imageAt(const QPointF &pos) const; QTextFormat formatAt(const QPointF &pos) const; + QTextBlock blockWithMarkerAt(const QPointF &pos) const; virtual int pageCount() const = 0; virtual QSizeF documentSize() const = 0; -- cgit v1.2.3