for (int i=0; i<insertCount; i++)
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
model.insertItems(insertIndex, newData);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("count").toInt(), model.count());
// check visibleItems.first() is in correct position
for (int i=0; i<insertCount; i++)
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
model.insertItems(insertIndex, newData);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("count").toInt(), model.count());
// now, moving to the top of the view should position the inserted items correctly
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
model.removeItems(removeIndex, removeCount);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("count").toInt(), model.count());
QString firstName;
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
model.clear();
+ gridview->forceLayout();
QVERIFY(gridview->count() == 0);
QVERIFY(gridview->currentItem() == 0);
// 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);
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());
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<QQuickGridView*>(window->rootObject());
+ gridview->setProperty("width", window->width());
+ gridview->setProperty("height", window->height());
qApp->processEvents();
QList<QPair<QString, QString> > items;
items << qMakePair(QString("value %1").arg(i), QString::number(i));
model.addItems(items);
- QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(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; i<items.count(); i++)
QCOMPARE(result[i].toString(), items[i].first);
ctxt->setContextProperty("delegateWidth", delegateWidth);
ctxt->setContextProperty("delegateHeight", delegateHeight);
window->setSource(testFileUrl("attachedSignals.qml"));
- QObject *object = window->rootObject();
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(window->rootObject());
model.removeItems(indexToRemove, removeCount);
- QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(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);
}
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();
// removing
model.removeItems(7, 10);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
for (int i = 0; i < 18; ++i) {
QQuickItem *item = 0;
// start animation
if (!newData.isEmpty()) {
model.insertItems(insertionIndex, newData);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
}
// start animation
model.moveItems(moveFrom, moveTo, moveCount);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("targetTransitionsDone").toInt(), expectedTargetData.count());
QTRY_COMPARE(gridview->property("displaceTransitionsDone").toInt(),
// start animation
model.removeItems(removalIndex, removalCount);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
if (shouldAnimateTargets || expectedDisplacedIndexes.isValid()) {
case ListChange::Polish:
break;
}
+ gridview->forceLayout();
QVariantList resultTargetIndexes = gridview->property("displacedTargetIndexes").toList();
QVariantList resultTargetItems = gridview->property("displacedTargetItems").toList();
for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
targetItems << qMakePair(QString("new item %1").arg(j), QString::number(j));
model.insertItems(changes[i].index, targetItems);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
if (i == changes.count() - 1) {
QTRY_VERIFY(!gridview->property("runningAddTargets").toBool());
}
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());
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());
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<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
break;
}
}
+ QTRY_COMPARE(gridview->count(), model.count());
QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
// verify all items moved to the correct final positions
void parentBinding();
void defaultHighlightMoveDuration();
void accessEmptyCurrentItem_QTBUG_30227();
+ void delayedChanges_QTBUG_30555();
private:
- template <class T> void items(const QUrl &source, bool forceLayout);
- template <class T> void changed(const QUrl &source, bool forceLayout);
+ template <class T> void items(const QUrl &source);
+ template <class T> void changed(const QUrl &source);
template <class T> void inserted(const QUrl &source);
template <class T> void inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom);
template <class T> void removed(const QUrl &source, bool animated);
}
template <class T>
-void tst_QQuickListView::items(const QUrl &source, bool forceLayout)
+void tst_QQuickListView::items(const QUrl &source)
{
QQuickView *window = createView();
QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QTRY_VERIFY(listview != 0);
+ listview->forceLayout();
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
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
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<QQuickItem>(contentItem, "wrapper").count();
QTRY_VERIFY(itemCount == 0);
template <class T>
-void tst_QQuickListView::changed(const QUrl &source, bool forceLayout)
+void tst_QQuickListView::changed(const QUrl &source)
{
QQuickView *window = createView();
window->setSource(source);
qApp->processEvents();
- QQuickFlickable *listview = findItem<QQuickFlickable>(window->rootObject(), "list");
+ QQuickListView *listview = findItem<QQuickListView>(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<QQuickText>(contentItem, "textName", 1);
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<QPair<QString, QString> > newData;
for (int i=0; i<insertCount; i++)
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
model.insertItems(insertIndex, newData);
+
+ //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
QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
QVERIFY(item0);
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
// 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);
// Remove section boundary
model.removeItem(5);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
// New section header created
QTRY_COMPARE(item->height(), 40.0);
model.insertItem(3, "New Item", "0");
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
// Section header moved
// insert item which will become a section header
model.insertItem(6, "Replace header", "1");
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
item = findItem<QQuickItem>(contentItem, "wrapper", 6);
// remove section boundary
model.removeItem(5);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
for (int i = 0; i < 3; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem,
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,
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);
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<QQuickItem>(contentItem, "wrapper", 0));
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());
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());
strings << "four" << "five" << "six" << "seven";
model.setStringList(strings);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.rowCount());
for (int i = 0; i < model.rowCount(); ++i) {
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)
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());
for (int i = 0; i < 10; i++)
model.addItem("Item" + QString::number(i), "");
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
item = findItem<QQuickItem>(contentItem, "wrapper", 1);
void tst_QQuickListView::incrementalModel()
{
QQuickView *window = createView();
+ QSKIP("QTBUG-30716");
IncrementalModel model;
QQmlContext *ctxt = window->rootContext();
QQuickListView *listview = findItem<QQuickListView>(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;
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<QQuickListView*>(window->rootObject());
+ listview->setProperty("width", window->width());
+ listview->setProperty("height", window->height());
qApp->processEvents();
QList<QPair<QString, QString> > items;
for (int i=0; i<itemsToAdd; i++)
items << qMakePair(QString("value %1").arg(i), QString::number(i));
model.addItems(items);
- QTRY_COMPARE(window->rootObject()->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; i<items.count(); i++)
QCOMPARE(result[i].toString(), items[i].first);
ctxt->setContextProperty("delegateHeight", delegateHeight);
window->setSource(testFileUrl("attachedSignals.qml"));
- QObject *object = window->rootObject();
+ QQuickListView *listview = qobject_cast<QQuickListView *>(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);
}
// 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);
void tst_QQuickListView::qAbstractItemModel_package_items()
{
- items<QaimModel>(testFileUrl("listviewtest-package.qml"), true);
+ items<QaimModel>(testFileUrl("listviewtest-package.qml"));
}
void tst_QQuickListView::qAbstractItemModel_items()
{
- items<QaimModel>(testFileUrl("listviewtest.qml"), false);
+ items<QaimModel>(testFileUrl("listviewtest.qml"));
}
void tst_QQuickListView::qAbstractItemModel_package_changed()
{
- changed<QaimModel>(testFileUrl("listviewtest-package.qml"), true);
+ changed<QaimModel>(testFileUrl("listviewtest-package.qml"));
}
void tst_QQuickListView::qAbstractItemModel_changed()
{
- changed<QaimModel>(testFileUrl("listviewtest.qml"), false);
+ changed<QaimModel>(testFileUrl("listviewtest.qml"));
}
void tst_QQuickListView::qAbstractItemModel_package_inserted()
// clear the model
window->rootContext()->setContextProperty("testModel", QVariant());
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), 0);
QTRY_COMPARE(findItems<QQuickItem>(contentItem, "wrapper").count(), 0);
listview->setProperty("countPopulateTransitions", 0);
if (!newData.isEmpty()) {
model.insertItems(insertionIndex, newData);
QTRY_COMPARE(model.count(), listview->count());
+ listview->forceLayout();
}
QList<QQuickItem *> targetItems = findItems<QQuickItem>(contentItem, "wrapper", targetIndexes);
case ListChange::Polish:
break;
}
+ listview->forceLayout();
QVariantList resultTargetIndexes = listview->property("displacedTargetIndexes").toList();
QVariantList resultTargetItems = listview->property("displacedTargetItems").toList();
break;
}
}
+ listview->forceLayout();
QCOMPARE(listview->count(), model.count());
// verify all items moved to the correct final positions
QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>();
QTRY_VERIFY(listview != 0);
+ listview->forceLayout();
QMetaObject::invokeMethod(window->rootObject(), "remove");
QVERIFY(window->rootObject()->property("isCurrentItemNull").toBool());
QVERIFY(!window->rootObject()->property("isCurrentItemNull").toBool());
}
+void tst_QQuickListView::delayedChanges_QTBUG_30555()
+{
+ QQuickView *window = createView();
+ window->setSource(testFileUrl("delayedChanges.qml"));
+
+ QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>();
+ 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)
#include "tst_qquicklistview.moc"