aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-06-19 11:30:59 +1000
committerQt by Nokia <qt-info@nokia.com>2012-06-25 08:57:36 +0200
commit3ae9c8c36097abffd73e29cea1b897ca7d704916 (patch)
tree0657805f357206636bd37b9b95e6d4557ce6473c
parent31ba131f9b166ef857f8559a23429d99609e6669 (diff)
Fix clicking on links in aligned or elided Text.
Adjust the mouse position to compensate for any alignment offsets and test the elided text layout for anchors if none is found in the normal layout. Change-Id: Idfda3f7e372d0f2d6c1b7bb5f22d7015d52e8239 Reviewed-by: Yann Bodson <yann.bodson@nokia.com>
-rw-r--r--src/quick/items/qquicktext.cpp108
-rw-r--r--src/quick/items/qquicktext_p_p.h3
-rw-r--r--src/quick/items/qquicktextutil.cpp33
-rw-r--r--src/quick/items/qquicktextutil_p.h4
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp340
5 files changed, 407 insertions, 81 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index f03afd657a..b19b13fec2 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -47,6 +47,8 @@
#include <private/qsgadaptationlayer_p.h>
#include "qquicktextnode_p.h"
#include "qquickimage_p_p.h"
+#include "qquicktextutil_p.h"
+
#include <QtQuick/private/qsgtexture_p.h>
#include <QtQml/qqmlinfo.h>
@@ -2011,36 +2013,13 @@ QRectF QQuickText::boundingRect() const
Q_D(const QQuickText);
QRectF rect = d->layedOutTextRect;
+ rect.moveLeft(QQuickTextUtil::alignedX(rect, width(), d->hAlign));
+ rect.moveTop(QQuickTextUtil::alignedY(rect, height(), d->vAlign));
+
if (d->style != Normal)
rect.adjust(-1, 0, 1, 2);
-
// Could include font max left/right bearings to either side of rectangle.
- qreal w = width();
- switch (d->hAlign) {
- case AlignLeft:
- case AlignJustify:
- break;
- case AlignRight:
- rect.moveLeft(w - rect.width());
- break;
- case AlignHCenter:
- rect.moveLeft((w - rect.width()) / 2);
- break;
- }
-
- qreal h = height();
- switch (d->vAlign) {
- case AlignTop:
- break;
- case AlignBottom:
- rect.moveTop(h - rect.height());
- break;
- case AlignVCenter:
- rect.moveTop((h - rect.height()) / 2);
- break;
- }
-
return rect;
}
@@ -2131,7 +2110,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
d->updateType = QQuickTextPrivate::UpdateNone;
- QRectF bounds = boundingRect();
+ const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect, height(), d->vAlign);
// We need to make sure the layout is done in the current thread
#if defined(Q_OS_MAC)
@@ -2156,27 +2135,28 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
if (d->richText) {
d->ensureDoc();
- node->addTextDocument(bounds.topLeft(), d->extra->doc, color, d->style, styleColor, linkColor);
- } else if (d->elideMode == QQuickText::ElideNone || bounds.width() > 0.) {
+ const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect, width(), d->hAlign);
+ node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor);
+ } else if (d->elideMode == QQuickText::ElideNone || d->layedOutTextRect.width() > 0.) {
int unelidedLineCount = d->lineCount;
if (d->elideLayout)
unelidedLineCount -= 1;
if (unelidedLineCount > 0) {
node->addTextLayout(
- QPoint(0, bounds.y()),
+ QPoint(0, dy),
&d->layout,
color, d->style, styleColor, linkColor,
QColor(), QColor(), -1, -1,
0, unelidedLineCount);
}
if (d->elideLayout)
- node->addTextLayout(QPoint(0, bounds.y()), d->elideLayout, color, d->style, styleColor, linkColor);
+ node->addTextLayout(QPoint(0, dy), d->elideLayout, color, d->style, styleColor, linkColor);
}
foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) {
QQuickPixmap *pix = img->pix;
if (pix && pix->isReady())
- node->addImage(QRectF(img->pos.x(), img->pos.y() + bounds.y(), pix->width(), pix->height()), pix->image());
+ node->addImage(QRectF(img->pos.x(), img->pos.y() + dy, pix->width(), pix->height()), pix->image());
}
return node;
}
@@ -2397,28 +2377,42 @@ void QQuickText::componentComplete()
d->updateLayout();
}
-
-QString QQuickTextPrivate::anchorAt(const QPointF &mousePos)
+QString QQuickTextPrivate::anchorAt(const QTextLayout *layout, const QPointF &mousePos)
{
- if (styledText) {
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- if (line.naturalTextRect().contains(mousePos)) {
- int charPos = line.xToCursor(mousePos.x());
- foreach (const QTextLayout::FormatRange &formatRange, layout.additionalFormats()) {
- if (formatRange.format.isAnchor()
- && charPos >= formatRange.start
- && charPos <= formatRange.start + formatRange.length) {
- return formatRange.format.anchorHref();
- }
+ for (int i = 0; i < layout->lineCount(); ++i) {
+ QTextLine line = layout->lineAt(i);
+ if (line.naturalTextRect().contains(mousePos)) {
+ int charPos = line.xToCursor(mousePos.x(), QTextLine::CursorOnCharacter);
+ foreach (const QTextLayout::FormatRange &formatRange, layout->additionalFormats()) {
+ if (formatRange.format.isAnchor()
+ && charPos >= formatRange.start
+ && charPos < formatRange.start + formatRange.length) {
+ return formatRange.format.anchorHref();
}
- break;
}
+ break;
}
}
return QString();
}
+QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
+{
+ Q_Q(const QQuickText);
+ QPointF translatedMousePos = mousePos;
+ translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect, q->height(), vAlign);
+ if (styledText) {
+ QString link = anchorAt(&layout, translatedMousePos);
+ if (link.isEmpty() && elideLayout)
+ link = anchorAt(elideLayout, translatedMousePos);
+ return link;
+ } else if (richText && extra.isAllocated() && extra->doc) {
+ translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect, q->width(), hAlign);
+ return extra->doc->documentLayout()->anchorAt(translatedMousePos);
+ }
+ return QString();
+}
+
bool QQuickTextPrivate::isLinkActivatedConnected()
{
Q_Q(QQuickText);
@@ -2431,14 +2425,8 @@ void QQuickText::mousePressEvent(QMouseEvent *event)
Q_D(QQuickText);
QString link;
- if (d->isLinkActivatedConnected()) {
- if (d->styledText)
- link = d->anchorAt(event->localPos());
- else if (d->richText) {
- d->ensureDoc();
- link = d->extra->doc->documentLayout()->anchorAt(event->localPos());
- }
- }
+ if (d->isLinkActivatedConnected())
+ link = d->anchorAt(event->localPos());
if (link.isEmpty()) {
event->setAccepted(false);
@@ -2450,9 +2438,9 @@ void QQuickText::mousePressEvent(QMouseEvent *event)
if (!event->isAccepted())
QQuickItem::mousePressEvent(event);
-
}
+
/*! \internal */
void QQuickText::mouseReleaseEvent(QMouseEvent *event)
{
@@ -2461,14 +2449,8 @@ void QQuickText::mouseReleaseEvent(QMouseEvent *event)
// ### confirm the link, and send a signal out
QString link;
- if (d->isLinkActivatedConnected()) {
- if (d->styledText)
- link = d->anchorAt(event->localPos());
- else if (d->richText) {
- d->ensureDoc();
- link = d->extra->doc->documentLayout()->anchorAt(event->localPos());
- }
- }
+ if (d->isLinkActivatedConnected())
+ link = d->anchorAt(event->localPos());
if (!link.isEmpty() && d->extra.isAllocated() && d->extra->activeLink == link)
emit linkActivated(d->extra->activeLink);
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 2afcd8f369..985b1e1c80 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -166,7 +166,8 @@ public:
QRectF setupTextLayout(qreal *const naturalWidth, qreal * const baseline);
void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
bool isLinkActivatedConnected();
- QString anchorAt(const QPointF &pos);
+ static QString anchorAt(const QTextLayout *layout, const QPointF &mousePos);
+ QString anchorAt(const QPointF &pos) const;
inline qreal lineHeight() const { return extra.isAllocated() ? extra->lineHeight : 1.0; }
inline int maximumLineCount() const { return extra.isAllocated() ? extra->maximumLineCount : INT_MAX; }
diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp
index c2c11b3daa..176301d450 100644
--- a/src/quick/items/qquicktextutil.cpp
+++ b/src/quick/items/qquicktextutil.cpp
@@ -78,4 +78,37 @@ QQuickItem *QQuickTextUtil::createCursor(
return item;
}
+qreal QQuickTextUtil::alignedX(const QRectF &rect, qreal width, int alignment)
+{
+ qreal x = 0;
+ switch (alignment) {
+ case Qt::AlignLeft:
+ case Qt::AlignJustify:
+ break;
+ case Qt::AlignRight:
+ x = width - rect.width();
+ break;
+ case Qt::AlignHCenter:
+ x = (width - rect.width()) / 2;
+ break;
+ }
+ return x;
+}
+
+qreal QQuickTextUtil::alignedY(const QRectF &rect, const qreal height, int alignment)
+{
+ qreal y = 0;
+ switch (alignment) {
+ case Qt::AlignTop:
+ break;
+ case Qt::AlignBottom:
+ y = height - rect.height();
+ break;
+ case Qt::AlignVCenter:
+ y = (height - rect.height()) / 2;
+ break;
+ }
+ return y;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextutil_p.h b/src/quick/items/qquicktextutil_p.h
index 91ef40b221..d6c05aac3b 100644
--- a/src/quick/items/qquicktextutil_p.h
+++ b/src/quick/items/qquicktextutil_p.h
@@ -66,12 +66,16 @@ public:
template <typename Private> static void setCursorDelegate(Private *d, QQmlComponent *delegate);
template <typename Private> static void createCursor(Private *d);
+ static qreal alignedX(const QRectF &rect, qreal width, int alignment);
+ static qreal alignedY(const QRectF &rect, qreal height, int alignment);
+
private:
static QQuickItem *createCursor(
QQmlComponent *component,
QQuickItem *parent,
const QRectF &cursorRectangle,
const char *className);
+
};
template <typename Private>
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 7d24de6ccd..2bdf4a91b4 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -105,6 +105,7 @@ private slots:
void letterSpacing();
void wordSpacing();
+ void clickLink_data();
void clickLink();
void implicitSize_data();
@@ -1438,6 +1439,8 @@ public:
mousePressEvent(event);
else if (event->type() == QEvent::MouseButtonRelease)
mouseReleaseEvent(event);
+ else if (event->type() == QEvent::MouseMove)
+ mouseMoveEvent(event);
else
qWarning() << "Trying to send unsupported event type";
}
@@ -1455,36 +1458,339 @@ public slots:
void linkClicked(QString l) { link = l; }
};
-void tst_qquicktext::clickLink()
+class TextMetrics
{
+public:
+ TextMetrics(const QString &text, Qt::TextElideMode elideMode = Qt::ElideNone)
{
- QString componentStr = "import QtQuick 2.0\nText { text: \"<a href=\\\"http://qt.nokia.com\\\">Hello world!</a>\" }";
- QQmlComponent textComponent(&engine);
- textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
- QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
-
- QVERIFY(textObject != 0);
+ QString adjustedText = text;
+ adjustedText.replace(QLatin1Char('\n'), QChar(QChar::LineSeparator));
+ if (elideMode == Qt::ElideLeft)
+ adjustedText = QChar(0x2026) + adjustedText;
+ else if (elideMode == Qt::ElideRight)
+ adjustedText = adjustedText + QChar(0x2026);
+
+ layout.setText(adjustedText);
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
- LinkTest test;
- QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
+ layout.beginLayout();
+ qreal height = 0;
+ QTextLine line = layout.createLine();
+ while (line.isValid()) {
+ line.setLineWidth(FLT_MAX);
+ line.setPosition(QPointF(0, height));
+ height += line.height();
+ line = layout.createLine();
+ }
+ layout.endLayout();
+ }
- {
- QMouseEvent me(QEvent::MouseButtonPress,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
- static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+ qreal width() const { return layout.maximumWidth(); }
+ QRectF characterRectangle(
+ int position,
+ int hAlign = Qt::AlignLeft,
+ int vAlign = Qt::AlignTop,
+ const QSizeF &bounds = QSizeF(240, 320)) const
+ {
+ qreal dy = 0;
+ switch (vAlign) {
+ case Qt::AlignBottom:
+ dy = bounds.height() - layout.boundingRect().height();
+ break;
+ case Qt::AlignVCenter:
+ dy = (bounds.height() - layout.boundingRect().height()) / 2;
+ break;
+ default:
+ break;
}
- {
- QMouseEvent me(QEvent::MouseButtonRelease,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
- static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+ for (int i = 0; i < layout.lineCount(); ++i) {
+ QTextLine line = layout.lineAt(i);
+ if (position >= line.textStart() + line.textLength())
+ continue;
+ qreal dx = 0;
+ switch (hAlign) {
+ case Qt::AlignRight:
+ dx = bounds.width() - line.naturalTextWidth();
+ break;
+ case Qt::AlignHCenter:
+ dx = (bounds.width() - line.naturalTextWidth()) / 2;
+ break;
+ default:
+ break;
+ }
+ QRectF rect;
+ rect.setLeft(dx + line.cursorToX(position, QTextLine::Leading));
+ rect.setRight(dx + line.cursorToX(position, QTextLine::Trailing));
+ rect.setTop(dy + line.y());
+ rect.setBottom(dy + line.y() + line.height());
+
+ return rect;
}
+ return QRectF();
+ }
+ QTextLayout layout;
+};
- QCOMPARE(test.link, QLatin1String("http://qt.nokia.com"));
- delete textObject;
+typedef QVector<QPointF> PointVector;
+Q_DECLARE_METATYPE(PointVector);
+
+void tst_qquicktext::clickLink_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<qreal>("width");
+ QTest::addColumn<QString>("bindings");
+ QTest::addColumn<PointVector>("mousePositions");
+ QTest::addColumn<QString>("link");
+
+ const QString singleLineText = "this text has a <a href=\\\"http://qt-project.org/single\\\">link</a> in it";
+ const QString singleLineLink = "http://qt-project.org/single";
+ const QString multipleLineText = "this text<br/>has <a href=\\\"http://qt-project.org/multiple\\\">multiple<br/>lines</a> in it";
+ const QString multipleLineLink = "http://qt-project.org/multiple";
+ const QString nestedText = "this text has a <a href=\\\"http://qt-project.org/outer\\\">nested <a href=\\\"http://qt-project.org/inner\\\">link</a> in it</a>";
+ const QString outerLink = "http://qt-project.org/outer";
+ const QString innerLink = "http://qt-project.org/inner";
+
+ {
+ const TextMetrics metrics("this text has a link in it");
+
+ QTest::newRow("click on link")
+ << singleLineText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(18).center())
+ << singleLineLink;
+ QTest::newRow("click on text")
+ << singleLineText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(13).center())
+ << QString();
+ QTest::newRow("drag within link")
+ << singleLineText << 240.
+ << ""
+ << (PointVector()
+ << metrics.characterRectangle(17).center()
+ << metrics.characterRectangle(19).center())
+ << singleLineLink;
+ QTest::newRow("drag away from link")
+ << singleLineText << 240.
+ << ""
+ << (PointVector()
+ << metrics.characterRectangle(18).center()
+ << metrics.characterRectangle(13).center())
+ << QString();
+ QTest::newRow("drag on to link")
+ << singleLineText << 240.
+ << ""
+ << (PointVector()
+ << metrics.characterRectangle(13).center()
+ << metrics.characterRectangle(18).center())
+ << QString();
+ QTest::newRow("click on bottom right aligned link")
+ << singleLineText << 240.
+ << "horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignBottom"
+ << (PointVector() << metrics.characterRectangle(18, Qt::AlignRight, Qt::AlignBottom).center())
+ << singleLineLink;
+ QTest::newRow("click on center aligned link")
+ << singleLineText << 240.
+ << "horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter"
+ << (PointVector() << metrics.characterRectangle(18, Qt::AlignHCenter, Qt::AlignVCenter).center())
+ << singleLineLink;
+ QTest::newRow("click on rich text link")
+ << singleLineText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(18).center())
+ << singleLineLink;
+ QTest::newRow("click on rich text")
+ << singleLineText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(13).center())
+ << QString();
+ QTest::newRow("click on bottom right aligned rich text link")
+ << singleLineText << 240.
+ << "textFormat: Text.RichText; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignBottom"
+ << (PointVector() << metrics.characterRectangle(18, Qt::AlignRight, Qt::AlignBottom).center())
+ << singleLineLink;
+ QTest::newRow("click on center aligned rich text link")
+ << singleLineText << 240.
+ << "textFormat: Text.RichText; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter"
+ << (PointVector() << metrics.characterRectangle(18, Qt::AlignHCenter, Qt::AlignVCenter).center())
+ << singleLineLink;
+ } {
+ const TextMetrics metrics("this text has a li", Qt::ElideRight);
+ QTest::newRow("click on right elided link")
+ << singleLineText << metrics.width() + 2
+ << "elide: Text.ElideRight"
+ << (PointVector() << metrics.characterRectangle(17).center())
+ << singleLineLink;
+ } {
+ const TextMetrics metrics("ink in it", Qt::ElideLeft);
+ QTest::newRow("click on left elided link")
+ << singleLineText << metrics.width() + 2
+ << "elide: Text.ElideLeft"
+ << (PointVector() << metrics.characterRectangle(2).center())
+ << singleLineLink;
+ } {
+ const TextMetrics metrics("this text\nhas multiple\nlines in it");
+ QTest::newRow("click on second line")
+ << multipleLineText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(18).center())
+ << multipleLineLink;
+ QTest::newRow("click on third line")
+ << multipleLineText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(25).center())
+ << multipleLineLink;
+ QTest::newRow("drag from second line to third")
+ << multipleLineText << 240.
+ << ""
+ << (PointVector()
+ << metrics.characterRectangle(18).center()
+ << metrics.characterRectangle(25).center())
+ << multipleLineLink;
+ QTest::newRow("click on rich text second line")
+ << multipleLineText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(18).center())
+ << multipleLineLink;
+ QTest::newRow("click on rich text third line")
+ << multipleLineText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(25).center())
+ << multipleLineLink;
+ QTest::newRow("drag rich text from second line to third")
+ << multipleLineText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector()
+ << metrics.characterRectangle(18).center()
+ << metrics.characterRectangle(25).center())
+ << multipleLineLink;
+ } {
+ const TextMetrics metrics("this text has a nested link in it");
+ QTest::newRow("click on left outer link")
+ << nestedText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(22).center())
+ << outerLink;
+ QTest::newRow("click on right outer link")
+ << nestedText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(27).center())
+ << outerLink;
+ QTest::newRow("click on inner link left")
+ << nestedText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(23).center())
+ << innerLink;
+ QTest::newRow("click on inner link right")
+ << nestedText << 240.
+ << ""
+ << (PointVector() << metrics.characterRectangle(26).center())
+ << innerLink;
+ QTest::newRow("drag from inner to outer link")
+ << nestedText << 240.
+ << ""
+ << (PointVector()
+ << metrics.characterRectangle(25).center()
+ << metrics.characterRectangle(30).center())
+ << QString();
+ QTest::newRow("drag from outer to inner link")
+ << nestedText << 240.
+ << ""
+ << (PointVector()
+ << metrics.characterRectangle(30).center()
+ << metrics.characterRectangle(25).center())
+ << QString();
+ QTest::newRow("click on left outer rich text link")
+ << nestedText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(22).center())
+ << outerLink;
+ QTest::newRow("click on right outer rich text link")
+ << nestedText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(27).center())
+ << outerLink;
+ QTest::newRow("click on inner rich text link left")
+ << nestedText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(23).center())
+ << innerLink;
+ QTest::newRow("click on inner rich text link right")
+ << nestedText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector() << metrics.characterRectangle(26).center())
+ << innerLink;
+ QTest::newRow("drag from inner to outer rich text link")
+ << nestedText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector()
+ << metrics.characterRectangle(25).center()
+ << metrics.characterRectangle(30).center())
+ << QString();
+ QTest::newRow("drag from outer to inner rich text link")
+ << nestedText << 240.
+ << "textFormat: Text.RichText"
+ << (PointVector()
+ << metrics.characterRectangle(30).center()
+ << metrics.characterRectangle(25).center())
+ << QString();
+ }
+}
+
+void tst_qquicktext::clickLink()
+{
+ QFETCH(QString, text);
+ QFETCH(qreal, width);
+ QFETCH(QString, bindings);
+ QFETCH(PointVector, mousePositions);
+ QFETCH(QString, link);
+
+ QString componentStr =
+ "import QtQuick 2.0\nText {\n"
+ "width: " + QString::number(width) + "\n"
+ "height: 320\n"
+ "text: \"" + text + "\"\n"
+ "" + bindings + "\n"
+ "}";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+
+ LinkTest test;
+ QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
+
+ QVERIFY(mousePositions.count() > 0);
+
+ QPointF mousePosition = mousePositions.first();
+ {
+ QMouseEvent me(QEvent::MouseButtonPress, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
}
+
+ for (int i = 1; i < mousePositions.count(); ++i) {
+ mousePosition = mousePositions.at(i);
+
+ QMouseEvent me(QEvent::MouseMove, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+ }
+
+ {
+ QMouseEvent me(QEvent::MouseButtonRelease, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+ }
+
+ QCOMPARE(test.link, link);
+
+ delete textObject;
}
void tst_qquicktext::baseUrl()