Commit 336c338c authored by Andrew den Exter's avatar Andrew den Exter Committed by Qt by Nokia

Fix text wrapping and eliding with implicitWidth.

Update the implicitWidth of the item before continuing with the layout
rather than after it's completed this gives any bindings dependent on
the implicitWidth the opportunity to update the width before the layout
continues.

Task-number: QTBUG-22680
Task-number: QTBUG-24251
Change-Id: I61cd96ad9891b22d8b83937ad2c06719f88976b6
Reviewed-by: default avatarMartin Jones <martin.jones@nokia.com>
parent 793a01d2
...@@ -421,6 +421,10 @@ void QQuickTextPrivate::updateSize() ...@@ -421,6 +421,10 @@ void QQuickTextPrivate::updateSize()
//setup instance of QTextLayout for all cases other than richtext //setup instance of QTextLayout for all cases other than richtext
if (!richText) { if (!richText) {
QRectF textRect = setupTextLayout(&naturalWidth); 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; layedOutTextRect = textRect;
size = textRect.size(); size = textRect.size();
dy -= size.height(); dy -= size.height();
...@@ -443,7 +447,13 @@ void QQuickTextPrivate::updateSize() ...@@ -443,7 +447,13 @@ void QQuickTextPrivate::updateSize()
if (requireImplicitWidth && q->widthValid()) { if (requireImplicitWidth && q->widthValid()) {
extra->doc->setTextWidth(-1); extra->doc->setTextWidth(-1);
naturalWidth = extra->doc->idealWidth(); naturalWidth = extra->doc->idealWidth();
const bool wasInLayout = internalWidthUpdate;
internalWidthUpdate = true;
q->setImplicitWidth(naturalWidth);
internalWidthUpdate = wasInLayout;
} }
if (internalWidthUpdate)
return;
if (wrapMode != QQuickText::NoWrap && q->widthValid()) if (wrapMode != QQuickText::NoWrap && q->widthValid())
extra->doc->setTextWidth(q->width()); extra->doc->setTextWidth(q->width());
else else
...@@ -468,8 +478,6 @@ void QQuickTextPrivate::updateSize() ...@@ -468,8 +478,6 @@ void QQuickTextPrivate::updateSize()
qreal iWidth = -1; qreal iWidth = -1;
if (!q->widthValid()) if (!q->widthValid())
iWidth = size.width(); iWidth = size.width();
else if (requireImplicitWidth)
iWidth = naturalWidth;
if (iWidth > -1) if (iWidth > -1)
q->setImplicitSize(iWidth, size.height()); q->setImplicitSize(iWidth, size.height());
internalWidthUpdate = false; internalWidthUpdate = false;
...@@ -697,6 +705,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) ...@@ -697,6 +705,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
layout.endLayout(); layout.endLayout();
*naturalWidth = layout.maximumWidth(); *naturalWidth = layout.maximumWidth();
layout.clearLayout(); layout.clearLayout();
bool wasInLayout = internalWidthUpdate;
internalWidthUpdate = true;
q->setImplicitWidth(*naturalWidth);
internalWidthUpdate = wasInLayout;
} }
QFontMetrics fm(font); QFontMetrics fm(font);
...@@ -704,7 +717,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) ...@@ -704,7 +717,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
return QRect(0, 0, 0, height); 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 qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
const bool customLayout = isLineLaidOutConnected(); const bool customLayout = isLineLaidOutConnected();
...@@ -735,6 +748,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) ...@@ -735,6 +748,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
QTextLine line; QTextLine line;
int visibleCount = 0; int visibleCount = 0;
bool elide; bool elide;
bool widthChanged;
qreal height = 0; qreal height = 0;
QString elideText; QString elideText;
bool once = true; bool once = true;
...@@ -755,13 +769,14 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) ...@@ -755,13 +769,14 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
scaledFont.setPointSize(scaledFontSize); scaledFont.setPointSize(scaledFontSize);
layout.setFont(scaledFont); layout.setFont(scaledFont);
} }
layout.beginLayout();
layout.beginLayout();
bool wrapped = false; bool wrapped = false;
bool truncateHeight = false; bool truncateHeight = false;
truncated = false; truncated = false;
elide = false; elide = false;
widthChanged = false;
int characterCount = 0; int characterCount = 0;
int unwrappedLineCount = 1; int unwrappedLineCount = 1;
int maxLineCount = maximumLineCount(); int maxLineCount = maximumLineCount();
...@@ -864,7 +879,6 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) ...@@ -864,7 +879,6 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
br = br.united(line.naturalTextRect()); br = br.united(line.naturalTextRect());
line = nextLine; line = nextLine;
} }
layout.endLayout(); layout.endLayout();
br.moveTop(0); br.moveTop(0);
...@@ -886,8 +900,21 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) ...@@ -886,8 +900,21 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
if (!line.isValid()) if (!line.isValid())
break; break;
} }
*naturalWidth = qMax(*naturalWidth, widthLayout.maximumWidth()); *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 // If the next needs to be elided and there's an abbreviated string available
...@@ -911,32 +938,36 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) ...@@ -911,32 +938,36 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
if (horizontalFit) { if (horizontalFit) {
if (unelidedRect.width() > lineWidth || (!verticalFit && wrapped)) { if (unelidedRect.width() > lineWidth || (!verticalFit && wrapped)) {
largeFont = scaledFontSize - 1; largeFont = scaledFontSize - 1;
scaledFontSize = (smallFont + largeFont) / 2;
if (smallFont > largeFont) if (smallFont > largeFont)
break; break;
scaledFontSize = (smallFont + largeFont) / 2;
if (pixelSize)
scaledFont.setPixelSize(scaledFontSize);
else
scaledFont.setPointSize(scaledFontSize);
continue; continue;
} else if (!verticalFit) { } else if (!verticalFit) {
smallFont = scaledFontSize; smallFont = scaledFontSize;
scaledFontSize = (smallFont + largeFont + 1) / 2;
if (smallFont == largeFont) if (smallFont == largeFont)
break; break;
scaledFontSize = (smallFont + largeFont + 1) / 2;
} }
} }
if (verticalFit) { if (verticalFit) {
if (truncateHeight || unelidedRect.height() > maxHeight) { if (truncateHeight || unelidedRect.height() > maxHeight) {
largeFont = scaledFontSize - 1; largeFont = scaledFontSize - 1;
scaledFontSize = (smallFont + largeFont + 1) / 2;
if (smallFont > largeFont) if (smallFont > largeFont)
break; break;
scaledFontSize = (smallFont + largeFont) / 2;
} else { } else {
smallFont = scaledFontSize; smallFont = scaledFontSize;
scaledFontSize = (smallFont + largeFont + 1) / 2;
if (smallFont == largeFont) if (smallFont == largeFont)
break; break;
scaledFontSize = (smallFont + largeFont + 1) / 2;
} }
} }
} }
if (eos != multilengthEos) if (eos != multilengthEos)
......
...@@ -1143,7 +1143,8 @@ void QQuickTextEdit::setInputMethodHints(Qt::InputMethodHints hints) ...@@ -1143,7 +1143,8 @@ void QQuickTextEdit::setInputMethodHints(Qt::InputMethodHints hints)
void QQuickTextEdit::geometryChanged(const QRectF &newGeometry, void QQuickTextEdit::geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry) const QRectF &oldGeometry)
{ {
if (newGeometry.width() != oldGeometry.width()) Q_D(QQuickTextEdit);
if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap && !d->inLayout)
updateSize(); updateSize();
QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry); QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
} }
...@@ -1857,6 +1858,13 @@ void QQuickTextEdit::updateSize() ...@@ -1857,6 +1858,13 @@ void QQuickTextEdit::updateSize()
if (d->requireImplicitWidth) { if (d->requireImplicitWidth) {
d->document->setTextWidth(-1); d->document->setTextWidth(-1);
naturalWidth = d->document->idealWidth(); 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()) if (d->document->textWidth() != width())
d->document->setTextWidth(width()); d->document->setTextWidth(width());
...@@ -1888,11 +1896,11 @@ void QQuickTextEdit::updateSize() ...@@ -1888,11 +1896,11 @@ void QQuickTextEdit::updateSize()
d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug) 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. // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
qreal iWidth = -1; qreal iWidth = -1;
if (!widthValid()) if (!widthValid() && !d->requireImplicitWidth)
iWidth = newWidth; iWidth = newWidth;
else if (d->requireImplicitWidth)
iWidth = naturalWidth;
qreal newHeight = d->document->isEmpty() ? fm.height() : d->document->size().height(); qreal newHeight = d->document->isEmpty() ? fm.height() : d->document->size().height();
if (iWidth > -1) if (iWidth > -1)
setImplicitSize(iWidth, newHeight); setImplicitSize(iWidth, newHeight);
else else
......
...@@ -78,7 +78,7 @@ public: ...@@ -78,7 +78,7 @@ public:
, documentDirty(true), dirty(false), richText(false), cursorVisible(false) , documentDirty(true), dirty(false), richText(false), cursorVisible(false)
, focusOnPress(true), persistentSelection(false), requireImplicitWidth(false) , focusOnPress(true), persistentSelection(false), requireImplicitWidth(false)
, selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true) , selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true)
, rightToLeftText(false), textCached(false) , rightToLeftText(false), textCached(false), inLayout(false)
{ {
} }
...@@ -144,6 +144,7 @@ public: ...@@ -144,6 +144,7 @@ public:
bool hAlignImplicit:1; bool hAlignImplicit:1;
bool rightToLeftText:1; bool rightToLeftText:1;
bool textCached:1; bool textCached:1;
bool inLayout:1;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE
......
...@@ -1604,9 +1604,11 @@ void QQuickTextInput::geometryChanged(const QRectF &newGeometry, ...@@ -1604,9 +1604,11 @@ void QQuickTextInput::geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry) const QRectF &oldGeometry)
{ {
Q_D(QQuickTextInput); Q_D(QQuickTextInput);
if (newGeometry.width() != oldGeometry.width()) if (!d->inLayout) {
d->updateLayout(); if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap)
updateCursorRectangle(); d->updateLayout();
updateCursorRectangle();
}
QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry); QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
} }
...@@ -2699,6 +2701,38 @@ void QQuickTextInputPrivate::updateDisplayText(bool forceUpdate) ...@@ -2699,6 +2701,38 @@ void QQuickTextInputPrivate::updateDisplayText(bool forceUpdate)
} }
} }
qreal QQuickTextInputPrivate::getImplicitWidth() const
{
Q_Q(const QQuickTextInput);
if (!requireImplicitWidth) {
QQuickTextInputPrivate *d = const_cast<QQuickTextInputPrivate *>(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() void QQuickTextInputPrivate::updateLayout()
{ {
Q_Q(QQuickTextInput); Q_Q(QQuickTextInput);
...@@ -2718,6 +2752,15 @@ void QQuickTextInputPrivate::updateLayout() ...@@ -2718,6 +2752,15 @@ void QQuickTextInputPrivate::updateLayout()
boundingRect = QRectF(); boundingRect = QRectF();
m_textLayout.beginLayout(); m_textLayout.beginLayout();
QTextLine line = m_textLayout.createLine(); 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 lineWidth = q->widthValid() ? q->width() : INT_MAX;
qreal height = 0; qreal height = 0;
do { do {
...@@ -2737,7 +2780,11 @@ void QQuickTextInputPrivate::updateLayout() ...@@ -2737,7 +2780,11 @@ void QQuickTextInputPrivate::updateLayout()
updateType = UpdatePaintNode; updateType = UpdatePaintNode;
q->update(); 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) if (previousRect != boundingRect)
emit q->contentSizeChanged(); emit q->contentSizeChanged();
......
...@@ -125,6 +125,8 @@ public: ...@@ -125,6 +125,8 @@ public:
, m_acceptableInput(1) , m_acceptableInput(1)
, m_blinkStatus(0) , m_blinkStatus(0)
, m_passwordEchoEditing(false) , m_passwordEchoEditing(false)
, inLayout(false)
, requireImplicitWidth(false)
{ {
} }
...@@ -256,7 +258,8 @@ public: ...@@ -256,7 +258,8 @@ public:
bool m_acceptableInput : 1; bool m_acceptableInput : 1;
bool m_blinkStatus : 1; bool m_blinkStatus : 1;
bool m_passwordEchoEditing : 1; bool m_passwordEchoEditing : 1;
bool inLayout:1;
bool requireImplicitWidth:1;
static inline QQuickTextInputPrivate *get(QQuickTextInput *t) { static inline QQuickTextInputPrivate *get(QQuickTextInput *t) {
return t->d_func(); return t->d_func();
...@@ -404,6 +407,8 @@ public: ...@@ -404,6 +407,8 @@ public:
void updateLayout(); void updateLayout();
qreal getImplicitWidth() const;
private: private:
void removeSelectedText(); void removeSelectedText();
void internalSetText(const QString &txt, int pos = -1, bool edited = true); void internalSetText(const QString &txt, int pos = -1, bool edited = true);
......
...@@ -107,6 +107,8 @@ private slots: ...@@ -107,6 +107,8 @@ private slots:
void implicitSize_data(); void implicitSize_data();
void implicitSize(); void implicitSize();
void contentSize(); void contentSize();
void implicitSizeBinding_data();
void implicitSizeBinding();
void lineLaidOut(); void lineLaidOut();
...@@ -1548,29 +1550,36 @@ void tst_qquicktext::implicitSize_data() ...@@ -1548,29 +1550,36 @@ void tst_qquicktext::implicitSize_data()
QTest::addColumn<QString>("width"); QTest::addColumn<QString>("width");
QTest::addColumn<QString>("wrap"); QTest::addColumn<QString>("wrap");
QTest::addColumn<QString>("elide"); QTest::addColumn<QString>("elide");
QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone"; QTest::addColumn<QString>("format");
QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone"; QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText";
QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone"; QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText";
QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight"; QTest::newRow("styledtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText";
QTest::newRow("plain, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideRight"; QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText";
QTest::newRow("richtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone"; QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight" << "Text.PlainText";
QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone"; 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_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone"; QTest::newRow("richtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText";
QTest::newRow("plain_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone"; QTest::newRow("styledtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText";
QTest::newRow("plain_wrap, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideRight"; QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.PlainText";
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") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText";
QTest::newRow("richtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone"; QTest::newRow("styledtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "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") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText";
QTest::newRow("styledtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.StyledText";
} }
void tst_qquicktext::implicitSize() void tst_qquicktext::implicitSize()
{ {
QFETCH(QString, text); QFETCH(QString, text);
QFETCH(QString, width); QFETCH(QString, width);
QFETCH(QString, format);
QFETCH(QString, wrap); QFETCH(QString, wrap);
QFETCH(QString, elide); QFETCH(QString, elide);
QString componentStr = "import QtQuick 2.0\nText { " QString componentStr = "import QtQuick 2.0\nText { "
"text: \"" + text + "\"; " "text: \"" + text + "\"; "
"width: " + width + "; " "width: " + width + "; "
"textFormat: " + format + "; "
"wrapMode: " + wrap + "; " "wrapMode: " + wrap + "; "
"elide: " + elide + "; " "elide: " + elide + "; "
"maximumLineCount: 1 }"; "maximumLineCount: 1 }";
...@@ -1631,6 +1640,35 @@ void tst_qquicktext::contentSize() ...@@ -1631,6 +1640,35 @@ void tst_qquicktext::contentSize()
QCOMPARE(spy.count(), ++spyCount); 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<QObject> object(textComponent.create());
QQuickText *textObject = qobject_cast<QQuickText *>(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() void tst_qquicktext::lineLaidOut()
{ {
QQuickView *canvas = createView(testFile("lineLayout.qml")); QQuickView *canvas = createView(testFile("lineLayout.qml"));
......
...@@ -152,6 +152,8 @@ private slots: ...@@ -152,6 +152,8 @@ private slots:
void implicitSize_data(); void implicitSize_data();
void implicitSize(); void implicitSize();
void contentSize(); void contentSize();
void implicitSizeBinding_data();
void implicitSizeBinding();
void preeditCursorRectangle(); void preeditCursorRectangle();
void inputMethodComposing(); void inputMethodComposing();
...@@ -2512,17 +2514,19 @@ void tst_qquicktextedit::implicitSize_data() ...@@ -2512,17 +2514,19 @@ void tst_qquicktextedit::implicitSize_data()
{ {
QTest::addColumn<QString>("text"); QTest::addColumn<QString>("text");
QTest::addColumn<QString>("wrap"); QTest::addColumn<QString>("wrap");
QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; QTest::addColumn<QString>("format");
QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap"; QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap" << "TextEdit.PlainText";
QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap" << "TextEdit.RichText";
QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap"; QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap" << "TextEdit.PlainText";
QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap" << "TextEdit.RichText";
} }
void tst_qquicktextedit::implicitSize() void tst_qquicktextedit::implicitSize()
{ {
QFETCH(QString, text); QFETCH(QString, text);
QFETCH(QString, wrap); 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); QQmlComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create()); QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
...@@ -2563,6 +2567,34 @@ void tst_qquicktextedit::contentSize() ...@@ -2563,6 +2567,34 @@ void tst_qquicktextedit::contentSize()
QCOMPARE(spy.count(), 3); 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<QObject> object(textComponent.create());
QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit *>(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() void tst_qquicktextedit::preeditCursorRectangle()
{ {
QString preeditText = "super"; QString preeditText = "super";
......
...@@ -192,6 +192,11 @@ private slots: ...@@ -192,6 +192,11 @@ private slots:
void QTBUG_19956_data(); void QTBUG_19956_data();
void QTBUG_19956_regexp(); void QTBUG_19956_regexp();
void implicitSize_data();
void implicitSize();
void implicitSizeBinding_data();
void implicitSizeBinding();
void negativeDimensions(); void negativeDimensions();
private: private:
...@@ -4940,6 +4945,58 @@ void tst_qquicktextinput::QTBUG_19956_regexp() ...@@ -4940,6 +4945,58 @@ void tst_qquicktextinput::QTBUG_19956_regexp()
QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
} }
void tst_qquicktextinput::implicitSize_data()
{
QTest::addColumn<QString>("text");
QTest::addColumn<QString>("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<QQuickTextInput*>(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);