f198510ad582b830f67bc0a4af7fbaef5e9b870b
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick1 / qdeclarativegridview / tst_qdeclarativegridview.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtTest/QtTest>
43 #include <QtCore/qstringlistmodel.h>
44 #include <QtQuick1/qdeclarativeview.h>
45 #include <QtDeclarative/qdeclarativeengine.h>
46 #include <QtDeclarative/qdeclarativecomponent.h>
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/qdeclarativeexpression.h>
49 #include <QtQuick1/private/qdeclarativeitem_p.h>
50 #include <QtQuick1/private/qdeclarativegridview_p.h>
51 #include <QtQuick1/private/qdeclarativetext_p.h>
52
53 class tst_QDeclarative1GridView : public QObject
54 {
55     Q_OBJECT
56 public:
57     tst_QDeclarative1GridView();
58
59 private slots:
60     void items();
61     void changed();
62     void inserted();
63     void removed();
64     void clear();
65     void moved();
66     void changeFlow();
67     void currentIndex();
68     void noCurrentIndex();
69     void defaultValues();
70     void properties();
71     void propertyChanges();
72     void componentChanges();
73     void modelChanges();
74     void positionViewAtIndex();
75     void positionViewAtIndex_rightToLeft();
76     void mirroring();
77     void snapping();
78     void resetModel();
79     void enforceRange();
80     void enforceRange_rightToLeft();
81     void QTBUG_8456();
82     void manualHighlight();
83     void footer();
84     void header();
85     void indexAt();
86     void onAdd();
87     void onAdd_data();
88     void onRemove();
89     void onRemove_data();
90     void testQtQuick11Attributes();
91     void testQtQuick11Attributes_data();
92     void contentPosJump();
93
94 private:
95     QDeclarativeView *createView();
96     template<typename T>
97     T *findItem(QGraphicsObject *parent, const QString &id, int index=-1);
98     template<typename T>
99     QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
100     void dumpTree(QDeclarativeItem *parent, int depth = 0);
101 };
102
103 class TestModel : public QAbstractListModel
104 {
105 public:
106     enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
107
108     TestModel(QObject *parent=0) : QAbstractListModel(parent) {
109         QHash<int, QByteArray> roles;
110         roles[Name] = "name";
111         roles[Number] = "number";
112         setRoleNames(roles);
113     }
114
115     int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
116     QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
117         QVariant rv;
118         if (role == Name)
119             rv = list.at(index.row()).first;
120         else if (role == Number)
121             rv = list.at(index.row()).second;
122
123         return rv;
124     }
125
126     int count() const { return rowCount(); }
127     QString name(int index) const { return list.at(index).first; }
128     QString number(int index) const { return list.at(index).second; }
129
130     void addItem(const QString &name, const QString &number) {
131         emit beginInsertRows(QModelIndex(), list.count(), list.count());
132         list.append(QPair<QString,QString>(name, number));
133         emit endInsertRows();
134     }
135
136     void addItems(const QList<QPair<QString, QString> > &items) {
137         emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
138         for (int i=0; i<items.count(); i++)
139             list.append(QPair<QString,QString>(items[i].first, items[i].second));
140         emit endInsertRows();
141     }
142
143     void insertItem(int index, const QString &name, const QString &number) {
144         emit beginInsertRows(QModelIndex(), index, index);
145         list.insert(index, QPair<QString,QString>(name, number));
146         emit endInsertRows();
147     }
148
149     void removeItem(int index) {
150         emit beginRemoveRows(QModelIndex(), index, index);
151         list.removeAt(index);
152         emit endRemoveRows();
153     }
154
155     void removeItems(int index, int count) {
156         emit beginRemoveRows(QModelIndex(), index, index+count-1);
157         while (count--)
158             list.removeAt(index);
159         emit endRemoveRows();
160     }
161
162     void moveItem(int from, int to) {
163         emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
164         list.move(from, to);
165         emit endMoveRows();
166     }
167
168     void modifyItem(int idx, const QString &name, const QString &number) {
169         list[idx] = QPair<QString,QString>(name, number);
170         emit dataChanged(index(idx,0), index(idx,0));
171     }
172
173     void clear() {
174         int count = list.count();
175         emit beginRemoveRows(QModelIndex(), 0, count-1);
176         list.clear();
177         emit endRemoveRows();
178     }
179
180
181 private:
182     QList<QPair<QString,QString> > list;
183 };
184
185 tst_QDeclarative1GridView::tst_QDeclarative1GridView()
186 {
187 }
188
189 void tst_QDeclarative1GridView::items()
190 {
191     QDeclarativeView *canvas = createView();
192
193     TestModel model;
194     model.addItem("Fred", "12345");
195     model.addItem("John", "2345");
196     model.addItem("Bob", "54321");
197     model.addItem("Billy", "22345");
198     model.addItem("Sam", "2945");
199     model.addItem("Ben", "04321");
200     model.addItem("Jim", "0780");
201
202     QDeclarativeContext *ctxt = canvas->rootContext();
203     ctxt->setContextProperty("testModel", &model);
204     ctxt->setContextProperty("testRightToLeft", QVariant(false));
205     ctxt->setContextProperty("testTopToBottom", QVariant(false));
206
207     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
208     qApp->processEvents();
209
210     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
211     QTRY_VERIFY(gridview != 0);
212
213     QDeclarativeItem *contentItem = gridview->contentItem();
214     QTRY_VERIFY(contentItem != 0);
215
216     QTRY_COMPARE(gridview->count(), model.count());
217     QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
218     QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
219
220     for (int i = 0; i < model.count(); ++i) {
221         QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", i);
222         QTRY_VERIFY(name != 0);
223         QTRY_COMPARE(name->text(), model.name(i));
224         QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
225         QTRY_VERIFY(number != 0);
226         QTRY_COMPARE(number->text(), model.number(i));
227     }
228
229     // set an empty model and confirm that items are destroyed
230     TestModel model2;
231     ctxt->setContextProperty("testModel", &model2);
232
233     int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
234     QTRY_VERIFY(itemCount == 0);
235
236     delete canvas;
237 }
238
239 void tst_QDeclarative1GridView::changed()
240 {
241     QDeclarativeView *canvas = createView();
242
243     TestModel model;
244     model.addItem("Fred", "12345");
245     model.addItem("John", "2345");
246     model.addItem("Bob", "54321");
247     model.addItem("Billy", "22345");
248     model.addItem("Sam", "2945");
249     model.addItem("Ben", "04321");
250     model.addItem("Jim", "0780");
251
252     QDeclarativeContext *ctxt = canvas->rootContext();
253     ctxt->setContextProperty("testModel", &model);
254     ctxt->setContextProperty("testRightToLeft", QVariant(false));
255     ctxt->setContextProperty("testTopToBottom", QVariant(false));
256
257     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
258     qApp->processEvents();
259
260     QDeclarative1Flickable *gridview = findItem<QDeclarative1Flickable>(canvas->rootObject(), "grid");
261     QTRY_VERIFY(gridview != 0);
262
263     QDeclarativeItem *contentItem = gridview->contentItem();
264     QTRY_VERIFY(contentItem != 0);
265
266     model.modifyItem(1, "Will", "9876");
267     QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
268     QTRY_VERIFY(name != 0);
269     QTRY_COMPARE(name->text(), model.name(1));
270     QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
271     QTRY_VERIFY(number != 0);
272     QTRY_COMPARE(number->text(), model.number(1));
273
274     delete canvas;
275 }
276
277 void tst_QDeclarative1GridView::inserted()
278 {
279     QDeclarativeView *canvas = createView();
280
281     TestModel model;
282     model.addItem("Fred", "12345");
283     model.addItem("John", "2345");
284     model.addItem("Bob", "54321");
285
286     QDeclarativeContext *ctxt = canvas->rootContext();
287     ctxt->setContextProperty("testModel", &model);
288     ctxt->setContextProperty("testRightToLeft", QVariant(false));
289     ctxt->setContextProperty("testTopToBottom", QVariant(false));
290
291     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
292     qApp->processEvents();
293
294     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
295     QTRY_VERIFY(gridview != 0);
296
297     QDeclarativeItem *contentItem = gridview->contentItem();
298     QTRY_VERIFY(contentItem != 0);
299
300     model.insertItem(1, "Will", "9876");
301     QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
302
303     QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
304
305     QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
306     QTRY_VERIFY(name != 0);
307     QTRY_COMPARE(name->text(), model.name(1));
308     QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
309     QTRY_VERIFY(number != 0);
310     QTRY_COMPARE(number->text(), model.number(1));
311
312     // Checks that onAdd is called
313     int added = canvas->rootObject()->property("added").toInt();
314     QTRY_COMPARE(added, 1);
315
316     // Confirm items positioned correctly
317     for (int i = 0; i < model.count(); ++i) {
318         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
319         QTRY_COMPARE(item->x(), (i%3)*80.0);
320         QTRY_COMPARE(item->y(), (i/3)*60.0);
321     }
322
323     model.insertItem(0, "Foo", "1111"); // zero index, and current item
324
325     QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
326
327     name = findItem<QDeclarative1Text>(contentItem, "textName", 0);
328     QTRY_VERIFY(name != 0);
329     QTRY_COMPARE(name->text(), model.name(0));
330     number = findItem<QDeclarative1Text>(contentItem, "textNumber", 0);
331     QTRY_VERIFY(number != 0);
332     QTRY_COMPARE(number->text(), model.number(0));
333
334     QTRY_COMPARE(gridview->currentIndex(), 1);
335
336     // Confirm items positioned correctly
337     for (int i = 0; i < model.count(); ++i) {
338         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
339         QTRY_VERIFY(item->x() == (i%3)*80);
340         QTRY_VERIFY(item->y() == (i/3)*60);
341     }
342
343     for (int i = model.count(); i < 30; ++i)
344         model.insertItem(i, "Hello", QString::number(i));
345
346     gridview->setContentY(120);
347
348     // Insert item outside visible area
349     model.insertItem(1, "Hello", "1324");
350
351     QTRY_VERIFY(gridview->contentY() == 120);
352
353     delete canvas;
354 }
355
356 void tst_QDeclarative1GridView::removed()
357 {
358     QDeclarativeView *canvas = createView();
359
360     TestModel model;
361     for (int i = 0; i < 40; i++)
362         model.addItem("Item" + QString::number(i), "");
363
364     QDeclarativeContext *ctxt = canvas->rootContext();
365     ctxt->setContextProperty("testModel", &model);
366     ctxt->setContextProperty("testRightToLeft", QVariant(false));
367     ctxt->setContextProperty("testTopToBottom", QVariant(false));
368
369     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
370     qApp->processEvents();
371
372     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
373     QTRY_VERIFY(gridview != 0);
374
375     QDeclarativeItem *contentItem = gridview->contentItem();
376     QTRY_VERIFY(contentItem != 0);
377
378     model.removeItem(1);
379     QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
380
381     QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
382     QTRY_VERIFY(name != 0);
383     QTRY_COMPARE(name->text(), model.name(1));
384     QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
385     QTRY_VERIFY(number != 0);
386     QTRY_COMPARE(number->text(), model.number(1));
387
388     // Checks that onRemove is called
389     QString removed = canvas->rootObject()->property("removed").toString();
390     QTRY_COMPARE(removed, QString("Item1"));
391
392     // Confirm items positioned correctly
393     int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
394     for (int i = 0; i < model.count() && i < itemCount; ++i) {
395         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
396         if (!item) qWarning() << "Item" << i << "not found";
397         QTRY_VERIFY(item);
398         QTRY_VERIFY(item->x() == (i%3)*80);
399         QTRY_VERIFY(item->y() == (i/3)*60);
400     }
401
402     // Remove first item (which is the current item);
403     model.removeItem(0);
404
405     name = findItem<QDeclarative1Text>(contentItem, "textName", 0);
406     QTRY_VERIFY(name != 0);
407     QTRY_COMPARE(name->text(), model.name(0));
408     number = findItem<QDeclarative1Text>(contentItem, "textNumber", 0);
409     QTRY_VERIFY(number != 0);
410     QTRY_COMPARE(number->text(), model.number(0));
411
412     // Confirm items positioned correctly
413     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
414     for (int i = 0; i < model.count() && i < itemCount; ++i) {
415         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
416         if (!item) qWarning() << "Item" << i << "not found";
417         QTRY_VERIFY(item);
418         QTRY_VERIFY(item->x() == (i%3)*80);
419         QTRY_VERIFY(item->y() == (i/3)*60);
420     }
421
422     // Remove items not visible
423     model.removeItem(25);
424
425     // Confirm items positioned correctly
426     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
427     for (int i = 0; i < model.count() && i < itemCount; ++i) {
428         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
429         if (!item) qWarning() << "Item" << i << "not found";
430         QTRY_VERIFY(item);
431         QTRY_VERIFY(item->x() == (i%3)*80);
432         QTRY_VERIFY(item->y() == (i/3)*60);
433     }
434
435     // Remove items before visible
436     gridview->setContentY(120);
437     gridview->setCurrentIndex(10);
438
439     // Setting currentIndex above shouldn't cause view to scroll
440     QTRY_COMPARE(gridview->contentY(), 120.0);
441
442     model.removeItem(1);
443
444     // Confirm items positioned correctly
445     for (int i = 3; i < 15; ++i) {
446         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
447         if (!item) qWarning() << "Item" << i << "not found";
448         QTRY_VERIFY(item);
449         QTRY_COMPARE(item->x(), (i%3)*80.0);
450         QTRY_COMPARE(item->y(), 60+(i/3)*60.0);
451     }
452
453     // Remove currentIndex
454     QDeclarativeItem *oldCurrent = gridview->currentItem();
455     model.removeItem(9);
456
457     QTRY_COMPARE(gridview->currentIndex(), 9);
458     QTRY_VERIFY(gridview->currentItem() != oldCurrent);
459
460     gridview->setContentY(0);
461     // let transitions settle.
462     QTest::qWait(100);
463
464     // Confirm items positioned correctly
465     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
466     for (int i = 0; i < model.count() && i < itemCount; ++i) {
467         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
468         if (!item) qWarning() << "Item" << i << "not found";
469         QTRY_VERIFY(item);
470         QTRY_VERIFY(item->x() == (i%3)*80);
471         QTRY_VERIFY(item->y() == 60+(i/3)*60);
472     }
473
474     // remove item outside current view.
475     gridview->setCurrentIndex(32);
476     gridview->setContentY(240);
477
478     model.removeItem(30);
479     QTRY_VERIFY(gridview->currentIndex() == 31);
480
481     // remove current item beyond visible items.
482     gridview->setCurrentIndex(20);
483     gridview->setContentY(0);
484     model.removeItem(20);
485
486     QTRY_COMPARE(gridview->currentIndex(), 20);
487     QTRY_VERIFY(gridview->currentItem() != 0);
488
489     // remove item before current, but visible
490     gridview->setCurrentIndex(8);
491     gridview->setContentY(240);
492     oldCurrent = gridview->currentItem();
493     model.removeItem(6);
494
495     QTRY_COMPARE(gridview->currentIndex(), 7);
496     QTRY_VERIFY(gridview->currentItem() == oldCurrent);
497
498     delete canvas;
499 }
500
501 void tst_QDeclarative1GridView::clear()
502 {
503     QDeclarativeView *canvas = createView();
504
505     TestModel model;
506     for (int i = 0; i < 30; i++)
507         model.addItem("Item" + QString::number(i), "");
508
509     QDeclarativeContext *ctxt = canvas->rootContext();
510     ctxt->setContextProperty("testModel", &model);
511     ctxt->setContextProperty("testRightToLeft", QVariant(false));
512     ctxt->setContextProperty("testTopToBottom", QVariant(false));
513
514     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
515     qApp->processEvents();
516
517     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
518     QVERIFY(gridview != 0);
519
520     QDeclarativeItem *contentItem = gridview->contentItem();
521     QVERIFY(contentItem != 0);
522
523     model.clear();
524
525     QVERIFY(gridview->count() == 0);
526     QVERIFY(gridview->currentItem() == 0);
527     QVERIFY(gridview->contentY() == 0);
528     QVERIFY(gridview->currentIndex() == -1);
529
530     // confirm sanity when adding an item to cleared list
531     model.addItem("New", "1");
532     QVERIFY(gridview->count() == 1);
533     QVERIFY(gridview->currentItem() != 0);
534     QVERIFY(gridview->currentIndex() == 0);
535
536     delete canvas;
537 }
538
539 void tst_QDeclarative1GridView::moved()
540 {
541     QDeclarativeView *canvas = createView();
542
543     TestModel model;
544     for (int i = 0; i < 30; i++)
545         model.addItem("Item" + QString::number(i), "");
546
547     QDeclarativeContext *ctxt = canvas->rootContext();
548     ctxt->setContextProperty("testModel", &model);
549     ctxt->setContextProperty("testRightToLeft", QVariant(false));
550     ctxt->setContextProperty("testTopToBottom", QVariant(false));
551
552     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
553     qApp->processEvents();
554
555     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
556     QTRY_VERIFY(gridview != 0);
557
558     QDeclarativeItem *contentItem = gridview->contentItem();
559     QTRY_VERIFY(contentItem != 0);
560
561     model.moveItem(1, 8);
562
563     QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
564     QTRY_VERIFY(name != 0);
565     QTRY_COMPARE(name->text(), model.name(1));
566     QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
567     QTRY_VERIFY(number != 0);
568     QTRY_COMPARE(number->text(), model.number(1));
569
570     name = findItem<QDeclarative1Text>(contentItem, "textName", 8);
571     QTRY_VERIFY(name != 0);
572     QTRY_COMPARE(name->text(), model.name(8));
573     number = findItem<QDeclarative1Text>(contentItem, "textNumber", 8);
574     QTRY_VERIFY(number != 0);
575     QTRY_COMPARE(number->text(), model.number(8));
576
577     // Confirm items positioned correctly
578     int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
579     for (int i = 0; i < model.count() && i < itemCount; ++i) {
580         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
581         if (!item) qWarning() << "Item" << i << "not found";
582         QTRY_VERIFY(item);
583         QTRY_VERIFY(item->x() == (i%3)*80);
584         QTRY_VERIFY(item->y() == (i/3)*60);
585     }
586
587     gridview->setContentY(120);
588
589     // move outside visible area
590     model.moveItem(1, 25);
591
592     // Confirm items positioned correctly and indexes correct
593     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count()-1;
594     for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
595         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
596         if (!item) qWarning() << "Item" << i << "not found";
597         QTRY_VERIFY(item);
598         QTRY_COMPARE(item->x(), qreal((i%3)*80));
599         QTRY_COMPARE(item->y(), qreal((i/3)*60));
600         name = findItem<QDeclarative1Text>(contentItem, "textName", i);
601         QTRY_VERIFY(name != 0);
602         QTRY_COMPARE(name->text(), model.name(i));
603         number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
604         QTRY_VERIFY(number != 0);
605         QTRY_COMPARE(number->text(), model.number(i));
606     }
607
608     // move from outside visible into visible
609     model.moveItem(28, 8);
610
611     // Confirm items positioned correctly and indexes correct
612     for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
613         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
614         if (!item) qWarning() << "Item" << i << "not found";
615         QTRY_VERIFY(item);
616         QTRY_VERIFY(item->x() == (i%3)*80);
617         QTRY_VERIFY(item->y() == (i/3)*60);
618         name = findItem<QDeclarative1Text>(contentItem, "textName", i);
619         QTRY_VERIFY(name != 0);
620         QTRY_COMPARE(name->text(), model.name(i));
621         number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
622         QTRY_VERIFY(number != 0);
623         QTRY_COMPARE(number->text(), model.number(i));
624     }
625
626     // ensure content position is stable
627     gridview->setContentY(0);
628     model.moveItem(10, 0);
629     QTRY_VERIFY(gridview->contentY() == 0);
630
631     delete canvas;
632 }
633
634 void tst_QDeclarative1GridView::currentIndex()
635 {
636     TestModel model;
637     for (int i = 0; i < 60; i++)
638         model.addItem("Item" + QString::number(i), QString::number(i));
639
640     QDeclarativeView *canvas = new QDeclarativeView(0);
641     canvas->setFixedSize(240,320);
642
643     QDeclarativeContext *ctxt = canvas->rootContext();
644     ctxt->setContextProperty("testModel", &model);
645
646     QString filename(SRCDIR "/data/gridview-initCurrent.qml");
647     canvas->setSource(QUrl::fromLocalFile(filename));
648
649     qApp->processEvents();
650
651     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
652     QVERIFY(gridview != 0);
653
654     QDeclarativeItem *contentItem = gridview->contentItem();
655     QVERIFY(contentItem != 0);
656
657     // current item should be third item
658     QCOMPARE(gridview->currentIndex(), 35);
659     QCOMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 35));
660     QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y());
661     QCOMPARE(gridview->contentY(), 400.0);
662
663     gridview->moveCurrentIndexRight();
664     QCOMPARE(gridview->currentIndex(), 36);
665     gridview->moveCurrentIndexDown();
666     QCOMPARE(gridview->currentIndex(), 39);
667     gridview->moveCurrentIndexUp();
668     QCOMPARE(gridview->currentIndex(), 36);
669     gridview->moveCurrentIndexLeft();
670     QCOMPARE(gridview->currentIndex(), 35);
671
672     // no wrap
673     gridview->setCurrentIndex(0);
674     QCOMPARE(gridview->currentIndex(), 0);
675     // confirm that the velocity is updated
676     QTRY_VERIFY(gridview->verticalVelocity() != 0.0);
677
678     gridview->moveCurrentIndexUp();
679     QCOMPARE(gridview->currentIndex(), 0);
680
681     gridview->moveCurrentIndexLeft();
682     QCOMPARE(gridview->currentIndex(), 0);
683
684     gridview->setCurrentIndex(model.count()-1);
685     QCOMPARE(gridview->currentIndex(), model.count()-1);
686
687     gridview->moveCurrentIndexRight();
688     QCOMPARE(gridview->currentIndex(), model.count()-1);
689
690     gridview->moveCurrentIndexDown();
691     QCOMPARE(gridview->currentIndex(), model.count()-1);
692
693     // with wrap
694     gridview->setWrapEnabled(true);
695
696     gridview->setCurrentIndex(0);
697     QCOMPARE(gridview->currentIndex(), 0);
698
699     gridview->moveCurrentIndexLeft();
700     QCOMPARE(gridview->currentIndex(), model.count()-1);
701
702     QTRY_COMPARE(gridview->contentY(), 880.0);
703
704     gridview->moveCurrentIndexRight();
705     QCOMPARE(gridview->currentIndex(), 0);
706
707     QTRY_COMPARE(gridview->contentY(), 0.0);
708
709     // Test keys
710     canvas->show();
711     qApp->setActiveWindow(canvas);
712 #ifdef Q_WS_X11
713     // to be safe and avoid failing setFocus with window managers
714     qt_x11_wait_for_window_manager(canvas);
715 #endif
716     QTRY_VERIFY(canvas->hasFocus());
717     QTRY_VERIFY(canvas->scene()->hasFocus());
718     qApp->processEvents();
719
720     QTest::keyClick(canvas, Qt::Key_Down);
721     QCOMPARE(gridview->currentIndex(), 3);
722
723     QTest::keyClick(canvas, Qt::Key_Up);
724     QCOMPARE(gridview->currentIndex(), 0);
725
726     gridview->setFlow(QDeclarative1GridView::TopToBottom);
727
728     qApp->setActiveWindow(canvas);
729 #ifdef Q_WS_X11
730     // to be safe and avoid failing setFocus with window managers
731     qt_x11_wait_for_window_manager(canvas);
732 #endif
733     QTRY_VERIFY(canvas->hasFocus());
734     QTRY_VERIFY(canvas->scene()->hasFocus());
735     qApp->processEvents();
736
737     QTest::keyClick(canvas, Qt::Key_Right);
738     QCOMPARE(gridview->currentIndex(), 5);
739
740     QTest::keyClick(canvas, Qt::Key_Left);
741     QCOMPARE(gridview->currentIndex(), 0);
742
743     QTest::keyClick(canvas, Qt::Key_Down);
744     QCOMPARE(gridview->currentIndex(), 1);
745
746     QTest::keyClick(canvas, Qt::Key_Up);
747     QCOMPARE(gridview->currentIndex(), 0);
748
749
750     // turn off auto highlight
751     gridview->setHighlightFollowsCurrentItem(false);
752     QVERIFY(gridview->highlightFollowsCurrentItem() == false);
753     QVERIFY(gridview->highlightItem());
754     qreal hlPosX = gridview->highlightItem()->x();
755     qreal hlPosY = gridview->highlightItem()->y();
756
757     gridview->setCurrentIndex(5);
758     QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
759     QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
760
761     // insert item before currentIndex
762     gridview->setCurrentIndex(28);
763     model.insertItem(0, "Foo", "1111");
764     QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
765
766     // check removing highlight by setting currentIndex to -1;
767     gridview->setCurrentIndex(-1);
768
769     QCOMPARE(gridview->currentIndex(), -1);
770     QVERIFY(!gridview->highlightItem());
771     QVERIFY(!gridview->currentItem());
772
773     gridview->setHighlightFollowsCurrentItem(true);
774
775     gridview->setFlow(QDeclarative1GridView::LeftToRight);
776     gridview->setLayoutDirection(Qt::RightToLeft);
777
778     qApp->setActiveWindow(canvas);
779 #ifdef Q_WS_X11
780     // to be safe and avoid failing setFocus with window managers
781     qt_x11_wait_for_window_manager(canvas);
782 #endif
783     QTRY_VERIFY(canvas->hasFocus());
784     QTRY_VERIFY(canvas->scene()->hasFocus());
785     qApp->processEvents();
786
787     gridview->setCurrentIndex(35);
788
789     QTest::keyClick(canvas, Qt::Key_Right);
790     QCOMPARE(gridview->currentIndex(), 34);
791
792     QTest::keyClick(canvas, Qt::Key_Down);
793     QCOMPARE(gridview->currentIndex(), 37);
794
795     QTest::keyClick(canvas, Qt::Key_Up);
796     QCOMPARE(gridview->currentIndex(), 34);
797
798     QTest::keyClick(canvas, Qt::Key_Left);
799     QCOMPARE(gridview->currentIndex(), 35);
800
801
802     // turn off auto highlight
803     gridview->setHighlightFollowsCurrentItem(false);
804     QVERIFY(gridview->highlightFollowsCurrentItem() == false);
805     QVERIFY(gridview->highlightItem());
806     hlPosX = gridview->highlightItem()->x();
807     hlPosY = gridview->highlightItem()->y();
808
809     gridview->setCurrentIndex(5);
810     QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
811     QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
812
813     // insert item before currentIndex
814     gridview->setCurrentIndex(28);
815     model.insertItem(0, "Foo", "1111");
816     QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
817
818     // check removing highlight by setting currentIndex to -1;
819     gridview->setCurrentIndex(-1);
820
821     QCOMPARE(gridview->currentIndex(), -1);
822     QVERIFY(!gridview->highlightItem());
823     QVERIFY(!gridview->currentItem());
824
825     delete canvas;
826 }
827
828 void tst_QDeclarative1GridView::noCurrentIndex()
829 {
830     TestModel model;
831     for (int i = 0; i < 60; i++)
832         model.addItem("Item" + QString::number(i), QString::number(i));
833
834     QDeclarativeView *canvas = new QDeclarativeView(0);
835     canvas->setFixedSize(240,320);
836
837     QDeclarativeContext *ctxt = canvas->rootContext();
838     ctxt->setContextProperty("testModel", &model);
839
840     QString filename(SRCDIR "/data/gridview-noCurrent.qml");
841     canvas->setSource(QUrl::fromLocalFile(filename));
842
843     qApp->processEvents();
844
845     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
846     QVERIFY(gridview != 0);
847
848     QDeclarativeItem *contentItem = gridview->contentItem();
849     QVERIFY(contentItem != 0);
850
851     // current index should be -1
852     QCOMPARE(gridview->currentIndex(), -1);
853     QVERIFY(!gridview->currentItem());
854     QVERIFY(!gridview->highlightItem());
855     QCOMPARE(gridview->contentY(), 0.0);
856
857     gridview->setCurrentIndex(5);
858     QCOMPARE(gridview->currentIndex(), 5);
859     QVERIFY(gridview->currentItem());
860     QVERIFY(gridview->highlightItem());
861
862     delete canvas;
863 }
864
865 void tst_QDeclarative1GridView::changeFlow()
866 {
867     QDeclarativeView *canvas = createView();
868
869     TestModel model;
870     for (int i = 0; i < 30; i++)
871         model.addItem("Item" + QString::number(i), QString::number(i));
872
873     QDeclarativeContext *ctxt = canvas->rootContext();
874     ctxt->setContextProperty("testModel", &model);
875     ctxt->setContextProperty("testRightToLeft", QVariant(false));
876     ctxt->setContextProperty("testTopToBottom", QVariant(false));
877
878     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
879     qApp->processEvents();
880
881     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
882     QTRY_VERIFY(gridview != 0);
883
884     QDeclarativeItem *contentItem = gridview->contentItem();
885     QTRY_VERIFY(contentItem != 0);
886
887     // Confirm items positioned correctly and indexes correct
888     int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
889     for (int i = 0; i < model.count() && i < itemCount; ++i) {
890         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
891         if (!item) qWarning() << "Item" << i << "not found";
892         QTRY_VERIFY(item);
893         QTRY_COMPARE(item->x(), qreal((i%3)*80));
894         QTRY_COMPARE(item->y(), qreal((i/3)*60));
895         QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", i);
896         QTRY_VERIFY(name != 0);
897         QTRY_COMPARE(name->text(), model.name(i));
898         QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
899         QTRY_VERIFY(number != 0);
900         QTRY_COMPARE(number->text(), model.number(i));
901     }
902
903     ctxt->setContextProperty("testTopToBottom", QVariant(true));
904
905     // Confirm items positioned correctly and indexes correct
906     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
907     for (int i = 0; i < model.count() && i < itemCount; ++i) {
908         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
909         if (!item) qWarning() << "Item" << i << "not found";
910         QTRY_VERIFY(item);
911         QTRY_COMPARE(item->x(), qreal((i/5)*80));
912         QTRY_COMPARE(item->y(), qreal((i%5)*60));
913         QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", i);
914         QTRY_VERIFY(name != 0);
915         QTRY_COMPARE(name->text(), model.name(i));
916         QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
917         QTRY_VERIFY(number != 0);
918         QTRY_COMPARE(number->text(), model.number(i));
919     }
920
921     ctxt->setContextProperty("testRightToLeft", QVariant(true));
922
923     // Confirm items positioned correctly and indexes correct
924     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
925     for (int i = 0; i < model.count() && i < itemCount; ++i) {
926         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
927         if (!item) qWarning() << "Item" << i << "not found";
928         QTRY_VERIFY(item);
929         QTRY_COMPARE(item->x(), qreal(-(i/5)*80 - item->width()));
930         QTRY_COMPARE(item->y(), qreal((i%5)*60));
931         QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", i);
932         QTRY_VERIFY(name != 0);
933         QTRY_COMPARE(name->text(), model.name(i));
934         QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
935         QTRY_VERIFY(number != 0);
936         QTRY_COMPARE(number->text(), model.number(i));
937     }
938     gridview->setContentX(100);
939     QTRY_COMPARE(gridview->contentX(), 100.);
940     ctxt->setContextProperty("testTopToBottom", QVariant(false));
941     QTRY_COMPARE(gridview->contentX(), 0.);
942
943     // Confirm items positioned correctly and indexes correct
944     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
945     for (int i = 0; i < model.count() && i < itemCount; ++i) {
946         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
947         if (!item) qWarning() << "Item" << i << "not found";
948         QTRY_VERIFY(item);
949         QTRY_COMPARE(item->x(), qreal(240 - (i%3+1)*80));
950         QTRY_COMPARE(item->y(), qreal((i/3)*60));
951         QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", i);
952         QTRY_VERIFY(name != 0);
953         QTRY_COMPARE(name->text(), model.name(i));
954         QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
955         QTRY_VERIFY(number != 0);
956         QTRY_COMPARE(number->text(), model.number(i));
957     }
958
959     delete canvas;
960 }
961
962 void tst_QDeclarative1GridView::defaultValues()
963 {
964     QDeclarativeEngine engine;
965     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview3.qml"));
966     QDeclarative1GridView *obj = qobject_cast<QDeclarative1GridView*>(c.create());
967
968     QTRY_VERIFY(obj != 0);
969     QTRY_VERIFY(obj->model() == QVariant());
970     QTRY_VERIFY(obj->delegate() == 0);
971     QTRY_COMPARE(obj->currentIndex(), -1);
972     QTRY_VERIFY(obj->currentItem() == 0);
973     QTRY_COMPARE(obj->count(), 0);
974     QTRY_VERIFY(obj->highlight() == 0);
975     QTRY_VERIFY(obj->highlightItem() == 0);
976     QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true);
977     QTRY_VERIFY(obj->flow() == 0);
978     QTRY_COMPARE(obj->isWrapEnabled(), false);
979     QTRY_COMPARE(obj->cacheBuffer(), 0);
980     QTRY_COMPARE(obj->cellWidth(), 100); //### Should 100 be the default?
981     QTRY_COMPARE(obj->cellHeight(), 100);
982     delete obj;
983 }
984
985 void tst_QDeclarative1GridView::properties()
986 {
987     QDeclarativeEngine engine;
988     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview2.qml"));
989     QDeclarative1GridView *obj = qobject_cast<QDeclarative1GridView*>(c.create());
990
991     QTRY_VERIFY(obj != 0);
992     QTRY_VERIFY(obj->model() != QVariant());
993     QTRY_VERIFY(obj->delegate() != 0);
994     QTRY_COMPARE(obj->currentIndex(), 0);
995     QTRY_VERIFY(obj->currentItem() != 0);
996     QTRY_COMPARE(obj->count(), 4);
997     QTRY_VERIFY(obj->highlight() != 0);
998     QTRY_VERIFY(obj->highlightItem() != 0);
999     QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false);
1000     QTRY_VERIFY(obj->flow() == 0);
1001     QTRY_COMPARE(obj->isWrapEnabled(), true);
1002     QTRY_COMPARE(obj->cacheBuffer(), 200);
1003     QTRY_COMPARE(obj->cellWidth(), 100);
1004     QTRY_COMPARE(obj->cellHeight(), 100);
1005     delete obj;
1006 }
1007
1008 void tst_QDeclarative1GridView::propertyChanges()
1009 {
1010     QDeclarativeView *canvas = createView();
1011     QTRY_VERIFY(canvas);
1012     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1013
1014     QDeclarative1GridView *gridView = canvas->rootObject()->findChild<QDeclarative1GridView*>("gridView");
1015     QTRY_VERIFY(gridView);
1016
1017     QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged()));
1018     QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged()));
1019     QSignalSpy layoutSpy(gridView, SIGNAL(layoutDirectionChanged()));
1020     QSignalSpy flowSpy(gridView, SIGNAL(flowChanged()));
1021
1022     QTRY_COMPARE(gridView->isWrapEnabled(), true);
1023     QTRY_COMPARE(gridView->cacheBuffer(), 10);
1024     QTRY_COMPARE(gridView->flow(), QDeclarative1GridView::LeftToRight);
1025
1026     gridView->setWrapEnabled(false);
1027     gridView->setCacheBuffer(3);
1028     gridView->setFlow(QDeclarative1GridView::TopToBottom);
1029
1030     QTRY_COMPARE(gridView->isWrapEnabled(), false);
1031     QTRY_COMPARE(gridView->cacheBuffer(), 3);
1032     QTRY_COMPARE(gridView->flow(), QDeclarative1GridView::TopToBottom);
1033
1034     QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1035     QTRY_COMPARE(cacheBufferSpy.count(),1);
1036     QTRY_COMPARE(flowSpy.count(),1);
1037
1038     gridView->setWrapEnabled(false);
1039     gridView->setCacheBuffer(3);
1040     gridView->setFlow(QDeclarative1GridView::TopToBottom);
1041
1042     QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1043     QTRY_COMPARE(cacheBufferSpy.count(),1);
1044     QTRY_COMPARE(flowSpy.count(),1);
1045
1046     gridView->setFlow(QDeclarative1GridView::LeftToRight);
1047     QTRY_COMPARE(gridView->flow(), QDeclarative1GridView::LeftToRight);
1048
1049     gridView->setWrapEnabled(true);
1050     gridView->setCacheBuffer(5);
1051     gridView->setLayoutDirection(Qt::RightToLeft);
1052
1053     QTRY_COMPARE(gridView->isWrapEnabled(), true);
1054     QTRY_COMPARE(gridView->cacheBuffer(), 5);
1055     QTRY_COMPARE(gridView->layoutDirection(), Qt::RightToLeft);
1056
1057     QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
1058     QTRY_COMPARE(cacheBufferSpy.count(),2);
1059     QTRY_COMPARE(layoutSpy.count(),1);
1060     QTRY_COMPARE(flowSpy.count(),2);
1061
1062     gridView->setWrapEnabled(true);
1063     gridView->setCacheBuffer(5);
1064     gridView->setLayoutDirection(Qt::RightToLeft);
1065
1066     QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
1067     QTRY_COMPARE(cacheBufferSpy.count(),2);
1068     QTRY_COMPARE(layoutSpy.count(),1);
1069     QTRY_COMPARE(flowSpy.count(),2);
1070
1071     gridView->setFlow(QDeclarative1GridView::TopToBottom);
1072     QTRY_COMPARE(gridView->flow(), QDeclarative1GridView::TopToBottom);
1073     QTRY_COMPARE(flowSpy.count(),3);
1074
1075     gridView->setFlow(QDeclarative1GridView::TopToBottom);
1076     QTRY_COMPARE(flowSpy.count(),3);
1077
1078     delete canvas;
1079 }
1080
1081 void tst_QDeclarative1GridView::componentChanges()
1082 {
1083     QDeclarativeView *canvas = createView();
1084     QTRY_VERIFY(canvas);
1085     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1086
1087     QDeclarative1GridView *gridView = canvas->rootObject()->findChild<QDeclarative1GridView*>("gridView");
1088     QTRY_VERIFY(gridView);
1089
1090     QDeclarativeComponent component(canvas->engine());
1091     component.setData("import QtQuick 1.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
1092
1093     QDeclarativeComponent delegateComponent(canvas->engine());
1094     delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
1095
1096     QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged()));
1097     QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged()));
1098     QSignalSpy headerSpy(gridView, SIGNAL(headerChanged()));
1099     QSignalSpy footerSpy(gridView, SIGNAL(footerChanged()));
1100
1101     gridView->setHighlight(&component);
1102     gridView->setDelegate(&delegateComponent);
1103     gridView->setHeader(&component);
1104     gridView->setFooter(&component);
1105
1106     QTRY_COMPARE(gridView->highlight(), &component);
1107     QTRY_COMPARE(gridView->delegate(), &delegateComponent);
1108     QTRY_COMPARE(gridView->header(), &component);
1109     QTRY_COMPARE(gridView->footer(), &component);
1110
1111     QTRY_COMPARE(highlightSpy.count(),1);
1112     QTRY_COMPARE(delegateSpy.count(),1);
1113     QTRY_COMPARE(headerSpy.count(),1);
1114     QTRY_COMPARE(footerSpy.count(),1);
1115
1116     gridView->setHighlight(&component);
1117     gridView->setDelegate(&delegateComponent);
1118     gridView->setHeader(&component);
1119     gridView->setFooter(&component);
1120
1121     QTRY_COMPARE(highlightSpy.count(),1);
1122     QTRY_COMPARE(delegateSpy.count(),1);
1123     QTRY_COMPARE(headerSpy.count(),1);
1124     QTRY_COMPARE(footerSpy.count(),1);
1125
1126     delete canvas;
1127 }
1128
1129 void tst_QDeclarative1GridView::modelChanges()
1130 {
1131     QDeclarativeView *canvas = createView();
1132     QTRY_VERIFY(canvas);
1133     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1134
1135     QDeclarative1GridView *gridView = canvas->rootObject()->findChild<QDeclarative1GridView*>("gridView");
1136     QTRY_VERIFY(gridView);
1137
1138     QObject *alternateModel = canvas->rootObject()->findChild<QObject*>("alternateModel");
1139     QTRY_VERIFY(alternateModel);
1140     QVariant modelVariant = QVariant::fromValue(alternateModel);
1141     QSignalSpy modelSpy(gridView, SIGNAL(modelChanged()));
1142
1143     gridView->setModel(modelVariant);
1144     QTRY_COMPARE(gridView->model(), modelVariant);
1145     QTRY_COMPARE(modelSpy.count(),1);
1146
1147     gridView->setModel(modelVariant);
1148     QTRY_COMPARE(modelSpy.count(),1);
1149
1150     gridView->setModel(QVariant());
1151     QTRY_COMPARE(modelSpy.count(),2);
1152     delete canvas;
1153 }
1154
1155 void tst_QDeclarative1GridView::positionViewAtIndex()
1156 {
1157     QDeclarativeView *canvas = createView();
1158
1159     TestModel model;
1160     for (int i = 0; i < 40; i++)
1161         model.addItem("Item" + QString::number(i), "");
1162
1163     QDeclarativeContext *ctxt = canvas->rootContext();
1164     ctxt->setContextProperty("testModel", &model);
1165     ctxt->setContextProperty("testRightToLeft", QVariant(false));
1166     ctxt->setContextProperty("testTopToBottom", QVariant(false));
1167
1168     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1169     qApp->processEvents();
1170
1171     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1172     QTRY_VERIFY(gridview != 0);
1173
1174     QDeclarativeItem *contentItem = gridview->contentItem();
1175     QTRY_VERIFY(contentItem != 0);
1176
1177     // Confirm items positioned correctly
1178     int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1179     for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1180         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1181         if (!item) qWarning() << "Item" << i << "not found";
1182         QTRY_VERIFY(item);
1183         QTRY_COMPARE(item->x(), (i%3)*80.);
1184         QTRY_COMPARE(item->y(), (i/3)*60.);
1185     }
1186
1187     // Position on a currently visible item
1188     gridview->positionViewAtIndex(4, QDeclarative1GridView::Beginning);
1189     QTRY_COMPARE(gridview->indexAt(120, 90), 4);
1190     QTRY_COMPARE(gridview->contentY(), 60.);
1191
1192     // Confirm items positioned correctly
1193     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1194     for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
1195         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1196         if (!item) qWarning() << "Item" << i << "not found";
1197         QTRY_VERIFY(item);
1198         QTRY_COMPARE(item->x(), (i%3)*80.);
1199         QTRY_COMPARE(item->y(), (i/3)*60.);
1200     }
1201
1202     // Position on an item beyond the visible items
1203     gridview->positionViewAtIndex(21, QDeclarative1GridView::Beginning);
1204     QTRY_COMPARE(gridview->indexAt(40, 450), 21);
1205     QTRY_COMPARE(gridview->contentY(), 420.);
1206
1207     // Confirm items positioned correctly
1208     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1209     for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
1210         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1211         if (!item) qWarning() << "Item" << i << "not found";
1212         QTRY_VERIFY(item);
1213         QTRY_COMPARE(item->x(), (i%3)*80.);
1214         QTRY_COMPARE(item->y(), (i/3)*60.);
1215     }
1216
1217     // Position on an item that would leave empty space if positioned at the top
1218     gridview->positionViewAtIndex(31, QDeclarative1GridView::Beginning);
1219     QTRY_COMPARE(gridview->indexAt(120, 630), 31);
1220     QTRY_COMPARE(gridview->contentY(), 520.);
1221
1222     // Confirm items positioned correctly
1223     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1224     for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
1225         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1226         if (!item) qWarning() << "Item" << i << "not found";
1227         QTRY_VERIFY(item);
1228         QTRY_COMPARE(item->x(), (i%3)*80.);
1229         QTRY_COMPARE(item->y(), (i/3)*60.);
1230     }
1231
1232     // Position at the beginning again
1233     gridview->positionViewAtIndex(0, QDeclarative1GridView::Beginning);
1234     QTRY_COMPARE(gridview->indexAt(0, 0), 0);
1235     QTRY_COMPARE(gridview->indexAt(40, 30), 0);
1236     QTRY_COMPARE(gridview->indexAt(80, 60), 4);
1237     QTRY_COMPARE(gridview->contentY(), 0.);
1238
1239     // Confirm items positioned correctly
1240     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1241     for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1242         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1243         if (!item) qWarning() << "Item" << i << "not found";
1244         QTRY_VERIFY(item);
1245         QTRY_COMPARE(item->x(), (i%3)*80.);
1246         QTRY_COMPARE(item->y(), (i/3)*60.);
1247     }
1248
1249     // Position at End
1250     gridview->positionViewAtIndex(30, QDeclarative1GridView::End);
1251     QTRY_COMPARE(gridview->contentY(), 340.);
1252
1253     // Position in Center
1254     gridview->positionViewAtIndex(15, QDeclarative1GridView::Center);
1255     QTRY_COMPARE(gridview->contentY(), 170.);
1256
1257     // Ensure at least partially visible
1258     gridview->positionViewAtIndex(15, QDeclarative1GridView::Visible);
1259     QTRY_COMPARE(gridview->contentY(), 170.);
1260
1261     gridview->setContentY(302);
1262     gridview->positionViewAtIndex(15, QDeclarative1GridView::Visible);
1263     QTRY_COMPARE(gridview->contentY(), 302.);
1264
1265     gridview->setContentY(360);
1266     gridview->positionViewAtIndex(15, QDeclarative1GridView::Visible);
1267     QTRY_COMPARE(gridview->contentY(), 300.);
1268
1269     gridview->setContentY(60);
1270     gridview->positionViewAtIndex(20, QDeclarative1GridView::Visible);
1271     QTRY_COMPARE(gridview->contentY(), 60.);
1272
1273     gridview->setContentY(20);
1274     gridview->positionViewAtIndex(20, QDeclarative1GridView::Visible);
1275     QTRY_COMPARE(gridview->contentY(), 100.);
1276
1277     // Ensure completely visible
1278     gridview->setContentY(120);
1279     gridview->positionViewAtIndex(20, QDeclarative1GridView::Contain);
1280     QTRY_COMPARE(gridview->contentY(), 120.);
1281
1282     gridview->setContentY(302);
1283     gridview->positionViewAtIndex(15, QDeclarative1GridView::Contain);
1284     QTRY_COMPARE(gridview->contentY(), 300.);
1285
1286     gridview->setContentY(60);
1287     gridview->positionViewAtIndex(20, QDeclarative1GridView::Contain);
1288     QTRY_COMPARE(gridview->contentY(), 100.);
1289
1290     // Test for Top To Bottom layout
1291     ctxt->setContextProperty("testTopToBottom", QVariant(true));
1292
1293     // Confirm items positioned correctly
1294     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1295     for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1296         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1297         if (!item) qWarning() << "Item" << i << "not found";
1298         QTRY_VERIFY(item);
1299         QTRY_COMPARE(item->x(), (i/5)*80.);
1300         QTRY_COMPARE(item->y(), (i%5)*60.);
1301     }
1302
1303     // Position at End
1304     gridview->positionViewAtIndex(30, QDeclarative1GridView::End);
1305     QTRY_COMPARE(gridview->contentX(), 320.);
1306     QTRY_COMPARE(gridview->contentY(), 0.);
1307
1308     // Position in Center
1309     gridview->positionViewAtIndex(15, QDeclarative1GridView::Center);
1310     QTRY_COMPARE(gridview->contentX(), 160.);
1311
1312     // Ensure at least partially visible
1313     gridview->positionViewAtIndex(15, QDeclarative1GridView::Visible);
1314     QTRY_COMPARE(gridview->contentX(), 160.);
1315
1316     gridview->setContentX(170);
1317     gridview->positionViewAtIndex(25, QDeclarative1GridView::Visible);
1318     QTRY_COMPARE(gridview->contentX(), 170.);
1319
1320     gridview->positionViewAtIndex(30, QDeclarative1GridView::Visible);
1321     QTRY_COMPARE(gridview->contentX(), 320.);
1322
1323     gridview->setContentX(170);
1324     gridview->positionViewAtIndex(25, QDeclarative1GridView::Contain);
1325     QTRY_COMPARE(gridview->contentX(), 240.);
1326
1327     // positionViewAtBeginning
1328     gridview->positionViewAtBeginning();
1329     QTRY_COMPARE(gridview->contentX(), 0.);
1330
1331     gridview->setContentX(80);
1332     canvas->rootObject()->setProperty("showHeader", true);
1333     gridview->positionViewAtBeginning();
1334     QTRY_COMPARE(gridview->contentX(), -30.);
1335
1336     // positionViewAtEnd
1337     gridview->positionViewAtEnd();
1338     QTRY_COMPARE(gridview->contentX(), 430.);
1339
1340     gridview->setContentX(80);
1341     canvas->rootObject()->setProperty("showFooter", true);
1342     gridview->positionViewAtEnd();
1343     QTRY_COMPARE(gridview->contentX(), 460.);
1344
1345     delete canvas;
1346 }
1347
1348 void tst_QDeclarative1GridView::snapping()
1349 {
1350     QDeclarativeView *canvas = createView();
1351
1352     TestModel model;
1353     for (int i = 0; i < 40; i++)
1354         model.addItem("Item" + QString::number(i), "");
1355
1356     QDeclarativeContext *ctxt = canvas->rootContext();
1357     ctxt->setContextProperty("testModel", &model);
1358     ctxt->setContextProperty("testTopToBottom", QVariant(false));
1359     ctxt->setContextProperty("testRightToLeft", QVariant(false));
1360
1361     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1362     qApp->processEvents();
1363
1364     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1365     QTRY_VERIFY(gridview != 0);
1366
1367     gridview->setHeight(220);
1368     QCOMPARE(gridview->height(), 220.);
1369
1370     gridview->positionViewAtIndex(12, QDeclarative1GridView::Visible);
1371     QCOMPARE(gridview->contentY(), 80.);
1372
1373     gridview->setContentY(0);
1374     QCOMPARE(gridview->contentY(), 0.);
1375
1376     gridview->setSnapMode(QDeclarative1GridView::SnapToRow);
1377     QCOMPARE(gridview->snapMode(), QDeclarative1GridView::SnapToRow);
1378
1379     gridview->positionViewAtIndex(12, QDeclarative1GridView::Visible);
1380     QCOMPARE(gridview->contentY(), 60.);
1381
1382     gridview->positionViewAtIndex(15, QDeclarative1GridView::End);
1383     QCOMPARE(gridview->contentY(), 120.);
1384
1385     delete canvas;
1386
1387 }
1388
1389 void tst_QDeclarative1GridView::mirroring()
1390 {
1391     QDeclarativeView *canvasA = createView();
1392     canvasA->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
1393     QDeclarative1GridView *gridviewA = findItem<QDeclarative1GridView>(canvasA->rootObject(), "view");
1394     QTRY_VERIFY(gridviewA != 0);
1395
1396     QDeclarativeView *canvasB = createView();
1397     canvasB->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
1398     QDeclarative1GridView *gridviewB = findItem<QDeclarative1GridView>(canvasB->rootObject(), "view");
1399     QTRY_VERIFY(gridviewA != 0);
1400     qApp->processEvents();
1401
1402     QList<QString> objectNames;
1403     objectNames << "item1" << "item2"; // << "item3"
1404
1405     gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1406     gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
1407     QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection());
1408
1409     // LTR != RTL
1410     foreach(const QString objectName, objectNames)
1411         QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1412
1413     gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1414     gridviewB->setProperty("layoutDirection", Qt::LeftToRight);
1415
1416     // LTR == LTR
1417     foreach(const QString objectName, objectNames)
1418         QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1419
1420     QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection());
1421     QDeclarativeItemPrivate::get(gridviewB)->setLayoutMirror(true);
1422     QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection());
1423
1424     // LTR != LTR+mirror
1425     foreach(const QString objectName, objectNames)
1426         QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1427
1428     gridviewA->setProperty("layoutDirection", Qt::RightToLeft);
1429
1430     // RTL == LTR+mirror
1431     foreach(const QString objectName, objectNames)
1432         QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1433
1434     gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
1435
1436     // RTL != RTL+mirror
1437     foreach(const QString objectName, objectNames)
1438         QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1439
1440     gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1441
1442     // LTR == RTL+mirror
1443     foreach(const QString objectName, objectNames)
1444         QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1445
1446     delete canvasA;
1447     delete canvasB;
1448 }
1449
1450 void tst_QDeclarative1GridView::positionViewAtIndex_rightToLeft()
1451 {
1452     QDeclarativeView *canvas = createView();
1453
1454     TestModel model;
1455     for (int i = 0; i < 40; i++)
1456         model.addItem("Item" + QString::number(i), "");
1457
1458     QDeclarativeContext *ctxt = canvas->rootContext();
1459     ctxt->setContextProperty("testModel", &model);
1460     ctxt->setContextProperty("testTopToBottom", QVariant(true));
1461     ctxt->setContextProperty("testRightToLeft", QVariant(true));
1462
1463     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1464     qApp->processEvents();
1465
1466     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1467     QTRY_VERIFY(gridview != 0);
1468
1469     QDeclarativeItem *contentItem = gridview->contentItem();
1470     QTRY_VERIFY(contentItem != 0);
1471
1472     // Confirm items positioned correctly
1473     int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1474     for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1475         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1476         if (!item) qWarning() << "Item" << i << "not found";
1477         QTRY_VERIFY(item);
1478         QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1479         QTRY_COMPARE(item->y(), qreal((i%5)*60));
1480     }
1481
1482     // Position on a currently visible item
1483     gridview->positionViewAtIndex(6, QDeclarative1GridView::Beginning);
1484     QTRY_COMPARE(gridview->contentX(), -320.);
1485
1486     // Confirm items positioned correctly
1487     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1488     for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
1489         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1490         if (!item) qWarning() << "Item" << i << "not found";
1491         QTRY_VERIFY(item);
1492         QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1493         QTRY_COMPARE(item->y(), qreal((i%5)*60));
1494     }
1495
1496     // Position on an item beyond the visible items
1497     gridview->positionViewAtIndex(21, QDeclarative1GridView::Beginning);
1498     QTRY_COMPARE(gridview->contentX(), -560.);
1499
1500     // Confirm items positioned correctly
1501     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1502     for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
1503         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1504         if (!item) qWarning() << "Item" << i << "not found";
1505         QTRY_VERIFY(item);
1506         QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1507         QTRY_COMPARE(item->y(), qreal((i%5)*60));
1508     }
1509
1510     // Position on an item that would leave empty space if positioned at the top
1511     gridview->positionViewAtIndex(31, QDeclarative1GridView::Beginning);
1512     QTRY_COMPARE(gridview->contentX(), -639.);
1513
1514     // Confirm items positioned correctly
1515     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1516     for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
1517         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1518         if (!item) qWarning() << "Item" << i << "not found";
1519         QTRY_VERIFY(item);
1520         QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1521         QTRY_COMPARE(item->y(), qreal((i%5)*60));
1522     }
1523
1524     // Position at the beginning again
1525     gridview->positionViewAtIndex(0, QDeclarative1GridView::Beginning);
1526     QTRY_COMPARE(gridview->contentX(), -240.);
1527
1528     // Confirm items positioned correctly
1529     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1530     for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1531         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1532         if (!item) qWarning() << "Item" << i << "not found";
1533         QTRY_VERIFY(item);
1534         QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1535         QTRY_COMPARE(item->y(), qreal((i%5)*60));
1536     }
1537
1538     // Position at End
1539     gridview->positionViewAtIndex(30, QDeclarative1GridView::End);
1540     QTRY_COMPARE(gridview->contentX(), -560.);
1541
1542     // Position in Center
1543     gridview->positionViewAtIndex(15, QDeclarative1GridView::Center);
1544     QTRY_COMPARE(gridview->contentX(), -400.);
1545
1546     // Ensure at least partially visible
1547     gridview->positionViewAtIndex(15, QDeclarative1GridView::Visible);
1548     QTRY_COMPARE(gridview->contentX(), -400.);
1549
1550     gridview->setContentX(-555.);
1551     gridview->positionViewAtIndex(15, QDeclarative1GridView::Visible);
1552     QTRY_COMPARE(gridview->contentX(), -555.);
1553
1554     gridview->setContentX(-239);
1555     gridview->positionViewAtIndex(15, QDeclarative1GridView::Visible);
1556     QTRY_COMPARE(gridview->contentX(), -320.);
1557
1558     gridview->setContentX(-239);
1559     gridview->positionViewAtIndex(20, QDeclarative1GridView::Visible);
1560     QTRY_COMPARE(gridview->contentX(), -400.);
1561
1562     gridview->setContentX(-640);
1563     gridview->positionViewAtIndex(20, QDeclarative1GridView::Visible);
1564     QTRY_COMPARE(gridview->contentX(), -560.);
1565
1566     // Ensure completely visible
1567     gridview->setContentX(-400);
1568     gridview->positionViewAtIndex(20, QDeclarative1GridView::Contain);
1569     QTRY_COMPARE(gridview->contentX(), -400.);
1570
1571     gridview->setContentX(-315);
1572     gridview->positionViewAtIndex(15, QDeclarative1GridView::Contain);
1573     QTRY_COMPARE(gridview->contentX(), -320.);
1574
1575     gridview->setContentX(-640);
1576     gridview->positionViewAtIndex(20, QDeclarative1GridView::Contain);
1577     QTRY_COMPARE(gridview->contentX(), -560.);
1578
1579     delete canvas;
1580 }
1581
1582 void tst_QDeclarative1GridView::resetModel()
1583 {
1584     QDeclarativeView *canvas = createView();
1585
1586     QStringList strings;
1587     strings << "one" << "two" << "three";
1588     QStringListModel model(strings);
1589
1590     QDeclarativeContext *ctxt = canvas->rootContext();
1591     ctxt->setContextProperty("testModel", &model);
1592
1593     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaygrid.qml"));
1594     qApp->processEvents();
1595
1596     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1597     QTRY_VERIFY(gridview != 0);
1598
1599     QDeclarativeItem *contentItem = gridview->contentItem();
1600     QTRY_VERIFY(contentItem != 0);
1601
1602     QTRY_COMPARE(gridview->count(), model.rowCount());
1603
1604     for (int i = 0; i < model.rowCount(); ++i) {
1605         QDeclarative1Text *display = findItem<QDeclarative1Text>(contentItem, "displayText", i);
1606         QTRY_VERIFY(display != 0);
1607         QTRY_COMPARE(display->text(), strings.at(i));
1608     }
1609
1610     strings.clear();
1611     strings << "four" << "five" << "six" << "seven";
1612     model.setStringList(strings);
1613
1614     QTRY_COMPARE(gridview->count(), model.rowCount());
1615
1616     for (int i = 0; i < model.rowCount(); ++i) {
1617         QDeclarative1Text *display = findItem<QDeclarative1Text>(contentItem, "displayText", i);
1618         QTRY_VERIFY(display != 0);
1619         QTRY_COMPARE(display->text(), strings.at(i));
1620     }
1621
1622     delete canvas;
1623 }
1624
1625 void tst_QDeclarative1GridView::enforceRange()
1626 {
1627     QDeclarativeView *canvas = createView();
1628
1629     TestModel model;
1630     for (int i = 0; i < 30; i++)
1631         model.addItem("Item" + QString::number(i), "");
1632
1633     QDeclarativeContext *ctxt = canvas->rootContext();
1634     ctxt->setContextProperty("testModel", &model);
1635     ctxt->setContextProperty("testRightToLeft", QVariant(false));
1636     ctxt->setContextProperty("testTopToBottom", QVariant(false));
1637
1638     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1639     qApp->processEvents();
1640     QVERIFY(canvas->rootObject() != 0);
1641
1642     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1643     QTRY_VERIFY(gridview != 0);
1644
1645     QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1646     QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1647     QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarative1GridView::StrictlyEnforceRange);
1648
1649     QDeclarativeItem *contentItem = gridview->contentItem();
1650     QTRY_VERIFY(contentItem != 0);
1651
1652     // view should be positioned at the top of the range.
1653     QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1654     QTRY_VERIFY(item);
1655     QTRY_COMPARE(gridview->contentY(), -100.0);
1656
1657     QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 0);
1658     QTRY_VERIFY(name != 0);
1659     QTRY_COMPARE(name->text(), model.name(0));
1660     QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 0);
1661     QTRY_VERIFY(number != 0);
1662     QTRY_COMPARE(number->text(), model.number(0));
1663
1664     // Check currentIndex is updated when contentItem moves
1665     gridview->setContentY(0);
1666     QTRY_COMPARE(gridview->currentIndex(), 2);
1667
1668     gridview->setCurrentIndex(5);
1669     QTRY_COMPARE(gridview->contentY(), 100.);
1670
1671     TestModel model2;
1672     for (int i = 0; i < 5; i++)
1673         model2.addItem("Item" + QString::number(i), "");
1674
1675     ctxt->setContextProperty("testModel", &model2);
1676     QCOMPARE(gridview->count(), 5);
1677
1678     delete canvas;
1679 }
1680
1681 void tst_QDeclarative1GridView::enforceRange_rightToLeft()
1682 {
1683     QDeclarativeView *canvas = createView();
1684
1685     TestModel model;
1686     for (int i = 0; i < 30; i++)
1687         model.addItem("Item" + QString::number(i), "");
1688
1689     QDeclarativeContext *ctxt = canvas->rootContext();
1690     ctxt->setContextProperty("testModel", &model);
1691     ctxt->setContextProperty("testRightToLeft", QVariant(true));
1692     ctxt->setContextProperty("testTopToBottom", QVariant(true));
1693
1694     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1695     qApp->processEvents();
1696     QVERIFY(canvas->rootObject() != 0);
1697
1698     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1699     QTRY_VERIFY(gridview != 0);
1700
1701     QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1702     QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1703     QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarative1GridView::StrictlyEnforceRange);
1704
1705     QDeclarativeItem *contentItem = gridview->contentItem();
1706     QTRY_VERIFY(contentItem != 0);
1707
1708     // view should be positioned at the top of the range.
1709     QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1710     QTRY_VERIFY(item);
1711     QTRY_COMPARE(gridview->contentX(), -100.);
1712     QTRY_COMPARE(gridview->contentY(), 0.0);
1713
1714     QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 0);
1715     QTRY_VERIFY(name != 0);
1716     QTRY_COMPARE(name->text(), model.name(0));
1717     QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 0);
1718     QTRY_VERIFY(number != 0);
1719     QTRY_COMPARE(number->text(), model.number(0));
1720
1721     // Check currentIndex is updated when contentItem moves
1722     gridview->setContentX(-200);
1723     QTRY_COMPARE(gridview->currentIndex(), 3);
1724
1725     gridview->setCurrentIndex(7);
1726     QTRY_COMPARE(gridview->contentX(), -300.);
1727     QTRY_COMPARE(gridview->contentY(), 0.0);
1728
1729     TestModel model2;
1730     for (int i = 0; i < 5; i++)
1731         model2.addItem("Item" + QString::number(i), "");
1732
1733     ctxt->setContextProperty("testModel", &model2);
1734     QCOMPARE(gridview->count(), 5);
1735
1736     delete canvas;
1737 }
1738
1739 void tst_QDeclarative1GridView::QTBUG_8456()
1740 {
1741     QDeclarativeView *canvas = createView();
1742
1743     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/setindex.qml"));
1744     qApp->processEvents();
1745
1746     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1747     QTRY_VERIFY(gridview != 0);
1748
1749     QTRY_COMPARE(gridview->currentIndex(), 0);
1750
1751     delete canvas;
1752 }
1753
1754 void tst_QDeclarative1GridView::manualHighlight()
1755 {
1756     QDeclarativeView *canvas = createView();
1757
1758     QString filename(SRCDIR "/data/manual-highlight.qml");
1759     canvas->setSource(QUrl::fromLocalFile(filename));
1760
1761     qApp->processEvents();
1762
1763     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1764     QTRY_VERIFY(gridview != 0);
1765
1766     QDeclarativeItem *contentItem = gridview->contentItem();
1767     QTRY_VERIFY(contentItem != 0);
1768
1769     QTRY_COMPARE(gridview->currentIndex(), 0);
1770     QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
1771     QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1772     QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1773
1774     gridview->setCurrentIndex(2);
1775
1776     QTRY_COMPARE(gridview->currentIndex(), 2);
1777     QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2));
1778     QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1779     QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1780
1781     gridview->positionViewAtIndex(8, QDeclarative1GridView::Contain);
1782
1783     QTRY_COMPARE(gridview->currentIndex(), 2);
1784     QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2));
1785     QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1786     QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1787
1788     gridview->setFlow(QDeclarative1GridView::TopToBottom);
1789     QTRY_COMPARE(gridview->flow(), QDeclarative1GridView::TopToBottom);
1790
1791     gridview->setCurrentIndex(0);
1792     QTRY_COMPARE(gridview->currentIndex(), 0);
1793     QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
1794     QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1795     QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1796
1797     delete canvas;
1798 }
1799
1800 void tst_QDeclarative1GridView::footer()
1801 {
1802     QDeclarativeView *canvas = createView();
1803
1804     TestModel model;
1805     for (int i = 0; i < 7; i++)
1806         model.addItem("Item" + QString::number(i), "");
1807
1808     QDeclarativeContext *ctxt = canvas->rootContext();
1809     ctxt->setContextProperty("testModel", &model);
1810
1811     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/footer.qml"));
1812     qApp->processEvents();
1813
1814     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1815     QTRY_VERIFY(gridview != 0);
1816
1817     QDeclarativeItem *contentItem = gridview->contentItem();
1818     QTRY_VERIFY(contentItem != 0);
1819
1820     QDeclarative1Text *footer = findItem<QDeclarative1Text>(contentItem, "footer");
1821     QVERIFY(footer);
1822
1823     QCOMPARE(footer->y(), 180.0);
1824     QCOMPARE(footer->height(), 30.0);
1825
1826     model.removeItem(2);
1827     QTRY_COMPARE(footer->y(), 120.0);
1828
1829     model.clear();
1830     QTRY_COMPARE(footer->y(), 0.0);
1831
1832     for (int i = 0; i < 30; i++)
1833         model.addItem("Item" + QString::number(i), "");
1834
1835     QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
1836
1837     footer = findItem<QDeclarative1Text>(contentItem, "footer");
1838     QVERIFY(!footer);
1839     footer = findItem<QDeclarative1Text>(contentItem, "footer2");
1840     QVERIFY(footer);
1841
1842     QCOMPARE(footer->y(), 600.0);
1843     QCOMPARE(footer->height(), 20.0);
1844     QCOMPARE(gridview->contentY(), 0.0);
1845
1846     delete canvas;
1847 }
1848
1849 void tst_QDeclarative1GridView::header()
1850 {
1851     QDeclarativeView *canvas = createView();
1852
1853     TestModel model;
1854     for (int i = 0; i < 30; i++)
1855         model.addItem("Item" + QString::number(i), "");
1856
1857     QDeclarativeContext *ctxt = canvas->rootContext();
1858     ctxt->setContextProperty("testModel", &model);
1859
1860     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
1861     qApp->processEvents();
1862
1863     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1864     QTRY_VERIFY(gridview != 0);
1865
1866     QDeclarativeItem *contentItem = gridview->contentItem();
1867     QTRY_VERIFY(contentItem != 0);
1868
1869     QDeclarative1Text *header = findItem<QDeclarative1Text>(contentItem, "header");
1870     QVERIFY(header);
1871
1872     QCOMPARE(header->y(), 0.0);
1873     QCOMPARE(header->height(), 30.0);
1874     QCOMPARE(gridview->contentY(), 0.0);
1875
1876     QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1877     QVERIFY(item);
1878     QCOMPARE(item->y(), 30.0);
1879
1880     model.clear();
1881     QTRY_COMPARE(header->y(), 0.0);
1882
1883     for (int i = 0; i < 30; i++)
1884         model.addItem("Item" + QString::number(i), "");
1885
1886     QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
1887
1888     header = findItem<QDeclarative1Text>(contentItem, "header");
1889     QVERIFY(!header);
1890     header = findItem<QDeclarative1Text>(contentItem, "header2");
1891     QVERIFY(header);
1892
1893     QCOMPARE(header->y(), 10.0);
1894     QCOMPARE(header->height(), 20.0);
1895     QCOMPARE(gridview->contentY(), 10.0);
1896
1897     delete canvas;
1898 }
1899
1900 void tst_QDeclarative1GridView::indexAt()
1901 {
1902     QDeclarativeView *canvas = createView();
1903
1904     TestModel model;
1905     model.addItem("Fred", "12345");
1906     model.addItem("John", "2345");
1907     model.addItem("Bob", "54321");
1908     model.addItem("Billy", "22345");
1909     model.addItem("Sam", "2945");
1910     model.addItem("Ben", "04321");
1911     model.addItem("Jim", "0780");
1912
1913     QDeclarativeContext *ctxt = canvas->rootContext();
1914     ctxt->setContextProperty("testModel", &model);
1915     ctxt->setContextProperty("testRightToLeft", QVariant(false));
1916     ctxt->setContextProperty("testTopToBottom", QVariant(false));
1917
1918     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1919     qApp->processEvents();
1920
1921     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
1922     QTRY_VERIFY(gridview != 0);
1923
1924     QDeclarativeItem *contentItem = gridview->contentItem();
1925     QTRY_VERIFY(contentItem != 0);
1926
1927     QTRY_COMPARE(gridview->count(), model.count());
1928
1929     QCOMPARE(gridview->indexAt(0, 0), 0);
1930     QCOMPARE(gridview->indexAt(79, 59), 0);
1931     QCOMPARE(gridview->indexAt(80, 0), 1);
1932     QCOMPARE(gridview->indexAt(0, 60), 3);
1933     QCOMPARE(gridview->indexAt(240, 0), -1);
1934
1935     delete canvas;
1936 }
1937
1938 void tst_QDeclarative1GridView::onAdd()
1939 {
1940     QFETCH(int, initialItemCount);
1941     QFETCH(int, itemsToAdd);
1942
1943     const int delegateWidth = 50;
1944     const int delegateHeight = 100;
1945     TestModel model;
1946     QDeclarativeView *canvas = createView();
1947     canvas->setFixedSize(5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit
1948
1949     // these initial items should not trigger GridView.onAdd
1950     for (int i=0; i<initialItemCount; i++)
1951         model.addItem("dummy value", "dummy value");
1952
1953     QDeclarativeContext *ctxt = canvas->rootContext();
1954     ctxt->setContextProperty("testModel", &model);
1955     ctxt->setContextProperty("delegateWidth", delegateWidth);
1956     ctxt->setContextProperty("delegateHeight", delegateHeight);
1957     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
1958
1959     QObject *object = canvas->rootObject();
1960     object->setProperty("width", canvas->width());
1961     object->setProperty("height", canvas->height());
1962     qApp->processEvents();
1963
1964     QList<QPair<QString, QString> > items;
1965     for (int i=0; i<itemsToAdd; i++)
1966         items << qMakePair(QString("value %1").arg(i), QString::number(i));
1967     model.addItems(items);
1968
1969     qApp->processEvents();
1970
1971     QVariantList result = object->property("addedDelegates").toList();
1972     QCOMPARE(result.count(), items.count());
1973     for (int i=0; i<items.count(); i++)
1974         QCOMPARE(result[i].toString(), items[i].first);
1975
1976     delete canvas;
1977 }
1978
1979 void tst_QDeclarative1GridView::onAdd_data()
1980 {
1981     QTest::addColumn<int>("initialItemCount");
1982     QTest::addColumn<int>("itemsToAdd");
1983
1984     QTest::newRow("0, add 1") << 0 << 1;
1985     QTest::newRow("0, add 2") << 0 << 2;
1986     QTest::newRow("0, add 10") << 0 << 10;
1987
1988     QTest::newRow("1, add 1") << 1 << 1;
1989     QTest::newRow("1, add 2") << 1 << 2;
1990     QTest::newRow("1, add 10") << 1 << 10;
1991
1992     QTest::newRow("5, add 1") << 5 << 1;
1993     QTest::newRow("5, add 2") << 5 << 2;
1994     QTest::newRow("5, add 10") << 5 << 10;
1995 }
1996
1997 void tst_QDeclarative1GridView::onRemove()
1998 {
1999     QFETCH(int, initialItemCount);
2000     QFETCH(int, indexToRemove);
2001     QFETCH(int, removeCount);
2002
2003     const int delegateWidth = 50;
2004     const int delegateHeight = 100;
2005     TestModel model;
2006     for (int i=0; i<initialItemCount; i++)
2007         model.addItem(QString("value %1").arg(i), "dummy value");
2008
2009     QDeclarativeView *canvas = createView();
2010     QDeclarativeContext *ctxt = canvas->rootContext();
2011     ctxt->setContextProperty("testModel", &model);
2012     ctxt->setContextProperty("delegateWidth", delegateWidth);
2013     ctxt->setContextProperty("delegateHeight", delegateHeight);
2014     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
2015     QObject *object = canvas->rootObject();
2016
2017     qApp->processEvents();
2018
2019     model.removeItems(indexToRemove, removeCount);
2020     qApp->processEvents();
2021     QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
2022
2023     delete canvas;
2024 }
2025
2026 void tst_QDeclarative1GridView::onRemove_data()
2027 {
2028     QTest::addColumn<int>("initialItemCount");
2029     QTest::addColumn<int>("indexToRemove");
2030     QTest::addColumn<int>("removeCount");
2031
2032     QTest::newRow("remove first") << 1 << 0 << 1;
2033     QTest::newRow("two items, remove first") << 2 << 0 << 1;
2034     QTest::newRow("two items, remove last") << 2 << 1 << 1;
2035     QTest::newRow("two items, remove all") << 2 << 0 << 2;
2036
2037     QTest::newRow("four items, remove first") << 4 << 0 << 1;
2038     QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
2039     QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
2040     QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
2041     QTest::newRow("four items, remove last") << 4 << 3 << 1;
2042     QTest::newRow("four items, remove all") << 4 << 0 << 4;
2043
2044     QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
2045     QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
2046     QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
2047 }
2048
2049 void tst_QDeclarative1GridView::testQtQuick11Attributes()
2050 {
2051     QFETCH(QString, code);
2052     QFETCH(QString, warning);
2053     QFETCH(QString, error);
2054
2055     QDeclarativeEngine engine;
2056     QObject *obj;
2057
2058     QDeclarativeComponent valid(&engine);
2059     valid.setData("import QtQuick 1.1; GridView { " + code.toUtf8() + " }", QUrl(""));
2060     obj = valid.create();
2061     QVERIFY(obj);
2062     QVERIFY(valid.errorString().isEmpty());
2063     delete obj;
2064
2065     QDeclarativeComponent invalid(&engine);
2066     invalid.setData("import QtQuick 1.0; GridView { " + code.toUtf8() + " }", QUrl(""));
2067     QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2068     obj = invalid.create();
2069     QCOMPARE(invalid.errorString(), error);
2070     delete obj;
2071 }
2072
2073 void tst_QDeclarative1GridView::testQtQuick11Attributes_data()
2074 {
2075     QTest::addColumn<QString>("code");
2076     QTest::addColumn<QString>("warning");
2077     QTest::addColumn<QString>("error");
2078
2079     QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()"
2080         << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning"
2081         << "";
2082
2083     QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()"
2084         << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd"
2085         << "";
2086 }
2087
2088 void tst_QDeclarative1GridView::contentPosJump()
2089 {
2090     QDeclarativeView *canvas = createView();
2091
2092     TestModel model;
2093     for (int i = 0; i < 100; i++)
2094         model.addItem("Item" + QString::number(i), "");
2095
2096     QDeclarativeContext *ctxt = canvas->rootContext();
2097     ctxt->setContextProperty("testModel", &model);
2098     ctxt->setContextProperty("testRightToLeft", QVariant(false));
2099     ctxt->setContextProperty("testTopToBottom", QVariant(false));
2100
2101     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
2102     qApp->processEvents();
2103
2104     QDeclarative1GridView *gridview = findItem<QDeclarative1GridView>(canvas->rootObject(), "grid");
2105     QVERIFY(gridview != 0);
2106
2107     QDeclarativeItem *contentItem = gridview->contentItem();
2108     QVERIFY(contentItem != 0);
2109
2110     // Test jumping more than a page of items.
2111     gridview->setContentY(500);
2112
2113     // Confirm items positioned correctly
2114     int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2115     for (int i = 24; i < model.count() && i < itemCount; ++i) {
2116         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2117         if (!item) qWarning() << "Item" << i << "not found";
2118         QVERIFY(item);
2119         QVERIFY(item->x() == (i%3)*80);
2120         QVERIFY(item->y() == (i/3)*60);
2121     }
2122
2123     gridview->setContentY(-100);
2124     itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2125     QVERIFY(itemCount < 15);
2126     // Confirm items positioned correctly
2127     for (int i = 0; i < model.count() && i < itemCount; ++i) {
2128         QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2129         if (!item) qWarning() << "Item" << i << "not found";
2130         QVERIFY(item);
2131         QVERIFY(item->x() == (i%3)*80);
2132         QVERIFY(item->y() == (i/3)*60);
2133     }
2134
2135     delete canvas;
2136 }
2137
2138 QDeclarativeView *tst_QDeclarative1GridView::createView()
2139 {
2140     QDeclarativeView *canvas = new QDeclarativeView(0);
2141     canvas->setFixedSize(240,320);
2142
2143     return canvas;
2144 }
2145
2146 /*
2147    Find an item with the specified objectName.  If index is supplied then the
2148    item must also evaluate the {index} expression equal to index
2149 */
2150 template<typename T>
2151 T *tst_QDeclarative1GridView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
2152 {
2153     const QMetaObject &mo = T::staticMetaObject;
2154     //qDebug() << parent->childItems().count() << "children";
2155     for (int i = 0; i < parent->childItems().count(); ++i) {
2156         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2157         if(!item)
2158             continue;
2159         //qDebug() << "try" << item;
2160         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2161             if (index != -1) {
2162                 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2163                 if (context) {
2164                     if (context->contextProperty("index").toInt() == index) {
2165                         return static_cast<T*>(item);
2166                     }
2167                 }
2168             } else {
2169                 return static_cast<T*>(item);
2170             }
2171         }
2172         item = findItem<T>(item, objectName, index);
2173         if (item)
2174             return static_cast<T*>(item);
2175     }
2176
2177     return 0;
2178 }
2179
2180 template<typename T>
2181 QList<T*> tst_QDeclarative1GridView::findItems(QGraphicsObject *parent, const QString &objectName)
2182 {
2183     QList<T*> items;
2184     const QMetaObject &mo = T::staticMetaObject;
2185     //qDebug() << parent->childItems().count() << "children";
2186     for (int i = 0; i < parent->childItems().count(); ++i) {
2187         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2188         if(!item)
2189             continue;
2190         //qDebug() << "try" << item;
2191         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2192             items.append(static_cast<T*>(item));
2193             //qDebug() << " found:" << item;
2194         }
2195         items += findItems<T>(item, objectName);
2196     }
2197
2198     return items;
2199 }
2200
2201 void tst_QDeclarative1GridView::dumpTree(QDeclarativeItem *parent, int depth)
2202 {
2203     static QString padding("                       ");
2204     for (int i = 0; i < parent->childItems().count(); ++i) {
2205         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2206         if(!item)
2207             continue;
2208         QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2209         qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
2210         dumpTree(item, depth+1);
2211     }
2212 }
2213
2214
2215 QTEST_MAIN(tst_QDeclarative1GridView)
2216
2217 #include "tst_qdeclarativegridview.moc"