1
/****************************************************************************
3
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
7
** This file is part of the QtDeclarative module of the Qt Toolkit.
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
40
****************************************************************************/
42
#include "private/qdeclarativetext_p.h"
43
#include "private/qdeclarativetext_p_p.h"
44
#include <private/qtextdocumentlayout_p.h>
45
#include <qdeclarativestyledtext_p.h>
46
#include <qdeclarativeinfo.h>
47
#include <qdeclarativepixmapcache_p.h>
50
#include <QTextLayout>
52
#include <QTextDocument>
53
#include <QGraphicsSceneMouseEvent>
55
#include <QAbstractTextDocumentLayout>
61
extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
63
class QTextDocumentWithImageResources : public QTextDocument {
67
QTextDocumentWithImageResources(QDeclarativeText *parent);
68
virtual ~QTextDocumentWithImageResources();
70
void setText(const QString &);
71
int resourcesLoading() const { return outstanding; }
74
QVariant loadResource(int type, const QUrl &name);
77
void requestFinished();
80
QHash<QUrl, QDeclarativePixmap *> m_resources;
83
static QSet<QUrl> errors;
86
class QDeclarativeTextDocumentLayout : public QTextDocumentLayout
90
QDeclarativeTextDocumentLayout(QTextDocument *doc);
91
void setLineHeight(qreal lineHeight, QDeclarativeText::LineHeightMode mode);
94
DEFINE_BOOL_CONFIG_OPTION(enableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE);
96
QString QDeclarativeTextPrivate::elideChar = QString(0x2026);
98
QDeclarativeTextPrivate::QDeclarativeTextPrivate()
99
: color((QRgb)0), style(QDeclarativeText::Normal), hAlign(QDeclarativeText::AlignLeft),
100
vAlign(QDeclarativeText::AlignTop), elideMode(QDeclarativeText::ElideNone),
101
format(QDeclarativeText::AutoText), wrapMode(QDeclarativeText::NoWrap), lineHeight(1),
102
lineHeightMode(QDeclarativeText::ProportionalHeight), lineCount(1), truncated(false), maximumLineCount(INT_MAX),
103
maximumLineCountValid(false), imageCacheDirty(true), updateOnComponentComplete(true), richText(false), singleline(false),
104
cacheAllTextAsImage(true), internalWidthUpdate(false), requireImplicitWidth(false), hAlignImplicit(true),
105
rightToLeftText(false), layoutTextElided(false), naturalWidth(0), doc(0)
107
cacheAllTextAsImage = enableImageCache();
108
QGraphicsItemPrivate::acceptedMouseButtons = Qt::LeftButton;
109
QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
112
QTextDocumentWithImageResources::QTextDocumentWithImageResources(QDeclarativeText *parent)
113
: QTextDocument(parent), outstanding(0)
117
QTextDocumentWithImageResources::~QTextDocumentWithImageResources()
119
if (!m_resources.isEmpty())
120
qDeleteAll(m_resources);
123
QVariant QTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
125
QDeclarativeContext *context = qmlContext(parent());
126
QUrl url = context->resolvedUrl(name);
128
if (type == QTextDocument::ImageResource) {
129
QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
131
if (iter == m_resources.end()) {
132
QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
133
iter = m_resources.insert(name, p);
135
if (p->isLoading()) {
136
p->connectFinished(this, SLOT(requestFinished()));
141
QDeclarativePixmap *p = *iter;
144
} else if (p->isError()) {
145
if (!errors.contains(url)) {
147
qmlInfo(parent()) << p->error();
152
return QTextDocument::loadResource(type,url); // The *resolved* URL
155
void QTextDocumentWithImageResources::requestFinished()
158
if (outstanding == 0) {
159
QDeclarativeText *textItem = static_cast<QDeclarativeText*>(parent());
160
QString text = textItem->text();
161
#ifndef QT_NO_TEXTHTMLPARSER
166
QDeclarativeTextPrivate *d = QDeclarativeTextPrivate::get(textItem);
171
void QTextDocumentWithImageResources::setText(const QString &text)
173
if (!m_resources.isEmpty()) {
174
qDeleteAll(m_resources);
179
#ifndef QT_NO_TEXTHTMLPARSER
186
QSet<QUrl> QTextDocumentWithImageResources::errors;
188
QDeclarativeTextDocumentLayout::QDeclarativeTextDocumentLayout(QTextDocument *doc)
189
: QTextDocumentLayout(doc) {
192
void QDeclarativeTextDocumentLayout::setLineHeight(qreal lineHeight, QDeclarativeText::LineHeightMode mode = QDeclarativeText::ProportionalHeight)
194
QTextDocumentLayout::setLineHeight(lineHeight, QTextDocumentLayout::LineHeightMode(mode));
197
QDeclarativeTextPrivate::~QDeclarativeTextPrivate()
201
qreal QDeclarativeTextPrivate::implicitWidth() const
203
if (!requireImplicitWidth) {
204
// We don't calculate implicitWidth unless it is required.
205
// We need to force a size update now to ensure implicitWidth is calculated
206
QDeclarativeTextPrivate *me = const_cast<QDeclarativeTextPrivate*>(this);
207
me->requireImplicitWidth = true;
210
return mImplicitWidth;
213
void QDeclarativeTextPrivate::updateLayout()
215
Q_Q(QDeclarativeText);
216
if (!q->isComponentComplete()) {
217
updateOnComponentComplete = true;
221
layoutTextElided = false;
222
// Setup instance of QTextLayout for all cases other than richtext
224
layout.clearLayout();
225
layout.setFont(font);
226
if (format != QDeclarativeText::StyledText) {
228
tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
229
singleline = !tmp.contains(QChar::LineSeparator);
230
if (singleline && !maximumLineCountValid && elideMode != QDeclarativeText::ElideNone && q->widthValid()) {
231
QFontMetrics fm(font);
232
tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width());
234
layoutTextElided = true;
237
emit q->truncatedChanged();
244
QDeclarativeStyledText::parse(text, layout);
248
QDeclarativeTextDocumentLayout *layout = new QDeclarativeTextDocumentLayout(doc);
249
layout->setLineHeight(lineHeight, lineHeightMode);
250
doc->setDocumentLayout(layout);
256
void QDeclarativeTextPrivate::updateSize()
258
Q_Q(QDeclarativeText);
260
if (!q->isComponentComplete()) {
261
updateOnComponentComplete = true;
265
if (!requireImplicitWidth) {
266
emit q->implicitWidthChanged();
267
// if the implicitWidth is used, then updateSize() has already been called (recursively)
268
if (requireImplicitWidth)
272
invalidateImageCache();
274
QFontMetrics fm(font);
275
if (text.isEmpty()) {
276
q->setImplicitWidth(0);
277
q->setImplicitHeight(fm.height());
278
paintedSize = QSize(0, fm.height());
279
emit q->paintedSizeChanged();
284
int dy = q->height();
287
//setup instance of QTextLayout for all cases other than richtext
289
QRect textRect = setupTextLayout();
290
if (layedOutTextRect.size() != textRect.size())
291
q->prepareGeometryChange();
292
layedOutTextRect = textRect;
293
size = textRect.size();
296
singleline = false; // richtext can't elide or be optimized for single-line case
298
doc->setDefaultFont(font);
300
QDeclarativeText::HAlignment horizontalAlignment = q->effectiveHAlign();
301
if (rightToLeftText) {
302
if (horizontalAlignment == QDeclarativeText::AlignLeft)
303
horizontalAlignment = QDeclarativeText::AlignRight;
304
else if (horizontalAlignment == QDeclarativeText::AlignRight)
305
horizontalAlignment = QDeclarativeText::AlignLeft;
308
option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign));
309
option.setWrapMode(QTextOption::WrapMode(wrapMode));
310
doc->setDefaultTextOption(option);
311
if (requireImplicitWidth && q->widthValid()) {
312
doc->setTextWidth(-1);
313
naturalWidth = doc->idealWidth();
315
if (wrapMode != QDeclarativeText::NoWrap && q->widthValid())
316
doc->setTextWidth(q->width());
318
doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
319
dy -= (int)doc->size().height();
320
QSize dsize = doc->size().toSize();
321
if (dsize != layedOutTextRect.size()) {
322
q->prepareGeometryChange();
323
layedOutTextRect = QRect(QPoint(0,0), dsize);
325
size = QSize(int(doc->idealWidth()),dsize.height());
329
if (q->heightValid()) {
330
if (vAlign == QDeclarativeText::AlignBottom)
332
else if (vAlign == QDeclarativeText::AlignVCenter)
335
q->setBaselineOffset(fm.ascent() + yoff);
337
//### need to comfirm cost of always setting these for richText
338
internalWidthUpdate = true;
339
if (!q->widthValid())
340
q->setImplicitWidth(size.width());
341
else if (requireImplicitWidth)
342
q->setImplicitWidth(naturalWidth);
343
internalWidthUpdate = false;
344
q->setImplicitHeight(size.height());
345
if (paintedSize != size) {
347
emit q->paintedSizeChanged();
353
Lays out the QDeclarativeTextPrivate::layout QTextLayout in the constraints of the QDeclarativeText.
355
Returns the size of the final text. This can be used to position the text vertically (the text is
356
already absolutely positioned horizontally).
358
QRect QDeclarativeTextPrivate::setupTextLayout()
360
// ### text layout handling should be profiled and optimized as needed
361
// what about QStackTextEngine engine(tmp, d->font.font()); QTextLayout textLayout(&engine);
362
Q_Q(QDeclarativeText);
363
layout.setCacheEnabled(true);
366
int visibleCount = 0;
370
lineWidth = q->width();
372
QTextOption textOption = layout.textOption();
373
textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
374
textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
375
layout.setTextOption(textOption);
377
bool elideText = false;
378
bool truncate = false;
380
QFontMetrics fm(layout.font());
381
elidePos = QPointF();
383
if (requireImplicitWidth && q->widthValid()) {
384
// requires an extra layout
386
if (layoutTextElided) {
387
// We have provided elided text to the layout, but we must calculate unelided width.
388
elidedText = layout.text();
389
layout.setText(text);
391
layout.beginLayout();
393
QTextLine line = layout.createLine();
399
for (int i = 0; i < layout.lineCount(); ++i) {
400
QTextLine line = layout.lineAt(i);
401
br = br.united(line.naturalTextRect());
403
naturalWidth = br.width();
404
if (layoutTextElided)
405
layout.setText(elidedText);
408
if (maximumLineCountValid) {
409
layout.beginLayout();
412
int linesLeft = maximumLineCount;
413
int visibleTextLength = 0;
414
while (linesLeft > 0) {
415
QTextLine line = layout.createLine();
421
line.setLineWidth(lineWidth);
422
visibleTextLength += line.textLength();
424
if (--linesLeft == 0) {
425
if (visibleTextLength < text.length()) {
427
if (elideMode==QDeclarativeText::ElideRight && q->widthValid()) {
428
qreal elideWidth = fm.width(elideChar);
429
// Need to correct for alignment
430
line.setLineWidth(lineWidth-elideWidth);
431
if (layout.text().mid(line.textStart(), line.textLength()).isRightToLeft()) {
432
line.setPosition(QPointF(line.position().x() + elideWidth, line.position().y()));
433
elidePos.setX(line.naturalTextRect().left() - elideWidth);
435
elidePos.setX(line.naturalTextRect().right());
445
if (truncated != truncate) {
446
truncated = truncate;
447
emit q->truncatedChanged();
450
layout.beginLayout();
452
QTextLine line = layout.createLine();
457
line.setLineWidth(lineWidth);
464
for (int i = 0; i < layout.lineCount(); ++i) {
465
QTextLine line = layout.lineAt(i);
467
line.setPosition(QPointF(line.position().x(), height));
468
if (elideText && i == layout.lineCount()-1) {
469
elidePos.setY(height + fm.ascent());
470
br = br.united(QRectF(elidePos, QSizeF(fm.width(elideChar), fm.ascent())));
472
br = br.united(line.naturalTextRect());
473
height += (lineHeightMode == QDeclarativeText::FixedHeight) ? lineHeight : line.height() * lineHeight;
475
br.setHeight(height);
477
if (!q->widthValid())
478
naturalWidth = br.width();
480
//Update the number of visible lines
481
if (lineCount != visibleCount) {
482
lineCount = visibleCount;
483
emit q->lineCountChanged();
486
return QRect(qRound(br.x()), qRound(br.y()), qCeil(br.width()), qCeil(br.height()));
490
Returns a painted version of the QDeclarativeTextPrivate::layout QTextLayout.
491
If \a drawStyle is true, the style color overrides all colors in the document.
493
QPixmap QDeclarativeTextPrivate::textLayoutImage(bool drawStyle)
496
QSize size = layedOutTextRect.size();
499
if (!size.isEmpty()) {
500
img.fill(Qt::transparent);
502
bool oldSmooth = qt_applefontsmoothing_enabled;
503
qt_applefontsmoothing_enabled = false;
507
qt_applefontsmoothing_enabled = oldSmooth;
509
drawTextLayout(&p, QPointF(-layedOutTextRect.x(),0), drawStyle);
515
Paints the QDeclarativeTextPrivate::layout QTextLayout into \a painter at \a pos. If
516
\a drawStyle is true, the style color overrides all colors in the document.
518
void QDeclarativeTextPrivate::drawTextLayout(QPainter *painter, const QPointF &pos, bool drawStyle)
521
painter->setPen(styleColor);
523
painter->setPen(color);
524
painter->setFont(font);
525
layout.draw(painter, pos);
526
if (!elidePos.isNull())
527
painter->drawText(pos + elidePos, elideChar);
531
Returns a painted version of the QDeclarativeTextPrivate::doc QTextDocument.
532
If \a drawStyle is true, the style color overrides all colors in the document.
534
QPixmap QDeclarativeTextPrivate::textDocumentImage(bool drawStyle)
536
QSize size = doc->size().toSize();
540
img.fill(Qt::transparent);
542
bool oldSmooth = qt_applefontsmoothing_enabled;
543
qt_applefontsmoothing_enabled = false;
547
qt_applefontsmoothing_enabled = oldSmooth;
550
QAbstractTextDocumentLayout::PaintContext context;
552
QTextOption oldOption(doc->defaultTextOption());
554
context.palette.setColor(QPalette::Text, styleColor);
555
QTextOption colorOption(doc->defaultTextOption());
556
colorOption.setFlags(QTextOption::SuppressColors);
557
doc->setDefaultTextOption(colorOption);
559
context.palette.setColor(QPalette::Text, color);
561
doc->documentLayout()->draw(&p, context);
563
doc->setDefaultTextOption(oldOption);
568
Mark the image cache as dirty.
570
void QDeclarativeTextPrivate::invalidateImageCache()
572
Q_Q(QDeclarativeText);
574
if(cacheAllTextAsImage || style != QDeclarativeText::Normal){//If actually using the image cache
578
imageCacheDirty = true;
579
imageCache = QPixmap();
581
if (q->isComponentComplete())
586
Tests if the image cache is dirty, and repaints it if it is.
588
void QDeclarativeTextPrivate::checkImageCache()
590
if (!imageCacheDirty)
593
if (text.isEmpty()) {
595
imageCache = QPixmap();
603
textImage = textDocumentImage(false);
604
if (style != QDeclarativeText::Normal)
605
styledImage = textDocumentImage(true); //### should use styleColor
607
textImage = textLayoutImage(false);
608
if (style != QDeclarativeText::Normal)
609
styledImage = textLayoutImage(true); //### should use styleColor
613
case QDeclarativeText::Outline:
614
imageCache = drawOutline(textImage, styledImage);
616
case QDeclarativeText::Sunken:
617
imageCache = drawOutline(textImage, styledImage, -1);
619
case QDeclarativeText::Raised:
620
imageCache = drawOutline(textImage, styledImage, 1);
623
imageCache = textImage;
629
imageCacheDirty = false;
633
Ensures the QDeclarativeTextPrivate::doc variable is set to a valid text document
635
void QDeclarativeTextPrivate::ensureDoc()
638
Q_Q(QDeclarativeText);
639
doc = new QTextDocumentWithImageResources(q);
640
doc->setDocumentMargin(0);
645
Draw \a styleSource as an outline around \a source and return the new image.
647
QPixmap QDeclarativeTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource)
649
QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
650
img.fill(Qt::transparent);
655
pos += QPoint(-1, 0);
656
ppm.drawPixmap(pos, styleSource);
658
ppm.drawPixmap(pos, styleSource);
659
pos += QPoint(-1, -1);
660
ppm.drawPixmap(pos, styleSource);
662
ppm.drawPixmap(pos, styleSource);
664
pos += QPoint(0, -1);
665
ppm.drawPixmap(pos, source);
672
Draw \a styleSource below \a source at \a yOffset and return the new image.
674
QPixmap QDeclarativeTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset)
676
QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
677
img.fill(Qt::transparent);
681
ppm.drawPixmap(QPoint(0, yOffset), styleSource);
682
ppm.drawPixmap(0, 0, source);
690
\qmlclass Text QDeclarativeText
691
\ingroup qml-basic-visual-elements
693
\brief The Text item allows you to add formatted text to a scene.
696
Text items can display both plain and rich text. For example, red text with
697
a specific font and size can be defined like this:
702
font.family: "Helvetica"
708
Rich text is defined using HTML-style markup:
712
text: "<b>Hello</b> <i>World!</i>"
716
\image declarative-text.png
718
If height and width are not explicitly set, Text will attempt to determine how
719
much room is needed and set it accordingly. Unless \l wrapMode is set, it will always
720
prefer width to height (all text will be placed on a single line).
722
The \l elide property can alternatively be used to fit a single line of
723
plain text to a set width.
725
Note that the \l{Supported HTML Subset} is limited. Also, if the text contains
726
HTML img tags that load remote images, the text is reloaded.
728
Text provides read-only text. For editable text, see \l TextEdit.
730
\sa {declarative/text/fonts}{Fonts example}
732
QDeclarativeText::QDeclarativeText(QDeclarativeItem *parent)
733
: QDeclarativeImplicitSizeItem(*(new QDeclarativeTextPrivate), parent)
737
QDeclarativeText::~QDeclarativeText()
742
\qmlproperty bool Text::clip
743
This property holds whether the text is clipped.
745
Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
747
If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
751
\qmlproperty bool Text::smooth
753
This property holds whether the text is smoothly scaled or transformed.
755
Smooth filtering gives better visual quality, but is slower. If
756
the item is displayed at its natural size, this property has no visual or
759
\note Generally scaling artifacts are only visible if the item is stationary on
760
the screen. A common pattern when animating an item is to disable smooth
761
filtering at the beginning of the animation and reenable it at the conclusion.
765
\qmlsignal Text::onLinkActivated(string link)
767
This handler is called when the user clicks on a link embedded in the text.
768
The link must be in rich text or HTML format and the
769
\a link string provides access to the particular link.
771
\snippet doc/src/snippets/declarative/text/onLinkActivated.qml 0
773
The example code will display the text
774
"The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}."
776
Clicking on the highlighted link will output
777
\tt{http://qt.nokia.com link activated} to the console.
781
\qmlproperty string Text::font.family
783
Sets the family name of the font.
785
The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
786
If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
787
If the family isn't available a family will be set using the font matching algorithm.
791
\qmlproperty bool Text::font.bold
793
Sets whether the font weight is bold.
797
\qmlproperty enumeration Text::font.weight
799
Sets the font's weight.
801
The weight can be one of:
804
\o Font.Normal - the default
811
Text { text: "Hello"; font.weight: Font.DemiBold }
816
\qmlproperty bool Text::font.italic
818
Sets whether the font has an italic style.
822
\qmlproperty bool Text::font.underline
824
Sets whether the text is underlined.
828
\qmlproperty bool Text::font.strikeout
830
Sets whether the font has a strikeout style.
834
\qmlproperty real Text::font.pointSize
836
Sets the font size in points. The point size must be greater than zero.
840
\qmlproperty int Text::font.pixelSize
842
Sets the font size in pixels.
844
Using this function makes the font device dependent.
845
Use \c pointSize to set the size of the font in a device independent manner.
849
\qmlproperty real Text::font.letterSpacing
851
Sets the letter spacing for the font.
853
Letter spacing changes the default spacing between individual letters in the font.
854
A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
858
\qmlproperty real Text::font.wordSpacing
860
Sets the word spacing for the font.
862
Word spacing changes the default spacing between individual words.
863
A positive value increases the word spacing by a corresponding amount of pixels,
864
while a negative value decreases the inter-word spacing accordingly.
868
\qmlproperty enumeration Text::font.capitalization
870
Sets the capitalization for the text.
873
\o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
874
\o Font.AllUppercase - This alters the text to be rendered in all uppercase type.
875
\o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
876
\o Font.SmallCaps - This alters the text to be rendered in small-caps type.
877
\o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
881
Text { text: "Hello"; font.capitalization: Font.AllLowercase }
884
QFont QDeclarativeText::font() const
886
Q_D(const QDeclarativeText);
887
return d->sourceFont;
890
void QDeclarativeText::setFont(const QFont &font)
892
Q_D(QDeclarativeText);
893
if (d->sourceFont == font)
896
d->sourceFont = font;
897
QFont oldFont = d->font;
899
if (d->font.pointSizeF() != -1) {
901
qreal size = qRound(d->font.pointSizeF()*2.0);
902
d->font.setPointSizeF(size/2.0);
905
if (oldFont != d->font)
908
emit fontChanged(d->sourceFont);
912
\qmlproperty string Text::text
914
The text to display. Text supports both plain and rich text strings.
916
The item will try to automatically determine whether the text should
917
be treated as rich text. This determination is made using Qt::mightBeRichText().
919
QString QDeclarativeText::text() const
921
Q_D(const QDeclarativeText);
925
void QDeclarativeText::setText(const QString &n)
927
Q_D(QDeclarativeText);
931
d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(n));
933
if (isComponentComplete()) {
937
d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
939
d->rightToLeftText = d->text.isRightToLeft();
941
d->determineHorizontalAlignment();
944
emit textChanged(d->text);
949
\qmlproperty color Text::color
953
An example of green text defined using hexadecimal notation:
961
An example of steel blue text defined using an SVG color name:
969
QColor QDeclarativeText::color() const
971
Q_D(const QDeclarativeText);
975
void QDeclarativeText::setColor(const QColor &color)
977
Q_D(QDeclarativeText);
978
if (d->color == color)
982
d->invalidateImageCache();
983
emit colorChanged(d->color);
987
\qmlproperty enumeration Text::style
989
Set an additional text style.
991
Supported text styles are:
993
\o Text.Normal - the default
1001
Text { font.pointSize: 24; text: "Normal" }
1002
Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" }
1003
Text { font.pointSize: 24; text: "Outline";style: Text.Outline; styleColor: "red" }
1004
Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" }
1008
\image declarative-textstyle.png
1010
QDeclarativeText::TextStyle QDeclarativeText::style() const
1012
Q_D(const QDeclarativeText);
1016
void QDeclarativeText::setStyle(QDeclarativeText::TextStyle style)
1018
Q_D(QDeclarativeText);
1019
if (d->style == style)
1022
// changing to/from Normal requires the boundingRect() to change
1023
if (isComponentComplete() && (d->style == Normal || style == Normal))
1024
prepareGeometryChange();
1026
d->invalidateImageCache();
1027
emit styleChanged(d->style);
1031
\qmlproperty color Text::styleColor
1033
Defines the secondary color used by text styles.
1035
\c styleColor is used as the outline color for outlined text, and as the
1036
shadow color for raised or sunken text. If no style has been set, it is not
1040
Text { font.pointSize: 18; text: "hello"; style: Text.Raised; styleColor: "gray" }
1045
QColor QDeclarativeText::styleColor() const
1047
Q_D(const QDeclarativeText);
1048
return d->styleColor;
1051
void QDeclarativeText::setStyleColor(const QColor &color)
1053
Q_D(QDeclarativeText);
1054
if (d->styleColor == color)
1057
d->styleColor = color;
1058
d->invalidateImageCache();
1059
emit styleColorChanged(d->styleColor);
1064
\qmlproperty enumeration Text::horizontalAlignment
1065
\qmlproperty enumeration Text::verticalAlignment
1067
Sets the horizontal and vertical alignment of the text within the Text items
1068
width and height. By default, the text is vertically aligned to the top. Horizontal
1069
alignment follows the natural alignment of the text, for example text that is read
1070
from left to right will be aligned to the left.
1072
The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight, \c Text.AlignHCenter and
1073
\c Text.AlignJustify. The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
1074
and \c Text.AlignVCenter.
1076
Note that for a single line of text, the size of the text is the area of the text. In this common case,
1077
all alignments are equivalent. If you want the text to be, say, centered in its parent, then you will
1078
need to either modify the Item::anchors, or set horizontalAlignment to Text.AlignHCenter and bind the width to
1081
When using the attached property \l {LayoutMirroring::enabled} to mirror application
1082
layouts, the horizontal alignment of text will also be mirrored. However, the property
1083
\c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
1084
of Text, use the property \l {LayoutMirroring::enabled}.
1086
QDeclarativeText::HAlignment QDeclarativeText::hAlign() const
1088
Q_D(const QDeclarativeText);
1092
void QDeclarativeText::setHAlign(HAlignment align)
1094
Q_D(QDeclarativeText);
1095
bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
1096
d->hAlignImplicit = false;
1097
if (d->setHAlign(align, forceAlign) && isComponentComplete())
1101
void QDeclarativeText::resetHAlign()
1103
Q_D(QDeclarativeText);
1104
d->hAlignImplicit = true;
1105
if (d->determineHorizontalAlignment() && isComponentComplete())
1109
QDeclarativeText::HAlignment QDeclarativeText::effectiveHAlign() const
1111
Q_D(const QDeclarativeText);
1112
QDeclarativeText::HAlignment effectiveAlignment = d->hAlign;
1113
if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
1114
switch (d->hAlign) {
1115
case QDeclarativeText::AlignLeft:
1116
effectiveAlignment = QDeclarativeText::AlignRight;
1118
case QDeclarativeText::AlignRight:
1119
effectiveAlignment = QDeclarativeText::AlignLeft;
1125
return effectiveAlignment;
1128
bool QDeclarativeTextPrivate::setHAlign(QDeclarativeText::HAlignment alignment, bool forceAlign)
1130
Q_Q(QDeclarativeText);
1131
if (hAlign != alignment || forceAlign) {
1132
QDeclarativeText::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
1134
emit q->horizontalAlignmentChanged(hAlign);
1140
bool QDeclarativeTextPrivate::determineHorizontalAlignment()
1142
Q_Q(QDeclarativeText);
1143
if (hAlignImplicit && q->isComponentComplete()) {
1144
bool alignToRight = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
1145
return setHAlign(alignToRight ? QDeclarativeText::AlignRight : QDeclarativeText::AlignLeft);
1150
void QDeclarativeTextPrivate::mirrorChange()
1152
Q_Q(QDeclarativeText);
1153
if (q->isComponentComplete()) {
1154
if (!hAlignImplicit && (hAlign == QDeclarativeText::AlignRight || hAlign == QDeclarativeText::AlignLeft)) {
1160
QTextDocument *QDeclarativeTextPrivate::textDocument()
1165
QDeclarativeText::VAlignment QDeclarativeText::vAlign() const
1167
Q_D(const QDeclarativeText);
1171
void QDeclarativeText::setVAlign(VAlignment align)
1173
Q_D(QDeclarativeText);
1174
if (d->vAlign == align)
1177
if (isComponentComplete())
1178
prepareGeometryChange();
1180
emit verticalAlignmentChanged(align);
1184
\qmlproperty enumeration Text::wrapMode
1186
Set this property to wrap the text to the Text item's width. The text will only
1187
wrap if an explicit width has been set. wrapMode can be one of:
1190
\o Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l paintedWidth will exceed a set width.
1191
\o Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l paintedWidth will exceed a set width.
1192
\o Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
1193
\o Text.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
1196
QDeclarativeText::WrapMode QDeclarativeText::wrapMode() const
1198
Q_D(const QDeclarativeText);
1202
void QDeclarativeText::setWrapMode(WrapMode mode)
1204
Q_D(QDeclarativeText);
1205
if (mode == d->wrapMode)
1211
emit wrapModeChanged();
1215
\qmlproperty int Text::lineCount
1218
Returns the number of lines visible in the text item.
1220
This property is not supported for rich text.
1222
\sa maximumLineCount
1224
int QDeclarativeText::lineCount() const
1226
Q_D(const QDeclarativeText);
1227
return d->lineCount;
1231
\qmlproperty bool Text::truncated
1234
Returns true if the text has been truncated due to \l maximumLineCount
1237
This property is not supported for rich text.
1239
\sa maximumLineCount, elide
1241
bool QDeclarativeText::truncated() const
1243
Q_D(const QDeclarativeText);
1244
return d->truncated;
1248
\qmlproperty int Text::maximumLineCount
1251
Set this property to limit the number of lines that the text item will show.
1252
If elide is set to Text.ElideRight, the text will be elided appropriately.
1253
By default, this is the value of the largest possible integer.
1255
This property is not supported for rich text.
1257
\sa lineCount, elide
1259
int QDeclarativeText::maximumLineCount() const
1261
Q_D(const QDeclarativeText);
1262
return d->maximumLineCount;
1265
void QDeclarativeText::setMaximumLineCount(int lines)
1267
Q_D(QDeclarativeText);
1269
d->maximumLineCountValid = lines==INT_MAX ? false : true;
1270
if (d->maximumLineCount != lines) {
1271
d->maximumLineCount = lines;
1273
emit maximumLineCountChanged();
1277
void QDeclarativeText::resetMaximumLineCount()
1279
Q_D(QDeclarativeText);
1280
setMaximumLineCount(INT_MAX);
1281
d->elidePos = QPointF();
1282
if (d->truncated != false) {
1283
d->truncated = false;
1284
emit truncatedChanged();
1289
\qmlproperty enumeration Text::textFormat
1291
The way the text property should be displayed.
1293
Supported text formats are:
1296
\o Text.AutoText (default)
1302
If the text format is \c Text.AutoText the text element
1303
will automatically determine whether the text should be treated as
1304
rich text. This determination is made using Qt::mightBeRichText().
1306
Text.StyledText is an optimized format supporting some basic text
1307
styling markup, in the style of html 3.2:
1310
<font size="4" color="#ff0000">font size and color</font>
1317
\c Text.StyledText parser is strict, requiring tags to be correctly nested.
1326
text: "<b>Hello</b> <i>World!</i>"
1330
textFormat: Text.RichText
1331
text: "<b>Hello</b> <i>World!</i>"
1335
textFormat: Text.PlainText
1336
text: "<b>Hello</b> <i>World!</i>"
1340
\o \image declarative-textformat.png
1343
QDeclarativeText::TextFormat QDeclarativeText::textFormat() const
1345
Q_D(const QDeclarativeText);
1349
void QDeclarativeText::setTextFormat(TextFormat format)
1351
Q_D(QDeclarativeText);
1352
if (format == d->format)
1355
bool wasRich = d->richText;
1356
d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));
1358
if (!wasRich && d->richText && isComponentComplete()) {
1360
d->doc->setText(d->text);
1365
emit textFormatChanged(d->format);
1369
\qmlproperty enumeration Text::elide
1371
Set this property to elide parts of the text fit to the Text item's width.
1372
The text will only elide if an explicit width has been set.
1374
This property cannot be used with rich text.
1378
\o Text.ElideNone - the default
1384
If this property is set to Text.ElideRight, it can be used with multiline
1385
text. The text will only elide if maximumLineCount has been set.
1387
If the text is a multi-length string, and the mode is not \c Text.ElideNone,
1388
the first string that fits will be used, otherwise the last will be elided.
1390
Multi-length strings are ordered from longest to shortest, separated by the
1391
Unicode "String Terminator" character \c U009C (write this in QML with \c{"\u009C"} or \c{"\x9C"}).
1393
QDeclarativeText::TextElideMode QDeclarativeText::elideMode() const
1395
Q_D(const QDeclarativeText);
1396
return d->elideMode;
1399
void QDeclarativeText::setElideMode(QDeclarativeText::TextElideMode mode)
1401
Q_D(QDeclarativeText);
1402
if (mode == d->elideMode)
1405
d->elideMode = mode;
1408
emit elideModeChanged(d->elideMode);
1412
QRectF QDeclarativeText::boundingRect() const
1414
Q_D(const QDeclarativeText);
1416
QRect rect = d->layedOutTextRect;
1417
if (d->style != Normal)
1418
rect.adjust(-1, 0, 1, 2);
1420
// Could include font max left/right bearings to either side of rectangle.
1423
switch (d->vAlign) {
1427
rect.moveTop(h - rect.height());
1430
rect.moveTop((h - rect.height()) / 2);
1434
return QRectF(rect);
1438
void QDeclarativeText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
1440
Q_D(QDeclarativeText);
1441
if ((!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width())
1442
&& (d->wrapMode != QDeclarativeText::NoWrap
1443
|| d->elideMode != QDeclarativeText::ElideNone
1444
|| d->hAlign != QDeclarativeText::AlignLeft)) {
1445
if ((d->singleline || d->maximumLineCountValid) && d->elideMode != QDeclarativeText::ElideNone && widthValid()) {
1446
// We need to re-elide
1449
// We just need to re-layout
1454
QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
1458
\qmlproperty real Text::paintedWidth
1460
Returns the width of the text, including width past the width
1461
which is covered due to insufficient wrapping if WrapMode is set.
1463
qreal QDeclarativeText::paintedWidth() const
1465
Q_D(const QDeclarativeText);
1466
return d->paintedSize.width();
1470
\qmlproperty real Text::paintedHeight
1472
Returns the height of the text, including height past the height
1473
which is covered due to there being more text than fits in the set height.
1475
qreal QDeclarativeText::paintedHeight() const
1477
Q_D(const QDeclarativeText);
1478
return d->paintedSize.height();
1482
\qmlproperty real Text::lineHeight
1485
Sets the line height for the text.
1486
The value can be in pixels or a multiplier depending on lineHeightMode.
1488
The default value is a multiplier of 1.0.
1489
The line height must be a positive value.
1491
qreal QDeclarativeText::lineHeight() const
1493
Q_D(const QDeclarativeText);
1494
return d->lineHeight;
1497
void QDeclarativeText::setLineHeight(qreal lineHeight)
1499
Q_D(QDeclarativeText);
1501
if ((d->lineHeight == lineHeight) || (lineHeight < 0.0))
1504
d->lineHeight = lineHeight;
1506
emit lineHeightChanged(lineHeight);
1510
\qmlproperty enumeration Text::lineHeightMode
1512
This property determines how the line height is specified.
1513
The possible values are:
1516
\o Text.ProportionalHeight (default) - this sets the spacing proportional to the
1517
line (as a multiplier). For example, set to 2 for double spacing.
1518
\o Text.FixedHeight - this sets the line height to a fixed line height (in pixels).
1521
QDeclarativeText::LineHeightMode QDeclarativeText::lineHeightMode() const
1523
Q_D(const QDeclarativeText);
1524
return d->lineHeightMode;
1527
void QDeclarativeText::setLineHeightMode(LineHeightMode mode)
1529
Q_D(QDeclarativeText);
1530
if (mode == d->lineHeightMode)
1533
d->lineHeightMode = mode;
1536
emit lineHeightModeChanged(mode);
1540
Returns the number of resources (images) that are being loaded asynchronously.
1542
int QDeclarativeText::resourcesLoading() const
1544
Q_D(const QDeclarativeText);
1545
return d->doc ? d->doc->resourcesLoading() : 0;
1549
void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
1551
Q_D(QDeclarativeText);
1553
if (d->cacheAllTextAsImage || d->style != Normal) {
1554
d->checkImageCache();
1555
if (d->imageCache.isNull())
1558
bool oldAA = p->testRenderHint(QPainter::Antialiasing);
1559
bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
1561
p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
1563
QRect br = boundingRect().toRect();
1565
bool needClip = clip() && (d->imageCache.width() > width() ||
1566
d->imageCache.height() > height());
1569
p->drawPixmap(0, 0, width(), height(), d->imageCache, -br.x(), -br.y(), width(), height());
1571
p->drawPixmap(br.x(), br.y(), d->imageCache);
1574
p->setRenderHint(QPainter::Antialiasing, oldAA);
1575
p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
1578
QRectF bounds = boundingRect();
1580
bool needClip = clip() && (d->layedOutTextRect.width() > width() ||
1581
d->layedOutTextRect.height() > height());
1585
p->setClipRect(0, 0, width(), height(), Qt::IntersectClip);
1588
QAbstractTextDocumentLayout::PaintContext context;
1589
context.palette.setColor(QPalette::Text, d->color);
1590
p->translate(bounds.x(), bounds.y());
1591
d->doc->documentLayout()->draw(p, context);
1592
p->translate(-bounds.x(), -bounds.y());
1594
d->drawTextLayout(p, QPointF(0, bounds.y()), false);
1604
void QDeclarativeText::componentComplete()
1606
Q_D(QDeclarativeText);
1607
QDeclarativeItem::componentComplete();
1608
if (d->updateOnComponentComplete) {
1609
d->updateOnComponentComplete = false;
1612
d->doc->setText(d->text);
1613
d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
1615
d->rightToLeftText = d->text.isRightToLeft();
1617
d->determineHorizontalAlignment();
1623
void QDeclarativeText::mousePressEvent(QGraphicsSceneMouseEvent *event)
1625
Q_D(QDeclarativeText);
1627
if (!d->richText || !d->doc || d->doc->documentLayout()->anchorAt(event->pos()).isEmpty()) {
1628
event->setAccepted(false);
1629
d->activeLink.clear();
1631
d->activeLink = d->doc->documentLayout()->anchorAt(event->pos());
1634
// ### may malfunction if two of the same links are clicked & dragged onto each other)
1636
if (!event->isAccepted())
1637
QDeclarativeItem::mousePressEvent(event);
1642
void QDeclarativeText::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
1644
Q_D(QDeclarativeText);
1646
// ### confirm the link, and send a signal out
1647
if (d->richText && d->doc && d->activeLink == d->doc->documentLayout()->anchorAt(event->pos()))
1648
emit linkActivated(d->activeLink);
1650
event->setAccepted(false);
1652
if (!event->isAccepted())
1653
QDeclarativeItem::mouseReleaseEvent(event);
1658
#include "qdeclarativetext.moc"