aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-12-23 16:04:44 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-04 05:43:14 +0100
commit8bd497a614be0c469d9729861b4815aeb83d2597 (patch)
tree14fa6b04094d16265b38482d007118c95f119ef2
parentbe72fb26c2405c84878fd974c52f0950b4ec3478 (diff)
Fix crash in TextInput.
Ensure the text is laid out before calling componentComplete() on QImplicitSizeItem, as that can potentially evaluate bindings which would then access the uninitialized layout. Change-Id: I5152c1494c54209dae61c13b2f45d343fb76bf9e Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
-rw-r--r--src/quick/items/qquicktextinput.cpp16
-rw-r--r--tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml19
-rw-r--r--tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp15
3 files changed, 43 insertions, 7 deletions
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 2d5f5af49d..b4f31e37ef 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1412,13 +1412,14 @@ void QQuickTextInputPrivate::updateHorizontalScroll()
Q_Q(QQuickTextInput);
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + m_preeditCursor);
const int preeditLength = m_textLayout.preeditAreaText().length();
- const int width = q->width();
+ const int width = qMax(0, qFloor(q->width()));
int widthUsed = currentLine.isValid() ? qRound(currentLine.naturalTextWidth()) : 0;
int previousScroll = hscroll;
if (!autoScroll || widthUsed <= width || m_echoMode == QQuickTextInput::NoEcho) {
hscroll = 0;
} else {
+ Q_ASSERT(currentLine.isValid());
int cix = qRound(currentLine.cursorToX(m_cursor + preeditLength));
if (cix - hscroll >= width) {
// text doesn't fit, cursor is to the right of br (scroll right)
@@ -1447,7 +1448,7 @@ void QQuickTextInputPrivate::updateVerticalScroll()
{
Q_Q(QQuickTextInput);
const int preeditLength = m_textLayout.preeditAreaText().length();
- const int height = q->height();
+ const int height = qMax(0, qFloor(q->height()));
int heightUsed = boundingRect.height();
int previousScroll = vscroll;
@@ -1466,7 +1467,8 @@ void QQuickTextInputPrivate::updateVerticalScroll()
break;
}
} else {
- QRectF r = m_textLayout.lineForTextPosition(m_cursor + preeditLength).rect();
+ QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + preeditLength);
+ QRectF r = currentLine.isValid() ? currentLine.rect() : QRectF();
int top = qFloor(r.top());
int bottom = qCeil(r.bottom());
@@ -1484,10 +1486,10 @@ void QQuickTextInputPrivate::updateVerticalScroll()
if (preeditLength > 0) {
// check to ensure long pre-edit text doesn't push the cursor
// off the top
- top = qRound(m_textLayout.lineForTextPosition(
- m_cursor + qMax(0, m_preeditCursor - 1)).rect().top());
- if (top < vscroll)
- vscroll = top;
+ currentLine = m_textLayout.lineForTextPosition(m_cursor + qMax(0, m_preeditCursor - 1));
+ top = currentLine.isValid() ? qRound(currentLine.rect().top()) : 0;
+ if (top < vscroll)
+ vscroll = top;
}
}
if (previousScroll != vscroll)
diff --git a/tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml b/tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml
new file mode 100644
index 0000000000..7a58c85b1d
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+Item {
+ TextInput {
+ objectName: "input"
+
+ focus: true
+ width: -1
+ height: -1
+ text: "sushi"
+
+ anchors {
+ left: parent.left;
+ leftMargin: 5
+ top: parent.top
+ topMargin: font.pixelSize
+ }
+ }
+}
diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
index 3319936616..0286cea343 100644
--- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
@@ -176,6 +176,8 @@ private slots:
void QTBUG_19956_data();
void QTBUG_19956_regexp();
+ void negativeDimensions();
+
private:
void simulateKey(QQuickView *, int key);
@@ -3390,6 +3392,19 @@ void tst_qquicktextinput::QTBUG_19956_regexp()
QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
}
+
+void tst_qquicktextinput::negativeDimensions()
+{
+ // Verify this doesn't assert during initialization.
+ QDeclarativeComponent component(&engine, testFileUrl("negativeDimensions.qml"));
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o);
+ QQuickTextInput *input = o->findChild<QQuickTextInput *>("input");
+ QVERIFY(input);
+ QCOMPARE(input->width(), qreal(-1));
+ QCOMPARE(input->height(), qreal(-1));
+}
+
QTEST_MAIN(tst_qquicktextinput)
#include "tst_qquicktextinput.moc"