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