summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.cpp15
-rw-r--r--tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp32
2 files changed, 47 insertions, 0 deletions
diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp
index 589c0f701f..e14cfe0f82 100644
--- a/src/gui/text/qabstracttextdocumentlayout.cpp
+++ b/src/gui/text/qabstracttextdocumentlayout.cpp
@@ -577,6 +577,21 @@ QString QAbstractTextDocumentLayout::anchorAt(const QPointF& pos) const
if (cursorPos == -1)
return QString();
+ // compensate for preedit in the hit text block
+ QTextBlock block = document()->firstBlock();
+ while (block.isValid()) {
+ QRectF blockBr = blockBoundingRect(block);
+ if (blockBr.contains(pos)) {
+ QTextLayout *layout = block.layout();
+ int relativeCursorPos = cursorPos - block.position();
+ const int preeditLength = layout ? layout->preeditAreaText().length() : 0;
+ if (preeditLength > 0 && relativeCursorPos > layout->preeditAreaPosition())
+ cursorPos -= qMin(cursorPos - layout->preeditAreaPosition(), preeditLength);
+ break;
+ }
+ block = block.next();
+ }
+
QTextDocumentPrivate *pieceTable = qobject_cast<const QTextDocument *>(parent())->docHandle();
QTextDocumentPrivate::FragmentIterator it = pieceTable->find(cursorPos);
QTextCharFormat fmt = pieceTable->formatCollection()->charFormat(it->format);
diff --git a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp
index c609b4a1ed..a33e3cd13b 100644
--- a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp
+++ b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp
@@ -47,6 +47,7 @@
#include <qabstracttextdocumentlayout.h>
#include <qimage.h>
#include <qtextobject.h>
+#include <qfontmetrics.h>
class tst_QAbstractTextDocumentLayout : public QObject
{
@@ -59,6 +60,7 @@ public:
private slots:
void getSetCheck();
void maximumBlockCount();
+ void anchorAt();
};
tst_QAbstractTextDocumentLayout::tst_QAbstractTextDocumentLayout()
@@ -152,5 +154,35 @@ void tst_QAbstractTextDocumentLayout::maximumBlockCount()
QCOMPARE(layout.blockCount, 10);
}
+void tst_QAbstractTextDocumentLayout::anchorAt()
+{
+ QTextDocument doc;
+ doc.setHtml("<a href=\"link\">foo</a>");
+ QAbstractTextDocumentLayout *documentLayout = doc.documentLayout();
+ QTextBlock firstBlock = doc.begin();
+ QTextLayout *layout = firstBlock.layout();
+ layout->setPreeditArea(doc.toPlainText().length(), "xxx");
+
+ doc.setPageSize(QSizeF(1000, 1000));
+ QFontMetrics metrics(layout->font());
+ QPointF blockStart = documentLayout->blockBoundingRect(firstBlock).topLeft();
+
+ // anchorAt on start returns link
+ QRect linkBr = metrics.boundingRect("foo");
+ QPointF linkPoint(linkBr.width() + blockStart.x(), (linkBr.height() / 2) + blockStart.y());
+ QCOMPARE(documentLayout->anchorAt(linkPoint), QString("link"));
+
+ // anchorAt() on top of preedit at end should not assert
+ QRect preeditBr = metrics.boundingRect(doc.toPlainText() + "xx");
+ QPointF preeditPoint(preeditBr.width() + blockStart.x(), (preeditBr.height() / 2) + blockStart.y());
+ QCOMPARE(documentLayout->anchorAt(preeditPoint), QString());
+
+ // preedit at start should not return link
+ layout->setPreeditArea(0, "xxx");
+ preeditBr = metrics.boundingRect("xx");
+ preeditPoint = QPointF(preeditBr.width() + blockStart.x(), (preeditBr.height() / 2) + blockStart.y());
+ QCOMPARE(documentLayout->anchorAt(preeditPoint), QString());
+}
+
QTEST_MAIN(tst_QAbstractTextDocumentLayout)
#include "tst_qabstracttextdocumentlayout.moc"