Protect QAbstractTextDocumentLayout::anchorAt() from preedit

Previously the method didn't take into account that hitTest()
returns visual index, i.e. containing the preedit, and thus was easily
hitting assertion. Need to compensate for that before checking for actual
link.

Change-Id: I119e7f91088b4db9d347a3da338f6df915ce9719
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
bb10
Pekka Vuorela 2011-12-08 14:52:19 +02:00 committed by Qt by Nokia
parent 5e4ed93b1c
commit 2744105419
2 changed files with 47 additions and 0 deletions

View File

@ -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);

View File

@ -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"