diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 9f22dfdd08..d7303352c5 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -421,6 +421,10 @@ void QQuickTextPrivate::updateSize() //setup instance of QTextLayout for all cases other than richtext if (!richText) { QRectF textRect = setupTextLayout(&naturalWidth); + + 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(); @@ -443,7 +447,13 @@ 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 @@ -468,8 +478,6 @@ void QQuickTextPrivate::updateSize() qreal iWidth = -1; if (!q->widthValid()) iWidth = size.width(); - else if (requireImplicitWidth) - iWidth = naturalWidth; if (iWidth > -1) q->setImplicitSize(iWidth, size.height()); internalWidthUpdate = false; @@ -697,6 +705,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) layout.endLayout(); *naturalWidth = layout.maximumWidth(); layout.clearLayout(); + + bool wasInLayout = internalWidthUpdate; + internalWidthUpdate = true; + q->setImplicitWidth(*naturalWidth); + internalWidthUpdate = wasInLayout; } QFontMetrics fm(font); @@ -704,7 +717,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) return QRect(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(); @@ -735,6 +748,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) QTextLine line; int visibleCount = 0; bool elide; + bool widthChanged; qreal height = 0; QString elideText; bool once = true; @@ -755,13 +769,14 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) scaledFont.setPointSize(scaledFontSize); layout.setFont(scaledFont); } - layout.beginLayout(); + layout.beginLayout(); bool wrapped = false; bool truncateHeight = false; truncated = false; elide = false; + widthChanged = false; int characterCount = 0; int unwrappedLineCount = 1; int maxLineCount = maximumLineCount(); @@ -864,7 +879,6 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) br = br.united(line.naturalTextRect()); line = nextLine; } - layout.endLayout(); br.moveTop(0); @@ -886,8 +900,21 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) if (!line.isValid()) break; } + *naturalWidth = qMax(*naturalWidth, widthLayout.maximumWidth()); } + + bool wasInLayout = internalWidthUpdate; + internalWidthUpdate = true; + q->setImplicitWidth(*naturalWidth); + internalWidthUpdate = wasInLayout; + + const qreal oldWidth = lineWidth; + lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX; + if (lineWidth != oldWidth && (singlelineElide || multilineElide || canWrap || horizontalFit)) { + widthChanged = true; + continue; + } } // If the next needs to be elided and there's an abbreviated string available @@ -911,32 +938,36 @@ 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) diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 79df5abd11..4fa5233b9a 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1143,7 +1143,8 @@ void QQuickTextEdit::setInputMethodHints(Qt::InputMethodHints hints) void QQuickTextEdit::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { - if (newGeometry.width() != oldGeometry.width()) + Q_D(QQuickTextEdit); + if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap && !d->inLayout) updateSize(); QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry); } @@ -1857,6 +1858,13 @@ void QQuickTextEdit::updateSize() if (d->requireImplicitWidth) { d->document->setTextWidth(-1); naturalWidth = d->document->idealWidth(); + + const bool wasInLayout = d->inLayout; + d->inLayout = true; + setImplicitWidth(naturalWidth); + d->inLayout = wasInLayout; + if (d->inLayout) // probably the result of a binding loop, but by letting it + return; // get this far we'll get a warning to that effect. } if (d->document->textWidth() != width()) d->document->setTextWidth(width()); @@ -1888,11 +1896,11 @@ void QQuickTextEdit::updateSize() d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug) // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed. qreal iWidth = -1; - if (!widthValid()) + if (!widthValid() && !d->requireImplicitWidth) iWidth = newWidth; - else if (d->requireImplicitWidth) - iWidth = naturalWidth; + qreal newHeight = d->document->isEmpty() ? fm.height() : d->document->size().height(); + if (iWidth > -1) setImplicitSize(iWidth, newHeight); else diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index 055b5c7929..f0a35d5266 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -78,7 +78,7 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate , documentDirty(true), dirty(false), richText(false), cursorVisible(false) , focusOnPress(true), persistentSelection(false), requireImplicitWidth(false) , selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true) - , rightToLeftText(false), textCached(false) + , rightToLeftText(false), textCached(false), inLayout(false) { } @@ -144,6 +144,7 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate bool hAlignImplicit:1; bool rightToLeftText:1; bool textCached:1; + bool inLayout:1; }; QT_END_NAMESPACE diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index c9b2e7b41e..7d7fe851b3 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1604,9 +1604,11 @@ void QQuickTextInput::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickTextInput); - if (newGeometry.width() != oldGeometry.width()) - d->updateLayout(); - updateCursorRectangle(); + if (!d->inLayout) { + if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap) + d->updateLayout(); + updateCursorRectangle(); + } QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry); } @@ -2699,6 +2701,38 @@ void QQuickTextInputPrivate::updateDisplayText(bool forceUpdate) } } +qreal QQuickTextInputPrivate::getImplicitWidth() const +{ + Q_Q(const QQuickTextInput); + if (!requireImplicitWidth) { + QQuickTextInputPrivate *d = const_cast(this); + d->requireImplicitWidth = true; + + if (q->isComponentComplete()) { + // One time cost, only incurred if implicitWidth is first requested after + // componentComplete. + QTextLayout layout(m_text); + + QTextOption option = m_textLayout.textOption(); + option.setTextDirection(m_layoutDirection); + option.setFlags(QTextOption::IncludeTrailingSpaces); + option.setWrapMode(QTextOption::WrapMode(wrapMode)); + option.setAlignment(Qt::Alignment(q->effectiveHAlign())); + layout.setTextOption(option); + layout.setFont(font); + layout.setPreeditArea(m_textLayout.preeditAreaPosition(), m_textLayout.preeditAreaText()); + layout.beginLayout(); + + QTextLine line = layout.createLine(); + line.setLineWidth(INT_MAX); + d->implicitWidth = qCeil(line.naturalTextWidth()); + + layout.endLayout(); + } + } + return implicitWidth; +} + void QQuickTextInputPrivate::updateLayout() { Q_Q(QQuickTextInput); @@ -2718,6 +2752,15 @@ void QQuickTextInputPrivate::updateLayout() boundingRect = QRectF(); m_textLayout.beginLayout(); QTextLine line = m_textLayout.createLine(); + if (requireImplicitWidth) { + line.setLineWidth(INT_MAX); + const bool wasInLayout = inLayout; + inLayout = true; + q->setImplicitWidth(qCeil(line.naturalTextWidth())); + inLayout = wasInLayout; + if (inLayout) // probably the result of a binding loop, but by letting it + return; // get this far we'll get a warning to that effect. + } qreal lineWidth = q->widthValid() ? q->width() : INT_MAX; qreal height = 0; do { @@ -2737,7 +2780,11 @@ void QQuickTextInputPrivate::updateLayout() updateType = UpdatePaintNode; q->update(); - q->setImplicitSize(boundingRect.width(), boundingRect.height()); + + if (!requireImplicitWidth && !q->widthValid()) + q->setImplicitSize(qCeil(boundingRect.width()), qCeil(boundingRect.height())); + else + q->setImplicitHeight(qCeil(boundingRect.height())); if (previousRect != boundingRect) emit q->contentSizeChanged(); diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index bb00600661..165155acd0 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -125,6 +125,8 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr , m_acceptableInput(1) , m_blinkStatus(0) , m_passwordEchoEditing(false) + , inLayout(false) + , requireImplicitWidth(false) { } @@ -256,7 +258,8 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr bool m_acceptableInput : 1; bool m_blinkStatus : 1; bool m_passwordEchoEditing : 1; - + bool inLayout:1; + bool requireImplicitWidth:1; static inline QQuickTextInputPrivate *get(QQuickTextInput *t) { return t->d_func(); @@ -404,6 +407,8 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr void updateLayout(); + qreal getImplicitWidth() const; + private: void removeSelectedText(); void internalSetText(const QString &txt, int pos = -1, bool edited = true); diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 92e8528a0d..45d09bc866 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -107,6 +107,8 @@ private slots: void implicitSize_data(); void implicitSize(); void contentSize(); + void implicitSizeBinding_data(); + void implicitSizeBinding(); void lineLaidOut(); @@ -1548,29 +1550,36 @@ void tst_qquicktext::implicitSize_data() QTest::addColumn("width"); QTest::addColumn("wrap"); QTest::addColumn("elide"); - QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone"; - QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" <<" 50" << "Text.NoWrap" << "Text.ElideNone"; - QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone"; - QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight"; - QTest::newRow("plain, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideRight"; - QTest::newRow("richtext, 0 width") << "The quick red fox jumped over the lazy brown dog" <<" 0" << "Text.NoWrap" << "Text.ElideNone"; - QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone"; - QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone"; - QTest::newRow("plain_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone"; - QTest::newRow("plain_wrap, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideRight"; - QTest::newRow("plain_wrap, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideRight"; - QTest::newRow("richtext_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone"; + QTest::addColumn("format"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText"; + QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText"; + QTest::newRow("styledtext") << "The quick red fox jumped over the lazy brown dog" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText"; + QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText"; + QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight" << "Text.PlainText"; + QTest::newRow("plain, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideRight" << "Text.PlainText"; + QTest::newRow("richtext, 0 width") << "The quick red fox jumped over the lazy brown dog" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText"; + QTest::newRow("styledtext, 0 width") << "The quick red fox jumped over the lazy brown dog" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.PlainText"; + QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText"; + QTest::newRow("styledtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.StyledText"; + QTest::newRow("plain_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.PlainText"; + QTest::newRow("plain_wrap, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideRight" << "Text.PlainText"; + QTest::newRow("plain_wrap, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideRight" << "Text.PlainText"; + QTest::newRow("richtext_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText"; + QTest::newRow("styledtext_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.StyledText"; } void tst_qquicktext::implicitSize() { QFETCH(QString, text); QFETCH(QString, width); + QFETCH(QString, format); QFETCH(QString, wrap); QFETCH(QString, elide); QString componentStr = "import QtQuick 2.0\nText { " "text: \"" + text + "\"; " "width: " + width + "; " + "textFormat: " + format + "; " "wrapMode: " + wrap + "; " "elide: " + elide + "; " "maximumLineCount: 1 }"; @@ -1631,6 +1640,35 @@ void tst_qquicktext::contentSize() QCOMPARE(spy.count(), ++spyCount); } +void tst_qquicktext::implicitSizeBinding_data() +{ + implicitSize_data(); +} + +void tst_qquicktext::implicitSizeBinding() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QFETCH(QString, format); + QString componentStr = "import QtQuick 2.0\nText { text: \"" + text + "\"; width: implicitWidth; height: implicitHeight; wrapMode: " + wrap + "; textFormat: " + format + " }"; + + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QScopedPointer object(textComponent.create()); + QQuickText *textObject = qobject_cast(object.data()); + + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); + + textObject->resetWidth(); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); + + textObject->resetHeight(); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); +} + void tst_qquicktext::lineLaidOut() { QQuickView *canvas = createView(testFile("lineLayout.qml")); diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 46a4ea46dd..83e7e78866 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -152,6 +152,8 @@ private slots: void implicitSize_data(); void implicitSize(); void contentSize(); + void implicitSizeBinding_data(); + void implicitSizeBinding(); void preeditCursorRectangle(); void inputMethodComposing(); @@ -2512,17 +2514,19 @@ void tst_qquicktextedit::implicitSize_data() { QTest::addColumn("text"); QTest::addColumn("wrap"); - QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; - QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; - QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; - QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; + QTest::addColumn("format"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap" << "TextEdit.PlainText"; + QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap" << "TextEdit.RichText"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap" << "TextEdit.PlainText"; + QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap" << "TextEdit.RichText"; } void tst_qquicktextedit::implicitSize() { QFETCH(QString, text); QFETCH(QString, wrap); - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; + QFETCH(QString, format); + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + "; textFormat: " + format + " }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickTextEdit *textObject = qobject_cast(textComponent.create()); @@ -2563,6 +2567,34 @@ void tst_qquicktextedit::contentSize() QCOMPARE(spy.count(), 3); } +void tst_qquicktextedit::implicitSizeBinding_data() +{ + implicitSize_data(); +} + +void tst_qquicktextedit::implicitSizeBinding() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QFETCH(QString, format); + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: implicitWidth; height: implicitHeight; wrapMode: " + wrap + "; textFormat: " + format + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QScopedPointer object(textComponent.create()); + QQuickTextEdit *textObject = qobject_cast(object.data()); + + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); + + textObject->resetWidth(); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); + + textObject->resetHeight(); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); +} + void tst_qquicktextedit::preeditCursorRectangle() { QString preeditText = "super"; diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index e3a9bfcea1..8467a171a6 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -192,6 +192,11 @@ private slots: void QTBUG_19956_data(); void QTBUG_19956_regexp(); + void implicitSize_data(); + void implicitSize(); + void implicitSizeBinding_data(); + void implicitSizeBinding(); + void negativeDimensions(); private: @@ -4940,6 +4945,58 @@ void tst_qquicktextinput::QTBUG_19956_regexp() QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); } +void tst_qquicktextinput::implicitSize_data() +{ + QTest::addColumn("text"); + QTest::addColumn("wrap"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextInput.NoWrap"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextInput.Wrap"; +} + +void tst_qquicktextinput::implicitSize() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickTextInput *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject->width() < textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + + textObject->resetWidth(); + QVERIFY(textObject->width() == textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); +} + +void tst_qquicktextinput::implicitSizeBinding_data() +{ + implicitSize_data(); +} + +void tst_qquicktextinput::implicitSizeBinding() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + text + "\"; width: implicitWidth; height: implicitHeight; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QScopedPointer object(textComponent.create()); + QQuickTextInput *textObject = qobject_cast(object.data()); + + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); + + textObject->resetWidth(); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); + + textObject->resetHeight(); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); +} + void tst_qquicktextinput::negativeDimensions() {