Skip to content

Commit

Permalink
Fix multi-length string substitution.
Browse files Browse the repository at this point in the history
Multi-length string eliding was provided by QFontMetrics::elidedText()
which is no longer used for layouts.  So we instead have to do the
string substitution ourselves if the text doesn't fit before finally
eliding.

Change-Id: Iab2e54b332390290d656299a5be148f39f78df9d
Reviewed-by: Martin Jones <martin.jones@nokia.com>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Feb 16, 2012
1 parent 990a95f commit 7127120
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 7 deletions.
33 changes: 26 additions & 7 deletions src/quick/items/qquicktext.cpp
Expand Up @@ -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),
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand All @@ -674,7 +675,9 @@ QRect QQuickTextPrivate::setupTextLayout()

naturalWidth = 0;

do {
int eos = multilengthEos;

for (;;) {
if (!once) {
if (pixelSize)
scaledFont.setPixelSize(scaledFontSize);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -826,7 +839,13 @@ QRect QQuickTextPrivate::setupTextLayout()
break;
}
}
} while (horizontalFit || verticalFit);

if (!horizontalFit && !verticalFit)
break;
}

if (eos != multilengthEos)
truncated = true;

if (elide) {
if (!elideLayout)
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/quick/items/qquicktext_p_p.h
Expand Up @@ -104,6 +104,7 @@ class Q_AUTOTEST_EXPORT QQuickTextPrivate : public QQuickImplicitSizeItemPrivate
int maximumLineCount;
int maximumLineCountValid;
QQuickText::FontSizeMode fontSizeMode;
int multilengthEos;
int minimumPixelSize;
int minimumPointSize;
QPointF elidePos;
Expand Down
14 changes: 14 additions & 0 deletions 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"
}
}
16 changes: 16 additions & 0 deletions 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
}
}
66 changes: 66 additions & 0 deletions tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
Expand Up @@ -120,6 +120,8 @@ private slots:
void fontSizeMode();
void fontSizeModeMultiline_data();
void fontSizeModeMultiline();
void multilengthStrings_data();
void multilengthStrings();

private:
QStringList standard;
Expand Down Expand Up @@ -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"

0 comments on commit 7127120

Please sign in to comment.