diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickgridview.cpp qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickgridview.cpp --- qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickgridview.cpp 2013-05-06 13:48:52.121661964 +0000 +++ qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickgridview.cpp 2013-05-06 13:52:50.325652001 +0000 @@ -2561,6 +2561,22 @@ \b Note: methods should only be called after the Component has completed. */ + +/*! + \qmlmethod QtQuick2::GridView::forceLayout() + + Responding to changes in the model is usually batched to happen only once + per frame. This means that inside script blocks it is possible for the + underlying model to have changed, but the GridView has not caught up yet. + + This method forces the GridView to immediately respond to any outstanding + changes in the model. + + \since 5.1 + + \b Note: methods should only be called after the Component has completed. +*/ + QQuickGridViewAttached *QQuickGridView::qmlAttachedProperties(QObject *obj) { return new QQuickGridViewAttached(obj); diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickitemsmodule.cpp qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickitemsmodule.cpp --- qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickitemsmodule.cpp 2013-05-06 13:48:52.121661964 +0000 +++ qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickitemsmodule.cpp 2013-05-06 13:58:00.481639030 +0000 @@ -228,6 +228,10 @@ #ifndef QT_NO_ACCESSIBILITY qmlRegisterUncreatableType("QtQuick", 2, 0, "Accessible",QQuickAccessibleAttached::tr("Accessible is only available via attached properties")); #endif + + qmlRegisterUncreatableType(uri, 2, 1, "ItemView", QQuickItemView::tr("ItemView is an abstract base class")); + qmlRegisterType(uri, 2, 1, "ListView"); + qmlRegisterType(uri, 2, 1, "GridView"); } void QQuickItemsModule::defineModule() diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickitemview.cpp qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickitemview.cpp --- qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickitemview.cpp 2013-05-06 13:48:52.121661964 +0000 +++ qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickitemview.cpp 2013-05-06 13:55:46.797644621 +0000 @@ -250,7 +250,6 @@ Q_D(const QQuickItemView); if (!d->currentItem) return 0; - const_cast(d)->applyPendingChanges(); return d->currentItem->item; } @@ -379,14 +378,12 @@ Q_D(const QQuickItemView); if (!d->model) return 0; - const_cast(d)->applyPendingChanges(); return d->model->count(); } int QQuickItemView::currentIndex() const { Q_D(const QQuickItemView); - const_cast(d)->applyPendingChanges(); return d->currentIndex; } @@ -496,7 +493,6 @@ QQuickItem *QQuickItemView::headerItem() const { Q_D(const QQuickItemView); - const_cast(d)->applyPendingChanges(); return d->header ? d->header->item : 0; } @@ -532,7 +528,6 @@ QQuickItem *QQuickItemView::footerItem() const { Q_D(const QQuickItemView); - const_cast(d)->applyPendingChanges(); return d->footer ? d->footer->item : 0; } @@ -559,7 +554,6 @@ QQmlComponent *QQuickItemView::highlight() const { Q_D(const QQuickItemView); - const_cast(d)->applyPendingChanges(); return d->highlightComponent; } @@ -579,7 +573,6 @@ QQuickItem *QQuickItemView::highlightItem() const { Q_D(const QQuickItemView); - const_cast(d)->applyPendingChanges(); return d->highlight ? d->highlight->item : 0; } @@ -965,6 +958,12 @@ return 0; } +void QQuickItemView::forceLayout() +{ + Q_D(QQuickItemView); + d->applyPendingChanges(); +} + void QQuickItemViewPrivate::applyPendingChanges() { Q_Q(QQuickItemView); diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickitemview_p.h qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickitemview_p.h --- qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquickitemview_p.h 2013-05-06 13:48:52.117661964 +0000 +++ qtdeclarative-opensource-src-5.0.2/src/quick/items/qquickitemview_p.h 2013-05-06 13:52:50.329652001 +0000 @@ -204,6 +204,7 @@ Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const; Q_INVOKABLE void positionViewAtBeginning(); Q_INVOKABLE void positionViewAtEnd(); + Q_REVISION(1) Q_INVOKABLE void forceLayout(); virtual void setContentX(qreal pos); virtual void setContentY(qreal pos); diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquicklistview.cpp qtdeclarative-opensource-src-5.0.2/src/quick/items/qquicklistview.cpp --- qtdeclarative-opensource-src-5.0.2_with_01/src/quick/items/qquicklistview.cpp 2013-05-06 13:48:52.121661964 +0000 +++ qtdeclarative-opensource-src-5.0.2/src/quick/items/qquicklistview.cpp 2013-05-06 13:52:50.329652001 +0000 @@ -3103,6 +3103,21 @@ \b Note: methods should only be called after the Component has completed. */ +/*! + \qmlmethod QtQuick2::ListView::forceLayout() + + Responding to changes in the model is usually batched to happen only once + per frame. This means that inside script blocks it is possible for the + underlying model to have changed, but the ListView has not caught up yet. + + This method forces the ListView to immediately respond to any outstanding + changes in the model. + + \since 5.1 + + \b Note: methods should only be called after the Component has completed. +*/ + QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj) { return new QQuickListViewAttached(obj); diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/qmltest/listview/tst_listview.qml qtdeclarative-opensource-src-5.0.2/tests/auto/qmltest/listview/tst_listview.qml --- qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/qmltest/listview/tst_listview.qml 2013-05-06 13:48:52.209661960 +0000 +++ qtdeclarative-opensource-src-5.0.2/tests/auto/qmltest/listview/tst_listview.qml 2013-05-06 13:52:50.329652001 +0000 @@ -168,6 +168,7 @@ modelalter.currentIndex = 1; compare(modelalter.currentItem.text, "AlterModelElement1") altermodel.clear() + modelalter.forceLayout() tryCompare(modelalter.count, 0) compare(modelalter.currentItem, null) } diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp --- qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp 2013-05-06 13:48:52.217661960 +0000 +++ qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp 2013-05-06 13:52:50.329652001 +0000 @@ -533,6 +533,7 @@ for (int i=0; iforceLayout(); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); // check visibleItems.first() is in correct position @@ -729,6 +730,7 @@ for (int i=0; iforceLayout(); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); // now, moving to the top of the view should position the inserted items correctly @@ -959,6 +961,7 @@ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.removeItems(removeIndex, removeCount); + gridview->forceLayout(); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); QString firstName; @@ -1246,6 +1249,7 @@ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.clear(); + gridview->forceLayout(); QVERIFY(gridview->count() == 0); QVERIFY(gridview->currentItem() == 0); @@ -1255,6 +1259,7 @@ // confirm sanity when adding an item to cleared list model.addItem("New", "1"); + gridview->forceLayout(); QTRY_COMPARE(gridview->count(), 1); QVERIFY(gridview->currentItem() != 0); QVERIFY(gridview->currentIndex() == 0); @@ -3483,6 +3488,7 @@ QCOMPARE(gridview->originY(), origin_empty.y()); for (int i=0; i<30; i++) model.addItem("Item" + QString::number(i), ""); + gridview->forceLayout(); QTRY_COMPARE(gridview->count(), model.count()); QCOMPARE(gridview->originX(), origin_nonEmpty.x()); QCOMPARE(gridview->originY(), origin_nonEmpty.y()); @@ -3942,9 +3948,9 @@ ctxt->setContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); - object->setProperty("width", window->width()); - object->setProperty("height", window->height()); + QQuickGridView *gridview = qobject_cast(window->rootObject()); + gridview->setProperty("width", window->width()); + gridview->setProperty("height", window->height()); qApp->processEvents(); QList > items; @@ -3952,10 +3958,11 @@ items << qMakePair(QString("value %1").arg(i), QString::number(i)); model.addItems(items); - QTRY_COMPARE(model.count(), qobject_cast(window->rootObject())->count()); + gridview->forceLayout(); + QTRY_COMPARE(model.count(), gridview->count()); qApp->processEvents(); - QVariantList result = object->property("addedDelegates").toList(); + QVariantList result = gridview->property("addedDelegates").toList(); QTRY_COMPARE(result.count(), items.count()); for (int i=0; isetContextProperty("delegateWidth", delegateWidth); ctxt->setContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); + QQuickGridView *gridview = qobject_cast(window->rootObject()); model.removeItems(indexToRemove, removeCount); - QTRY_COMPARE(model.count(), qobject_cast(window->rootObject())->count()); - QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); + gridview->forceLayout(); + QTRY_COMPARE(model.count(), gridview->count()); + QCOMPARE(gridview->property("removedDelegateCount"), QVariant(removeCount)); releaseView(window); } @@ -4151,6 +4159,7 @@ gridview->setContentX(-400); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.removeItems(0, 4); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); gridview->setContentX(-240+50); gridview->returnToBounds(); @@ -4458,6 +4467,7 @@ // removing model.removeItems(7, 10); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); for (int i = 0; i < 18; ++i) { QQuickItem *item = 0; @@ -4663,6 +4673,7 @@ // start animation if (!newData.isEmpty()) { model.insertItems(insertionIndex, newData); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); } @@ -4866,6 +4877,7 @@ // start animation model.moveItems(moveFrom, moveTo, moveCount); + gridview->forceLayout(); QTRY_COMPARE(gridview->property("targetTransitionsDone").toInt(), expectedTargetData.count()); QTRY_COMPARE(gridview->property("displaceTransitionsDone").toInt(), @@ -5114,6 +5126,7 @@ // start animation model.removeItems(removalIndex, removalCount); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); if (shouldAnimateTargets || expectedDisplacedIndexes.isValid()) { @@ -5327,6 +5340,7 @@ case ListChange::Polish: break; } + gridview->forceLayout(); QVariantList resultTargetIndexes = gridview->property("displacedTargetIndexes").toList(); QVariantList resultTargetItems = gridview->property("displacedTargetItems").toList(); @@ -5534,6 +5548,7 @@ for (int j=changes[i].index; jforceLayout(); QTRY_COMPARE(model.count(), gridview->count()); if (i == changes.count() - 1) { QTRY_VERIFY(!gridview->property("runningAddTargets").toBool()); @@ -5545,6 +5560,7 @@ } case ListChange::Removed: model.removeItems(changes[i].index, changes[i].count); + gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); if (i == changes.count() - 1) { QTRY_VERIFY(!gridview->property("runningRemoveTargets").toBool()); @@ -5555,6 +5571,7 @@ break; case ListChange::Moved: model.moveItems(changes[i].index, changes[i].to, changes[i].count); + gridview->forceLayout(); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); if (i == changes.count() - 1) { QTRY_VERIFY(!gridview->property("runningMoveTargets").toBool()); @@ -5566,16 +5583,17 @@ case ListChange::SetCurrent: gridview->setCurrentIndex(changes[i].index); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + gridview->forceLayout(); break; case ListChange::SetContentY: gridview->setContentY(changes[i].pos); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + gridview->forceLayout(); break; case ListChange::Polish: break; } } - QCOMPARE(gridview->count(), model.count()); QList items = findItems(contentItem, "wrapper"); int firstVisibleIndex = -1; @@ -5586,6 +5604,7 @@ break; } } + QTRY_COMPARE(gridview->count(), model.count()); QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // verify all items moved to the correct final positions diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquicklistview/data/delayedChanges.qml qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquicklistview/data/delayedChanges.qml --- qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquicklistview/data/delayedChanges.qml 1970-01-01 00:00:00.000000000 +0000 +++ qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquicklistview/data/delayedChanges.qml 2013-05-06 13:52:50.329652001 +0000 @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Item { + width: 400 + height: 400 + function takeTwo() + { + listView.model.remove(0); + listView.model.remove(0); + } + function takeTwo_sync() + { + listView.model.remove(0); + listView.forceLayout(); + listView.model.remove(0); + listView.forceLayout(); + } + + ListView { + id: listView + height: parent.height + width: 400 + model: ListModel { + ListElement { name: "A" } + ListElement { name: "B" } + ListElement { name: "C" } + ListElement { name: "D" } + ListElement { name: "E" } + ListElement { name: "F" } + ListElement { name: "G" } + ListElement { name: "H" } + ListElement { name: "I" } + ListElement { name: "J" } + } + delegate: Text { + text: index + listView.count + } + } +} diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp --- qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp 2013-05-06 13:48:52.213661960 +0000 +++ qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp 2013-05-06 13:56:02.721643955 +0000 @@ -206,10 +206,11 @@ void destroyItemOnCreation(); void parentBinding(); + void delayedChanges_QTBUG_30555(); private: - template void items(const QUrl &source, bool forceLayout); - template void changed(const QUrl &source, bool forceLayout); + template void items(const QUrl &source); + template void changed(const QUrl &source); template void inserted(const QUrl &source); template void inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom); template void removed(const QUrl &source, bool animated); @@ -327,7 +328,7 @@ } template -void tst_QQuickListView::items(const QUrl &source, bool forceLayout) +void tst_QQuickListView::items(const QUrl &source) { QQuickView *window = createView(); @@ -347,6 +348,7 @@ QQuickListView *listview = findItem(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); @@ -357,6 +359,7 @@ QTRY_VERIFY(listview->highlightItem() != 0); QTRY_COMPARE(listview->count(), model.count()); QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count()); + listview->forceLayout(); QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item // current item should be first item @@ -396,8 +399,7 @@ ctxt->setContextProperty("testModel", &model2); // Force a layout, necessary if ListView is completed before VisualDataModel. - if (forceLayout) - QCOMPARE(listview->property("count").toInt(), 0); + listview->forceLayout(); int itemCount = findItems(contentItem, "wrapper").count(); QTRY_VERIFY(itemCount == 0); @@ -411,7 +413,7 @@ template -void tst_QQuickListView::changed(const QUrl &source, bool forceLayout) +void tst_QQuickListView::changed(const QUrl &source) { QQuickView *window = createView(); @@ -429,15 +431,15 @@ window->setSource(source); qApp->processEvents(); - QQuickFlickable *listview = findItem(window->rootObject(), "list"); + QQuickListView *listview = findItem(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); // Force a layout, necessary if ListView is completed before VisualDataModel. - if (forceLayout) - QCOMPARE(listview->property("count").toInt(), model.count()); + listview->forceLayout(); model.modifyItem(1, "Will", "9876"); QQuickText *name = findItem(contentItem, "textName", 1); @@ -577,22 +579,24 @@ QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); - bool waitForPolish = (contentY != 0); if (verticalLayoutDirection == QQuickItemView::BottomToTop) { listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); contentY = -listview->height() - contentY; } listview->setContentY(contentY); - if (waitForPolish) - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); QList > newData; for (int i=0; ipolishScheduled, false); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); + // check visibleItems.first() is in correct position QQuickItem *item0 = findItem(contentItem, "wrapper", 0); QVERIFY(item0); @@ -1017,17 +1021,17 @@ QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); - bool waitForPolish = (contentY != 0); if (verticalLayoutDirection == QQuickItemView::BottomToTop) { listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); contentY = -listview->height() - contentY; } listview->setContentY(contentY); - if (waitForPolish) - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.removeItems(removeIndex, removeCount); + //Wait for polish (updates list to the model changes) + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); // check visibleItems.first() is in correct position @@ -1217,6 +1221,7 @@ // confirm sanity when adding an item to cleared list model.addItem("New", "1"); + listview->forceLayout(); QTRY_VERIFY(listview->count() == 1); QVERIFY(listview->currentItem() != 0); QVERIFY(listview->currentIndex() == 0); @@ -1943,6 +1948,7 @@ // Remove section boundary model.removeItem(5); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); // New section header created @@ -1951,6 +1957,7 @@ QTRY_COMPARE(item->height(), 40.0); model.insertItem(3, "New Item", "0"); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); // Section header moved @@ -1964,6 +1971,7 @@ // insert item which will become a section header model.insertItem(6, "Replace header", "1"); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); item = findItem(contentItem, "wrapper", 6); @@ -2059,6 +2067,7 @@ // remove section boundary model.removeItem(5); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); for (int i = 0; i < 3; ++i) { QQuickItem *item = findItem(contentItem, @@ -2286,6 +2295,7 @@ listview->setContentY(120); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.removeItem(5); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); for (int i = 1; i < 3; ++i) { QQuickItem *item = findVisibleChild(contentItem, @@ -2483,7 +2493,8 @@ QTRY_VERIFY(contentItem != 0); QSignalSpy spy(listview, SIGNAL(currentItemChanged())); - QCOMPARE(listview->currentIndex(), 0); + //QCOMPARE(listview->currentIndex(), 0); + listview->forceLayout(); QTRY_COMPARE(spy.count(), 1); releaseView(window); @@ -2534,6 +2545,7 @@ for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), QString::number(i)); ctxt->setContextProperty("testModel", &model); + listview->forceLayout(); QCOMPARE(listview->currentIndex(), 0); QCOMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 0)); @@ -2677,6 +2689,7 @@ QTRY_COMPARE(listview->currentIndex(), i+1); } QTest::keyRelease(window, forwardsKey); + listview->forceLayout(); QTRY_COMPARE(listview->currentIndex(), model.count()-1); QTRY_COMPARE(listview->contentX(), contentPosAtLastItem.x()); QTRY_COMPARE(listview->contentY(), contentPosAtLastItem.y()); @@ -2687,6 +2700,7 @@ QTRY_COMPARE(listview->currentIndex(), i-1); } QTest::keyRelease(window, backwardsKey); + listview->forceLayout(); QTRY_COMPARE(listview->currentIndex(), 0); QTRY_COMPARE(listview->contentX(), contentPosAtFirstItem.x()); QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y()); @@ -3121,6 +3135,7 @@ strings << "four" << "five" << "six" << "seven"; model.setStringList(strings); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.rowCount()); for (int i = 0; i < model.rowCount(); ++i) { @@ -3468,6 +3483,7 @@ QCOMPARE(item->position(), firstDelegatePos); model.clear(); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); QCOMPARE(header->position(), initialHeaderPos); // header should stay where it is if (orientation == QQuickListView::Vertical) @@ -3863,6 +3879,7 @@ QCOMPARE(listview->originY(), origin_empty.y()); for (int i=0; i<30; i++) model.addItem("Item" + QString::number(i), ""); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); QCOMPARE(listview->originX(), origin_nonEmpty.x()); QCOMPARE(listview->originY(), origin_nonEmpty.y()); @@ -4260,6 +4277,7 @@ for (int i = 0; i < 10; i++) model.addItem("Item" + QString::number(i), ""); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); item = findItem(contentItem, "wrapper", 1); @@ -4459,6 +4477,7 @@ void tst_QQuickListView::incrementalModel() { QQuickView *window = createView(); + QSKIP("QTBUG-30716"); IncrementalModel model; QQmlContext *ctxt = window->rootContext(); @@ -4469,14 +4488,17 @@ QQuickListView *listview = findItem(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); + listview->forceLayout(); QTRY_COMPARE(listview->count(), 20); listview->positionViewAtIndex(10, QQuickListView::Beginning); + listview->forceLayout(); QTRY_COMPARE(listview->count(), 25); delete window; @@ -4501,18 +4523,19 @@ ctxt->setContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); - object->setProperty("width", window->width()); - object->setProperty("height", window->height()); + QQuickListView* listview = qobject_cast(window->rootObject()); + listview->setProperty("width", window->width()); + listview->setProperty("height", window->height()); qApp->processEvents(); QList > items; for (int i=0; irootObject()->property("count").toInt(), model.count()); + listview->forceLayout(); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); - QVariantList result = object->property("addedDelegates").toList(); + QVariantList result = listview->property("addedDelegates").toList(); QCOMPARE(result.count(), items.count()); for (int i=0; isetContextProperty("delegateHeight", delegateHeight); window->setSource(testFileUrl("attachedSignals.qml")); - QObject *object = window->rootObject(); + QQuickListView *listview = qobject_cast(window->rootObject()); model.removeItems(indexToRemove, removeCount); - QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count()); + listview->forceLayout(); + QTRY_COMPARE(listview->property("count").toInt(), model.count()); - QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); + QCOMPARE(listview->property("removedDelegateCount"), QVariant(removeCount)); releaseView(window); } @@ -4739,6 +4763,7 @@ // and originY is updated listview->setContentY(100); model.removeItem(1); + listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); listview->setContentY(-50); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); @@ -4977,22 +5002,22 @@ void tst_QQuickListView::qAbstractItemModel_package_items() { - items(testFileUrl("listviewtest-package.qml"), true); + items(testFileUrl("listviewtest-package.qml")); } void tst_QQuickListView::qAbstractItemModel_items() { - items(testFileUrl("listviewtest.qml"), false); + items(testFileUrl("listviewtest.qml")); } void tst_QQuickListView::qAbstractItemModel_package_changed() { - changed(testFileUrl("listviewtest-package.qml"), true); + changed(testFileUrl("listviewtest-package.qml")); } void tst_QQuickListView::qAbstractItemModel_changed() { - changed(testFileUrl("listviewtest.qml"), false); + changed(testFileUrl("listviewtest.qml")); } void tst_QQuickListView::qAbstractItemModel_package_inserted() @@ -5553,6 +5578,7 @@ // clear the model window->rootContext()->setContextProperty("testModel", QVariant()); + listview->forceLayout(); QTRY_COMPARE(listview->count(), 0); QTRY_COMPARE(findItems(contentItem, "wrapper").count(), 0); listview->setProperty("countPopulateTransitions", 0); @@ -5681,6 +5707,7 @@ if (!newData.isEmpty()) { model.insertItems(insertionIndex, newData); QTRY_COMPARE(model.count(), listview->count()); + listview->forceLayout(); } QList targetItems = findItems(contentItem, "wrapper", targetIndexes); @@ -6289,6 +6316,7 @@ case ListChange::Polish: break; } + listview->forceLayout(); QVariantList resultTargetIndexes = listview->property("displacedTargetIndexes").toList(); QVariantList resultTargetItems = listview->property("displacedTargetItems").toList(); @@ -6537,6 +6565,7 @@ break; } } + listview->forceLayout(); QCOMPARE(listview->count(), model.count()); // verify all items moved to the correct final positions @@ -6724,6 +6753,7 @@ QQuickListView *listview = findItem(window->rootObject(), "list"); QTRY_VERIFY(listview != 0); + listview->forceLayout(); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); @@ -6800,6 +6830,26 @@ delete window; } + +void tst_QQuickListView::delayedChanges_QTBUG_30555() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("delayedChanges.qml")); + + QQuickListView *listview = window->rootObject()->findChild(); + QTRY_VERIFY(listview != 0); + + QCOMPARE(listview->count(), 10); + + //Takes two just like in the bug report + QMetaObject::invokeMethod(window->rootObject(), "takeTwo"); + QTRY_COMPARE(listview->count(), 8); + + QMetaObject::invokeMethod(window->rootObject(), "takeTwo_sync"); + QCOMPARE(listview->count(), 6); + + delete window; +} QTEST_MAIN(tst_QQuickListView) diff -rubN qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp --- qtdeclarative-opensource-src-5.0.2_with_01/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp 2013-05-06 13:48:52.221661960 +0000 +++ qtdeclarative-opensource-src-5.0.2/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp 2013-05-06 13:52:55.757651774 +0000 @@ -615,6 +615,7 @@ vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0)))); QCOMPARE(listview->count(), 1); + listview->forceLayout(); QQuickText *name = findItem(contentItem, "display", 0); QVERIFY(name); QCOMPARE(name->text(), QString("Row 2 Child Item")); @@ -628,6 +629,7 @@ model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2"))); QCOMPARE(listview->count(), 2); + listview->forceLayout(); name = findItem(contentItem, "display", 1); QVERIFY(name != 0); QCOMPARE(name->text(), QString("Row 2 Child Item 2")); @@ -638,6 +640,8 @@ vdm->setRootIndex(QVariant::fromValue(QModelIndex())); QCOMPARE(listview->count(), 3); + + listview->forceLayout(); name = findItem(contentItem, "display", 0); QVERIFY(name); QCOMPARE(name->text(), QString("Row 1 Item")); @@ -989,6 +993,8 @@ QQuickItem *rightContent = rightview->contentItem(); QTRY_VERIFY(rightContent != 0); + leftview->forceLayout(); + rightview->forceLayout(); QCOMPARE(leftview->currentIndex(), 0); QCOMPARE(rightview->currentIndex(), 0); @@ -3548,6 +3554,7 @@ evaluate(visualModel, setupExpression); QCOMPARE(evaluate(listView, "count"), unresolvedCount); + listView->forceLayout(); evaluate(visualModel, resolveExpression); QCOMPARE(evaluate(listView, "count"), inItems ? visualCount : modelCount);