summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-02-09 16:14:40 +1000
committerQt by Nokia <qt-info@nokia.com>2012-02-09 09:10:31 +0100
commit8550ed69156f0472450fd11aabcaa5d4dcc676db (patch)
tree91b1d6848e1ce5199db4040decb4a3cd79352788
parenta4b4932efb631a3c467c9bb4b3e4f99ca70a066d (diff)
Add linkColor property to Text.
Allows the color of links in text to be changed from the default blue. This currently only works with StyledText and the distance field rendererer. It could be made to work with RichText overwriting the specified foreground color in all instances or by not setting a default color in the html parser. The former would prevent the color being set with CSS or some future means for altering text formats. The latter would break rendering with QPainter. Task-number: QTBUG-23048 Change-Id: I98df215cabe8a089f648fd4a6206622b4318fb8f Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--examples/declarative/twitter/TwitterCore/FatDelegate.qml6
-rw-r--r--src/quick/items/qquicktext.cpp37
-rw-r--r--src/quick/items/qquicktext_p.h5
-rw-r--r--src/quick/items/qquicktext_p_p.h1
-rw-r--r--src/quick/items/qquicktextinput.cpp2
-rw-r--r--src/quick/items/qquicktextnode.cpp35
-rw-r--r--src/quick/items/qquicktextnode_p.h2
-rw-r--r--src/quick/util/qdeclarativestyledtext.cpp1
-rw-r--r--tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp87
9 files changed, 157 insertions, 19 deletions
diff --git a/examples/declarative/twitter/TwitterCore/FatDelegate.qml b/examples/declarative/twitter/TwitterCore/FatDelegate.qml
index d23079a26e..5fd0d1622b 100644
--- a/examples/declarative/twitter/TwitterCore/FatDelegate.qml
+++ b/examples/declarative/twitter/TwitterCore/FatDelegate.qml
@@ -92,11 +92,11 @@ Component {
}
Text { id:txt; y:4; x: 56
- text: '<html><style type="text/css">a:link {color:"#aaccaa"}; a:visited {color:"#336633"}</style>'
+ text: '<html>'
+ '<a href="app://@'+userName(name)+'"><b>'+userName(name) + "</b></a> from " +source
+ "<br /><b>" + statusText + "</b></html>";
- textFormat: Qt.RichText
- color: "#cccccc"; style: Text.Raised; styleColor: "black"; wrapMode: Text.WordWrap
+ textFormat: Text.StyledText
+ color: "#cccccc"; style: Text.Raised; styleColor: "black"; wrapMode: Text.WordWrap; linkColor: "#aaccaa"
anchors.left: image.right; anchors.right: blackRect.right; anchors.leftMargin: 6; anchors.rightMargin: 6
onLinkActivated: wrapper.handleLink(link)
}
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 14016777c1..c671320fb9 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
const QChar QQuickTextPrivate::elideChar = QChar(0x2026);
QQuickTextPrivate::QQuickTextPrivate()
-: color((QRgb)0), style(QQuickText::Normal), hAlign(QQuickText::AlignLeft),
+: color((QRgb)0), linkColor((QRgb)255), style(QQuickText::Normal), hAlign(QQuickText::AlignLeft),
vAlign(QQuickText::AlignTop), elideMode(QQuickText::ElideNone),
format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap), lineHeight(1),
lineHeightMode(QQuickText::ProportionalHeight), lineCount(1), maximumLineCount(INT_MAX),
@@ -1279,6 +1279,34 @@ void QQuickText::setColor(const QColor &color)
}
emit colorChanged(d->color);
}
+
+/*!
+ \qmlproperty color QtQuick2::Text::linkColor
+
+ The color of links in the text.
+
+ This property works with the StyledText \l textFormat, but not with RichText.
+ Link color in RichText can be specified by including CSS style tags in the
+ text.
+*/
+
+QColor QQuickText::linkColor() const
+{
+ Q_D(const QQuickText);
+ return d->linkColor;
+}
+
+void QQuickText::setLinkColor(const QColor &color)
+{
+ Q_D(QQuickText);
+ if (d->linkColor == color)
+ return;
+
+ d->linkColor = color;
+ update();
+ emit linkColorChanged();
+}
+
/*!
\qmlproperty enumeration QtQuick2::Text::style
@@ -1894,12 +1922,11 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
if (d->richText) {
d->ensureDoc();
- node->addTextDocument(bounds.topLeft(), d->doc, d->color, d->style, d->styleColor);
-
+ node->addTextDocument(bounds.topLeft(), d->doc, d->color, d->style, d->styleColor, d->linkColor);
} else if (d->elideMode == QQuickText::ElideNone || bounds.width() > 0.) {
- node->addTextLayout(QPoint(0, bounds.y()), &d->layout, d->color, d->style, d->styleColor);
+ node->addTextLayout(QPoint(0, bounds.y()), &d->layout, d->color, d->style, d->styleColor, d->linkColor);
if (d->elideLayout)
- node->addTextLayout(QPoint(0, bounds.y()), d->elideLayout, d->color, d->style, d->styleColor);
+ node->addTextLayout(QPoint(0, bounds.y()), d->elideLayout, d->color, d->style, d->styleColor, d->linkColor);
}
foreach (QDeclarativeStyledTextImgTag *img, d->visibleImgTags) {
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index ff1f45e605..8f173f97cb 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -68,6 +68,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+ Q_PROPERTY(QColor linkColor READ linkColor WRITE setLinkColor NOTIFY linkColorChanged)
Q_PROPERTY(TextStyle style READ style WRITE setStyle NOTIFY styleChanged)
Q_PROPERTY(QColor styleColor READ styleColor WRITE setStyleColor NOTIFY styleColorChanged)
Q_PROPERTY(HAlignment horizontalAlignment READ hAlign WRITE setHAlign RESET resetHAlign NOTIFY horizontalAlignmentChanged)
@@ -136,6 +137,9 @@ public:
QColor color() const;
void setColor(const QColor &c);
+ QColor linkColor() const;
+ void setLinkColor(const QColor &color);
+
TextStyle style() const;
void setStyle(TextStyle style);
@@ -201,6 +205,7 @@ Q_SIGNALS:
void linkActivated(const QString &link);
void fontChanged(const QFont &font);
void colorChanged(const QColor &color);
+ void linkColorChanged();
void styleChanged(TextStyle style);
void styleColorChanged(const QColor &color);
void horizontalAlignmentChanged(HAlignment alignment);
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 6c9f22dffa..6fdde31a36 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -89,6 +89,7 @@ public:
QFont font;
QFont sourceFont;
QColor color;
+ QColor linkColor;
QQuickText::TextStyle style;
QColor styleColor;
QString activeLink;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index f8882286ef..d4f73f7514 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1752,7 +1752,7 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
if (!d->m_textLayout.text().isEmpty() || !d->m_textLayout.preeditAreaText().isEmpty()) {
node->addTextLayout(offset, &d->m_textLayout, d->color,
- QQuickText::Normal, QColor(),
+ QQuickText::Normal, QColor(), QColor(),
d->selectionColor, d->selectedTextColor,
d->selectionStart(),
d->selectionEnd() - 1); // selectionEnd() returns first char after
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index 82a3ada6c0..a3daead6cb 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -237,6 +237,7 @@ namespace {
static void insert(QVarLengthArray<BinaryTreeNode> *binaryTree,
const QGlyphRun &glyphRun,
SelectionState selectionState,
+ QQuickTextNode::Decorations decorations,
const QColor &textColor,
const QColor &backgroundColor,
const QPointF &position)
@@ -247,7 +248,6 @@ namespace {
if (qFuzzyIsNull(searchRect.width()) || qFuzzyIsNull(searchRect.height()))
return;
- QQuickTextNode::Decorations decorations = QQuickTextNode::NoDecoration;
decorations |= (glyphRun.underline() ? QQuickTextNode::Underline : QQuickTextNode::NoDecoration);
decorations |= (glyphRun.overline() ? QQuickTextNode::Overline : QQuickTextNode::NoDecoration);
decorations |= (glyphRun.strikeOut() ? QQuickTextNode::StrikeOut : QQuickTextNode::NoDecoration);
@@ -369,6 +369,11 @@ namespace {
m_textColor = textColor;
}
+ void setAnchorColor(const QColor &anchorColor)
+ {
+ m_anchorColor = anchorColor;
+ }
+
void setPosition(const QPointF &position)
{
m_position = position;
@@ -400,6 +405,7 @@ namespace {
QColor m_textColor;
QColor m_backgroundColor;
QColor m_selectedTextColor;
+ QColor m_anchorColor;
QPointF m_position;
QTextLine m_currentLine;
@@ -745,14 +751,14 @@ namespace {
void SelectionEngine::addUnselectedGlyphs(const QGlyphRun &glyphRun)
{
BinaryTreeNode::insert(&m_currentLineTree, glyphRun, BinaryTreeNode::Unselected,
- m_textColor, m_backgroundColor, m_position);
+ QQuickTextNode::NoDecoration, m_textColor, m_backgroundColor, m_position);
}
void SelectionEngine::addSelectedGlyphs(const QGlyphRun &glyphRun)
{
int currentSize = m_currentLineTree.size();
BinaryTreeNode::insert(&m_currentLineTree, glyphRun, BinaryTreeNode::Selected,
- m_textColor, m_backgroundColor, m_position);
+ QQuickTextNode::NoDecoration, m_textColor, m_backgroundColor, m_position);
m_hasSelection = m_hasSelection || m_currentLineTree.size() > currentSize;
}
@@ -771,11 +777,12 @@ namespace {
addGlyphsInRange(currentPosition, range.start - currentPosition,
QColor(), QColor(), selectionStart, selectionEnd);
}
-
int rangeEnd = qMin(range.start + range.length, currentPosition + remainingLength);
- QColor rangeColor = range.format.hasProperty(QTextFormat::ForegroundBrush)
- ? range.format.foreground().color()
- : QColor();
+ QColor rangeColor;
+ if (range.format.hasProperty(QTextFormat::ForegroundBrush))
+ rangeColor = range.format.foreground().color();
+ else if (range.format.isAnchor())
+ rangeColor = m_anchorColor;
QColor rangeBackgroundColor = range.format.hasProperty(QTextFormat::BackgroundBrush)
? range.format.background().color()
: QColor();
@@ -1038,7 +1045,8 @@ void QQuickTextNode::mergeFormats(QTextLayout *textLayout,
for (int i=0; i<additionalFormats.size(); ++i) {
QTextLayout::FormatRange additionalFormat = additionalFormats.at(i);
if (additionalFormat.format.hasProperty(QTextFormat::ForegroundBrush)
- || additionalFormat.format.hasProperty(QTextFormat::BackgroundBrush)) {
+ || additionalFormat.format.hasProperty(QTextFormat::BackgroundBrush)
+ || additionalFormat.format.isAnchor()) {
// Merge overlapping formats
if (!mergedFormats->isEmpty()) {
QTextLayout::FormatRange *lastFormat = mergedFormats->data() + mergedFormats->size() - 1;
@@ -1107,6 +1115,7 @@ void QQuickTextNode::addImage(const QRectF &rect, const QImage &image)
void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *textDocument,
const QColor &textColor,
QQuickText::TextStyle style, const QColor &styleColor,
+ const QColor &anchorColor,
const QColor &selectionColor, const QColor &selectedTextColor,
int selectionStart, int selectionEnd)
{
@@ -1114,6 +1123,7 @@ void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *tex
engine.setTextColor(textColor);
engine.setSelectedTextColor(selectedTextColor);
engine.setSelectionColor(selectionColor);
+ engine.setAnchorColor(anchorColor);
QList<QTextFrame *> frames;
frames.append(textDocument->rootFrame());
@@ -1244,6 +1254,13 @@ void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *tex
}
textPos += text.length();
} else {
+ if (charFormat.foreground().style() != Qt::NoBrush)
+ engine.setTextColor(charFormat.foreground().color());
+ else if (charFormat.isAnchor())
+ engine.setTextColor(anchorColor);
+ else
+ engine.setTextColor(textColor);
+
int fragmentEnd = textPos + fragment.length();
if (preeditPosition >= 0
&& preeditPosition >= textPos
@@ -1269,6 +1286,7 @@ void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *tex
void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color,
QQuickText::TextStyle style, const QColor &styleColor,
+ const QColor &anchorColor,
const QColor &selectionColor, const QColor &selectedTextColor,
int selectionStart, int selectionEnd)
{
@@ -1276,6 +1294,7 @@ void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLay
engine.setTextColor(color);
engine.setSelectedTextColor(selectedTextColor);
engine.setSelectionColor(selectionColor);
+ engine.setAnchorColor(anchorColor);
engine.setPosition(position);
int preeditLength = textLayout->preeditAreaText().length();
diff --git a/src/quick/items/qquicktextnode_p.h b/src/quick/items/qquicktextnode_p.h
index 47ed363ada..9c2217bfd0 100644
--- a/src/quick/items/qquicktextnode_p.h
+++ b/src/quick/items/qquicktextnode_p.h
@@ -82,10 +82,12 @@ public:
void deleteContent();
void addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color = QColor(),
QQuickText::TextStyle style = QQuickText::Normal, const QColor &styleColor = QColor(),
+ const QColor &anchorColor = QColor(),
const QColor &selectionColor = QColor(), const QColor &selectedTextColor = QColor(),
int selectionStart = -1, int selectionEnd = -1);
void addTextDocument(const QPointF &position, QTextDocument *textDocument, const QColor &color = QColor(),
QQuickText::TextStyle style = QQuickText::Normal, const QColor &styleColor = QColor(),
+ const QColor &anchorColor = QColor(),
const QColor &selectionColor = QColor(), const QColor &selectedTextColor = QColor(),
int selectionStart = -1, int selectionEnd = -1);
diff --git a/src/quick/util/qdeclarativestyledtext.cpp b/src/quick/util/qdeclarativestyledtext.cpp
index 3023fc53dc..8c26194968 100644
--- a/src/quick/util/qdeclarativestyledtext.cpp
+++ b/src/quick/util/qdeclarativestyledtext.cpp
@@ -625,7 +625,6 @@ bool QDeclarativeStyledTextPrivate::parseAnchorAttributes(const QChar *&ch, cons
format.setAnchorHref(attr.second.toString());
format.setAnchor(true);
format.setFontUnderline(true);
- format.setForeground(QColor("blue"));
valid = true;
}
} while (!ch->isNull() && !attr.first.isEmpty());
diff --git a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
index 8e3a1f4864..5a0086393c 100644
--- a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
@@ -904,6 +904,7 @@ void tst_qquicktext::color()
QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
QCOMPARE(textObject->styleColor(), QColor());
+ QCOMPARE(textObject->linkColor(), QColor("blue"));
delete textObject;
}
@@ -918,6 +919,22 @@ void tst_qquicktext::color()
QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i)));
// default color to black?
QCOMPARE(textObject->color(), QColor("black"));
+ QCOMPARE(textObject->linkColor(), QColor("blue"));
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < colorStrings.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { linkColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+ QDeclarativeComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->styleColor(), QColor());
+ // default color to black?
+ QCOMPARE(textObject->color(), QColor("black"));
+ QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(i)));
delete textObject;
}
@@ -926,13 +943,18 @@ void tst_qquicktext::color()
{
for (int j = 0; j < colorStrings.size(); j++)
{
- QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; styleColor: \"" + colorStrings.at(j) + "\"; text: \"Hello World\" }";
+ QString componentStr = "import QtQuick 2.0\nText { "
+ "color: \"" + colorStrings.at(i) + "\"; "
+ "styleColor: \"" + colorStrings.at(j) + "\"; "
+ "linkColor: \"" + colorStrings.at(j) + "\"; "
+ "text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j)));
+ QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(j)));
delete textObject;
}
@@ -950,6 +972,69 @@ void tst_qquicktext::color()
QCOMPARE(textObject->color(), testColor);
delete textObject;
+ } {
+ QString colorStr = "#001234";
+ QColor testColor(colorStr);
+
+ QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QDeclarativeComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
+
+ QSignalSpy spy(textObject, SIGNAL(colorChanged(QColor)));
+
+ QCOMPARE(textObject->color(), testColor);
+ textObject->setColor(testColor);
+ QCOMPARE(textObject->color(), testColor);
+ QCOMPARE(spy.count(), 0);
+
+ testColor = QColor("black");
+ textObject->setColor(testColor);
+ QCOMPARE(textObject->color(), testColor);
+ QCOMPARE(spy.count(), 1);
+ } {
+ QString colorStr = "#001234";
+ QColor testColor(colorStr);
+
+ QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QDeclarativeComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
+
+ QSignalSpy spy(textObject, SIGNAL(styleColorChanged(QColor)));
+
+ QCOMPARE(textObject->styleColor(), testColor);
+ textObject->setStyleColor(testColor);
+ QCOMPARE(textObject->styleColor(), testColor);
+ QCOMPARE(spy.count(), 0);
+
+ testColor = QColor("black");
+ textObject->setStyleColor(testColor);
+ QCOMPARE(textObject->styleColor(), testColor);
+ QCOMPARE(spy.count(), 1);
+ } {
+ QString colorStr = "#001234";
+ QColor testColor(colorStr);
+
+ QString componentStr = "import QtQuick 2.0\nText { linkColor: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QDeclarativeComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
+
+ QSignalSpy spy(textObject, SIGNAL(linkColorChanged()));
+
+ QCOMPARE(textObject->linkColor(), testColor);
+ textObject->setLinkColor(testColor);
+ QCOMPARE(textObject->linkColor(), testColor);
+ QCOMPARE(spy.count(), 0);
+
+ testColor = QColor("black");
+ textObject->setLinkColor(testColor);
+ QCOMPARE(textObject->linkColor(), testColor);
+ QCOMPARE(spy.count(), 1);
}
}