1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <QtTest/QSignalSpy>
44 #include <private/qlistmodelinterface_p.h>
45 #include <QtDeclarative/qdeclarativeengine.h>
46 #include <QtQuick/qquickview.h>
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/qdeclarativeexpression.h>
49 #include <QtDeclarative/qdeclarativeincubator.h>
50 #include <private/qquickrepeater_p.h>
51 #include <QtQuick/private/qquicktext_p.h>
53 #include "../../shared/util.h"
55 inline QUrl TEST_FILE(const QString &filename)
57 return QUrl::fromLocalFile(TESTDATA(filename));
60 class tst_QQuickRepeater : public QObject
70 void dataModel_adding();
71 void dataModel_removing();
72 void dataModel_changes();
81 QQuickView *createView();
83 T *findItem(QObject *parent, const QString &objectName, int index);
85 T *findItem(QObject *parent, const QString &id);
88 class TestObject : public QObject
92 Q_PROPERTY(bool error READ error WRITE setError)
93 Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
96 TestObject() : QObject(), mError(true), mUseModel(false) {}
98 bool error() const { return mError; }
99 void setError(bool err) { mError = err; }
101 bool useModel() const { return mUseModel; }
102 void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
105 void useModelChanged();
112 class TestModel : public QAbstractListModel
115 enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
117 TestModel(QObject *parent=0) : QAbstractListModel(parent) {
118 QHash<int, QByteArray> roles;
119 roles[Name] = "name";
120 roles[Number] = "number";
124 int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
125 QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
128 rv = list.at(index.row()).first;
129 else if (role == Number)
130 rv = list.at(index.row()).second;
135 int count() const { return rowCount(); }
136 QString name(int index) const { return list.at(index).first; }
137 QString number(int index) const { return list.at(index).second; }
139 void addItem(const QString &name, const QString &number) {
140 emit beginInsertRows(QModelIndex(), list.count(), list.count());
141 list.append(QPair<QString,QString>(name, number));
142 emit endInsertRows();
145 void insertItem(int index, const QString &name, const QString &number) {
146 emit beginInsertRows(QModelIndex(), index, index);
147 list.insert(index, QPair<QString,QString>(name, number));
148 emit endInsertRows();
151 void removeItem(int index) {
152 emit beginRemoveRows(QModelIndex(), index, index);
153 list.removeAt(index);
154 emit endRemoveRows();
157 void moveItem(int from, int to) {
158 emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
163 void modifyItem(int idx, const QString &name, const QString &number) {
164 list[idx] = QPair<QString,QString>(name, number);
165 emit dataChanged(index(idx,0), index(idx,0));
169 QList<QPair<QString,QString> > list;
173 tst_QQuickRepeater::tst_QQuickRepeater()
177 void tst_QQuickRepeater::numberModel()
179 QQuickView *canvas = createView();
181 QDeclarativeContext *ctxt = canvas->rootContext();
182 ctxt->setContextProperty("testData", 5);
183 TestObject *testObject = new TestObject;
184 ctxt->setContextProperty("testObject", testObject);
186 canvas->setSource(TEST_FILE("intmodel.qml"));
187 qApp->processEvents();
189 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
190 QVERIFY(repeater != 0);
191 QCOMPARE(repeater->parentItem()->childItems().count(), 5+1);
193 QVERIFY(!repeater->itemAt(-1));
194 for (int i=0; i<repeater->count(); i++)
195 QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
196 QVERIFY(!repeater->itemAt(repeater->count()));
198 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
199 QVERIFY(testObject->error() == false);
205 class MyObject : public QObject
208 Q_PROPERTY(int idx READ idx CONSTANT)
210 MyObject(int i) : QObject(), m_idx(i) {}
212 int idx() const { return m_idx; }
217 void tst_QQuickRepeater::objectList()
219 QQuickView *canvas = createView();
221 for (int i=0; i<100; i++)
222 data << new MyObject(i);
224 QDeclarativeContext *ctxt = canvas->rootContext();
225 ctxt->setContextProperty("testData", QVariant::fromValue(data));
227 canvas->setSource(TEST_FILE("objlist.qml"));
228 qApp->processEvents();
230 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
231 QVERIFY(repeater != 0);
232 QCOMPARE(repeater->property("errors").toInt(), 0);//If this fails either they are out of order or can't find the object's data
233 QCOMPARE(repeater->property("instantiated").toInt(), 100);
235 QVERIFY(!repeater->itemAt(-1));
236 for (int i=0; i<data.count(); i++)
237 QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
238 QVERIFY(!repeater->itemAt(data.count()));
240 QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
241 QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
242 ctxt->setContextProperty("testData", QVariant::fromValue(data));
243 QCOMPARE(addedSpy.count(), data.count());
244 QCOMPARE(removedSpy.count(), data.count());
251 The Repeater element creates children at its own position in its parent's
252 stacking order. In this test we insert a repeater between two other Text
253 elements to test this.
255 void tst_QQuickRepeater::stringList()
257 QQuickView *canvas = createView();
265 QDeclarativeContext *ctxt = canvas->rootContext();
266 ctxt->setContextProperty("testData", data);
268 canvas->setSource(TEST_FILE("repeater1.qml"));
269 qApp->processEvents();
271 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
272 QVERIFY(repeater != 0);
274 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
275 QVERIFY(container != 0);
277 QCOMPARE(container->childItems().count(), data.count() + 3);
279 bool saw_repeater = false;
280 for (int i = 0; i < container->childItems().count(); ++i) {
283 QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
285 QCOMPARE(name->text(), QLatin1String("Zero"));
286 } else if (i == container->childItems().count() - 2) {
287 // The repeater itself
288 QQuickRepeater *rep = qobject_cast<QQuickRepeater*>(container->childItems().at(i));
289 QCOMPARE(rep, repeater);
292 } else if (i == container->childItems().count() - 1) {
293 QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
295 QCOMPARE(name->text(), QLatin1String("Last"));
297 QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
299 QCOMPARE(name->text(), data.at(i-1));
302 QVERIFY(saw_repeater);
307 void tst_QQuickRepeater::dataModel_adding()
309 QQuickView *canvas = createView();
310 QDeclarativeContext *ctxt = canvas->rootContext();
311 TestObject *testObject = new TestObject;
312 ctxt->setContextProperty("testObject", testObject);
315 ctxt->setContextProperty("testData", &testModel);
316 canvas->setSource(TEST_FILE("repeater2.qml"));
317 qApp->processEvents();
319 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
320 QVERIFY(repeater != 0);
321 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
322 QVERIFY(container != 0);
324 QVERIFY(!repeater->itemAt(0));
326 QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
327 QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
329 // add to empty model
330 testModel.addItem("two", "2");
331 QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
332 QCOMPARE(countSpy.count(), 1); countSpy.clear();
333 QCOMPARE(addedSpy.count(), 1);
334 QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
335 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(0));
339 testModel.insertItem(0, "one", "1");
340 QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
341 QCOMPARE(countSpy.count(), 1); countSpy.clear();
342 QCOMPARE(addedSpy.count(), 1);
343 QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
344 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(0));
348 testModel.insertItem(2, "four", "4");
349 QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
350 QCOMPARE(countSpy.count(), 1); countSpy.clear();
351 QCOMPARE(addedSpy.count(), 1);
352 QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
353 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(2));
357 testModel.insertItem(2, "three", "3");
358 QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
359 QCOMPARE(countSpy.count(), 1); countSpy.clear();
360 QCOMPARE(addedSpy.count(), 1);
361 QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
362 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(2));
371 void tst_QQuickRepeater::dataModel_removing()
373 QQuickView *canvas = createView();
374 QDeclarativeContext *ctxt = canvas->rootContext();
375 TestObject *testObject = new TestObject;
376 ctxt->setContextProperty("testObject", testObject);
379 testModel.addItem("one", "1");
380 testModel.addItem("two", "2");
381 testModel.addItem("three", "3");
382 testModel.addItem("four", "4");
383 testModel.addItem("five", "5");
385 ctxt->setContextProperty("testData", &testModel);
386 canvas->setSource(TEST_FILE("repeater2.qml"));
387 qApp->processEvents();
389 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
390 QVERIFY(repeater != 0);
391 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
392 QVERIFY(container != 0);
393 QCOMPARE(container->childItems().count(), repeater->count()+1);
395 QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
396 QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
399 QQuickItem *item = repeater->itemAt(0);
400 QCOMPARE(item, container->childItems().at(0));
402 testModel.removeItem(0);
403 QVERIFY(repeater->itemAt(0) != item);
404 QCOMPARE(countSpy.count(), 1); countSpy.clear();
405 QCOMPARE(removedSpy.count(), 1);
406 QCOMPARE(removedSpy.at(0).at(0).toInt(), 0);
407 QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
411 int lastIndex = testModel.count()-1;
412 item = repeater->itemAt(lastIndex);
413 QCOMPARE(item, container->childItems().at(lastIndex));
415 testModel.removeItem(lastIndex);
416 QVERIFY(repeater->itemAt(lastIndex) != item);
417 QCOMPARE(countSpy.count(), 1); countSpy.clear();
418 QCOMPARE(removedSpy.count(), 1);
419 QCOMPARE(removedSpy.at(0).at(0).toInt(), lastIndex);
420 QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
423 // remove from middle
424 item = repeater->itemAt(1);
425 QCOMPARE(item, container->childItems().at(1));
427 testModel.removeItem(1);
428 QVERIFY(repeater->itemAt(lastIndex) != item);
429 QCOMPARE(countSpy.count(), 1); countSpy.clear();
430 QCOMPARE(removedSpy.count(), 1);
431 QCOMPARE(removedSpy.at(0).at(0).toInt(), 1);
432 QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
439 void tst_QQuickRepeater::dataModel_changes()
441 QQuickView *canvas = createView();
442 QDeclarativeContext *ctxt = canvas->rootContext();
443 TestObject *testObject = new TestObject;
444 ctxt->setContextProperty("testObject", testObject);
447 testModel.addItem("one", "1");
448 testModel.addItem("two", "2");
449 testModel.addItem("three", "3");
451 ctxt->setContextProperty("testData", &testModel);
452 canvas->setSource(TEST_FILE("repeater2.qml"));
453 qApp->processEvents();
455 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
456 QVERIFY(repeater != 0);
457 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
458 QVERIFY(container != 0);
459 QCOMPARE(container->childItems().count(), repeater->count()+1);
461 // Check that model changes are propagated
462 QQuickText *text = findItem<QQuickText>(canvas->rootObject(), "myName", 1);
464 QCOMPARE(text->text(), QString("two"));
466 testModel.modifyItem(1, "Item two", "_2");
467 text = findItem<QQuickText>(canvas->rootObject(), "myName", 1);
469 QCOMPARE(text->text(), QString("Item two"));
471 text = findItem<QQuickText>(canvas->rootObject(), "myNumber", 1);
473 QCOMPARE(text->text(), QString("_2"));
479 void tst_QQuickRepeater::itemModel()
481 QQuickView *canvas = createView();
482 QDeclarativeContext *ctxt = canvas->rootContext();
483 TestObject *testObject = new TestObject;
484 ctxt->setContextProperty("testObject", testObject);
486 canvas->setSource(TEST_FILE("itemlist.qml"));
487 qApp->processEvents();
489 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
490 QVERIFY(repeater != 0);
492 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
493 QVERIFY(container != 0);
495 QCOMPARE(container->childItems().count(), 1);
497 testObject->setUseModel(true);
498 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
499 QVERIFY(testObject->error() == false);
501 QCOMPARE(container->childItems().count(), 4);
502 QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item1");
503 QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item2");
504 QVERIFY(qobject_cast<QObject*>(container->childItems().at(2))->objectName() == "item3");
505 QVERIFY(container->childItems().at(3) == repeater);
507 QMetaObject::invokeMethod(canvas->rootObject(), "switchModel");
508 QCOMPARE(container->childItems().count(), 3);
509 QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item4");
510 QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item5");
511 QVERIFY(container->childItems().at(2) == repeater);
513 testObject->setUseModel(false);
514 QCOMPARE(container->childItems().count(), 1);
520 void tst_QQuickRepeater::resetModel()
522 QQuickView *canvas = createView();
525 for (int i=0; i<10; i++)
526 dataA << QString::number(i);
528 QDeclarativeContext *ctxt = canvas->rootContext();
529 ctxt->setContextProperty("testData", dataA);
530 canvas->setSource(TEST_FILE("repeater1.qml"));
531 qApp->processEvents();
532 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
533 QVERIFY(repeater != 0);
534 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
535 QVERIFY(container != 0);
537 QCOMPARE(repeater->count(), dataA.count());
538 for (int i=0; i<repeater->count(); i++)
539 QCOMPARE(repeater->itemAt(i), container->childItems().at(i+1)); // +1 to skip first Text object
541 QSignalSpy modelChangedSpy(repeater, SIGNAL(modelChanged()));
542 QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
543 QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
544 QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
547 for (int i=0; i<20; i++)
548 dataB << QString::number(i);
550 // reset context property
551 ctxt->setContextProperty("testData", dataB);
552 QCOMPARE(repeater->count(), dataB.count());
554 QCOMPARE(modelChangedSpy.count(), 1);
555 QCOMPARE(countSpy.count(), 1);
556 QCOMPARE(removedSpy.count(), dataA.count());
557 QCOMPARE(addedSpy.count(), dataB.count());
558 for (int i=0; i<dataB.count(); i++) {
559 QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
560 QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
562 modelChangedSpy.clear();
567 // reset via setModel()
568 repeater->setModel(dataA);
569 QCOMPARE(repeater->count(), dataA.count());
571 QCOMPARE(modelChangedSpy.count(), 1);
572 QCOMPARE(countSpy.count(), 1);
573 QCOMPARE(removedSpy.count(), dataB.count());
574 QCOMPARE(addedSpy.count(), dataA.count());
575 for (int i=0; i<dataA.count(); i++) {
576 QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
577 QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
580 modelChangedSpy.clear();
589 void tst_QQuickRepeater::modelChanged()
591 QDeclarativeEngine engine;
592 QDeclarativeComponent component(&engine, TEST_FILE("modelChanged.qml"));
594 QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
596 QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater");
599 repeater->setModel(4);
600 QCOMPARE(repeater->count(), 4);
601 QCOMPARE(repeater->property("itemsCount").toInt(), 4);
602 QCOMPARE(repeater->property("itemsFound").toList().count(), 4);
604 repeater->setModel(10);
605 QCOMPARE(repeater->count(), 10);
606 QCOMPARE(repeater->property("itemsCount").toInt(), 10);
607 QCOMPARE(repeater->property("itemsFound").toList().count(), 10);
612 void tst_QQuickRepeater::properties()
614 QDeclarativeEngine engine;
615 QDeclarativeComponent component(&engine, TEST_FILE("properties.qml"));
617 QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
620 QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater");
623 QSignalSpy modelSpy(repeater, SIGNAL(modelChanged()));
624 repeater->setModel(3);
625 QCOMPARE(modelSpy.count(),1);
626 repeater->setModel(3);
627 QCOMPARE(modelSpy.count(),1);
629 QSignalSpy delegateSpy(repeater, SIGNAL(delegateChanged()));
631 QDeclarativeComponent rectComponent(&engine);
632 rectComponent.setData("import QtQuick 2.0; Rectangle {}", QUrl::fromLocalFile(""));
634 repeater->setDelegate(&rectComponent);
635 QCOMPARE(delegateSpy.count(),1);
636 repeater->setDelegate(&rectComponent);
637 QCOMPARE(delegateSpy.count(),1);
642 void tst_QQuickRepeater::asynchronous()
644 QQuickView *canvas = createView();
646 QDeclarativeIncubationController controller;
647 canvas->engine()->setIncubationController(&controller);
649 canvas->setSource(TEST_FILE("asyncloader.qml"));
651 QQuickItem *rootObject = qobject_cast<QQuickItem*>(canvas->rootObject());
654 QQuickItem *container = findItem<QQuickItem>(rootObject, "container");
658 controller.incubateWhile(&b);
659 container = findItem<QQuickItem>(rootObject, "container");
662 QQuickRepeater *repeater = 0;
665 controller.incubateWhile(&b);
666 repeater = findItem<QQuickRepeater>(rootObject, "repeater");
669 // items will be created one at a time
670 for (int i = 0; i < 10; ++i) {
671 QString name("delegate");
672 name += QString::number(i);
673 QVERIFY(findItem<QQuickItem>(container, name) == 0);
674 QQuickItem *item = 0;
677 controller.incubateWhile(&b);
678 item = findItem<QQuickItem>(container, name);
684 controller.incubateWhile(&b);
687 // verify positioning
688 for (int i = 0; i < 10; ++i) {
689 QString name("delegate");
690 name += QString::number(i);
691 QQuickItem *item = findItem<QQuickItem>(container, name);
692 QTRY_COMPARE(item->y(), i * 50.0);
698 void tst_QQuickRepeater::initParent()
700 QDeclarativeEngine engine;
701 QDeclarativeComponent component(&engine, TEST_FILE("initparent.qml"));
703 QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
706 QCOMPARE(qvariant_cast<QQuickItem*>(rootObject->property("parentItem")), rootObject);
709 QQuickView *tst_QQuickRepeater::createView()
711 QQuickView *canvas = new QQuickView(0);
712 canvas->setGeometry(0,0,240,320);
718 T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName, int index)
720 const QMetaObject &mo = T::staticMetaObject;
721 //qDebug() << parent->children().count() << "children";
722 for (int i = 0; i < parent->children().count(); ++i) {
723 QQuickItem *item = qobject_cast<QQuickItem*>(parent->children().at(i));
726 //qDebug() << "try" << item;
727 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
729 QDeclarativeExpression e(qmlContext(item), item, "index");
730 if (e.evaluate().toInt() == index)
731 return static_cast<T*>(item);
733 return static_cast<T*>(item);
736 item = findItem<T>(item, objectName, index);
738 return static_cast<T*>(item);
745 T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName)
747 const QMetaObject &mo = T::staticMetaObject;
748 if (mo.cast(parent) && (objectName.isEmpty() || parent->objectName() == objectName))
749 return static_cast<T*>(parent);
750 for (int i = 0; i < parent->children().count(); ++i) {
751 QQuickItem *child = qobject_cast<QQuickItem*>(parent->children().at(i));
754 QQuickItem *item = findItem<T>(child, objectName);
756 return static_cast<T*>(item);
762 QTEST_MAIN(tst_QQuickRepeater)
764 #include "tst_qquickrepeater.moc"