Also check notifier endpoints when checking whether a signal is connected.
[profile/ivi/qtdeclarative.git] / src / quick / items / qquicktext.cpp
index 6d1cc0d..2407ade 100644 (file)
@@ -3,7 +3,7 @@
 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/
 **
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
 ** GNU Lesser General Public License Usage
 #include "qquicktext_p_p.h"
 
 #include <QtQuick/private/qsgcontext_p.h>
+#include <private/qqmlglobal_p.h>
 #include <private/qsgadaptationlayer_p.h>
 #include "qquicktextnode_p.h"
 #include "qquickimage_p_p.h"
 #include <QtQuick/private/qsgtexture_p.h>
 
-#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtQml/qqmlinfo.h>
 #include <QtGui/qevent.h>
 #include <QtGui/qabstracttextdocumentlayout.h>
 #include <QtGui/qpainter.h>
@@ -59,8 +60,8 @@
 #include <QtGui/qinputmethod.h>
 
 #include <private/qtextengine_p.h>
-#include <private/qdeclarativestyledtext_p.h>
-#include <QtQuick/private/qdeclarativepixmapcache_p.h>
+#include <private/qquickstyledtext_p.h>
+#include <QtQuick/private/qquickpixmapcache_p.h>
 
 #include <qmath.h>
 #include <limits.h>
@@ -122,11 +123,11 @@ QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
 
 QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
 {
-    QDeclarativeContext *context = qmlContext(parent());
+    QQmlContext *context = qmlContext(parent());
     QUrl url = m_baseUrl.resolved(name);
 
     if (type == QTextDocument::ImageResource) {
-        QDeclarativePixmap *p = loadPixmap(context, url);
+        QQuickPixmap *p = loadPixmap(context, url);
         return p->image();
     }
 
@@ -163,10 +164,10 @@ QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
 
         QSizeF size(width, height);
         if (!hasWidth || !hasHeight) {
-            QDeclarativeContext *context = qmlContext(parent());
+            QQmlContext *context = qmlContext(parent());
             QUrl url = m_baseUrl.resolved(QUrl(imageFormat.name()));
 
-            QDeclarativePixmap *p = loadPixmap(context, url);
+            QQuickPixmap *p = loadPixmap(context, url);
             if (!p->isReady()) {
                 if (!hasWidth)
                     size.setWidth(16);
@@ -201,10 +202,10 @@ void QQuickTextDocumentWithImageResources::drawObject(
 
 QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
 {
-    QDeclarativeContext *context = qmlContext(parent());
+    QQmlContext *context = qmlContext(parent());
     QUrl url = m_baseUrl.resolved(QUrl(format.name()));
 
-    QDeclarativePixmap *p = loadPixmap(context, url);
+    QQuickPixmap *p = loadPixmap(context, url);
     return p->image();
 }
 
@@ -217,14 +218,14 @@ void QQuickTextDocumentWithImageResources::setBaseUrl(const QUrl &url, bool clea
     }
 }
 
-QDeclarativePixmap *QQuickTextDocumentWithImageResources::loadPixmap(
-        QDeclarativeContext *context, const QUrl &url)
+QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap(
+        QQmlContext *context, const QUrl &url)
 {
 
-    QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
+    QHash<QUrl, QQuickPixmap *>::Iterator iter = m_resources.find(url);
 
     if (iter == m_resources.end()) {
-        QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
+        QQuickPixmap *p = new QQuickPixmap(context->engine(), url);
         iter = m_resources.insert(url, p);
 
         if (p->isLoading()) {
@@ -233,7 +234,7 @@ QDeclarativePixmap *QQuickTextDocumentWithImageResources::loadPixmap(
         }
     }
 
-    QDeclarativePixmap *p = *iter;
+    QQuickPixmap *p = *iter;
     if (p->isError()) {
         if (!errors.contains(url)) {
             errors.insert(url);
@@ -245,7 +246,7 @@ QDeclarativePixmap *QQuickTextDocumentWithImageResources::loadPixmap(
 
 void QQuickTextDocumentWithImageResources::clearResources()
 {
-    foreach (QDeclarativePixmap *pixmap, m_resources)
+    foreach (QQuickPixmap *pixmap, m_resources)
         pixmap->clear(this);
     qDeleteAll(m_resources);
     m_resources.clear();
@@ -312,7 +313,7 @@ void QQuickTextPrivate::updateLayout()
                 layout.setFont(font);
                 // needs temporary bool because formatModifiesFontSize is in a bit-field
                 bool fontSizeModified = false;
-                QDeclarativeStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid, &fontSizeModified);
+                QQuickStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid, &fontSizeModified);
                 formatModifiesFontSize = fontSizeModified;
             } else {
                 layout.clearAdditionalFormats();
@@ -364,7 +365,7 @@ void QQuickText::imageDownloadFinished()
 
     if (d->extra.isAllocated() && d->extra->nbActiveDownloads == 0) {
         bool needToUpdateLayout = false;
-        foreach (QDeclarativeStyledTextImgTag *img, d->visibleImgTags) {
+        foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) {
             if (!img->size.isValid()) {
                 img->size = img->pix->implicitSize();
                 needToUpdateLayout = true;
@@ -381,6 +382,22 @@ void QQuickText::imageDownloadFinished()
     }
 }
 
+void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy)
+{
+    Q_Q(QQuickText);
+
+    qreal yoff = 0;
+
+    if (q->heightValid()) {
+        if (vAlign == QQuickText::AlignBottom)
+            yoff = dy;
+        else if (vAlign == QQuickText::AlignVCenter)
+            yoff = dy/2;
+    }
+
+    q->setBaselineOffset(baseline + yoff);
+}
+
 void QQuickTextPrivate::updateSize()
 {
     Q_Q(QQuickText);
@@ -397,11 +414,21 @@ void QQuickTextPrivate::updateSize()
             return;
     }
 
-    QFontMetricsF fm(font);
-    if (text.isEmpty()) {
-        qreal fontHeight = fm.height();
+    if (text.isEmpty() && !isLineLaidOutConnected() && fontSizeMode() == QQuickText::FixedSize) {
+        // How much more expensive is it to just do a full layout on an empty string here?
+        // There may be subtle differences in the height and baseline calculations between
+        // QTextLayout and QFontMetrics and the number of variables that can affect the size
+        // and position of a line is increasing.
+        QFontMetricsF fm(font);
+        qreal fontHeight = qCeil(fm.height());  // QScriptLine and therefore QTextLine rounds up
+        if (!richText) {                        // line height, so we will as well.
+            fontHeight = lineHeightMode() == QQuickText::FixedHeight
+                    ? lineHeight()
+                    : fontHeight * lineHeight();
+        }
+        updateBaseline(fm.ascent(), q->height() - fontHeight);
         q->setImplicitSize(0, fontHeight);
-        layedOutTextRect = QRect(0, 0, 0, fontHeight);
+        layedOutTextRect = QRectF(0, 0, 0, fontHeight);
         emit q->contentSizeChanged();
         updateType = UpdatePaintNode;
         q->update();
@@ -410,7 +437,6 @@ void QQuickTextPrivate::updateSize()
 
     qreal naturalWidth = 0;
 
-    qreal dy = q->height();
     QSizeF size(0, 0);
     QSizeF previousSize = layedOutTextRect.size();
 #if defined(Q_OS_MAC)
@@ -419,10 +445,15 @@ void QQuickTextPrivate::updateSize()
 
     //setup instance of QTextLayout for all cases other than richtext
     if (!richText) {
-        QRectF textRect = setupTextLayout(&naturalWidth);
+        qreal baseline = 0;
+        QRectF textRect = setupTextLayout(&naturalWidth, &baseline);
+
+        if (internalWidthUpdate)    // probably the result of a binding loop, but by letting it
+            return;      // get this far we'll get a warning to that effect if it is.
+
         layedOutTextRect = textRect;
         size = textRect.size();
-        dy -= size.height();
+        updateBaseline(baseline, q->height() - size.height());
     } else {
         singleline = false; // richtext can't elide or be optimized for single-line case
         ensureDoc();
@@ -442,33 +473,30 @@ void QQuickTextPrivate::updateSize()
         if (requireImplicitWidth && q->widthValid()) {
             extra->doc->setTextWidth(-1);
             naturalWidth = extra->doc->idealWidth();
+            const bool wasInLayout = internalWidthUpdate;
+            internalWidthUpdate = true;
+            q->setImplicitWidth(naturalWidth);
+            internalWidthUpdate = wasInLayout;
         }
+        if (internalWidthUpdate)
+            return;
         if (wrapMode != QQuickText::NoWrap && q->widthValid())
             extra->doc->setTextWidth(q->width());
         else
             extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
-        dy -= extra->doc->size().height();
         QSizeF dsize = extra->doc->size();
         layedOutTextRect = QRectF(QPointF(0,0), dsize);
         size = QSizeF(extra->doc->idealWidth(),dsize.height());
-    }
-    qreal yoff = 0;
 
-    if (q->heightValid()) {
-        if (vAlign == QQuickText::AlignBottom)
-            yoff = dy;
-        else if (vAlign == QQuickText::AlignVCenter)
-            yoff = dy/2;
+        QFontMetricsF fm(font);
+        updateBaseline(fm.ascent(), q->height() - size.height());
     }
-    q->setBaselineOffset(fm.ascent() + yoff);
 
     //### need to comfirm cost of always setting these for richText
     internalWidthUpdate = true;
     qreal iWidth = -1;
     if (!q->widthValid())
         iWidth = size.width();
-    else if (requireImplicitWidth)
-        iWidth = naturalWidth;
     if (iWidth > -1)
         q->setImplicitSize(iWidth, size.height());
     internalWidthUpdate = false;
@@ -566,8 +594,8 @@ void QQuickText::doLayout()
 
 bool QQuickTextPrivate::isLineLaidOutConnected()
 {
-    static int idx = this->signalIndex("lineLaidOut(QQuickTextLine*)");
-    return this->isSignalConnected(idx);
+    Q_Q(QQuickText);
+    IS_SIGNAL_CONNECTED(q, "lineLaidOut(QQuickTextLine*)");
 }
 
 void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset)
@@ -660,7 +688,7 @@ QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QT
     already absolutely positioned horizontally).
 */
 
-QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
+QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *const baseline)
 {
     Q_Q(QQuickText);
     layout.setCacheEnabled(true);
@@ -672,8 +700,9 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
     layout.setTextOption(textOption);
     layout.setFont(font);
 
-    if ((q->widthValid() && q->width() <= 0. && elideMode != QQuickText::ElideNone)
-            || (q->heightValid() && q->height() <= 0. && wrapMode != QQuickText::NoWrap && elideMode == QQuickText::ElideRight)) {
+    if (!requireImplicitWidth
+            && ((q->widthValid() && q->width() <= 0. && elideMode != QQuickText::ElideNone)
+            || (q->heightValid() && q->height() <= 0. && wrapMode != QQuickText::NoWrap && elideMode == QQuickText::ElideRight))) {
         // we are elided and we have a zero width or height
         if (!truncated) {
             truncated = true;
@@ -684,40 +713,28 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
             emit q->lineCountChanged();
         }
 
-        if (requireImplicitWidth) {
-            // Layout to determine the implicit width.
-            layout.beginLayout();
-
-            for (int i = 0; i < maximumLineCount(); ++i) {
-                QTextLine line = layout.createLine();
-                if (!line.isValid())
-                    break;
-            }
-            layout.endLayout();
-            *naturalWidth = layout.maximumWidth();
-            layout.clearLayout();
-        }
-
-        QFontMetrics fm(font);
+        QFontMetricsF fm(font);
         qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : fm.height() * lineHeight();
-        return QRect(0, 0, 0, height);
+        *baseline = fm.ascent();
+        return QRectF(0, 0, 0, height);
     }
 
-    const qreal lineWidth = q->widthValid() ? q->width() : FLT_MAX;
+    qreal lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX;
     const qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
 
     const bool customLayout = isLineLaidOutConnected();
     const bool wasTruncated = truncated;
 
-    const bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
-    const bool multilineElide = elideMode == QQuickText::ElideRight
+    bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
+    bool multilineElide = elideMode == QQuickText::ElideRight
             && q->widthValid()
             && (q->heightValid() || maximumLineCountValid);
-    const bool canWrap = wrapMode != QQuickText::NoWrap && q->widthValid();
+    bool canWrap = wrapMode != QQuickText::NoWrap && q->widthValid();
 
-    const bool horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid();
-    const bool verticalFit = fontSizeMode() & QQuickText::VerticalFit
+    bool horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid();
+    bool verticalFit = fontSizeMode() & QQuickText::VerticalFit
             && (q->heightValid() || (maximumLineCountValid && canWrap));
+
     const bool pixelSize = font.pixelSize() != -1;
     QString layoutText = layout.text();
 
@@ -754,8 +771,8 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
                 scaledFont.setPointSize(scaledFontSize);
             layout.setFont(scaledFont);
         }
-        layout.beginLayout();
 
+        layout.beginLayout();
 
         bool wrapped = false;
         bool truncateHeight = false;
@@ -788,20 +805,16 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
                 height = preLayoutHeight;
 
                 characterCount = line.textStart() + line.textLength();
+                visibleCount -= 1;
 
-                QTextLine previousLine = layout.lineAt(visibleCount - 2);
+                QTextLine previousLine = layout.lineAt(visibleCount - 1);
                 elideText = layoutText.at(line.textStart() - 1) != QChar::LineSeparator
                         ? elidedText(lineWidth, previousLine, &line)
                         : elidedText(lineWidth, previousLine);
                 elideStart = previousLine.textStart();
                 // elideEnd isn't required for right eliding.
 
-                // The previous line is the last one visible so move the current one off somewhere
-                // out of the way and back everything up one line.
-                line.setLineWidth(0);
-                line.setPosition(QPointF(FLT_MAX, FLT_MAX));
                 line = previousLine;
-                --visibleCount;
                 height -= (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : previousLine.height() * lineHeight();
                 break;
             }
@@ -855,15 +868,12 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
                     } else {
                         br = br.united(line.naturalTextRect());
                     }
-                    nextLine.setLineWidth(0);
-                    nextLine.setPosition(QPointF(FLT_MAX, FLT_MAX));
                     break;
                 }
             }
             br = br.united(line.naturalTextRect());
             line = nextLine;
         }
-
         layout.endLayout();
         br.moveTop(0);
 
@@ -880,13 +890,35 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
                 QTextLayout widthLayout(layoutText.mid(characterCount), scaledFont);
                 widthLayout.setTextOption(layout.textOption());
 
+                widthLayout.beginLayout();
                 for (; unwrappedLineCount <= maxLineCount; ++unwrappedLineCount) {
                     QTextLine line = widthLayout.createLine();
                     if (!line.isValid())
                         break;
                 }
+                widthLayout.endLayout();
                 *naturalWidth = qMax(*naturalWidth, widthLayout.maximumWidth());
             }
+
+            bool wasInLayout = internalWidthUpdate;
+            internalWidthUpdate = true;
+            q->setImplicitWidth(*naturalWidth);
+            internalWidthUpdate = wasInLayout;
+
+            singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
+            multilineElide = elideMode == QQuickText::ElideRight
+                    && q->widthValid()
+                    && (q->heightValid() || maximumLineCountValid);
+            canWrap = wrapMode != QQuickText::NoWrap && q->widthValid();
+
+            horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid();
+            verticalFit = fontSizeMode() & QQuickText::VerticalFit
+                    && (q->heightValid() || (maximumLineCountValid && canWrap));
+
+            const qreal oldWidth = lineWidth;
+            lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX;
+            if (lineWidth != oldWidth && (singlelineElide || multilineElide || canWrap || horizontalFit))
+                continue;
         }
 
         // If the next needs to be elided and there's an abbreviated string available
@@ -910,40 +942,46 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
         if (horizontalFit) {
             if (unelidedRect.width() > lineWidth || (!verticalFit && wrapped)) {
                 largeFont = scaledFontSize - 1;
-                scaledFontSize = (smallFont + largeFont) / 2;
                 if (smallFont > largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont) / 2;
+                if (pixelSize)
+                    scaledFont.setPixelSize(scaledFontSize);
+                else
+                    scaledFont.setPointSize(scaledFontSize);
                 continue;
             } else if (!verticalFit) {
                 smallFont = scaledFontSize;
-                scaledFontSize = (smallFont + largeFont + 1) / 2;
                 if (smallFont == largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont + 1) / 2;
             }
         }
 
         if (verticalFit) {
             if (truncateHeight || unelidedRect.height() > maxHeight) {
                 largeFont = scaledFontSize - 1;
-                scaledFontSize = (smallFont + largeFont + 1) / 2;
                 if (smallFont > largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont) / 2;
+
             } else {
                 smallFont = scaledFontSize;
-                scaledFontSize = (smallFont + largeFont + 1) / 2;
                 if (smallFont == largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont + 1) / 2;
             }
         }
-
     }
 
     if (eos != multilengthEos)
         truncated = true;
 
     if (elide) {
-        if (!elideLayout)
+        if (!elideLayout) {
             elideLayout = new QTextLayout;
+            elideLayout->setCacheEnabled(true);
+        }
         if (styledText) {
             QList<QTextLayout::FormatRange> formats;
             switch (elideMode) {
@@ -987,15 +1025,19 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
 
         br = br.united(elidedLine.naturalTextRect());
 
-        if (visibleCount > 1)
-            line.setPosition(QPointF(FLT_MAX, FLT_MAX));
-        else
+        if (visibleCount == 1)
             layout.clearLayout();
     } else {
         delete elideLayout;
         elideLayout = 0;
     }
 
+    QTextLine firstLine = visibleCount == 1 && elideLayout
+            ? elideLayout->lineAt(0)
+            : layout.lineAt(0);
+    Q_ASSERT(firstLine.isValid());
+    *baseline = firstLine.y() + firstLine.ascent();
+
     if (!customLayout)
         br.setHeight(height);
 
@@ -1026,15 +1068,15 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
     qreal textHeight = line.height();
     qreal totalLineHeight = textHeight;
 
-    QList<QDeclarativeStyledTextImgTag *> imagesInLine;
+    QList<QQuickStyledTextImgTag *> imagesInLine;
 
-    foreach (QDeclarativeStyledTextImgTag *image, imgTags) {
+    foreach (QQuickStyledTextImgTag *image, imgTags) {
         if (image->position >= line.textStart() &&
             image->position < line.textStart() + line.textLength()) {
 
             if (!image->pix) {
                 QUrl url = q->baseUrl().resolved(image->url);
-                image->pix = new QDeclarativePixmap(qmlEngine(q), url, image->size);
+                image->pix = new QQuickPixmap(qmlEngine(q), url, image->size);
                 if (image->pix->isLoading()) {
                     image->pix->connectFinished(q, SLOT(imageDownloadFinished()));
                     if (!extra.isAllocated() || !extra->nbActiveDownloads)
@@ -1053,9 +1095,9 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
             }
 
             qreal ih = qreal(image->size.height());
-            if (image->align == QDeclarativeStyledTextImgTag::Top)
+            if (image->align == QQuickStyledTextImgTag::Top)
                 image->pos.setY(0);
-            else if (image->align == QDeclarativeStyledTextImgTag::Middle)
+            else if (image->align == QQuickStyledTextImgTag::Middle)
                 image->pos.setY((textHeight / 2.0) - (ih / 2.0));
             else
                 image->pos.setY(textHeight - ih);
@@ -1064,7 +1106,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
         }
     }
 
-    foreach (QDeclarativeStyledTextImgTag *image, imagesInLine) {
+    foreach (QQuickStyledTextImgTag *image, imagesInLine) {
         totalLineHeight = qMax(totalLineHeight, textTop + image->pos.y() + image->size.height());
         image->pos.setX(line.cursorToX(image->position));
         image->pos.setY(image->pos.y() + height + textTop);
@@ -1175,11 +1217,11 @@ QQuickText::~QQuickText()
 
     The properties of a line are:
     \list
-    \o number (read-only)
-    \o x
-    \o y
-    \o width
-    \o height
+    \li number (read-only)
+    \li x
+    \li y
+    \li width
+    \li height
     \endlist
 
     For example, this will move the first 5 lines of a text element by 100 pixels to the right:
@@ -1200,7 +1242,7 @@ QQuickText::~QQuickText()
     The link must be in rich text or HTML format and the
     \a link string provides access to the particular link.
 
-    \snippet doc/src/snippets/declarative/text/onLinkActivated.qml 0
+    \snippet doc/src/snippets/qml/text/onLinkActivated.qml 0
 
     The example code will display the text
     "The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}."
@@ -1232,11 +1274,11 @@ QQuickText::~QQuickText()
 
     The weight can be one of:
     \list
-    \o Font.Light
-    \o Font.Normal - the default
-    \o Font.DemiBold
-    \o Font.Bold
-    \o Font.Black
+    \li Font.Light
+    \li Font.Normal - the default
+    \li Font.DemiBold
+    \li Font.Bold
+    \li Font.Black
     \endlist
 
     \qml
@@ -1302,11 +1344,11 @@ QQuickText::~QQuickText()
     Sets the capitalization for the text.
 
     \list
-    \o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
-    \o Font.AllUppercase - This alters the text to be rendered in all uppercase type.
-    \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
-    \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
-    \o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
+    \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
+    \li Font.AllUppercase - This alters the text to be rendered in all uppercase type.
+    \li Font.AllLowercase - This alters the text to be rendered in all lowercase type.
+    \li Font.SmallCaps - This alters the text to be rendered in small-caps type.
+    \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
     \endlist
 
     \qml
@@ -1463,10 +1505,10 @@ void QQuickText::setLinkColor(const QColor &color)
 
     Supported text styles are:
     \list
-    \o Text.Normal - the default
-    \o Text.Outline
-    \o Text.Raised
-    \o Text.Sunken
+    \li Text.Normal - the default
+    \li Text.Outline
+    \li Text.Raised
+    \li Text.Sunken
     \endlist
 
     \qml
@@ -1660,10 +1702,10 @@ void QQuickText::setVAlign(VAlignment align)
     wrap if an explicit width has been set.  wrapMode can be one of:
 
     \list
-    \o Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l contentWidth will exceed a set width.
-    \o Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l contentWidth will exceed a set width.
-    \o Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
-    \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.
+    \li Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l contentWidth will exceed a set width.
+    \li Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l contentWidth will exceed a set width.
+    \li Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
+    \li 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.
     \endlist
 */
 QQuickText::WrapMode QQuickText::wrapMode() const
@@ -1762,10 +1804,10 @@ void QQuickText::resetMaximumLineCount()
     Supported text formats are:
 
     \list
-    \o Text.AutoText (default)
-    \o Text.PlainText
-    \o Text.StyledText
-    \o Text.RichText
+    \li Text.AutoText (default)
+    \li Text.PlainText
+    \li Text.StyledText
+    \li Text.RichText
     \endlist
 
     If the text format is \c Text.AutoText the text element
@@ -1799,7 +1841,7 @@ void QQuickText::resetMaximumLineCount()
 
     \table
     \row
-    \o
+    \li
     \qml
 Column {
     Text {
@@ -1818,7 +1860,7 @@ Column {
     }
 }
     \endqml
-    \o \image declarative-textformat.png
+    \li \image declarative-textformat.png
     \endtable
 */
 QQuickText::TextFormat QQuickText::textFormat() const
@@ -1862,10 +1904,10 @@ void QQuickText::setTextFormat(TextFormat format)
 
     Eliding can be:
     \list
-    \o Text.ElideNone  - the default
-    \o Text.ElideLeft
-    \o Text.ElideMiddle
-    \o Text.ElideRight
+    \li Text.ElideNone  - the default
+    \li Text.ElideLeft
+    \li Text.ElideMiddle
+    \li Text.ElideRight
     \endlist
 
     If this property is set to Text.ElideRight, it can be used with \l {wrapMode}{wrapped}
@@ -1907,14 +1949,14 @@ void QQuickText::setElideMode(QQuickText::TextElideMode mode)
     URL meaning any portion of the path after the last '/' will be ignored.
 
     \table
-    \header \o Base URL \o Relative URL \o Resolved URL
-    \row \o http://qt-project.org/ \o images/logo.png \o http://qt-project.org/images/logo.png
-    \row \o http://qt-project.org/index.html \o images/logo.png \o http://qt-project.org/images/logo.png
-    \row \o http://qt-project.org/content \o images/logo.png \o http://qt-project.org/content/images/logo.png
-    \row \o http://qt-project.org/content/ \o images/logo.png \o http://qt-project.org/content/images/logo.png
-    \row \o http://qt-project.org/content/index.html \o images/logo.png \o http://qt-project.org/content/images/logo.png
-    \row \o http://qt-project.org/content/index.html \o ../images/logo.png \o http://qt-project.org/images/logo.png
-    \row \o http://qt-project.org/content/index.html \o /images/logo.png \o http://qt-project.org/images/logo.png
+    \header \li Base URL \li Relative URL \li Resolved URL
+    \row \li http://qt-project.org/ \li images/logo.png \li http://qt-project.org/images/logo.png
+    \row \li http://qt-project.org/index.html \li images/logo.png \li http://qt-project.org/images/logo.png
+    \row \li http://qt-project.org/content \li images/logo.png \li http://qt-project.org/content/images/logo.png
+    \row \li http://qt-project.org/content/ \li images/logo.png \li http://qt-project.org/content/images/logo.png
+    \row \li http://qt-project.org/content/index.html \li images/logo.png \li http://qt-project.org/content/images/logo.png
+    \row \li http://qt-project.org/content/index.html \li ../images/logo.png \li http://qt-project.org/images/logo.png
+    \row \li http://qt-project.org/content/index.html \li /images/logo.png \li http://qt-project.org/images/logo.png
     \endtable
 
     By default is the url of the Text element.
@@ -1924,7 +1966,7 @@ QUrl QQuickText::baseUrl() const
 {
     Q_D(const QQuickText);
     if (d->baseUrl.isEmpty()) {
-        if (QDeclarativeContext *context = qmlContext(this))
+        if (QQmlContext *context = qmlContext(this))
             const_cast<QQuickTextPrivate *>(d)->baseUrl = context->baseUrl();
     }
     return d->baseUrl;
@@ -1952,7 +1994,7 @@ void QQuickText::setBaseUrl(const QUrl &url)
 
 void QQuickText::resetBaseUrl()
 {
-    if (QDeclarativeContext *context = qmlContext(this))
+    if (QQmlContext *context = qmlContext(this))
         setBaseUrl(context->baseUrl());
     else
         setBaseUrl(QUrl());
@@ -1969,7 +2011,20 @@ QRectF QQuickText::boundingRect() const
 
     // Could include font max left/right bearings to either side of rectangle.
 
-    int h = height();
+    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;
@@ -2088,13 +2143,23 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
         d->ensureDoc();
         node->addTextDocument(bounds.topLeft(), d->extra->doc, color, d->style, styleColor, linkColor);
     } else if (d->elideMode == QQuickText::ElideNone || bounds.width() > 0.) {
-        node->addTextLayout(QPoint(0, bounds.y()), &d->layout, color, d->style, styleColor, linkColor);
+        int unelidedLineCount = d->lineCount;
+        if (d->elideLayout)
+            unelidedLineCount -= 1;
+        if (unelidedLineCount > 0) {
+            node->addTextLayout(
+                        QPoint(0, bounds.y()),
+                        &d->layout,
+                        d->color, d->style, d->styleColor, d->linkColor,
+                        QColor(), QColor(), -1, -1,
+                        0, unelidedLineCount);
+        }
         if (d->elideLayout)
             node->addTextLayout(QPoint(0, bounds.y()), d->elideLayout, color, d->style, styleColor, linkColor);
     }
 
-    foreach (QDeclarativeStyledTextImgTag *img, d->visibleImgTags) {
-        QDeclarativePixmap *pix = img->pix;
+    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());
     }
@@ -2104,10 +2169,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
 void QQuickText::updatePolish()
 {
     Q_D(QQuickText);
-    if (d->updateLayoutOnPolish)
-        d->updateLayout();
-    else
-        d->updateSize();
+    d->updateSize();
 }
 
 /*!
@@ -2168,9 +2230,9 @@ void QQuickText::setLineHeight(qreal lineHeight)
     The possible values are:
 
     \list
-    \o Text.ProportionalHeight (default) - this sets the spacing proportional to the
+    \li Text.ProportionalHeight (default) - this sets the spacing proportional to the
        line (as a multiplier). For example, set to 2 for double spacing.
-    \o Text.FixedHeight - this sets the line height to a fixed line height (in pixels).
+    \li Text.FixedHeight - this sets the line height to a fixed line height (in pixels).
     \endlist
 */
 QQuickText::LineHeightMode QQuickText::lineHeightMode() const
@@ -2198,13 +2260,13 @@ void QQuickText::setLineHeightMode(LineHeightMode mode)
     The possible values are:
 
     \list
-    \o Text.FixedSize (default) - The size specified by \l font.pixelSize
+    \li Text.FixedSize (default) - The size specified by \l font.pixelSize
     or \l font.pointSize is used.
-    \o Text.HorizontalFit - The largest size up to the size specified that fits
+    \li Text.HorizontalFit - The largest size up to the size specified that fits
     within the width of the item without wrapping is used.
-    \o Text.VerticalFit - The largest size up to the size specified that fits
+    \li Text.VerticalFit - The largest size up to the size specified that fits
     the height of the item is used.
-    \o Text.Fit - The largest size up to the size specified the fits within the
+    \li Text.Fit - The largest size up to the size specified the fits within the
     width and height of the item is used.
     \endlist
 
@@ -2318,9 +2380,6 @@ void QQuickText::componentComplete()
     QQuickItem::componentComplete();
     if (d->updateOnComponentComplete)
         d->updateLayout();
-
-    // Enable accessibility for text items.
-    d->setAccessibleFlagAndListener();
 }
 
 
@@ -2347,8 +2406,8 @@ QString QQuickTextPrivate::anchorAt(const QPointF &mousePos)
 
 bool QQuickTextPrivate::isLinkActivatedConnected()
 {
-    static int idx = this->signalIndex("linkActivated(QString)");
-    return this->isSignalConnected(idx);
+    Q_Q(QQuickText);
+    IS_SIGNAL_CONNECTED(q, "linkActivated(QString)");
 }
 
 /*!  \internal */