QT_BEGIN_NAMESPACE
QQuickRepeaterPrivate::QQuickRepeaterPrivate()
- : model(0), ownModel(false), inRequest(false), dataSourceIsObject(false), delegateValidated(false), itemCount(0), createFrom(-1)
+ : model(0)
+ , ownModel(false)
+ , dataSourceIsObject(false)
+ , delegateValidated(false)
+ , itemCount(0)
{
}
d->itemCount = count();
d->deletables.resize(d->itemCount);
- d->createFrom = 0;
- d->createItems();
+ d->requestItems();
}
-void QQuickRepeaterPrivate::createItems()
+void QQuickRepeaterPrivate::requestItems()
{
- Q_Q(QQuickRepeater);
- if (createFrom == -1)
- return;
- inRequest = true;
- for (int ii = createFrom; ii < itemCount; ++ii) {
- if (!deletables.at(ii)) {
- QObject *object = model->object(ii, false);
- QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
- if (!item) {
- if (object) {
- model->release(object);
- if (!delegateValidated) {
- delegateValidated = true;
- QObject* delegate = q->delegate();
- qmlInfo(delegate ? delegate : q) << QQuickRepeater::tr("Delegate must be of Item type");
- }
+ for (int i = 0; i < itemCount; i++) {
+ QObject *object = model->object(i, false);
+ if (object)
+ model->release(object);
+ }
+}
+
+void QQuickRepeater::createdItem(int index, QObject *)
+{
+ Q_D(QQuickRepeater);
+ if (!d->deletables.at(index)) {
+ QObject *object = d->model->object(index, false);
+ QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
+ if (!item) {
+ if (object) {
+ d->model->release(object);
+ if (!d->delegateValidated) {
+ d->delegateValidated = true;
+ QObject* delegate = this->delegate();
+ qmlInfo(delegate ? delegate : this) << QQuickRepeater::tr("Delegate must be of Item type");
}
- createFrom = ii;
- break;
}
- deletables[ii] = item;
- item->setParentItem(q->parentItem());
- if (ii > 0 && deletables.at(ii-1)) {
- item->stackAfter(deletables.at(ii-1));
- } else {
- QQuickItem *after = q;
- for (int si = ii+1; si < itemCount; ++si) {
- if (deletables.at(si)) {
- after = deletables.at(si);
- break;
- }
+ return;
+ }
+ d->deletables[index] = item;
+ item->setParentItem(parentItem());
+ if (index > 0 && d->deletables.at(index-1)) {
+ item->stackAfter(d->deletables.at(index-1));
+ } else {
+ QQuickItem *after = this;
+ for (int si = index+1; si < d->itemCount; ++si) {
+ if (d->deletables.at(si)) {
+ after = d->deletables.at(si);
+ break;
}
- item->stackBefore(after);
}
- emit q->itemAdded(ii, item);
+ item->stackBefore(after);
}
+ emit itemAdded(index, item);
}
- inRequest = false;
-}
-
-void QQuickRepeater::createdItem(int, QObject *)
-{
- Q_D(QQuickRepeater);
- if (!d->inRequest)
- d->createItems();
}
void QQuickRepeater::initItem(int, QObject *object)
difference -= remove.count;
}
- d->createFrom = -1;
foreach (const QQmlChangeSet::Change &insert, changeSet.inserts()) {
int index = qMin(insert.index, d->deletables.count());
if (insert.isMove()) {
int modelIndex = index + i;
++d->itemCount;
d->deletables.insert(modelIndex, 0);
- if (d->createFrom == -1)
- d->createFrom = modelIndex;
+ QObject *object = d->model->object(modelIndex, false);
+ if (object)
+ d->model->release(object);
}
difference += insert.count;
}
- d->createItems();
-
if (difference != 0)
emit countChanged();
}
void invalidContextCrash();
void jsArrayChange();
void clearRemovalOrder();
+ void destroyCount();
};
class TestObject : public QObject
QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(2));
addedSpy.clear();
+ //insert in middle multiple
+ int childItemsSize = container->childItems().size();
+ QList<QPair<QString, QString> > multiData;
+ multiData << qMakePair(QStringLiteral("five"), QStringLiteral("5")) << qMakePair(QStringLiteral("six"), QStringLiteral("6")) << qMakePair(QStringLiteral("seven"), QStringLiteral("7"));
+ testModel.insertItems(1, multiData);
+ QCOMPARE(countSpy.count(), 1);
+ QCOMPARE(addedSpy.count(), 3);
+ QCOMPARE(container->childItems().size(), childItemsSize + 3);
+ QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
+ addedSpy.clear();
+ countSpy.clear();
+
delete testObject;
addedSpy.clear();
countSpy.clear();
}
// items will be created one at a time
- for (int i = 0; i < 10; ++i) {
+ // the order is incubator/model specific
+ for (int i = 9; i >= 0; --i) {
QString name("delegate");
name += QString::number(i);
QVERIFY(findItem<QQuickItem>(container, name) == 0);
delete rootObject;
}
+void tst_QQuickRepeater::destroyCount()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("destroycount.qml"));
+
+ QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(rootObject);
+
+ QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater");
+ QVERIFY(repeater);
+
+ repeater->setProperty("model", qVariantFromValue<int>(3));
+ QCOMPARE(repeater->property("componentCount").toInt(), 3);
+ repeater->setProperty("model", qVariantFromValue<int>(0));
+ QCOMPARE(repeater->property("componentCount").toInt(), 0);
+ repeater->setProperty("model", qVariantFromValue<int>(4));
+ QCOMPARE(repeater->property("componentCount").toInt(), 4);
+
+ QStringListModel model;
+ repeater->setProperty("model", qVariantFromValue<QStringListModel *>(&model));
+ QCOMPARE(repeater->property("componentCount").toInt(), 0);
+ QStringList list;
+ list << "1" << "2" << "3" << "4";
+ model.setStringList(list);
+ QCOMPARE(repeater->property("componentCount").toInt(), 4);
+ model.insertRows(2,1);
+ QModelIndex index = model.index(2);
+ model.setData(index, qVariantFromValue<QString>(QStringLiteral("foobar")));
+ QCOMPARE(repeater->property("componentCount").toInt(), 5);
+
+ model.removeRows(2,1);
+ QCOMPARE(model.rowCount(), 4);
+ QCOMPARE(repeater->property("componentCount").toInt(), 4);
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"