aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquicktext.cpp47
-rw-r--r--src/quick/items/qquicktext_p_p.h1
-rw-r--r--tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml27
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp18
4 files changed, 76 insertions, 17 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 9eaf9f8d6d..dd66930ef7 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -88,6 +88,7 @@ QQuickTextPrivate::QQuickTextPrivate()
, truncated(false), hAlignImplicit(true), rightToLeftText(false)
, layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
, polishSize(false)
+ , updateSizeRecursionGuard(false)
{
implicitAntialiasing = true;
}
@@ -442,6 +443,7 @@ void QQuickTextPrivate::updateSize()
//### need to confirm cost of always setting these for richText
internalWidthUpdate = true;
+ qreal oldWidth = q->width();
qreal iWidth = -1;
if (!q->widthValid())
iWidth = size.width();
@@ -449,24 +451,35 @@ void QQuickTextPrivate::updateSize()
q->setImplicitSize(iWidth + hPadding, size.height() + vPadding);
internalWidthUpdate = false;
- if (iWidth == -1)
- q->setImplicitHeight(size.height() + vPadding);
-
- QTextBlock firstBlock = extra->doc->firstBlock();
- while (firstBlock.layout()->lineCount() == 0)
- firstBlock = firstBlock.next();
-
- QTextBlock lastBlock = extra->doc->lastBlock();
- while (lastBlock.layout()->lineCount() == 0)
- lastBlock = lastBlock.previous();
-
- if (firstBlock.lineCount() > 0 && lastBlock.lineCount() > 0) {
- QTextLine firstLine = firstBlock.layout()->lineAt(0);
- QTextLine lastLine = lastBlock.layout()->lineAt(lastBlock.layout()->lineCount() - 1);
- advance = QSizeF(lastLine.horizontalAdvance(),
- (lastLine.y() + lastBlock.layout()->position().y()) - (firstLine.y() + firstBlock.layout()->position().y()));
+ // If the implicit width update caused a recursive change of the width,
+ // we will have skipped integral parts of the layout due to the
+ // internalWidthUpdate recursion guard. To make sure everything is up
+ // to date, we need to run a second pass over the layout when updateSize()
+ // is done.
+ if (!qFuzzyCompare(q->width(), oldWidth) && !updateSizeRecursionGuard) {
+ updateSizeRecursionGuard = true;
+ updateSize();
+ updateSizeRecursionGuard = false;
} else {
- advance = QSizeF();
+ if (iWidth == -1)
+ q->setImplicitHeight(size.height() + vPadding);
+
+ QTextBlock firstBlock = extra->doc->firstBlock();
+ while (firstBlock.layout()->lineCount() == 0)
+ firstBlock = firstBlock.next();
+
+ QTextBlock lastBlock = extra->doc->lastBlock();
+ while (lastBlock.layout()->lineCount() == 0)
+ lastBlock = lastBlock.previous();
+
+ if (firstBlock.lineCount() > 0 && lastBlock.lineCount() > 0) {
+ QTextLine firstLine = firstBlock.layout()->lineAt(0);
+ QTextLine lastLine = lastBlock.layout()->lineAt(lastBlock.layout()->lineCount() - 1);
+ advance = QSizeF(lastLine.horizontalAdvance(),
+ (lastLine.y() + lastBlock.layout()->position().y()) - (firstLine.y() + firstBlock.layout()->position().y()));
+ } else {
+ advance = QSizeF();
+ }
}
}
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index b0b1492d57..fd26d966c8 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -174,6 +174,7 @@ public:
bool needToUpdateLayout:1;
bool formatModifiesFontSize:1;
bool polishSize:1; // Workaround for problem with polish called after updateSize (QTBUG-42636)
+ bool updateSizeRecursionGuard:1;
static const QChar elideChar;
diff --git a/tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml b/tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml
new file mode 100644
index 0000000000..fb8626a75a
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/implicitSizeChangeRewrap.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+
+Item
+{
+ id : _rootItem
+ width : 200
+ height : 1000
+ ColumnLayout
+ {
+ id : _textContainer
+ anchors.centerIn: parent
+ Layout.maximumWidth: (_rootItem.width - 40) // to have some space left / right
+ Text
+ {
+ id : text
+ objectName: "text"
+ font.italic: true
+ textFormat: Text.RichText
+ horizontalAlignment : Text.AlignHCenter
+ verticalAlignment : Text.AlignVCenter
+ wrapMode: Text.Wrap
+ Layout.maximumWidth: (_rootItem.width - 60)
+ Component.onCompleted: text.text = "This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap This is a too long text for the interface with a stupid path also too long -> /home/long/long/long/to/force/it/to/need/to/wrap"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 89d2590c03..5f346a6e0a 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -105,6 +105,7 @@ private slots:
void implicitSize_data();
void implicitSize();
+ void implicitSizeChangeRewrap();
void dependentImplicitSizes();
void contentSize();
void implicitSizeBinding_data();
@@ -4369,6 +4370,23 @@ void tst_qquicktext::fontInfo()
QVERIFY(copy->font().pixelSize() < 1000);
}
+void tst_qquicktext::implicitSizeChangeRewrap()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("implicitSizeChangeRewrap.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QObject *root = window->rootObject();
+
+ QQuickText *text = root->findChild<QQuickText *>("text");
+ QVERIFY(text != nullptr);
+
+ QVERIFY(text->contentWidth() < window->width());
+}
+
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"