Fix view delegate parent binding regression.
authorMartin Jones <martin.jones@nokia.com>
Tue, 12 Jun 2012 01:54:40 +0000 (11:54 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 12 Jun 2012 13:40:13 +0000 (15:40 +0200)
762b4d90110465aeceb96f44cd06dcda229dfe89 introduced a regression by
setting the item parent after completion.  This was to avoid rendering
an incubated object before completion.  However this breaks bindings.

Restore setting the item parent before completion, and ensure items are
not rendered until completed.

Change-Id: Ifc9d0c34ee62e687889c32ffab7c091b4c8cc470
Reviewed-by: Bea Lam <bea.lam@nokia.com>
src/quick/items/qquickitem.cpp
src/quick/items/qquickitemview.cpp
tests/auto/quick/qquicklistview/data/parentBinding.qml [new file with mode: 0644]
tests/auto/quick/qquicklistview/tst_qquicklistview.cpp

index 4ec255b..e10572f 100644 (file)
@@ -3682,6 +3682,11 @@ void QQuickItem::componentComplete()
 
     if (d->extra.isAllocated() && d->extra->contents)
         d->extra->contents->complete();
+
+    if (d->canvas && d->dirtyAttributes) {
+        d->addToDirtyList();
+        QQuickCanvasPrivate::get(d->canvas)->dirtyItem(this);
+    }
 }
 
 QQuickStateGroup *QQuickItemPrivate::_states()
@@ -4336,7 +4341,7 @@ void QQuickItemPrivate::dirty(DirtyType type)
 
     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
         dirtyAttributes |= type;
-        if (canvas) {
+        if (canvas && componentComplete) {
             addToDirtyList();
             QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
         }
index e48db3d..26580e0 100644 (file)
@@ -2235,6 +2235,7 @@ void QQuickItemView::initItem(int index, QQuickItem *item)
     if (d->requestedIndex == index) {
         if (d->requestedAsync)
             QQuickItemPrivate::get(item)->setCulled(true);
+        item->setParentItem(contentItem());
         d->requestedItem = d->newViewItem(index, item);
     }
 }
diff --git a/tests/auto/quick/qquicklistview/data/parentBinding.qml b/tests/auto/quick/qquicklistview/data/parentBinding.qml
new file mode 100644 (file)
index 0000000..b563728
--- /dev/null
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+
+ListView {
+    width: 320; height: 480
+    model: ListModel {}
+    cacheBuffer: 300
+    delegate: Rectangle {
+        objectName: "wrapper"
+        width: parent.width
+        height: parent.parent.height/12
+        color: index % 2 ? "red" : "blue"
+    }
+    Component.onCompleted: {
+        for (var i = 0; i < 100; ++i)
+            model.append({"foo":"bar"+i})
+    }
+}
index b1ba5bb..4997e50 100644 (file)
@@ -209,6 +209,8 @@ private slots:
     void flickBeyondBounds();
     void destroyItemOnCreation();
 
+    void parentBinding();
+
 private:
     template <class T> void items(const QUrl &source, bool forceLayout);
     template <class T> void changed(const QUrl &source, bool forceLayout);
@@ -261,10 +263,18 @@ private:
     }
 #endif
 
+    static void errorMsgHandler(QtMsgType, const char *)
+    {
+        ++m_errorCount;
+    }
+
     QQuickView *m_view;
     QString testForView;
+    static int m_errorCount;
 };
 
+int tst_QQuickListView::m_errorCount = 0;
+
 class TestObject : public QObject
 {
     Q_OBJECT
@@ -6712,6 +6722,35 @@ void tst_QQuickListView::destroyItemOnCreation()
     delete canvas;
 }
 
+void tst_QQuickListView::parentBinding()
+{
+    QQuickView *canvas = createView();
+
+    m_errorCount = 0;
+    QtMsgHandler old = qInstallMsgHandler(errorMsgHandler);
+
+    canvas->setSource(testFileUrl("parentBinding.qml"));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+    QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->width(), listview->width());
+    QCOMPARE(item->height(), listview->height()/12);
+
+    // there should be no transient binding error
+    QVERIFY(!m_errorCount);
+
+    qInstallMsgHandler(old);
+}
+
 QTEST_MAIN(tst_QQuickListView)
 
 #include "tst_qquicklistview.moc"