1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtTest/QtTest>
43 #include <QtGui/qstringlistmodel.h>
44 #include <QtDeclarative/qdeclarativeview.h>
45 #include <QtDeclarative/qdeclarativeengine.h>
46 #include <QtDeclarative/qdeclarativecomponent.h>
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/qdeclarativeexpression.h>
49 #include <QtDeclarative/private/qdeclarativeitem_p.h>
50 #include <QtDeclarative/private/qlistmodelinterface_p.h>
51 #include <QtDeclarative/private/qdeclarativegridview_p.h>
52 #include <QtDeclarative/private/qdeclarativetext_p.h>
53 #include <QtDeclarative/private/qdeclarativelistmodel_p.h>
54 #include "../../../shared/util.h"
55
56 #ifdef Q_OS_SYMBIAN
57 // In Symbian OS test data is located in applications private dir
58 #define SRCDIR "."
59 #endif
60
61 class tst_QDeclarativeGridView : public QObject
62 {
63 Q_OBJECT
64 public:
65 tst_QDeclarativeGridView();
66
67 private slots:
68 void items();
69 void changed();
70 void inserted();
71 void removed();
72 void clear();
73 void moved();
74 void changeFlow();
75 void currentIndex();
76 void noCurrentIndex();
77 void defaultValues();
78 void properties();
79 void propertyChanges();
80 void componentChanges();
81 void modelChanges();
82 void positionViewAtIndex();
83 void positionViewAtIndex_rightToLeft();
84 void mirroring();
85 void snapping();
86 void resetModel();
87 void enforceRange();
88 void enforceRange_rightToLeft();
89 void QTBUG_8456();
90 void manualHighlight();
91 void footer();
92 void header();
93 void indexAt();
94 void onAdd();
95 void onAdd_data();
96 void onRemove();
97 void onRemove_data();
98 void testQtQuick11Attributes();
99 void testQtQuick11Attributes_data();
100 void contentPosJump();
101
102 private:
103 QDeclarativeView *createView();
104 template<typename T>
105 T *findItem(QGraphicsObject *parent, const QString &id, int index=-1);
106 template<typename T>
107 QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
108 void dumpTree(QDeclarativeItem *parent, int depth = 0);
109 };
110
111 class TestModel : public QAbstractListModel
112 {
113 public:
114 enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
115
TestModel(QObject * parent=0)116 TestModel(QObject *parent=0) : QAbstractListModel(parent) {
117 QHash<int, QByteArray> roles;
118 roles[Name] = "name";
119 roles[Number] = "number";
120 setRoleNames(roles);
121 }
122
rowCount(const QModelIndex & parent=QModelIndex ()) const123 int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
data(const QModelIndex & index,int role=Qt::DisplayRole) const124 QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
125 QVariant rv;
126 if (role == Name)
127 rv = list.at(index.row()).first;
128 else if (role == Number)
129 rv = list.at(index.row()).second;
130
131 return rv;
132 }
133
count() const134 int count() const { return rowCount(); }
name(int index) const135 QString name(int index) const { return list.at(index).first; }
number(int index) const136 QString number(int index) const { return list.at(index).second; }
137
addItem(const QString & name,const QString & number)138 void addItem(const QString &name, const QString &number) {
139 emit beginInsertRows(QModelIndex(), list.count(), list.count());
140 list.append(QPair<QString,QString>(name, number));
141 emit endInsertRows();
142 }
143
addItems(const QList<QPair<QString,QString>> & items)144 void addItems(const QList<QPair<QString, QString> > &items) {
145 emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
146 for (int i=0; i<items.count(); i++)
147 list.append(QPair<QString,QString>(items[i].first, items[i].second));
148 emit endInsertRows();
149 }
150
insertItem(int index,const QString & name,const QString & number)151 void insertItem(int index, const QString &name, const QString &number) {
152 emit beginInsertRows(QModelIndex(), index, index);
153 list.insert(index, QPair<QString,QString>(name, number));
154 emit endInsertRows();
155 }
156
removeItem(int index)157 void removeItem(int index) {
158 emit beginRemoveRows(QModelIndex(), index, index);
159 list.removeAt(index);
160 emit endRemoveRows();
161 }
162
removeItems(int index,int count)163 void removeItems(int index, int count) {
164 emit beginRemoveRows(QModelIndex(), index, index+count-1);
165 while (count--)
166 list.removeAt(index);
167 emit endRemoveRows();
168 }
169
moveItem(int from,int to)170 void moveItem(int from, int to) {
171 emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
172 list.move(from, to);
173 emit endMoveRows();
174 }
175
modifyItem(int idx,const QString & name,const QString & number)176 void modifyItem(int idx, const QString &name, const QString &number) {
177 list[idx] = QPair<QString,QString>(name, number);
178 emit dataChanged(index(idx,0), index(idx,0));
179 }
180
clear()181 void clear() {
182 int count = list.count();
183 emit beginRemoveRows(QModelIndex(), 0, count-1);
184 list.clear();
185 emit endRemoveRows();
186 }
187
188
189 private:
190 QList<QPair<QString,QString> > list;
191 };
192
tst_QDeclarativeGridView()193 tst_QDeclarativeGridView::tst_QDeclarativeGridView()
194 {
195 }
196
items()197 void tst_QDeclarativeGridView::items()
198 {
199 QDeclarativeView *canvas = createView();
200
201 TestModel model;
202 model.addItem("Fred", "12345");
203 model.addItem("John", "2345");
204 model.addItem("Bob", "54321");
205 model.addItem("Billy", "22345");
206 model.addItem("Sam", "2945");
207 model.addItem("Ben", "04321");
208 model.addItem("Jim", "0780");
209
210 QDeclarativeContext *ctxt = canvas->rootContext();
211 ctxt->setContextProperty("testModel", &model);
212 ctxt->setContextProperty("testRightToLeft", QVariant(false));
213 ctxt->setContextProperty("testTopToBottom", QVariant(false));
214
215 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
216 qApp->processEvents();
217
218 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
219 QTRY_VERIFY(gridview != 0);
220
221 QDeclarativeItem *contentItem = gridview->contentItem();
222 QTRY_VERIFY(contentItem != 0);
223
224 QTRY_COMPARE(gridview->count(), model.count());
225 QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
226 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
227
228 for (int i = 0; i < model.count(); ++i) {
229 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
230 QTRY_VERIFY(name != 0);
231 QTRY_COMPARE(name->text(), model.name(i));
232 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
233 QTRY_VERIFY(number != 0);
234 QTRY_COMPARE(number->text(), model.number(i));
235 }
236
237 // set an empty model and confirm that items are destroyed
238 TestModel model2;
239 ctxt->setContextProperty("testModel", &model2);
240
241 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
242 QTRY_VERIFY(itemCount == 0);
243
244 delete canvas;
245 }
246
changed()247 void tst_QDeclarativeGridView::changed()
248 {
249 QDeclarativeView *canvas = createView();
250
251 TestModel model;
252 model.addItem("Fred", "12345");
253 model.addItem("John", "2345");
254 model.addItem("Bob", "54321");
255 model.addItem("Billy", "22345");
256 model.addItem("Sam", "2945");
257 model.addItem("Ben", "04321");
258 model.addItem("Jim", "0780");
259
260 QDeclarativeContext *ctxt = canvas->rootContext();
261 ctxt->setContextProperty("testModel", &model);
262 ctxt->setContextProperty("testRightToLeft", QVariant(false));
263 ctxt->setContextProperty("testTopToBottom", QVariant(false));
264
265 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
266 qApp->processEvents();
267
268 QDeclarativeFlickable *gridview = findItem<QDeclarativeFlickable>(canvas->rootObject(), "grid");
269 QTRY_VERIFY(gridview != 0);
270
271 QDeclarativeItem *contentItem = gridview->contentItem();
272 QTRY_VERIFY(contentItem != 0);
273
274 model.modifyItem(1, "Will", "9876");
275 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
276 QTRY_VERIFY(name != 0);
277 QTRY_COMPARE(name->text(), model.name(1));
278 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
279 QTRY_VERIFY(number != 0);
280 QTRY_COMPARE(number->text(), model.number(1));
281
282 delete canvas;
283 }
284
inserted()285 void tst_QDeclarativeGridView::inserted()
286 {
287 QDeclarativeView *canvas = createView();
288
289 TestModel model;
290 model.addItem("Fred", "12345");
291 model.addItem("John", "2345");
292 model.addItem("Bob", "54321");
293
294 QDeclarativeContext *ctxt = canvas->rootContext();
295 ctxt->setContextProperty("testModel", &model);
296 ctxt->setContextProperty("testRightToLeft", QVariant(false));
297 ctxt->setContextProperty("testTopToBottom", QVariant(false));
298
299 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
300 qApp->processEvents();
301
302 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
303 QTRY_VERIFY(gridview != 0);
304
305 QDeclarativeItem *contentItem = gridview->contentItem();
306 QTRY_VERIFY(contentItem != 0);
307
308 model.insertItem(1, "Will", "9876");
309 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
310
311 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
312
313 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
314 QTRY_VERIFY(name != 0);
315 QTRY_COMPARE(name->text(), model.name(1));
316 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
317 QTRY_VERIFY(number != 0);
318 QTRY_COMPARE(number->text(), model.number(1));
319
320 // Checks that onAdd is called
321 int added = canvas->rootObject()->property("added").toInt();
322 QTRY_COMPARE(added, 1);
323
324 // Confirm items positioned correctly
325 for (int i = 0; i < model.count(); ++i) {
326 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
327 QTRY_COMPARE(item->x(), (i%3)*80.0);
328 QTRY_COMPARE(item->y(), (i/3)*60.0);
329 }
330
331 model.insertItem(0, "Foo", "1111"); // zero index, and current item
332
333 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
334
335 name = findItem<QDeclarativeText>(contentItem, "textName", 0);
336 QTRY_VERIFY(name != 0);
337 QTRY_COMPARE(name->text(), model.name(0));
338 number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
339 QTRY_VERIFY(number != 0);
340 QTRY_COMPARE(number->text(), model.number(0));
341
342 QTRY_COMPARE(gridview->currentIndex(), 1);
343
344 // Confirm items positioned correctly
345 for (int i = 0; i < model.count(); ++i) {
346 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
347 QTRY_VERIFY(item->x() == (i%3)*80);
348 QTRY_VERIFY(item->y() == (i/3)*60);
349 }
350
351 for (int i = model.count(); i < 30; ++i)
352 model.insertItem(i, "Hello", QString::number(i));
353
354 gridview->setContentY(120);
355
356 // Insert item outside visible area
357 model.insertItem(1, "Hello", "1324");
358
359 QTRY_VERIFY(gridview->contentY() == 120);
360
361 delete canvas;
362 }
363
removed()364 void tst_QDeclarativeGridView::removed()
365 {
366 QDeclarativeView *canvas = createView();
367
368 TestModel model;
369 for (int i = 0; i < 40; i++)
370 model.addItem("Item" + QString::number(i), "");
371
372 QDeclarativeContext *ctxt = canvas->rootContext();
373 ctxt->setContextProperty("testModel", &model);
374 ctxt->setContextProperty("testRightToLeft", QVariant(false));
375 ctxt->setContextProperty("testTopToBottom", QVariant(false));
376
377 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
378 qApp->processEvents();
379
380 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
381 QTRY_VERIFY(gridview != 0);
382
383 QDeclarativeItem *contentItem = gridview->contentItem();
384 QTRY_VERIFY(contentItem != 0);
385
386 model.removeItem(1);
387 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
388
389 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
390 QTRY_VERIFY(name != 0);
391 QTRY_COMPARE(name->text(), model.name(1));
392 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
393 QTRY_VERIFY(number != 0);
394 QTRY_COMPARE(number->text(), model.number(1));
395
396 // Checks that onRemove is called
397 QString removed = canvas->rootObject()->property("removed").toString();
398 QTRY_COMPARE(removed, QString("Item1"));
399
400 // Confirm items positioned correctly
401 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
402 for (int i = 0; i < model.count() && i < itemCount; ++i) {
403 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
404 if (!item) qWarning() << "Item" << i << "not found";
405 QTRY_VERIFY(item);
406 QTRY_VERIFY(item->x() == (i%3)*80);
407 QTRY_VERIFY(item->y() == (i/3)*60);
408 }
409
410 // Remove first item (which is the current item);
411 model.removeItem(0);
412
413 name = findItem<QDeclarativeText>(contentItem, "textName", 0);
414 QTRY_VERIFY(name != 0);
415 QTRY_COMPARE(name->text(), model.name(0));
416 number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
417 QTRY_VERIFY(number != 0);
418 QTRY_COMPARE(number->text(), model.number(0));
419
420 // Confirm items positioned correctly
421 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
422 for (int i = 0; i < model.count() && i < itemCount; ++i) {
423 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
424 if (!item) qWarning() << "Item" << i << "not found";
425 QTRY_VERIFY(item);
426 QTRY_VERIFY(item->x() == (i%3)*80);
427 QTRY_VERIFY(item->y() == (i/3)*60);
428 }
429
430 // Remove items not visible
431 model.removeItem(25);
432
433 // Confirm items positioned correctly
434 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
435 for (int i = 0; i < model.count() && i < itemCount; ++i) {
436 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
437 if (!item) qWarning() << "Item" << i << "not found";
438 QTRY_VERIFY(item);
439 QTRY_VERIFY(item->x() == (i%3)*80);
440 QTRY_VERIFY(item->y() == (i/3)*60);
441 }
442
443 // Remove items before visible
444 gridview->setContentY(120);
445 gridview->setCurrentIndex(10);
446
447 // Setting currentIndex above shouldn't cause view to scroll
448 QTRY_COMPARE(gridview->contentY(), 120.0);
449
450 model.removeItem(1);
451
452 // Confirm items positioned correctly
453 for (int i = 3; i < 15; ++i) {
454 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
455 if (!item) qWarning() << "Item" << i << "not found";
456 QTRY_VERIFY(item);
457 QTRY_COMPARE(item->x(), (i%3)*80.0);
458 QTRY_COMPARE(item->y(), 60+(i/3)*60.0);
459 }
460
461 // Remove currentIndex
462 QDeclarativeItem *oldCurrent = gridview->currentItem();
463 model.removeItem(9);
464
465 QTRY_COMPARE(gridview->currentIndex(), 9);
466 QTRY_VERIFY(gridview->currentItem() != oldCurrent);
467
468 gridview->setContentY(0);
469 // let transitions settle.
470 QTest::qWait(100);
471
472 // Confirm items positioned correctly
473 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
474 for (int i = 0; i < model.count() && i < itemCount; ++i) {
475 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
476 if (!item) qWarning() << "Item" << i << "not found";
477 QTRY_VERIFY(item);
478 QTRY_VERIFY(item->x() == (i%3)*80);
479 QTRY_VERIFY(item->y() == 60+(i/3)*60);
480 }
481
482 // remove item outside current view.
483 gridview->setCurrentIndex(32);
484 gridview->setContentY(240);
485
486 model.removeItem(30);
487 QTRY_VERIFY(gridview->currentIndex() == 31);
488
489 // remove current item beyond visible items.
490 gridview->setCurrentIndex(20);
491 gridview->setContentY(0);
492 model.removeItem(20);
493
494 QTRY_COMPARE(gridview->currentIndex(), 20);
495 QTRY_VERIFY(gridview->currentItem() != 0);
496
497 // remove item before current, but visible
498 gridview->setCurrentIndex(8);
499 gridview->setContentY(240);
500 oldCurrent = gridview->currentItem();
501 model.removeItem(6);
502
503 QTRY_COMPARE(gridview->currentIndex(), 7);
504 QTRY_VERIFY(gridview->currentItem() == oldCurrent);
505
506 delete canvas;
507 }
508
clear()509 void tst_QDeclarativeGridView::clear()
510 {
511 QDeclarativeView *canvas = createView();
512
513 TestModel model;
514 for (int i = 0; i < 30; i++)
515 model.addItem("Item" + QString::number(i), "");
516
517 QDeclarativeContext *ctxt = canvas->rootContext();
518 ctxt->setContextProperty("testModel", &model);
519 ctxt->setContextProperty("testRightToLeft", QVariant(false));
520 ctxt->setContextProperty("testTopToBottom", QVariant(false));
521
522 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
523 qApp->processEvents();
524
525 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
526 QVERIFY(gridview != 0);
527
528 QDeclarativeItem *contentItem = gridview->contentItem();
529 QVERIFY(contentItem != 0);
530
531 model.clear();
532
533 QVERIFY(gridview->count() == 0);
534 QVERIFY(gridview->currentItem() == 0);
535 QVERIFY(gridview->contentY() == 0);
536 QVERIFY(gridview->currentIndex() == -1);
537
538 // confirm sanity when adding an item to cleared list
539 model.addItem("New", "1");
540 QVERIFY(gridview->count() == 1);
541 QVERIFY(gridview->currentItem() != 0);
542 QVERIFY(gridview->currentIndex() == 0);
543
544 delete canvas;
545 }
546
moved()547 void tst_QDeclarativeGridView::moved()
548 {
549 QDeclarativeView *canvas = createView();
550
551 TestModel model;
552 for (int i = 0; i < 30; i++)
553 model.addItem("Item" + QString::number(i), "");
554
555 QDeclarativeContext *ctxt = canvas->rootContext();
556 ctxt->setContextProperty("testModel", &model);
557 ctxt->setContextProperty("testRightToLeft", QVariant(false));
558 ctxt->setContextProperty("testTopToBottom", QVariant(false));
559
560 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
561 qApp->processEvents();
562
563 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
564 QTRY_VERIFY(gridview != 0);
565
566 QDeclarativeItem *contentItem = gridview->contentItem();
567 QTRY_VERIFY(contentItem != 0);
568
569 model.moveItem(1, 8);
570
571 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
572 QTRY_VERIFY(name != 0);
573 QTRY_COMPARE(name->text(), model.name(1));
574 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
575 QTRY_VERIFY(number != 0);
576 QTRY_COMPARE(number->text(), model.number(1));
577
578 name = findItem<QDeclarativeText>(contentItem, "textName", 8);
579 QTRY_VERIFY(name != 0);
580 QTRY_COMPARE(name->text(), model.name(8));
581 number = findItem<QDeclarativeText>(contentItem, "textNumber", 8);
582 QTRY_VERIFY(number != 0);
583 QTRY_COMPARE(number->text(), model.number(8));
584
585 // Confirm items positioned correctly
586 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
587 for (int i = 0; i < model.count() && i < itemCount; ++i) {
588 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
589 if (!item) qWarning() << "Item" << i << "not found";
590 QTRY_VERIFY(item);
591 QTRY_VERIFY(item->x() == (i%3)*80);
592 QTRY_VERIFY(item->y() == (i/3)*60);
593 }
594
595 gridview->setContentY(120);
596
597 // move outside visible area
598 model.moveItem(1, 25);
599
600 // Confirm items positioned correctly and indexes correct
601 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count()-1;
602 for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
603 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
604 if (!item) qWarning() << "Item" << i << "not found";
605 QTRY_VERIFY(item);
606 QTRY_COMPARE(item->x(), qreal((i%3)*80));
607 QTRY_COMPARE(item->y(), qreal((i/3)*60));
608 name = findItem<QDeclarativeText>(contentItem, "textName", i);
609 QTRY_VERIFY(name != 0);
610 QTRY_COMPARE(name->text(), model.name(i));
611 number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
612 QTRY_VERIFY(number != 0);
613 QTRY_COMPARE(number->text(), model.number(i));
614 }
615
616 // move from outside visible into visible
617 model.moveItem(28, 8);
618
619 // Confirm items positioned correctly and indexes correct
620 for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
621 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
622 if (!item) qWarning() << "Item" << i << "not found";
623 QTRY_VERIFY(item);
624 QTRY_VERIFY(item->x() == (i%3)*80);
625 QTRY_VERIFY(item->y() == (i/3)*60);
626 name = findItem<QDeclarativeText>(contentItem, "textName", i);
627 QTRY_VERIFY(name != 0);
628 QTRY_COMPARE(name->text(), model.name(i));
629 number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
630 QTRY_VERIFY(number != 0);
631 QTRY_COMPARE(number->text(), model.number(i));
632 }
633
634 // ensure content position is stable
635 gridview->setContentY(0);
636 model.moveItem(10, 0);
637 QTRY_VERIFY(gridview->contentY() == 0);
638
639 delete canvas;
640 }
641
currentIndex()642 void tst_QDeclarativeGridView::currentIndex()
643 {
644 TestModel model;
645 for (int i = 0; i < 60; i++)
646 model.addItem("Item" + QString::number(i), QString::number(i));
647
648 QDeclarativeView *canvas = new QDeclarativeView(0);
649 canvas->setFixedSize(240,320);
650
651 QDeclarativeContext *ctxt = canvas->rootContext();
652 ctxt->setContextProperty("testModel", &model);
653
654 QString filename(SRCDIR "/data/gridview-initCurrent.qml");
655 canvas->setSource(QUrl::fromLocalFile(filename));
656
657 qApp->processEvents();
658
659 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
660 QVERIFY(gridview != 0);
661
662 QDeclarativeItem *contentItem = gridview->contentItem();
663 QVERIFY(contentItem != 0);
664
665 // current item should be third item
666 QCOMPARE(gridview->currentIndex(), 35);
667 QCOMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 35));
668 QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y());
669 QCOMPARE(gridview->contentY(), 400.0);
670
671 gridview->moveCurrentIndexRight();
672 QCOMPARE(gridview->currentIndex(), 36);
673 gridview->moveCurrentIndexDown();
674 QCOMPARE(gridview->currentIndex(), 39);
675 gridview->moveCurrentIndexUp();
676 QCOMPARE(gridview->currentIndex(), 36);
677 gridview->moveCurrentIndexLeft();
678 QCOMPARE(gridview->currentIndex(), 35);
679
680 // no wrap
681 gridview->setCurrentIndex(0);
682 QCOMPARE(gridview->currentIndex(), 0);
683 // confirm that the velocity is updated
684 QTRY_VERIFY(gridview->verticalVelocity() != 0.0);
685
686 gridview->moveCurrentIndexUp();
687 QCOMPARE(gridview->currentIndex(), 0);
688
689 gridview->moveCurrentIndexLeft();
690 QCOMPARE(gridview->currentIndex(), 0);
691
692 gridview->setCurrentIndex(model.count()-1);
693 QCOMPARE(gridview->currentIndex(), model.count()-1);
694
695 gridview->moveCurrentIndexRight();
696 QCOMPARE(gridview->currentIndex(), model.count()-1);
697
698 gridview->moveCurrentIndexDown();
699 QCOMPARE(gridview->currentIndex(), model.count()-1);
700
701 // with wrap
702 gridview->setWrapEnabled(true);
703
704 gridview->setCurrentIndex(0);
705 QCOMPARE(gridview->currentIndex(), 0);
706
707 gridview->moveCurrentIndexLeft();
708 QCOMPARE(gridview->currentIndex(), model.count()-1);
709
710 QTRY_COMPARE(gridview->contentY(), 880.0);
711
712 gridview->moveCurrentIndexRight();
713 QCOMPARE(gridview->currentIndex(), 0);
714
715 QTRY_COMPARE(gridview->contentY(), 0.0);
716
717 // Test keys
718 canvas->show();
719 qApp->setActiveWindow(canvas);
720 #ifdef Q_WS_X11
721 // to be safe and avoid failing setFocus with window managers
722 qt_x11_wait_for_window_manager(canvas);
723 #endif
724 QTRY_VERIFY(canvas->hasFocus());
725 QTRY_VERIFY(canvas->scene()->hasFocus());
726 qApp->processEvents();
727
728 QTest::keyClick(canvas, Qt::Key_Down);
729 QCOMPARE(gridview->currentIndex(), 3);
730
731 QTest::keyClick(canvas, Qt::Key_Up);
732 QCOMPARE(gridview->currentIndex(), 0);
733
734 gridview->setFlow(QDeclarativeGridView::TopToBottom);
735
736 qApp->setActiveWindow(canvas);
737 #ifdef Q_WS_X11
738 // to be safe and avoid failing setFocus with window managers
739 qt_x11_wait_for_window_manager(canvas);
740 #endif
741 QTRY_VERIFY(canvas->hasFocus());
742 QTRY_VERIFY(canvas->scene()->hasFocus());
743 qApp->processEvents();
744
745 QTest::keyClick(canvas, Qt::Key_Right);
746 QCOMPARE(gridview->currentIndex(), 5);
747
748 QTest::keyClick(canvas, Qt::Key_Left);
749 QCOMPARE(gridview->currentIndex(), 0);
750
751 QTest::keyClick(canvas, Qt::Key_Down);
752 QCOMPARE(gridview->currentIndex(), 1);
753
754 QTest::keyClick(canvas, Qt::Key_Up);
755 QCOMPARE(gridview->currentIndex(), 0);
756
757
758 // turn off auto highlight
759 gridview->setHighlightFollowsCurrentItem(false);
760 QVERIFY(gridview->highlightFollowsCurrentItem() == false);
761 QVERIFY(gridview->highlightItem());
762 qreal hlPosX = gridview->highlightItem()->x();
763 qreal hlPosY = gridview->highlightItem()->y();
764
765 gridview->setCurrentIndex(5);
766 QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
767 QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
768
769 // insert item before currentIndex
770 gridview->setCurrentIndex(28);
771 model.insertItem(0, "Foo", "1111");
772 QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
773
774 // check removing highlight by setting currentIndex to -1;
775 gridview->setCurrentIndex(-1);
776
777 QCOMPARE(gridview->currentIndex(), -1);
778 QVERIFY(!gridview->highlightItem());
779 QVERIFY(!gridview->currentItem());
780
781 gridview->setHighlightFollowsCurrentItem(true);
782
783 gridview->setFlow(QDeclarativeGridView::LeftToRight);
784 gridview->setLayoutDirection(Qt::RightToLeft);
785
786 qApp->setActiveWindow(canvas);
787 #ifdef Q_WS_X11
788 // to be safe and avoid failing setFocus with window managers
789 qt_x11_wait_for_window_manager(canvas);
790 #endif
791 QTRY_VERIFY(canvas->hasFocus());
792 QTRY_VERIFY(canvas->scene()->hasFocus());
793 qApp->processEvents();
794
795 gridview->setCurrentIndex(35);
796
797 QTest::keyClick(canvas, Qt::Key_Right);
798 QCOMPARE(gridview->currentIndex(), 34);
799
800 QTest::keyClick(canvas, Qt::Key_Down);
801 QCOMPARE(gridview->currentIndex(), 37);
802
803 QTest::keyClick(canvas, Qt::Key_Up);
804 QCOMPARE(gridview->currentIndex(), 34);
805
806 QTest::keyClick(canvas, Qt::Key_Left);
807 QCOMPARE(gridview->currentIndex(), 35);
808
809
810 // turn off auto highlight
811 gridview->setHighlightFollowsCurrentItem(false);
812 QVERIFY(gridview->highlightFollowsCurrentItem() == false);
813 QVERIFY(gridview->highlightItem());
814 hlPosX = gridview->highlightItem()->x();
815 hlPosY = gridview->highlightItem()->y();
816
817 gridview->setCurrentIndex(5);
818 QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
819 QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
820
821 // insert item before currentIndex
822 gridview->setCurrentIndex(28);
823 model.insertItem(0, "Foo", "1111");
824 QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
825
826 // check removing highlight by setting currentIndex to -1;
827 gridview->setCurrentIndex(-1);
828
829 QCOMPARE(gridview->currentIndex(), -1);
830 QVERIFY(!gridview->highlightItem());
831 QVERIFY(!gridview->currentItem());
832
833 delete canvas;
834 }
835
noCurrentIndex()836 void tst_QDeclarativeGridView::noCurrentIndex()
837 {
838 TestModel model;
839 for (int i = 0; i < 60; i++)
840 model.addItem("Item" + QString::number(i), QString::number(i));
841
842 QDeclarativeView *canvas = new QDeclarativeView(0);
843 canvas->setFixedSize(240,320);
844
845 QDeclarativeContext *ctxt = canvas->rootContext();
846 ctxt->setContextProperty("testModel", &model);
847
848 QString filename(SRCDIR "/data/gridview-noCurrent.qml");
849 canvas->setSource(QUrl::fromLocalFile(filename));
850
851 qApp->processEvents();
852
853 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
854 QVERIFY(gridview != 0);
855
856 QDeclarativeItem *contentItem = gridview->contentItem();
857 QVERIFY(contentItem != 0);
858
859 // current index should be -1
860 QCOMPARE(gridview->currentIndex(), -1);
861 QVERIFY(!gridview->currentItem());
862 QVERIFY(!gridview->highlightItem());
863 QCOMPARE(gridview->contentY(), 0.0);
864
865 gridview->setCurrentIndex(5);
866 QCOMPARE(gridview->currentIndex(), 5);
867 QVERIFY(gridview->currentItem());
868 QVERIFY(gridview->highlightItem());
869 }
870
changeFlow()871 void tst_QDeclarativeGridView::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 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(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 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
902 QTRY_VERIFY(name != 0);
903 QTRY_COMPARE(name->text(), model.name(i));
904 QDeclarativeText *number = findItem<QDeclarativeText>(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 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
920 QTRY_VERIFY(name != 0);
921 QTRY_COMPARE(name->text(), model.name(i));
922 QDeclarativeText *number = findItem<QDeclarativeText>(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 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
938 QTRY_VERIFY(name != 0);
939 QTRY_COMPARE(name->text(), model.name(i));
940 QDeclarativeText *number = findItem<QDeclarativeText>(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 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
958 QTRY_VERIFY(name != 0);
959 QTRY_COMPARE(name->text(), model.name(i));
960 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
961 QTRY_VERIFY(number != 0);
962 QTRY_COMPARE(number->text(), model.number(i));
963 }
964
965 delete canvas;
966 }
967
defaultValues()968 void tst_QDeclarativeGridView::defaultValues()
969 {
970 QDeclarativeEngine engine;
971 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview3.qml"));
972 QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(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
properties()991 void tst_QDeclarativeGridView::properties()
992 {
993 QDeclarativeEngine engine;
994 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview2.qml"));
995 QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(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
propertyChanges()1014 void tst_QDeclarativeGridView::propertyChanges()
1015 {
1016 QDeclarativeView *canvas = createView();
1017 QTRY_VERIFY(canvas);
1018 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1019
1020 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("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(), QDeclarativeGridView::LeftToRight);
1031
1032 gridView->setWrapEnabled(false);
1033 gridView->setCacheBuffer(3);
1034 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1035
1036 QTRY_COMPARE(gridView->isWrapEnabled(), false);
1037 QTRY_COMPARE(gridView->cacheBuffer(), 3);
1038 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::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(QDeclarativeGridView::TopToBottom);
1047
1048 QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1049 QTRY_COMPARE(cacheBufferSpy.count(),1);
1050 QTRY_COMPARE(flowSpy.count(),1);
1051
1052 gridView->setFlow(QDeclarativeGridView::LeftToRight);
1053 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::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(QDeclarativeGridView::TopToBottom);
1078 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::TopToBottom);
1079 QTRY_COMPARE(flowSpy.count(),3);
1080
1081 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1082 QTRY_COMPARE(flowSpy.count(),3);
1083
1084 delete canvas;
1085 }
1086
componentChanges()1087 void tst_QDeclarativeGridView::componentChanges()
1088 {
1089 QDeclarativeView *canvas = createView();
1090 QTRY_VERIFY(canvas);
1091 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1092
1093 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("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
modelChanges()1135 void tst_QDeclarativeGridView::modelChanges()
1136 {
1137 QDeclarativeView *canvas = createView();
1138 QTRY_VERIFY(canvas);
1139 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1140
1141 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
1142 QTRY_VERIFY(gridView);
1143
1144 QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("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
positionViewAtIndex()1161 void tst_QDeclarativeGridView::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 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(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, QDeclarativeGridView::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, QDeclarativeGridView::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, QDeclarativeGridView::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, QDeclarativeGridView::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, QDeclarativeGridView::End);
1257 QTRY_COMPARE(gridview->contentY(), 340.);
1258
1259 // Position in Center
1260 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1261 QTRY_COMPARE(gridview->contentY(), 170.);
1262
1263 // Ensure at least partially visible
1264 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1265 QTRY_COMPARE(gridview->contentY(), 170.);
1266
1267 gridview->setContentY(302);
1268 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1269 QTRY_COMPARE(gridview->contentY(), 302.);
1270
1271 gridview->setContentY(360);
1272 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1273 QTRY_COMPARE(gridview->contentY(), 300.);
1274
1275 gridview->setContentY(60);
1276 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1277 QTRY_COMPARE(gridview->contentY(), 60.);
1278
1279 gridview->setContentY(20);
1280 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1281 QTRY_COMPARE(gridview->contentY(), 100.);
1282
1283 // Ensure completely visible
1284 gridview->setContentY(120);
1285 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1286 QTRY_COMPARE(gridview->contentY(), 120.);
1287
1288 gridview->setContentY(302);
1289 gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain);
1290 QTRY_COMPARE(gridview->contentY(), 300.);
1291
1292 gridview->setContentY(60);
1293 gridview->positionViewAtIndex(20, QDeclarativeGridView::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, QDeclarativeGridView::End);
1311 QTRY_COMPARE(gridview->contentX(), 320.);
1312 QTRY_COMPARE(gridview->contentY(), 0.);
1313
1314 // Position in Center
1315 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1316 QTRY_COMPARE(gridview->contentX(), 160.);
1317
1318 // Ensure at least partially visible
1319 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1320 QTRY_COMPARE(gridview->contentX(), 160.);
1321
1322 gridview->setContentX(170);
1323 gridview->positionViewAtIndex(25, QDeclarativeGridView::Visible);
1324 QTRY_COMPARE(gridview->contentX(), 170.);
1325
1326 gridview->positionViewAtIndex(30, QDeclarativeGridView::Visible);
1327 QTRY_COMPARE(gridview->contentX(), 320.);
1328
1329 gridview->setContentX(170);
1330 gridview->positionViewAtIndex(25, QDeclarativeGridView::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
snapping()1354 void tst_QDeclarativeGridView::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 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1371 QTRY_VERIFY(gridview != 0);
1372
1373 gridview->setHeight(220);
1374 QCOMPARE(gridview->height(), 220.);
1375
1376 gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible);
1377 QCOMPARE(gridview->contentY(), 80.);
1378
1379 gridview->setContentY(0);
1380 QCOMPARE(gridview->contentY(), 0.);
1381
1382 gridview->setSnapMode(QDeclarativeGridView::SnapToRow);
1383 QCOMPARE(gridview->snapMode(), QDeclarativeGridView::SnapToRow);
1384
1385 gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible);
1386 QCOMPARE(gridview->contentY(), 60.);
1387
1388 gridview->positionViewAtIndex(15, QDeclarativeGridView::End);
1389 QCOMPARE(gridview->contentY(), 120.);
1390
1391 delete canvas;
1392
1393 }
1394
mirroring()1395 void tst_QDeclarativeGridView::mirroring()
1396 {
1397 QDeclarativeView *canvasA = createView();
1398 canvasA->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
1399 QDeclarativeGridView *gridviewA = findItem<QDeclarativeGridView>(canvasA->rootObject(), "view");
1400 QTRY_VERIFY(gridviewA != 0);
1401
1402 QDeclarativeView *canvasB = createView();
1403 canvasB->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
1404 QDeclarativeGridView *gridviewB = findItem<QDeclarativeGridView>(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
positionViewAtIndex_rightToLeft()1456 void tst_QDeclarativeGridView::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 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(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, QDeclarativeGridView::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, QDeclarativeGridView::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, QDeclarativeGridView::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, QDeclarativeGridView::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, QDeclarativeGridView::End);
1546 QTRY_COMPARE(gridview->contentX(), -560.);
1547
1548 // Position in Center
1549 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1550 QTRY_COMPARE(gridview->contentX(), -400.);
1551
1552 // Ensure at least partially visible
1553 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1554 QTRY_COMPARE(gridview->contentX(), -400.);
1555
1556 gridview->setContentX(-555.);
1557 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1558 QTRY_COMPARE(gridview->contentX(), -555.);
1559
1560 gridview->setContentX(-239);
1561 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1562 QTRY_COMPARE(gridview->contentX(), -320.);
1563
1564 gridview->setContentX(-239);
1565 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1566 QTRY_COMPARE(gridview->contentX(), -400.);
1567
1568 gridview->setContentX(-640);
1569 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1570 QTRY_COMPARE(gridview->contentX(), -560.);
1571
1572 // Ensure completely visible
1573 gridview->setContentX(-400);
1574 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1575 QTRY_COMPARE(gridview->contentX(), -400.);
1576
1577 gridview->setContentX(-315);
1578 gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain);
1579 QTRY_COMPARE(gridview->contentX(), -320.);
1580
1581 gridview->setContentX(-640);
1582 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1583 QTRY_COMPARE(gridview->contentX(), -560.);
1584
1585 delete canvas;
1586 }
1587
resetModel()1588 void tst_QDeclarativeGridView::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 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(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 QDeclarativeText *display = findItem<QDeclarativeText>(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 QDeclarativeText *display = findItem<QDeclarativeText>(contentItem, "displayText", i);
1624 QTRY_VERIFY(display != 0);
1625 QTRY_COMPARE(display->text(), strings.at(i));
1626 }
1627 }
1628
enforceRange()1629 void tst_QDeclarativeGridView::enforceRange()
1630 {
1631 QDeclarativeView *canvas = createView();
1632
1633 TestModel model;
1634 for (int i = 0; i < 30; i++)
1635 model.addItem("Item" + QString::number(i), "");
1636
1637 QDeclarativeContext *ctxt = canvas->rootContext();
1638 ctxt->setContextProperty("testModel", &model);
1639 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1640 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1641
1642 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1643 qApp->processEvents();
1644 QVERIFY(canvas->rootObject() != 0);
1645
1646 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1647 QTRY_VERIFY(gridview != 0);
1648
1649 QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1650 QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1651 QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarativeGridView::StrictlyEnforceRange);
1652
1653 QDeclarativeItem *contentItem = gridview->contentItem();
1654 QTRY_VERIFY(contentItem != 0);
1655
1656 // view should be positioned at the top of the range.
1657 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1658 QTRY_VERIFY(item);
1659 QTRY_COMPARE(gridview->contentY(), -100.0);
1660
1661 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 0);
1662 QTRY_VERIFY(name != 0);
1663 QTRY_COMPARE(name->text(), model.name(0));
1664 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
1665 QTRY_VERIFY(number != 0);
1666 QTRY_COMPARE(number->text(), model.number(0));
1667
1668 // Check currentIndex is updated when contentItem moves
1669 gridview->setContentY(0);
1670 QTRY_COMPARE(gridview->currentIndex(), 2);
1671
1672 gridview->setCurrentIndex(5);
1673 QTRY_COMPARE(gridview->contentY(), 100.);
1674
1675 TestModel model2;
1676 for (int i = 0; i < 5; i++)
1677 model2.addItem("Item" + QString::number(i), "");
1678
1679 ctxt->setContextProperty("testModel", &model2);
1680 QCOMPARE(gridview->count(), 5);
1681
1682 delete canvas;
1683 }
1684
enforceRange_rightToLeft()1685 void tst_QDeclarativeGridView::enforceRange_rightToLeft()
1686 {
1687 QDeclarativeView *canvas = createView();
1688
1689 TestModel model;
1690 for (int i = 0; i < 30; i++)
1691 model.addItem("Item" + QString::number(i), "");
1692
1693 QDeclarativeContext *ctxt = canvas->rootContext();
1694 ctxt->setContextProperty("testModel", &model);
1695 ctxt->setContextProperty("testRightToLeft", QVariant(true));
1696 ctxt->setContextProperty("testTopToBottom", QVariant(true));
1697
1698 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1699 qApp->processEvents();
1700 QVERIFY(canvas->rootObject() != 0);
1701
1702 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1703 QTRY_VERIFY(gridview != 0);
1704
1705 QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1706 QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1707 QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarativeGridView::StrictlyEnforceRange);
1708
1709 QDeclarativeItem *contentItem = gridview->contentItem();
1710 QTRY_VERIFY(contentItem != 0);
1711
1712 // view should be positioned at the top of the range.
1713 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1714 QTRY_VERIFY(item);
1715 QTRY_COMPARE(gridview->contentX(), -100.);
1716 QTRY_COMPARE(gridview->contentY(), 0.0);
1717
1718 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 0);
1719 QTRY_VERIFY(name != 0);
1720 QTRY_COMPARE(name->text(), model.name(0));
1721 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
1722 QTRY_VERIFY(number != 0);
1723 QTRY_COMPARE(number->text(), model.number(0));
1724
1725 // Check currentIndex is updated when contentItem moves
1726 gridview->setContentX(-200);
1727 QTRY_COMPARE(gridview->currentIndex(), 3);
1728
1729 gridview->setCurrentIndex(7);
1730 QTRY_COMPARE(gridview->contentX(), -300.);
1731 QTRY_COMPARE(gridview->contentY(), 0.0);
1732
1733 TestModel model2;
1734 for (int i = 0; i < 5; i++)
1735 model2.addItem("Item" + QString::number(i), "");
1736
1737 ctxt->setContextProperty("testModel", &model2);
1738 QCOMPARE(gridview->count(), 5);
1739
1740 delete canvas;
1741 }
1742
QTBUG_8456()1743 void tst_QDeclarativeGridView::QTBUG_8456()
1744 {
1745 QDeclarativeView *canvas = createView();
1746
1747 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/setindex.qml"));
1748 qApp->processEvents();
1749
1750 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1751 QTRY_VERIFY(gridview != 0);
1752
1753 QTRY_COMPARE(gridview->currentIndex(), 0);
1754 }
1755
manualHighlight()1756 void tst_QDeclarativeGridView::manualHighlight()
1757 {
1758 QDeclarativeView *canvas = createView();
1759
1760 QString filename(SRCDIR "/data/manual-highlight.qml");
1761 canvas->setSource(QUrl::fromLocalFile(filename));
1762
1763 qApp->processEvents();
1764
1765 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1766 QTRY_VERIFY(gridview != 0);
1767
1768 QDeclarativeItem *contentItem = gridview->contentItem();
1769 QTRY_VERIFY(contentItem != 0);
1770
1771 QTRY_COMPARE(gridview->currentIndex(), 0);
1772 QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
1773 QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1774 QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1775
1776 gridview->setCurrentIndex(2);
1777
1778 QTRY_COMPARE(gridview->currentIndex(), 2);
1779 QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2));
1780 QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1781 QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1782
1783 gridview->positionViewAtIndex(8, QDeclarativeGridView::Contain);
1784
1785 QTRY_COMPARE(gridview->currentIndex(), 2);
1786 QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2));
1787 QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1788 QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1789
1790 gridview->setFlow(QDeclarativeGridView::TopToBottom);
1791 QTRY_COMPARE(gridview->flow(), QDeclarativeGridView::TopToBottom);
1792
1793 gridview->setCurrentIndex(0);
1794 QTRY_COMPARE(gridview->currentIndex(), 0);
1795 QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
1796 QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1797 QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1798 }
1799
footer()1800 void tst_QDeclarativeGridView::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 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1815 QTRY_VERIFY(gridview != 0);
1816
1817 QDeclarativeItem *contentItem = gridview->contentItem();
1818 QTRY_VERIFY(contentItem != 0);
1819
1820 QDeclarativeText *footer = findItem<QDeclarativeText>(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<QDeclarativeText>(contentItem, "footer");
1838 QVERIFY(!footer);
1839 footer = findItem<QDeclarativeText>(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
header()1847 void tst_QDeclarativeGridView::header()
1848 {
1849 QDeclarativeView *canvas = createView();
1850
1851 TestModel model;
1852 for (int i = 0; i < 30; i++)
1853 model.addItem("Item" + QString::number(i), "");
1854
1855 QDeclarativeContext *ctxt = canvas->rootContext();
1856 ctxt->setContextProperty("testModel", &model);
1857
1858 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
1859 qApp->processEvents();
1860
1861 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1862 QTRY_VERIFY(gridview != 0);
1863
1864 QDeclarativeItem *contentItem = gridview->contentItem();
1865 QTRY_VERIFY(contentItem != 0);
1866
1867 QDeclarativeText *header = findItem<QDeclarativeText>(contentItem, "header");
1868 QVERIFY(header);
1869
1870 QCOMPARE(header->y(), 0.0);
1871 QCOMPARE(header->height(), 30.0);
1872 QCOMPARE(gridview->contentY(), 0.0);
1873
1874 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1875 QVERIFY(item);
1876 QCOMPARE(item->y(), 30.0);
1877
1878 model.clear();
1879 QTRY_COMPARE(header->y(), 0.0);
1880
1881 for (int i = 0; i < 30; i++)
1882 model.addItem("Item" + QString::number(i), "");
1883
1884 QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
1885
1886 header = findItem<QDeclarativeText>(contentItem, "header");
1887 QVERIFY(!header);
1888 header = findItem<QDeclarativeText>(contentItem, "header2");
1889 QVERIFY(header);
1890
1891 QCOMPARE(header->y(), 10.0);
1892 QCOMPARE(header->height(), 20.0);
1893 QCOMPARE(gridview->contentY(), 10.0);
1894 }
1895
indexAt()1896 void tst_QDeclarativeGridView::indexAt()
1897 {
1898 QDeclarativeView *canvas = createView();
1899
1900 TestModel model;
1901 model.addItem("Fred", "12345");
1902 model.addItem("John", "2345");
1903 model.addItem("Bob", "54321");
1904 model.addItem("Billy", "22345");
1905 model.addItem("Sam", "2945");
1906 model.addItem("Ben", "04321");
1907 model.addItem("Jim", "0780");
1908
1909 QDeclarativeContext *ctxt = canvas->rootContext();
1910 ctxt->setContextProperty("testModel", &model);
1911 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1912 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1913
1914 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1915 qApp->processEvents();
1916
1917 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1918 QTRY_VERIFY(gridview != 0);
1919
1920 QDeclarativeItem *contentItem = gridview->contentItem();
1921 QTRY_VERIFY(contentItem != 0);
1922
1923 QTRY_COMPARE(gridview->count(), model.count());
1924
1925 QCOMPARE(gridview->indexAt(0, 0), 0);
1926 QCOMPARE(gridview->indexAt(79, 59), 0);
1927 QCOMPARE(gridview->indexAt(80, 0), 1);
1928 QCOMPARE(gridview->indexAt(0, 60), 3);
1929 QCOMPARE(gridview->indexAt(240, 0), -1);
1930
1931 delete canvas;
1932 }
1933
onAdd()1934 void tst_QDeclarativeGridView::onAdd()
1935 {
1936 QFETCH(int, initialItemCount);
1937 QFETCH(int, itemsToAdd);
1938
1939 const int delegateWidth = 50;
1940 const int delegateHeight = 100;
1941 TestModel model;
1942 QDeclarativeView *canvas = createView();
1943 canvas->setFixedSize(5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit
1944
1945 // these initial items should not trigger GridView.onAdd
1946 for (int i=0; i<initialItemCount; i++)
1947 model.addItem("dummy value", "dummy value");
1948
1949 QDeclarativeContext *ctxt = canvas->rootContext();
1950 ctxt->setContextProperty("testModel", &model);
1951 ctxt->setContextProperty("delegateWidth", delegateWidth);
1952 ctxt->setContextProperty("delegateHeight", delegateHeight);
1953 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
1954
1955 QObject *object = canvas->rootObject();
1956 object->setProperty("width", canvas->width());
1957 object->setProperty("height", canvas->height());
1958 qApp->processEvents();
1959
1960 QList<QPair<QString, QString> > items;
1961 for (int i=0; i<itemsToAdd; i++)
1962 items << qMakePair(QString("value %1").arg(i), QString::number(i));
1963 model.addItems(items);
1964
1965 qApp->processEvents();
1966
1967 QVariantList result = object->property("addedDelegates").toList();
1968 QCOMPARE(result.count(), items.count());
1969 for (int i=0; i<items.count(); i++)
1970 QCOMPARE(result[i].toString(), items[i].first);
1971
1972 delete canvas;
1973 }
1974
onAdd_data()1975 void tst_QDeclarativeGridView::onAdd_data()
1976 {
1977 QTest::addColumn<int>("initialItemCount");
1978 QTest::addColumn<int>("itemsToAdd");
1979
1980 QTest::newRow("0, add 1") << 0 << 1;
1981 QTest::newRow("0, add 2") << 0 << 2;
1982 QTest::newRow("0, add 10") << 0 << 10;
1983
1984 QTest::newRow("1, add 1") << 1 << 1;
1985 QTest::newRow("1, add 2") << 1 << 2;
1986 QTest::newRow("1, add 10") << 1 << 10;
1987
1988 QTest::newRow("5, add 1") << 5 << 1;
1989 QTest::newRow("5, add 2") << 5 << 2;
1990 QTest::newRow("5, add 10") << 5 << 10;
1991 }
1992
onRemove()1993 void tst_QDeclarativeGridView::onRemove()
1994 {
1995 QFETCH(int, initialItemCount);
1996 QFETCH(int, indexToRemove);
1997 QFETCH(int, removeCount);
1998
1999 const int delegateWidth = 50;
2000 const int delegateHeight = 100;
2001 TestModel model;
2002 for (int i=0; i<initialItemCount; i++)
2003 model.addItem(QString("value %1").arg(i), "dummy value");
2004
2005 QDeclarativeView *canvas = createView();
2006 QDeclarativeContext *ctxt = canvas->rootContext();
2007 ctxt->setContextProperty("testModel", &model);
2008 ctxt->setContextProperty("delegateWidth", delegateWidth);
2009 ctxt->setContextProperty("delegateHeight", delegateHeight);
2010 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
2011 QObject *object = canvas->rootObject();
2012
2013 qApp->processEvents();
2014
2015 model.removeItems(indexToRemove, removeCount);
2016 qApp->processEvents();
2017 QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
2018
2019 delete canvas;
2020 }
2021
onRemove_data()2022 void tst_QDeclarativeGridView::onRemove_data()
2023 {
2024 QTest::addColumn<int>("initialItemCount");
2025 QTest::addColumn<int>("indexToRemove");
2026 QTest::addColumn<int>("removeCount");
2027
2028 QTest::newRow("remove first") << 1 << 0 << 1;
2029 QTest::newRow("two items, remove first") << 2 << 0 << 1;
2030 QTest::newRow("two items, remove last") << 2 << 1 << 1;
2031 QTest::newRow("two items, remove all") << 2 << 0 << 2;
2032
2033 QTest::newRow("four items, remove first") << 4 << 0 << 1;
2034 QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
2035 QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
2036 QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
2037 QTest::newRow("four items, remove last") << 4 << 3 << 1;
2038 QTest::newRow("four items, remove all") << 4 << 0 << 4;
2039
2040 QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
2041 QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
2042 QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
2043 }
2044
testQtQuick11Attributes()2045 void tst_QDeclarativeGridView::testQtQuick11Attributes()
2046 {
2047 QFETCH(QString, code);
2048 QFETCH(QString, warning);
2049 QFETCH(QString, error);
2050
2051 QDeclarativeEngine engine;
2052 QObject *obj;
2053
2054 QDeclarativeComponent valid(&engine);
2055 valid.setData("import QtQuick 1.1; GridView { " + code.toUtf8() + " }", QUrl(""));
2056 obj = valid.create();
2057 QVERIFY(obj);
2058 QVERIFY(valid.errorString().isEmpty());
2059 delete obj;
2060
2061 QDeclarativeComponent invalid(&engine);
2062 invalid.setData("import QtQuick 1.0; GridView { " + code.toUtf8() + " }", QUrl(""));
2063 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2064 obj = invalid.create();
2065 QCOMPARE(invalid.errorString(), error);
2066 delete obj;
2067 }
2068
testQtQuick11Attributes_data()2069 void tst_QDeclarativeGridView::testQtQuick11Attributes_data()
2070 {
2071 QTest::addColumn<QString>("code");
2072 QTest::addColumn<QString>("warning");
2073 QTest::addColumn<QString>("error");
2074
2075 QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()"
2076 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning"
2077 << "";
2078
2079 QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()"
2080 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd"
2081 << "";
2082 }
2083
contentPosJump()2084 void tst_QDeclarativeGridView::contentPosJump()
2085 {
2086 QDeclarativeView *canvas = createView();
2087
2088 TestModel model;
2089 for (int i = 0; i < 100; i++)
2090 model.addItem("Item" + QString::number(i), "");
2091
2092 QDeclarativeContext *ctxt = canvas->rootContext();
2093 ctxt->setContextProperty("testModel", &model);
2094 ctxt->setContextProperty("testRightToLeft", QVariant(false));
2095 ctxt->setContextProperty("testTopToBottom", QVariant(false));
2096
2097 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
2098 qApp->processEvents();
2099
2100 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
2101 QVERIFY(gridview != 0);
2102
2103 QDeclarativeItem *contentItem = gridview->contentItem();
2104 QVERIFY(contentItem != 0);
2105
2106 // Test jumping more than a page of items.
2107 gridview->setContentY(500);
2108
2109 // Confirm items positioned correctly
2110 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2111 for (int i = 24; i < model.count() && i < itemCount; ++i) {
2112 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2113 if (!item) qWarning() << "Item" << i << "not found";
2114 QVERIFY(item);
2115 QVERIFY(item->x() == (i%3)*80);
2116 QVERIFY(item->y() == (i/3)*60);
2117 }
2118
2119 gridview->setContentY(-100);
2120 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2121 QVERIFY(itemCount < 15);
2122 // Confirm items positioned correctly
2123 for (int i = 0; i < model.count() && i < itemCount; ++i) {
2124 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2125 if (!item) qWarning() << "Item" << i << "not found";
2126 QVERIFY(item);
2127 QVERIFY(item->x() == (i%3)*80);
2128 QVERIFY(item->y() == (i/3)*60);
2129 }
2130
2131 delete canvas;
2132 }
2133
createView()2134 QDeclarativeView *tst_QDeclarativeGridView::createView()
2135 {
2136 QDeclarativeView *canvas = new QDeclarativeView(0);
2137 canvas->setFixedSize(240,320);
2138
2139 return canvas;
2140 }
2141
2142 /*
2143 Find an item with the specified objectName. If index is supplied then the
2144 item must also evaluate the {index} expression equal to index
2145 */
2146 template<typename T>
findItem(QGraphicsObject * parent,const QString & objectName,int index)2147 T *tst_QDeclarativeGridView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
2148 {
2149 const QMetaObject &mo = T::staticMetaObject;
2150 //qDebug() << parent->childItems().count() << "children";
2151 for (int i = 0; i < parent->childItems().count(); ++i) {
2152 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2153 if(!item)
2154 continue;
2155 //qDebug() << "try" << item;
2156 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2157 if (index != -1) {
2158 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2159 if (context) {
2160 if (context->contextProperty("index").toInt() == index) {
2161 return static_cast<T*>(item);
2162 }
2163 }
2164 } else {
2165 return static_cast<T*>(item);
2166 }
2167 }
2168 item = findItem<T>(item, objectName, index);
2169 if (item)
2170 return static_cast<T*>(item);
2171 }
2172
2173 return 0;
2174 }
2175
2176 template<typename T>
findItems(QGraphicsObject * parent,const QString & objectName)2177 QList<T*> tst_QDeclarativeGridView::findItems(QGraphicsObject *parent, const QString &objectName)
2178 {
2179 QList<T*> items;
2180 const QMetaObject &mo = T::staticMetaObject;
2181 //qDebug() << parent->childItems().count() << "children";
2182 for (int i = 0; i < parent->childItems().count(); ++i) {
2183 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2184 if(!item)
2185 continue;
2186 //qDebug() << "try" << item;
2187 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2188 items.append(static_cast<T*>(item));
2189 //qDebug() << " found:" << item;
2190 }
2191 items += findItems<T>(item, objectName);
2192 }
2193
2194 return items;
2195 }
2196
dumpTree(QDeclarativeItem * parent,int depth)2197 void tst_QDeclarativeGridView::dumpTree(QDeclarativeItem *parent, int depth)
2198 {
2199 static QString padding(" ");
2200 for (int i = 0; i < parent->childItems().count(); ++i) {
2201 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2202 if(!item)
2203 continue;
2204 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2205 qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
2206 dumpTree(item, depth+1);
2207 }
2208 }
2209
2210
2211 QTEST_MAIN(tst_QDeclarativeGridView)
2212
2213 #include "tst_qdeclarativegridview.moc"
2214