diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 31f557f610d07db8aab0235d8ae5233555db0b5b..241086cc83fceb1748e11172937aeff63646d195 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -75,8 +75,8 @@ QQuickTextPrivate::QQuickTextPrivate() vAlign(QQuickText::AlignTop), elideMode(QQuickText::ElideNone), format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap), lineHeight(1), lineHeightMode(QQuickText::ProportionalHeight), lineCount(1), maximumLineCount(INT_MAX), - maximumLineCountValid(false), fontSizeMode(QQuickText::FixedSize), minimumPixelSize(12), - minimumPointSize(12), updateOnComponentComplete(true), + maximumLineCountValid(false), fontSizeMode(QQuickText::FixedSize), multilengthEos(-1), + minimumPixelSize(12), minimumPointSize(12), updateOnComponentComplete(true), richText(false), styledText(false), singleline(false), internalWidthUpdate(false), requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false), layoutTextElided(false), textHasChanged(true), @@ -301,7 +301,8 @@ void QQuickTextPrivate::updateLayout() QDeclarativeStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid); } else { layout.clearAdditionalFormats(); - QString tmp = text; + multilengthEos = text.indexOf(QLatin1Char('\x9c')); + QString tmp = multilengthEos != -1 ? text.mid(0, multilengthEos) : text; tmp.replace(QLatin1Char('\n'), QChar::LineSeparator); layout.setText(tmp); } @@ -653,7 +654,7 @@ QRect QQuickTextPrivate::setupTextLayout() const bool verticalFit = fontSizeMode & QQuickText::VerticalFit && (q->heightValid() || (maximumLineCountValid && canWrap)); const bool pixelSize = font.pixelSize() != -1; - const QString layoutText = layout.text(); + QString layoutText = layout.text(); int largeFont = pixelSize ? font.pixelSize() : font.pointSize(); int smallFont = fontSizeMode != QQuickText::FixedSize @@ -674,7 +675,9 @@ QRect QQuickTextPrivate::setupTextLayout() naturalWidth = 0; - do { + int eos = multilengthEos; + + for (;;) { if (!once) { if (pixelSize) scaledFont.setPixelSize(scaledFontSize); @@ -796,6 +799,16 @@ QRect QQuickTextPrivate::setupTextLayout() } } + if (eos != -1 && elide) { + int start = eos + 1; + eos = text.indexOf(QLatin1Char('\x9c'), start); + layoutText = text.mid(start, eos != -1 ? eos - start : -1); + layoutText.replace(QLatin1Char('\n'), QChar::LineSeparator); + layout.setText(layoutText); + textHasChanged = true; + continue; + } + QRectF unelidedRect = br.united(line.naturalTextRect()); if (horizontalFit) { @@ -826,7 +839,13 @@ QRect QQuickTextPrivate::setupTextLayout() break; } } - } while (horizontalFit || verticalFit); + + if (!horizontalFit && !verticalFit) + break; + } + + if (eos != multilengthEos) + truncated = true; if (elide) { if (!elideLayout) @@ -1878,7 +1897,7 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo goto geomChangeDone; // Multiline eliding not affected if we're already at max line count and we get higher. } - if (d->updateOnComponentComplete) { + if (d->updateOnComponentComplete || d->textHasChanged) { // We need to re-elide d->updateLayout(); } else { diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h index 6fdde31a36957f5cdc1535ef3a689b54d78c1001..0a7fc743b5d03ca33d0f9950c20052c3c3df8c94 100644 --- a/src/quick/items/qquicktext_p_p.h +++ b/src/quick/items/qquicktext_p_p.h @@ -104,6 +104,7 @@ public: int maximumLineCount; int maximumLineCountValid; QQuickText::FontSizeMode fontSizeMode; + int multilengthEos; int minimumPixelSize; int minimumPointSize; QPointF elidePos; diff --git a/tests/auto/qtquick2/qquicktext/data/multilengthStrings.qml b/tests/auto/qtquick2/qquicktext/data/multilengthStrings.qml new file mode 100644 index 0000000000000000000000000000000000000000..d26576eacdf477ba60541ec067f07b185defe5c2 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/multilengthStrings.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + width: 300 + height: 200 + + Text { + id: myText + objectName: "myText" + width: 100 + font.pixelSize: 15 + font.family: "Helvetica" + } +} diff --git a/tests/auto/qtquick2/qquicktext/data/multilengthStringsWrapped.qml b/tests/auto/qtquick2/qquicktext/data/multilengthStringsWrapped.qml new file mode 100644 index 0000000000000000000000000000000000000000..0da9bc353a65857496b5bf3984400d105257aa59 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/multilengthStringsWrapped.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Item { + width: 300 + height: 200 + + Text { + id: myText + objectName: "myText" + width: 100 + height: 36 + font.pixelSize: 15 + font.family: "Helvetica" + wrapMode: Text.Wrap + } +} diff --git a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp index 4f1225e9377762f6e6c111577269093e44f5bb4f..cbe3d30cbb6ab7b8db6167a4c04e167d9836f3b2 100644 --- a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp @@ -120,6 +120,8 @@ private slots: void fontSizeMode(); void fontSizeModeMultiline_data(); void fontSizeModeMultiline(); + void multilengthStrings_data(); + void multilengthStrings(); private: QStringList standard; @@ -2362,6 +2364,70 @@ void tst_qquicktext::fontSizeModeMultiline() } } +void tst_qquicktext::multilengthStrings_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("No Wrap") << testFile("multilengthStrings.qml"); + QTest::newRow("Wrap") << testFile("multilengthStringsWrapped.qml"); +} + +void tst_qquicktext::multilengthStrings() +{ + QFETCH(QString, source); + + QScopedPointer<QQuickView> canvas(createView(source)); + canvas->show(); + + QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText"); + QVERIFY(myText != 0); + + const QString longText = "the quick brown fox jumped over the lazy dog"; + const QString mediumText = "the brown fox jumped over the dog"; + const QString shortText = "fox jumped dog"; + + myText->setText(longText); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + const qreal longWidth = myText->contentWidth(); + const qreal longHeight = myText->contentHeight(); + + myText->setText(mediumText); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + const qreal mediumWidth = myText->contentWidth(); + const qreal mediumHeight = myText->contentHeight(); + + myText->setText(shortText); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + const qreal shortWidth = myText->contentWidth(); + const qreal shortHeight = myText->contentHeight(); + + myText->setElideMode(QQuickText::ElideRight); + myText->setText(longText + QLatin1Char('\x9c') + mediumText + QLatin1Char('\x9c') + shortText); + + myText->setSize(QSizeF(longWidth, longHeight)); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + + QCOMPARE(myText->contentWidth(), longWidth); + QCOMPARE(myText->contentHeight(), longHeight); + QCOMPARE(myText->truncated(), false); + + myText->setSize(QSizeF(mediumWidth, mediumHeight)); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + + QCOMPARE(myText->contentWidth(), mediumWidth); + QCOMPARE(myText->contentHeight(), mediumHeight); +#ifdef Q_OS_MAC + QEXPECT_FAIL("Wrap", "QTBUG-24310", Continue); +#endif + QCOMPARE(myText->truncated(), true); + + myText->setSize(QSizeF(shortWidth, shortHeight)); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + + QCOMPARE(myText->contentWidth(), shortWidth); + QCOMPARE(myText->contentHeight(), shortHeight); + QCOMPARE(myText->truncated(), true); +} + QTEST_MAIN(tst_qquicktext) #include "tst_qquicktext.moc"