1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
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"
57 // In Symbian OS test data is located in applications private dir
61 class tst_QDeclarativeGridView : public QObject
65 tst_QDeclarativeGridView();
76 void noCurrentIndex();
79 void propertyChanges();
80 void componentChanges();
82 void positionViewAtIndex();
83 void positionViewAtIndex_rightToLeft();
88 void enforceRange_rightToLeft();
90 void manualHighlight();
98 void testQtQuick11Attributes();
99 void testQtQuick11Attributes_data();
100 void contentPosJump();
103 QDeclarativeView *createView();
105 T *findItem(QGraphicsObject *parent, const QString &id, int index=-1);
107 QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
108 void dumpTree(QDeclarativeItem *parent, int depth = 0);
111 class TestModel : public QAbstractListModel
114 enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
116 TestModel(QObject *parent=0) : QAbstractListModel(parent) {
117 QHash<int, QByteArray> roles;
118 roles[Name] = "name";
119 roles[Number] = "number";
123 int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
124 QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
127 rv = list.at(index.row()).first;
128 else if (role == Number)
129 rv = list.at(index.row()).second;
134 int count() const { return rowCount(); }
135 QString name(int index) const { return list.at(index).first; }
136 QString number(int index) const { return list.at(index).second; }
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();
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();
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();
157 void removeItem(int index) {
158 emit beginRemoveRows(QModelIndex(), index, index);
159 list.removeAt(index);
160 emit endRemoveRows();
163 void removeItems(int index, int count) {
164 emit beginRemoveRows(QModelIndex(), index, index+count-1);
166 list.removeAt(index);
167 emit endRemoveRows();
170 void moveItem(int from, int to) {
171 emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
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));
182 int count = list.count();
183 emit beginRemoveRows(QModelIndex(), 0, count-1);
185 emit endRemoveRows();
190 QList<QPair<QString,QString> > list;
193 tst_QDeclarativeGridView::tst_QDeclarativeGridView()
197 void tst_QDeclarativeGridView::items()
199 QDeclarativeView *canvas = createView();
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");
210 QDeclarativeContext *ctxt = canvas->rootContext();
211 ctxt->setContextProperty("testModel", &model);
212 ctxt->setContextProperty("testRightToLeft", QVariant(false));
213 ctxt->setContextProperty("testTopToBottom", QVariant(false));
215 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
216 qApp->processEvents();
218 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
219 QTRY_VERIFY(gridview != 0);
221 QDeclarativeItem *contentItem = gridview->contentItem();
222 QTRY_VERIFY(contentItem != 0);
224 QTRY_COMPARE(gridview->count(), model.count());
225 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
227 for (int i = 0; i < model.count(); ++i) {
228 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
229 QTRY_VERIFY(name != 0);
230 QTRY_COMPARE(name->text(), model.name(i));
231 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
232 QTRY_VERIFY(number != 0);
233 QTRY_COMPARE(number->text(), model.number(i));
236 // set an empty model and confirm that items are destroyed
238 ctxt->setContextProperty("testModel", &model2);
240 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
241 QTRY_VERIFY(itemCount == 0);
246 void tst_QDeclarativeGridView::changed()
248 QDeclarativeView *canvas = createView();
251 model.addItem("Fred", "12345");
252 model.addItem("John", "2345");
253 model.addItem("Bob", "54321");
254 model.addItem("Billy", "22345");
255 model.addItem("Sam", "2945");
256 model.addItem("Ben", "04321");
257 model.addItem("Jim", "0780");
259 QDeclarativeContext *ctxt = canvas->rootContext();
260 ctxt->setContextProperty("testModel", &model);
261 ctxt->setContextProperty("testRightToLeft", QVariant(false));
262 ctxt->setContextProperty("testTopToBottom", QVariant(false));
264 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
265 qApp->processEvents();
267 QDeclarativeFlickable *gridview = findItem<QDeclarativeFlickable>(canvas->rootObject(), "grid");
268 QTRY_VERIFY(gridview != 0);
270 QDeclarativeItem *contentItem = gridview->contentItem();
271 QTRY_VERIFY(contentItem != 0);
273 model.modifyItem(1, "Will", "9876");
274 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
275 QTRY_VERIFY(name != 0);
276 QTRY_COMPARE(name->text(), model.name(1));
277 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
278 QTRY_VERIFY(number != 0);
279 QTRY_COMPARE(number->text(), model.number(1));
284 void tst_QDeclarativeGridView::inserted()
286 QDeclarativeView *canvas = createView();
289 model.addItem("Fred", "12345");
290 model.addItem("John", "2345");
291 model.addItem("Bob", "54321");
293 QDeclarativeContext *ctxt = canvas->rootContext();
294 ctxt->setContextProperty("testModel", &model);
295 ctxt->setContextProperty("testRightToLeft", QVariant(false));
296 ctxt->setContextProperty("testTopToBottom", QVariant(false));
298 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
299 qApp->processEvents();
301 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
302 QTRY_VERIFY(gridview != 0);
304 QDeclarativeItem *contentItem = gridview->contentItem();
305 QTRY_VERIFY(contentItem != 0);
307 model.insertItem(1, "Will", "9876");
309 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
311 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
312 QTRY_VERIFY(name != 0);
313 QTRY_COMPARE(name->text(), model.name(1));
314 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
315 QTRY_VERIFY(number != 0);
316 QTRY_COMPARE(number->text(), model.number(1));
318 // Checks that onAdd is called
319 int added = canvas->rootObject()->property("added").toInt();
320 QTRY_COMPARE(added, 1);
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);
329 model.insertItem(0, "Foo", "1111"); // zero index, and current item
331 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
333 name = findItem<QDeclarativeText>(contentItem, "textName", 0);
334 QTRY_VERIFY(name != 0);
335 QTRY_COMPARE(name->text(), model.name(0));
336 number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
337 QTRY_VERIFY(number != 0);
338 QTRY_COMPARE(number->text(), model.number(0));
340 QTRY_COMPARE(gridview->currentIndex(), 1);
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);
349 for (int i = model.count(); i < 30; ++i)
350 model.insertItem(i, "Hello", QString::number(i));
352 gridview->setContentY(120);
354 // Insert item outside visible area
355 model.insertItem(1, "Hello", "1324");
357 QTRY_VERIFY(gridview->contentY() == 120);
362 void tst_QDeclarativeGridView::removed()
364 QDeclarativeView *canvas = createView();
367 for (int i = 0; i < 40; i++)
368 model.addItem("Item" + QString::number(i), "");
370 QDeclarativeContext *ctxt = canvas->rootContext();
371 ctxt->setContextProperty("testModel", &model);
372 ctxt->setContextProperty("testRightToLeft", QVariant(false));
373 ctxt->setContextProperty("testTopToBottom", QVariant(false));
375 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
376 qApp->processEvents();
378 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
379 QTRY_VERIFY(gridview != 0);
381 QDeclarativeItem *contentItem = gridview->contentItem();
382 QTRY_VERIFY(contentItem != 0);
386 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
387 QTRY_VERIFY(name != 0);
388 QTRY_COMPARE(name->text(), model.name(1));
389 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
390 QTRY_VERIFY(number != 0);
391 QTRY_COMPARE(number->text(), model.number(1));
393 // Checks that onRemove is called
394 QString removed = canvas->rootObject()->property("removed").toString();
395 QTRY_COMPARE(removed, QString("Item1"));
397 // Confirm items positioned correctly
398 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
399 for (int i = 0; i < model.count() && i < itemCount; ++i) {
400 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
401 if (!item) qWarning() << "Item" << i << "not found";
403 QTRY_VERIFY(item->x() == (i%3)*80);
404 QTRY_VERIFY(item->y() == (i/3)*60);
407 // Remove first item (which is the current item);
410 name = findItem<QDeclarativeText>(contentItem, "textName", 0);
411 QTRY_VERIFY(name != 0);
412 QTRY_COMPARE(name->text(), model.name(0));
413 number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
414 QTRY_VERIFY(number != 0);
415 QTRY_COMPARE(number->text(), model.number(0));
417 // Confirm items positioned correctly
418 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
419 for (int i = 0; i < model.count() && i < itemCount; ++i) {
420 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
421 if (!item) qWarning() << "Item" << i << "not found";
423 QTRY_VERIFY(item->x() == (i%3)*80);
424 QTRY_VERIFY(item->y() == (i/3)*60);
427 // Remove items not visible
428 model.removeItem(25);
430 // Confirm items positioned correctly
431 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
432 for (int i = 0; i < model.count() && i < itemCount; ++i) {
433 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
434 if (!item) qWarning() << "Item" << i << "not found";
436 QTRY_VERIFY(item->x() == (i%3)*80);
437 QTRY_VERIFY(item->y() == (i/3)*60);
440 // Remove items before visible
441 gridview->setContentY(120);
442 gridview->setCurrentIndex(10);
444 // Setting currentIndex above shouldn't cause view to scroll
445 QTRY_COMPARE(gridview->contentY(), 120.0);
449 // Confirm items positioned correctly
450 for (int i = 6; i < 18; ++i) {
451 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
452 if (!item) qWarning() << "Item" << i << "not found";
454 QTRY_VERIFY(item->x() == (i%3)*80);
455 QTRY_VERIFY(item->y() == (i/3)*60);
458 // Remove currentIndex
459 QDeclarativeItem *oldCurrent = gridview->currentItem();
462 QTRY_COMPARE(gridview->currentIndex(), 9);
463 QTRY_VERIFY(gridview->currentItem() != oldCurrent);
465 gridview->setContentY(0);
466 // let transitions settle.
469 // Confirm items positioned correctly
470 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
471 for (int i = 0; i < model.count() && i < itemCount; ++i) {
472 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
473 if (!item) qWarning() << "Item" << i << "not found";
475 QTRY_VERIFY(item->x() == (i%3)*80);
476 QTRY_VERIFY(item->y() == (i/3)*60);
479 // remove item outside current view.
480 gridview->setCurrentIndex(32);
481 gridview->setContentY(240);
483 model.removeItem(30);
484 QTRY_VERIFY(gridview->currentIndex() == 31);
486 // remove current item beyond visible items.
487 gridview->setCurrentIndex(20);
488 gridview->setContentY(0);
489 model.removeItem(20);
491 QTRY_COMPARE(gridview->currentIndex(), 20);
492 QTRY_VERIFY(gridview->currentItem() != 0);
494 // remove item before current, but visible
495 gridview->setCurrentIndex(8);
496 gridview->setContentY(240);
497 oldCurrent = gridview->currentItem();
500 QTRY_COMPARE(gridview->currentIndex(), 7);
501 QTRY_VERIFY(gridview->currentItem() == oldCurrent);
506 void tst_QDeclarativeGridView::clear()
508 QDeclarativeView *canvas = createView();
511 for (int i = 0; i < 30; i++)
512 model.addItem("Item" + QString::number(i), "");
514 QDeclarativeContext *ctxt = canvas->rootContext();
515 ctxt->setContextProperty("testModel", &model);
516 ctxt->setContextProperty("testRightToLeft", QVariant(false));
517 ctxt->setContextProperty("testTopToBottom", QVariant(false));
519 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
520 qApp->processEvents();
522 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
523 QVERIFY(gridview != 0);
525 QDeclarativeItem *contentItem = gridview->contentItem();
526 QVERIFY(contentItem != 0);
530 QVERIFY(gridview->count() == 0);
531 QVERIFY(gridview->currentItem() == 0);
532 QVERIFY(gridview->contentY() == 0);
533 QVERIFY(gridview->currentIndex() == -1);
535 // confirm sanity when adding an item to cleared list
536 model.addItem("New", "1");
537 QVERIFY(gridview->count() == 1);
538 QVERIFY(gridview->currentItem() != 0);
539 QVERIFY(gridview->currentIndex() == 0);
544 void tst_QDeclarativeGridView::moved()
546 QDeclarativeView *canvas = createView();
549 for (int i = 0; i < 30; i++)
550 model.addItem("Item" + QString::number(i), "");
552 QDeclarativeContext *ctxt = canvas->rootContext();
553 ctxt->setContextProperty("testModel", &model);
554 ctxt->setContextProperty("testRightToLeft", QVariant(false));
555 ctxt->setContextProperty("testTopToBottom", QVariant(false));
557 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
558 qApp->processEvents();
560 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
561 QTRY_VERIFY(gridview != 0);
563 QDeclarativeItem *contentItem = gridview->contentItem();
564 QTRY_VERIFY(contentItem != 0);
566 model.moveItem(1, 8);
568 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1);
569 QTRY_VERIFY(name != 0);
570 QTRY_COMPARE(name->text(), model.name(1));
571 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 1);
572 QTRY_VERIFY(number != 0);
573 QTRY_COMPARE(number->text(), model.number(1));
575 name = findItem<QDeclarativeText>(contentItem, "textName", 8);
576 QTRY_VERIFY(name != 0);
577 QTRY_COMPARE(name->text(), model.name(8));
578 number = findItem<QDeclarativeText>(contentItem, "textNumber", 8);
579 QTRY_VERIFY(number != 0);
580 QTRY_COMPARE(number->text(), model.number(8));
582 // Confirm items positioned correctly
583 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
584 for (int i = 0; i < model.count() && i < itemCount; ++i) {
585 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
586 if (!item) qWarning() << "Item" << i << "not found";
588 QTRY_VERIFY(item->x() == (i%3)*80);
589 QTRY_VERIFY(item->y() == (i/3)*60);
592 gridview->setContentY(120);
594 // move outside visible area
595 model.moveItem(1, 25);
597 // Confirm items positioned correctly and indexes correct
598 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count()-1;
599 for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
600 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
601 if (!item) qWarning() << "Item" << i << "not found";
603 QTRY_COMPARE(item->x(), qreal((i%3)*80));
604 QTRY_COMPARE(item->y(), qreal((i/3)*60));
605 name = findItem<QDeclarativeText>(contentItem, "textName", i);
606 QTRY_VERIFY(name != 0);
607 QTRY_COMPARE(name->text(), model.name(i));
608 number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
609 QTRY_VERIFY(number != 0);
610 QTRY_COMPARE(number->text(), model.number(i));
613 // move from outside visible into visible
614 model.moveItem(28, 8);
616 // Confirm items positioned correctly and indexes correct
617 for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
618 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
619 if (!item) qWarning() << "Item" << i << "not found";
621 QTRY_VERIFY(item->x() == (i%3)*80);
622 QTRY_VERIFY(item->y() == (i/3)*60);
623 name = findItem<QDeclarativeText>(contentItem, "textName", i);
624 QTRY_VERIFY(name != 0);
625 QTRY_COMPARE(name->text(), model.name(i));
626 number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
627 QTRY_VERIFY(number != 0);
628 QTRY_COMPARE(number->text(), model.number(i));
631 // ensure content position is stable
632 gridview->setContentY(0);
633 model.moveItem(10, 0);
634 QTRY_VERIFY(gridview->contentY() == 0);
639 void tst_QDeclarativeGridView::currentIndex()
642 for (int i = 0; i < 60; i++)
643 model.addItem("Item" + QString::number(i), QString::number(i));
645 QDeclarativeView *canvas = new QDeclarativeView(0);
646 canvas->setFixedSize(240,320);
648 QDeclarativeContext *ctxt = canvas->rootContext();
649 ctxt->setContextProperty("testModel", &model);
651 QString filename(SRCDIR "/data/gridview-initCurrent.qml");
652 canvas->setSource(QUrl::fromLocalFile(filename));
654 qApp->processEvents();
656 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
657 QVERIFY(gridview != 0);
659 QDeclarativeItem *contentItem = gridview->contentItem();
660 QVERIFY(contentItem != 0);
662 // current item should be third item
663 QCOMPARE(gridview->currentIndex(), 35);
664 QCOMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 35));
665 QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y());
666 QCOMPARE(gridview->contentY(), 400.0);
668 gridview->moveCurrentIndexRight();
669 QCOMPARE(gridview->currentIndex(), 36);
670 gridview->moveCurrentIndexDown();
671 QCOMPARE(gridview->currentIndex(), 39);
672 gridview->moveCurrentIndexUp();
673 QCOMPARE(gridview->currentIndex(), 36);
674 gridview->moveCurrentIndexLeft();
675 QCOMPARE(gridview->currentIndex(), 35);
678 gridview->setCurrentIndex(0);
679 QCOMPARE(gridview->currentIndex(), 0);
680 // confirm that the velocity is updated
681 QTRY_VERIFY(gridview->verticalVelocity() != 0.0);
683 gridview->moveCurrentIndexUp();
684 QCOMPARE(gridview->currentIndex(), 0);
686 gridview->moveCurrentIndexLeft();
687 QCOMPARE(gridview->currentIndex(), 0);
689 gridview->setCurrentIndex(model.count()-1);
690 QCOMPARE(gridview->currentIndex(), model.count()-1);
692 gridview->moveCurrentIndexRight();
693 QCOMPARE(gridview->currentIndex(), model.count()-1);
695 gridview->moveCurrentIndexDown();
696 QCOMPARE(gridview->currentIndex(), model.count()-1);
699 gridview->setWrapEnabled(true);
701 gridview->setCurrentIndex(0);
702 QCOMPARE(gridview->currentIndex(), 0);
704 gridview->moveCurrentIndexLeft();
705 QCOMPARE(gridview->currentIndex(), model.count()-1);
707 QTRY_COMPARE(gridview->contentY(), 880.0);
709 gridview->moveCurrentIndexRight();
710 QCOMPARE(gridview->currentIndex(), 0);
712 QTRY_COMPARE(gridview->contentY(), 0.0);
716 qApp->setActiveWindow(canvas);
718 // to be safe and avoid failing setFocus with window managers
719 qt_x11_wait_for_window_manager(canvas);
721 QTRY_VERIFY(canvas->hasFocus());
722 QTRY_VERIFY(canvas->scene()->hasFocus());
723 qApp->processEvents();
725 QTest::keyClick(canvas, Qt::Key_Down);
726 QCOMPARE(gridview->currentIndex(), 3);
728 QTest::keyClick(canvas, Qt::Key_Up);
729 QCOMPARE(gridview->currentIndex(), 0);
731 gridview->setFlow(QDeclarativeGridView::TopToBottom);
733 qApp->setActiveWindow(canvas);
735 // to be safe and avoid failing setFocus with window managers
736 qt_x11_wait_for_window_manager(canvas);
738 QTRY_VERIFY(canvas->hasFocus());
739 QTRY_VERIFY(canvas->scene()->hasFocus());
740 qApp->processEvents();
742 QTest::keyClick(canvas, Qt::Key_Right);
743 QCOMPARE(gridview->currentIndex(), 5);
745 QTest::keyClick(canvas, Qt::Key_Left);
746 QCOMPARE(gridview->currentIndex(), 0);
748 QTest::keyClick(canvas, Qt::Key_Down);
749 QCOMPARE(gridview->currentIndex(), 1);
751 QTest::keyClick(canvas, Qt::Key_Up);
752 QCOMPARE(gridview->currentIndex(), 0);
755 // turn off auto highlight
756 gridview->setHighlightFollowsCurrentItem(false);
757 QVERIFY(gridview->highlightFollowsCurrentItem() == false);
758 QVERIFY(gridview->highlightItem());
759 qreal hlPosX = gridview->highlightItem()->x();
760 qreal hlPosY = gridview->highlightItem()->y();
762 gridview->setCurrentIndex(5);
763 QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
764 QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
766 // insert item before currentIndex
767 gridview->setCurrentIndex(28);
768 model.insertItem(0, "Foo", "1111");
769 QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
771 // check removing highlight by setting currentIndex to -1;
772 gridview->setCurrentIndex(-1);
774 QCOMPARE(gridview->currentIndex(), -1);
775 QVERIFY(!gridview->highlightItem());
776 QVERIFY(!gridview->currentItem());
778 gridview->setHighlightFollowsCurrentItem(true);
780 gridview->setFlow(QDeclarativeGridView::LeftToRight);
781 gridview->setLayoutDirection(Qt::RightToLeft);
783 qApp->setActiveWindow(canvas);
785 // to be safe and avoid failing setFocus with window managers
786 qt_x11_wait_for_window_manager(canvas);
788 QTRY_VERIFY(canvas->hasFocus());
789 QTRY_VERIFY(canvas->scene()->hasFocus());
790 qApp->processEvents();
792 gridview->setCurrentIndex(35);
794 QTest::keyClick(canvas, Qt::Key_Right);
795 QCOMPARE(gridview->currentIndex(), 34);
797 QTest::keyClick(canvas, Qt::Key_Down);
798 QCOMPARE(gridview->currentIndex(), 37);
800 QTest::keyClick(canvas, Qt::Key_Up);
801 QCOMPARE(gridview->currentIndex(), 34);
803 QTest::keyClick(canvas, Qt::Key_Left);
804 QCOMPARE(gridview->currentIndex(), 35);
807 // turn off auto highlight
808 gridview->setHighlightFollowsCurrentItem(false);
809 QVERIFY(gridview->highlightFollowsCurrentItem() == false);
810 QVERIFY(gridview->highlightItem());
811 hlPosX = gridview->highlightItem()->x();
812 hlPosY = gridview->highlightItem()->y();
814 gridview->setCurrentIndex(5);
815 QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
816 QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
818 // insert item before currentIndex
819 gridview->setCurrentIndex(28);
820 model.insertItem(0, "Foo", "1111");
821 QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
823 // check removing highlight by setting currentIndex to -1;
824 gridview->setCurrentIndex(-1);
826 QCOMPARE(gridview->currentIndex(), -1);
827 QVERIFY(!gridview->highlightItem());
828 QVERIFY(!gridview->currentItem());
833 void tst_QDeclarativeGridView::noCurrentIndex()
836 for (int i = 0; i < 60; i++)
837 model.addItem("Item" + QString::number(i), QString::number(i));
839 QDeclarativeView *canvas = new QDeclarativeView(0);
840 canvas->setFixedSize(240,320);
842 QDeclarativeContext *ctxt = canvas->rootContext();
843 ctxt->setContextProperty("testModel", &model);
845 QString filename(SRCDIR "/data/gridview-noCurrent.qml");
846 canvas->setSource(QUrl::fromLocalFile(filename));
848 qApp->processEvents();
850 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
851 QVERIFY(gridview != 0);
853 QDeclarativeItem *contentItem = gridview->contentItem();
854 QVERIFY(contentItem != 0);
856 // current index should be -1
857 QCOMPARE(gridview->currentIndex(), -1);
858 QVERIFY(!gridview->currentItem());
859 QVERIFY(!gridview->highlightItem());
860 QCOMPARE(gridview->contentY(), 0.0);
862 gridview->setCurrentIndex(5);
863 QCOMPARE(gridview->currentIndex(), 5);
864 QVERIFY(gridview->currentItem());
865 QVERIFY(gridview->highlightItem());
868 void tst_QDeclarativeGridView::changeFlow()
870 QDeclarativeView *canvas = createView();
873 for (int i = 0; i < 30; i++)
874 model.addItem("Item" + QString::number(i), QString::number(i));
876 QDeclarativeContext *ctxt = canvas->rootContext();
877 ctxt->setContextProperty("testModel", &model);
878 ctxt->setContextProperty("testRightToLeft", QVariant(false));
879 ctxt->setContextProperty("testTopToBottom", QVariant(false));
881 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
882 qApp->processEvents();
884 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
885 QTRY_VERIFY(gridview != 0);
887 QDeclarativeItem *contentItem = gridview->contentItem();
888 QTRY_VERIFY(contentItem != 0);
890 // Confirm items positioned correctly and indexes correct
891 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
892 for (int i = 0; i < model.count() && i < itemCount; ++i) {
893 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
894 if (!item) qWarning() << "Item" << i << "not found";
896 QTRY_COMPARE(item->x(), qreal((i%3)*80));
897 QTRY_COMPARE(item->y(), qreal((i/3)*60));
898 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
899 QTRY_VERIFY(name != 0);
900 QTRY_COMPARE(name->text(), model.name(i));
901 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
902 QTRY_VERIFY(number != 0);
903 QTRY_COMPARE(number->text(), model.number(i));
906 ctxt->setContextProperty("testTopToBottom", QVariant(true));
908 // Confirm items positioned correctly and indexes correct
909 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
910 for (int i = 0; i < model.count() && i < itemCount; ++i) {
911 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
912 if (!item) qWarning() << "Item" << i << "not found";
914 QTRY_COMPARE(item->x(), qreal((i/5)*80));
915 QTRY_COMPARE(item->y(), qreal((i%5)*60));
916 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
917 QTRY_VERIFY(name != 0);
918 QTRY_COMPARE(name->text(), model.name(i));
919 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
920 QTRY_VERIFY(number != 0);
921 QTRY_COMPARE(number->text(), model.number(i));
924 ctxt->setContextProperty("testRightToLeft", QVariant(true));
926 // Confirm items positioned correctly and indexes correct
927 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
928 for (int i = 0; i < model.count() && i < itemCount; ++i) {
929 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
930 if (!item) qWarning() << "Item" << i << "not found";
932 QTRY_COMPARE(item->x(), qreal(-(i/5)*80 - item->width()));
933 QTRY_COMPARE(item->y(), qreal((i%5)*60));
934 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
935 QTRY_VERIFY(name != 0);
936 QTRY_COMPARE(name->text(), model.name(i));
937 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
938 QTRY_VERIFY(number != 0);
939 QTRY_COMPARE(number->text(), model.number(i));
941 gridview->setContentX(100);
942 QTRY_COMPARE(gridview->contentX(), 100.);
943 ctxt->setContextProperty("testTopToBottom", QVariant(false));
944 QTRY_COMPARE(gridview->contentX(), 0.);
946 // Confirm items positioned correctly and indexes correct
947 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
948 for (int i = 0; i < model.count() && i < itemCount; ++i) {
949 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
950 if (!item) qWarning() << "Item" << i << "not found";
952 QTRY_COMPARE(item->x(), qreal(240 - (i%3+1)*80));
953 QTRY_COMPARE(item->y(), qreal((i/3)*60));
954 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", i);
955 QTRY_VERIFY(name != 0);
956 QTRY_COMPARE(name->text(), model.name(i));
957 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", i);
958 QTRY_VERIFY(number != 0);
959 QTRY_COMPARE(number->text(), model.number(i));
965 void tst_QDeclarativeGridView::defaultValues()
967 QDeclarativeEngine engine;
968 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview3.qml"));
969 QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(c.create());
971 QTRY_VERIFY(obj != 0);
972 QTRY_VERIFY(obj->model() == QVariant());
973 QTRY_VERIFY(obj->delegate() == 0);
974 QTRY_COMPARE(obj->currentIndex(), -1);
975 QTRY_VERIFY(obj->currentItem() == 0);
976 QTRY_COMPARE(obj->count(), 0);
977 QTRY_VERIFY(obj->highlight() == 0);
978 QTRY_VERIFY(obj->highlightItem() == 0);
979 QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true);
980 QTRY_VERIFY(obj->flow() == 0);
981 QTRY_COMPARE(obj->isWrapEnabled(), false);
982 QTRY_COMPARE(obj->cacheBuffer(), 0);
983 QTRY_COMPARE(obj->cellWidth(), 100); //### Should 100 be the default?
984 QTRY_COMPARE(obj->cellHeight(), 100);
988 void tst_QDeclarativeGridView::properties()
990 QDeclarativeEngine engine;
991 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview2.qml"));
992 QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(c.create());
994 QTRY_VERIFY(obj != 0);
995 QTRY_VERIFY(obj->model() != QVariant());
996 QTRY_VERIFY(obj->delegate() != 0);
997 QTRY_COMPARE(obj->currentIndex(), 0);
998 QTRY_VERIFY(obj->currentItem() != 0);
999 QTRY_COMPARE(obj->count(), 4);
1000 QTRY_VERIFY(obj->highlight() != 0);
1001 QTRY_VERIFY(obj->highlightItem() != 0);
1002 QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false);
1003 QTRY_VERIFY(obj->flow() == 0);
1004 QTRY_COMPARE(obj->isWrapEnabled(), true);
1005 QTRY_COMPARE(obj->cacheBuffer(), 200);
1006 QTRY_COMPARE(obj->cellWidth(), 100);
1007 QTRY_COMPARE(obj->cellHeight(), 100);
1011 void tst_QDeclarativeGridView::propertyChanges()
1013 QDeclarativeView *canvas = createView();
1014 QTRY_VERIFY(canvas);
1015 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1017 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
1018 QTRY_VERIFY(gridView);
1020 QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged()));
1021 QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged()));
1022 QSignalSpy layoutSpy(gridView, SIGNAL(layoutDirectionChanged()));
1023 QSignalSpy flowSpy(gridView, SIGNAL(flowChanged()));
1025 QTRY_COMPARE(gridView->isWrapEnabled(), true);
1026 QTRY_COMPARE(gridView->cacheBuffer(), 10);
1027 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::LeftToRight);
1029 gridView->setWrapEnabled(false);
1030 gridView->setCacheBuffer(3);
1031 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1033 QTRY_COMPARE(gridView->isWrapEnabled(), false);
1034 QTRY_COMPARE(gridView->cacheBuffer(), 3);
1035 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::TopToBottom);
1037 QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1038 QTRY_COMPARE(cacheBufferSpy.count(),1);
1039 QTRY_COMPARE(flowSpy.count(),1);
1041 gridView->setWrapEnabled(false);
1042 gridView->setCacheBuffer(3);
1043 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1045 QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1046 QTRY_COMPARE(cacheBufferSpy.count(),1);
1047 QTRY_COMPARE(flowSpy.count(),1);
1049 gridView->setFlow(QDeclarativeGridView::LeftToRight);
1050 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::LeftToRight);
1052 gridView->setWrapEnabled(true);
1053 gridView->setCacheBuffer(5);
1054 gridView->setLayoutDirection(Qt::RightToLeft);
1056 QTRY_COMPARE(gridView->isWrapEnabled(), true);
1057 QTRY_COMPARE(gridView->cacheBuffer(), 5);
1058 QTRY_COMPARE(gridView->layoutDirection(), Qt::RightToLeft);
1060 QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
1061 QTRY_COMPARE(cacheBufferSpy.count(),2);
1062 QTRY_COMPARE(layoutSpy.count(),1);
1063 QTRY_COMPARE(flowSpy.count(),2);
1065 gridView->setWrapEnabled(true);
1066 gridView->setCacheBuffer(5);
1067 gridView->setLayoutDirection(Qt::RightToLeft);
1069 QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
1070 QTRY_COMPARE(cacheBufferSpy.count(),2);
1071 QTRY_COMPARE(layoutSpy.count(),1);
1072 QTRY_COMPARE(flowSpy.count(),2);
1074 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1075 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::TopToBottom);
1076 QTRY_COMPARE(flowSpy.count(),3);
1078 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1079 QTRY_COMPARE(flowSpy.count(),3);
1084 void tst_QDeclarativeGridView::componentChanges()
1086 QDeclarativeView *canvas = createView();
1087 QTRY_VERIFY(canvas);
1088 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1090 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
1091 QTRY_VERIFY(gridView);
1093 QDeclarativeComponent component(canvas->engine());
1094 component.setData("import QtQuick 1.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
1096 QDeclarativeComponent delegateComponent(canvas->engine());
1097 delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
1099 QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged()));
1100 QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged()));
1101 QSignalSpy headerSpy(gridView, SIGNAL(headerChanged()));
1102 QSignalSpy footerSpy(gridView, SIGNAL(footerChanged()));
1104 gridView->setHighlight(&component);
1105 gridView->setDelegate(&delegateComponent);
1106 gridView->setHeader(&component);
1107 gridView->setFooter(&component);
1109 QTRY_COMPARE(gridView->highlight(), &component);
1110 QTRY_COMPARE(gridView->delegate(), &delegateComponent);
1111 QTRY_COMPARE(gridView->header(), &component);
1112 QTRY_COMPARE(gridView->footer(), &component);
1114 QTRY_COMPARE(highlightSpy.count(),1);
1115 QTRY_COMPARE(delegateSpy.count(),1);
1116 QTRY_COMPARE(headerSpy.count(),1);
1117 QTRY_COMPARE(footerSpy.count(),1);
1119 gridView->setHighlight(&component);
1120 gridView->setDelegate(&delegateComponent);
1121 gridView->setHeader(&component);
1122 gridView->setFooter(&component);
1124 QTRY_COMPARE(highlightSpy.count(),1);
1125 QTRY_COMPARE(delegateSpy.count(),1);
1126 QTRY_COMPARE(headerSpy.count(),1);
1127 QTRY_COMPARE(footerSpy.count(),1);
1132 void tst_QDeclarativeGridView::modelChanges()
1134 QDeclarativeView *canvas = createView();
1135 QTRY_VERIFY(canvas);
1136 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1138 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
1139 QTRY_VERIFY(gridView);
1141 QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
1142 QTRY_VERIFY(alternateModel);
1143 QVariant modelVariant = QVariant::fromValue(alternateModel);
1144 QSignalSpy modelSpy(gridView, SIGNAL(modelChanged()));
1146 gridView->setModel(modelVariant);
1147 QTRY_COMPARE(gridView->model(), modelVariant);
1148 QTRY_COMPARE(modelSpy.count(),1);
1150 gridView->setModel(modelVariant);
1151 QTRY_COMPARE(modelSpy.count(),1);
1153 gridView->setModel(QVariant());
1154 QTRY_COMPARE(modelSpy.count(),2);
1158 void tst_QDeclarativeGridView::positionViewAtIndex()
1160 QDeclarativeView *canvas = createView();
1163 for (int i = 0; i < 40; i++)
1164 model.addItem("Item" + QString::number(i), "");
1166 QDeclarativeContext *ctxt = canvas->rootContext();
1167 ctxt->setContextProperty("testModel", &model);
1168 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1169 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1171 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1172 qApp->processEvents();
1174 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1175 QTRY_VERIFY(gridview != 0);
1177 QDeclarativeItem *contentItem = gridview->contentItem();
1178 QTRY_VERIFY(contentItem != 0);
1180 // Confirm items positioned correctly
1181 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1182 for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1183 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1184 if (!item) qWarning() << "Item" << i << "not found";
1186 QTRY_COMPARE(item->x(), (i%3)*80.);
1187 QTRY_COMPARE(item->y(), (i/3)*60.);
1190 // Position on a currently visible item
1191 gridview->positionViewAtIndex(4, QDeclarativeGridView::Beginning);
1192 QTRY_COMPARE(gridview->indexAt(120, 90), 4);
1193 QTRY_COMPARE(gridview->contentY(), 60.);
1195 // Confirm items positioned correctly
1196 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1197 for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
1198 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1199 if (!item) qWarning() << "Item" << i << "not found";
1201 QTRY_COMPARE(item->x(), (i%3)*80.);
1202 QTRY_COMPARE(item->y(), (i/3)*60.);
1205 // Position on an item beyond the visible items
1206 gridview->positionViewAtIndex(21, QDeclarativeGridView::Beginning);
1207 QTRY_COMPARE(gridview->indexAt(40, 450), 21);
1208 QTRY_COMPARE(gridview->contentY(), 420.);
1210 // Confirm items positioned correctly
1211 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1212 for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
1213 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1214 if (!item) qWarning() << "Item" << i << "not found";
1216 QTRY_COMPARE(item->x(), (i%3)*80.);
1217 QTRY_COMPARE(item->y(), (i/3)*60.);
1220 // Position on an item that would leave empty space if positioned at the top
1221 gridview->positionViewAtIndex(31, QDeclarativeGridView::Beginning);
1222 QTRY_COMPARE(gridview->indexAt(120, 630), 31);
1223 QTRY_COMPARE(gridview->contentY(), 520.);
1225 // Confirm items positioned correctly
1226 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1227 for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
1228 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1229 if (!item) qWarning() << "Item" << i << "not found";
1231 QTRY_COMPARE(item->x(), (i%3)*80.);
1232 QTRY_COMPARE(item->y(), (i/3)*60.);
1235 // Position at the beginning again
1236 gridview->positionViewAtIndex(0, QDeclarativeGridView::Beginning);
1237 QTRY_COMPARE(gridview->indexAt(0, 0), 0);
1238 QTRY_COMPARE(gridview->indexAt(40, 30), 0);
1239 QTRY_COMPARE(gridview->indexAt(80, 60), 4);
1240 QTRY_COMPARE(gridview->contentY(), 0.);
1242 // Confirm items positioned correctly
1243 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1244 for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1245 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1246 if (!item) qWarning() << "Item" << i << "not found";
1248 QTRY_COMPARE(item->x(), (i%3)*80.);
1249 QTRY_COMPARE(item->y(), (i/3)*60.);
1253 gridview->positionViewAtIndex(30, QDeclarativeGridView::End);
1254 QTRY_COMPARE(gridview->contentY(), 340.);
1256 // Position in Center
1257 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1258 QTRY_COMPARE(gridview->contentY(), 170.);
1260 // Ensure at least partially visible
1261 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1262 QTRY_COMPARE(gridview->contentY(), 170.);
1264 gridview->setContentY(302);
1265 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1266 QTRY_COMPARE(gridview->contentY(), 302.);
1268 gridview->setContentY(360);
1269 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1270 QTRY_COMPARE(gridview->contentY(), 300.);
1272 gridview->setContentY(60);
1273 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1274 QTRY_COMPARE(gridview->contentY(), 60.);
1276 gridview->setContentY(20);
1277 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1278 QTRY_COMPARE(gridview->contentY(), 100.);
1280 // Ensure completely visible
1281 gridview->setContentY(120);
1282 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1283 QTRY_COMPARE(gridview->contentY(), 120.);
1285 gridview->setContentY(302);
1286 gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain);
1287 QTRY_COMPARE(gridview->contentY(), 300.);
1289 gridview->setContentY(60);
1290 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1291 QTRY_COMPARE(gridview->contentY(), 100.);
1293 // Test for Top To Bottom layout
1294 ctxt->setContextProperty("testTopToBottom", QVariant(true));
1296 // Confirm items positioned correctly
1297 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1298 for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1299 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1300 if (!item) qWarning() << "Item" << i << "not found";
1302 QTRY_COMPARE(item->x(), (i/5)*80.);
1303 QTRY_COMPARE(item->y(), (i%5)*60.);
1307 gridview->positionViewAtIndex(30, QDeclarativeGridView::End);
1308 QTRY_COMPARE(gridview->contentX(), 320.);
1309 QTRY_COMPARE(gridview->contentY(), 0.);
1311 // Position in Center
1312 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1313 QTRY_COMPARE(gridview->contentX(), 160.);
1315 // Ensure at least partially visible
1316 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1317 QTRY_COMPARE(gridview->contentX(), 160.);
1319 gridview->setContentX(170);
1320 gridview->positionViewAtIndex(25, QDeclarativeGridView::Visible);
1321 QTRY_COMPARE(gridview->contentX(), 170.);
1323 gridview->positionViewAtIndex(30, QDeclarativeGridView::Visible);
1324 QTRY_COMPARE(gridview->contentX(), 320.);
1326 gridview->setContentX(170);
1327 gridview->positionViewAtIndex(25, QDeclarativeGridView::Contain);
1328 QTRY_COMPARE(gridview->contentX(), 240.);
1330 // positionViewAtBeginning
1331 gridview->positionViewAtBeginning();
1332 QTRY_COMPARE(gridview->contentX(), 0.);
1334 gridview->setContentX(80);
1335 canvas->rootObject()->setProperty("showHeader", true);
1336 gridview->positionViewAtBeginning();
1337 QTRY_COMPARE(gridview->contentX(), -30.);
1339 // positionViewAtEnd
1340 gridview->positionViewAtEnd();
1341 QTRY_COMPARE(gridview->contentX(), 430.);
1343 gridview->setContentX(80);
1344 canvas->rootObject()->setProperty("showFooter", true);
1345 gridview->positionViewAtEnd();
1346 QTRY_COMPARE(gridview->contentX(), 460.);
1351 void tst_QDeclarativeGridView::snapping()
1353 QDeclarativeView *canvas = createView();
1356 for (int i = 0; i < 40; i++)
1357 model.addItem("Item" + QString::number(i), "");
1359 QDeclarativeContext *ctxt = canvas->rootContext();
1360 ctxt->setContextProperty("testModel", &model);
1361 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1362 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1364 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1365 qApp->processEvents();
1367 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1368 QTRY_VERIFY(gridview != 0);
1370 gridview->setHeight(220);
1371 QCOMPARE(gridview->height(), 220.);
1373 gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible);
1374 QCOMPARE(gridview->contentY(), 80.);
1376 gridview->setContentY(0);
1377 QCOMPARE(gridview->contentY(), 0.);
1379 gridview->setSnapMode(QDeclarativeGridView::SnapToRow);
1380 QCOMPARE(gridview->snapMode(), QDeclarativeGridView::SnapToRow);
1382 gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible);
1383 QCOMPARE(gridview->contentY(), 60.);
1385 gridview->positionViewAtIndex(15, QDeclarativeGridView::End);
1386 QCOMPARE(gridview->contentY(), 120.);
1392 void tst_QDeclarativeGridView::mirroring()
1394 QDeclarativeView *canvasA = createView();
1395 canvasA->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
1396 QDeclarativeGridView *gridviewA = findItem<QDeclarativeGridView>(canvasA->rootObject(), "view");
1397 QTRY_VERIFY(gridviewA != 0);
1399 QDeclarativeView *canvasB = createView();
1400 canvasB->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
1401 QDeclarativeGridView *gridviewB = findItem<QDeclarativeGridView>(canvasB->rootObject(), "view");
1402 QTRY_VERIFY(gridviewA != 0);
1403 qApp->processEvents();
1405 QList<QString> objectNames;
1406 objectNames << "item1" << "item2"; // << "item3"
1408 gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1409 gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
1410 QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection());
1413 foreach(const QString objectName, objectNames)
1414 QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1416 gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1417 gridviewB->setProperty("layoutDirection", Qt::LeftToRight);
1420 foreach(const QString objectName, objectNames)
1421 QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1423 QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection());
1424 QDeclarativeItemPrivate::get(gridviewB)->setLayoutMirror(true);
1425 QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection());
1427 // LTR != LTR+mirror
1428 foreach(const QString objectName, objectNames)
1429 QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1431 gridviewA->setProperty("layoutDirection", Qt::RightToLeft);
1433 // RTL == LTR+mirror
1434 foreach(const QString objectName, objectNames)
1435 QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1437 gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
1439 // RTL != RTL+mirror
1440 foreach(const QString objectName, objectNames)
1441 QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1443 gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1445 // LTR == RTL+mirror
1446 foreach(const QString objectName, objectNames)
1447 QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1453 void tst_QDeclarativeGridView::positionViewAtIndex_rightToLeft()
1455 QDeclarativeView *canvas = createView();
1458 for (int i = 0; i < 40; i++)
1459 model.addItem("Item" + QString::number(i), "");
1461 QDeclarativeContext *ctxt = canvas->rootContext();
1462 ctxt->setContextProperty("testModel", &model);
1463 ctxt->setContextProperty("testTopToBottom", QVariant(true));
1464 ctxt->setContextProperty("testRightToLeft", QVariant(true));
1466 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1467 qApp->processEvents();
1469 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1470 QTRY_VERIFY(gridview != 0);
1472 QDeclarativeItem *contentItem = gridview->contentItem();
1473 QTRY_VERIFY(contentItem != 0);
1475 // Confirm items positioned correctly
1476 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1477 for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1478 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1479 if (!item) qWarning() << "Item" << i << "not found";
1481 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1482 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1485 // Position on a currently visible item
1486 gridview->positionViewAtIndex(6, QDeclarativeGridView::Beginning);
1487 QTRY_COMPARE(gridview->contentX(), -320.);
1489 // Confirm items positioned correctly
1490 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1491 for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
1492 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1493 if (!item) qWarning() << "Item" << i << "not found";
1495 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1496 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1499 // Position on an item beyond the visible items
1500 gridview->positionViewAtIndex(21, QDeclarativeGridView::Beginning);
1501 QTRY_COMPARE(gridview->contentX(), -560.);
1503 // Confirm items positioned correctly
1504 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1505 for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
1506 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1507 if (!item) qWarning() << "Item" << i << "not found";
1509 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1510 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1513 // Position on an item that would leave empty space if positioned at the top
1514 gridview->positionViewAtIndex(31, QDeclarativeGridView::Beginning);
1515 QTRY_COMPARE(gridview->contentX(), -639.);
1517 // Confirm items positioned correctly
1518 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1519 for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
1520 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1521 if (!item) qWarning() << "Item" << i << "not found";
1523 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1524 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1527 // Position at the beginning again
1528 gridview->positionViewAtIndex(0, QDeclarativeGridView::Beginning);
1529 QTRY_COMPARE(gridview->contentX(), -240.);
1531 // Confirm items positioned correctly
1532 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1533 for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1534 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1535 if (!item) qWarning() << "Item" << i << "not found";
1537 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1538 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1542 gridview->positionViewAtIndex(30, QDeclarativeGridView::End);
1543 QTRY_COMPARE(gridview->contentX(), -560.);
1545 // Position in Center
1546 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1547 QTRY_COMPARE(gridview->contentX(), -400.);
1549 // Ensure at least partially visible
1550 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1551 QTRY_COMPARE(gridview->contentX(), -400.);
1553 gridview->setContentX(-555.);
1554 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1555 QTRY_COMPARE(gridview->contentX(), -555.);
1557 gridview->setContentX(-239);
1558 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1559 QTRY_COMPARE(gridview->contentX(), -320.);
1561 gridview->setContentX(-239);
1562 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1563 QTRY_COMPARE(gridview->contentX(), -400.);
1565 gridview->setContentX(-640);
1566 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1567 QTRY_COMPARE(gridview->contentX(), -560.);
1569 // Ensure completely visible
1570 gridview->setContentX(-400);
1571 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1572 QTRY_COMPARE(gridview->contentX(), -400.);
1574 gridview->setContentX(-315);
1575 gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain);
1576 QTRY_COMPARE(gridview->contentX(), -320.);
1578 gridview->setContentX(-640);
1579 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1580 QTRY_COMPARE(gridview->contentX(), -560.);
1585 void tst_QDeclarativeGridView::resetModel()
1587 QDeclarativeView *canvas = createView();
1589 QStringList strings;
1590 strings << "one" << "two" << "three";
1591 QStringListModel model(strings);
1593 QDeclarativeContext *ctxt = canvas->rootContext();
1594 ctxt->setContextProperty("testModel", &model);
1596 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaygrid.qml"));
1597 qApp->processEvents();
1599 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1600 QTRY_VERIFY(gridview != 0);
1602 QDeclarativeItem *contentItem = gridview->contentItem();
1603 QTRY_VERIFY(contentItem != 0);
1605 QTRY_COMPARE(gridview->count(), model.rowCount());
1607 for (int i = 0; i < model.rowCount(); ++i) {
1608 QDeclarativeText *display = findItem<QDeclarativeText>(contentItem, "displayText", i);
1609 QTRY_VERIFY(display != 0);
1610 QTRY_COMPARE(display->text(), strings.at(i));
1614 strings << "four" << "five" << "six" << "seven";
1615 model.setStringList(strings);
1617 QTRY_COMPARE(gridview->count(), model.rowCount());
1619 for (int i = 0; i < model.rowCount(); ++i) {
1620 QDeclarativeText *display = findItem<QDeclarativeText>(contentItem, "displayText", i);
1621 QTRY_VERIFY(display != 0);
1622 QTRY_COMPARE(display->text(), strings.at(i));
1626 void tst_QDeclarativeGridView::enforceRange()
1628 QDeclarativeView *canvas = createView();
1631 for (int i = 0; i < 30; i++)
1632 model.addItem("Item" + QString::number(i), "");
1634 QDeclarativeContext *ctxt = canvas->rootContext();
1635 ctxt->setContextProperty("testModel", &model);
1636 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1637 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1639 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1640 qApp->processEvents();
1641 QVERIFY(canvas->rootObject() != 0);
1643 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1644 QTRY_VERIFY(gridview != 0);
1646 QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1647 QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1648 QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarativeGridView::StrictlyEnforceRange);
1650 QDeclarativeItem *contentItem = gridview->contentItem();
1651 QTRY_VERIFY(contentItem != 0);
1653 // view should be positioned at the top of the range.
1654 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1656 QTRY_COMPARE(gridview->contentY(), -100.0);
1658 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 0);
1659 QTRY_VERIFY(name != 0);
1660 QTRY_COMPARE(name->text(), model.name(0));
1661 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
1662 QTRY_VERIFY(number != 0);
1663 QTRY_COMPARE(number->text(), model.number(0));
1665 // Check currentIndex is updated when contentItem moves
1666 gridview->setContentY(0);
1667 QTRY_COMPARE(gridview->currentIndex(), 2);
1669 gridview->setCurrentIndex(5);
1670 QTRY_COMPARE(gridview->contentY(), 100.);
1673 for (int i = 0; i < 5; i++)
1674 model2.addItem("Item" + QString::number(i), "");
1676 ctxt->setContextProperty("testModel", &model2);
1677 QCOMPARE(gridview->count(), 5);
1682 void tst_QDeclarativeGridView::enforceRange_rightToLeft()
1684 QDeclarativeView *canvas = createView();
1687 for (int i = 0; i < 30; i++)
1688 model.addItem("Item" + QString::number(i), "");
1690 QDeclarativeContext *ctxt = canvas->rootContext();
1691 ctxt->setContextProperty("testModel", &model);
1692 ctxt->setContextProperty("testRightToLeft", QVariant(true));
1693 ctxt->setContextProperty("testTopToBottom", QVariant(true));
1695 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1696 qApp->processEvents();
1697 QVERIFY(canvas->rootObject() != 0);
1699 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1700 QTRY_VERIFY(gridview != 0);
1702 QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1703 QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1704 QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarativeGridView::StrictlyEnforceRange);
1706 QDeclarativeItem *contentItem = gridview->contentItem();
1707 QTRY_VERIFY(contentItem != 0);
1709 // view should be positioned at the top of the range.
1710 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1712 QTRY_COMPARE(gridview->contentX(), -100.);
1713 QTRY_COMPARE(gridview->contentY(), 0.0);
1715 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 0);
1716 QTRY_VERIFY(name != 0);
1717 QTRY_COMPARE(name->text(), model.name(0));
1718 QDeclarativeText *number = findItem<QDeclarativeText>(contentItem, "textNumber", 0);
1719 QTRY_VERIFY(number != 0);
1720 QTRY_COMPARE(number->text(), model.number(0));
1722 // Check currentIndex is updated when contentItem moves
1723 gridview->setContentX(-200);
1724 QTRY_COMPARE(gridview->currentIndex(), 3);
1726 gridview->setCurrentIndex(7);
1727 QTRY_COMPARE(gridview->contentX(), -300.);
1728 QTRY_COMPARE(gridview->contentY(), 0.0);
1731 for (int i = 0; i < 5; i++)
1732 model2.addItem("Item" + QString::number(i), "");
1734 ctxt->setContextProperty("testModel", &model2);
1735 QCOMPARE(gridview->count(), 5);
1740 void tst_QDeclarativeGridView::QTBUG_8456()
1742 QDeclarativeView *canvas = createView();
1744 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/setindex.qml"));
1745 qApp->processEvents();
1747 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1748 QTRY_VERIFY(gridview != 0);
1750 QTRY_COMPARE(gridview->currentIndex(), 0);
1753 void tst_QDeclarativeGridView::manualHighlight()
1755 QDeclarativeView *canvas = createView();
1757 QString filename(SRCDIR "/data/manual-highlight.qml");
1758 canvas->setSource(QUrl::fromLocalFile(filename));
1760 qApp->processEvents();
1762 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1763 QTRY_VERIFY(gridview != 0);
1765 QDeclarativeItem *contentItem = gridview->contentItem();
1766 QTRY_VERIFY(contentItem != 0);
1768 QTRY_COMPARE(gridview->currentIndex(), 0);
1769 QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
1770 QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1771 QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1773 gridview->setCurrentIndex(2);
1775 QTRY_COMPARE(gridview->currentIndex(), 2);
1776 QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2));
1777 QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1778 QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1780 gridview->positionViewAtIndex(8, QDeclarativeGridView::Contain);
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());
1787 gridview->setFlow(QDeclarativeGridView::TopToBottom);
1788 QTRY_COMPARE(gridview->flow(), QDeclarativeGridView::TopToBottom);
1790 gridview->setCurrentIndex(0);
1791 QTRY_COMPARE(gridview->currentIndex(), 0);
1792 QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
1793 QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
1794 QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
1797 void tst_QDeclarativeGridView::footer()
1799 QDeclarativeView *canvas = createView();
1802 for (int i = 0; i < 7; i++)
1803 model.addItem("Item" + QString::number(i), "");
1805 QDeclarativeContext *ctxt = canvas->rootContext();
1806 ctxt->setContextProperty("testModel", &model);
1808 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/footer.qml"));
1809 qApp->processEvents();
1811 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1812 QTRY_VERIFY(gridview != 0);
1814 QDeclarativeItem *contentItem = gridview->contentItem();
1815 QTRY_VERIFY(contentItem != 0);
1817 QDeclarativeText *footer = findItem<QDeclarativeText>(contentItem, "footer");
1820 QCOMPARE(footer->y(), 180.0);
1821 QCOMPARE(footer->height(), 30.0);
1823 model.removeItem(2);
1824 QTRY_COMPARE(footer->y(), 120.0);
1827 QTRY_COMPARE(footer->y(), 0.0);
1829 for (int i = 0; i < 30; i++)
1830 model.addItem("Item" + QString::number(i), "");
1832 QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
1834 footer = findItem<QDeclarativeText>(contentItem, "footer");
1836 footer = findItem<QDeclarativeText>(contentItem, "footer2");
1839 QCOMPARE(footer->y(), 600.0);
1840 QCOMPARE(footer->height(), 20.0);
1841 QCOMPARE(gridview->contentY(), 0.0);
1844 void tst_QDeclarativeGridView::header()
1846 QDeclarativeView *canvas = createView();
1849 for (int i = 0; i < 30; i++)
1850 model.addItem("Item" + QString::number(i), "");
1852 QDeclarativeContext *ctxt = canvas->rootContext();
1853 ctxt->setContextProperty("testModel", &model);
1855 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
1856 qApp->processEvents();
1858 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1859 QTRY_VERIFY(gridview != 0);
1861 QDeclarativeItem *contentItem = gridview->contentItem();
1862 QTRY_VERIFY(contentItem != 0);
1864 QDeclarativeText *header = findItem<QDeclarativeText>(contentItem, "header");
1867 QCOMPARE(header->y(), 0.0);
1868 QCOMPARE(header->height(), 30.0);
1869 QCOMPARE(gridview->contentY(), 0.0);
1871 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1873 QCOMPARE(item->y(), 30.0);
1876 QTRY_COMPARE(header->y(), 0.0);
1878 for (int i = 0; i < 30; i++)
1879 model.addItem("Item" + QString::number(i), "");
1881 QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
1883 header = findItem<QDeclarativeText>(contentItem, "header");
1885 header = findItem<QDeclarativeText>(contentItem, "header2");
1888 QCOMPARE(header->y(), 10.0);
1889 QCOMPARE(header->height(), 20.0);
1890 QCOMPARE(gridview->contentY(), 10.0);
1893 void tst_QDeclarativeGridView::indexAt()
1895 QDeclarativeView *canvas = createView();
1898 model.addItem("Fred", "12345");
1899 model.addItem("John", "2345");
1900 model.addItem("Bob", "54321");
1901 model.addItem("Billy", "22345");
1902 model.addItem("Sam", "2945");
1903 model.addItem("Ben", "04321");
1904 model.addItem("Jim", "0780");
1906 QDeclarativeContext *ctxt = canvas->rootContext();
1907 ctxt->setContextProperty("testModel", &model);
1908 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1909 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1911 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1912 qApp->processEvents();
1914 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1915 QTRY_VERIFY(gridview != 0);
1917 QDeclarativeItem *contentItem = gridview->contentItem();
1918 QTRY_VERIFY(contentItem != 0);
1920 QTRY_COMPARE(gridview->count(), model.count());
1922 QCOMPARE(gridview->indexAt(0, 0), 0);
1923 QCOMPARE(gridview->indexAt(79, 59), 0);
1924 QCOMPARE(gridview->indexAt(80, 0), 1);
1925 QCOMPARE(gridview->indexAt(0, 60), 3);
1926 QCOMPARE(gridview->indexAt(240, 0), -1);
1931 void tst_QDeclarativeGridView::onAdd()
1933 QFETCH(int, initialItemCount);
1934 QFETCH(int, itemsToAdd);
1936 const int delegateWidth = 50;
1937 const int delegateHeight = 100;
1939 QDeclarativeView *canvas = createView();
1940 canvas->setFixedSize(5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit
1942 // these initial items should not trigger GridView.onAdd
1943 for (int i=0; i<initialItemCount; i++)
1944 model.addItem("dummy value", "dummy value");
1946 QDeclarativeContext *ctxt = canvas->rootContext();
1947 ctxt->setContextProperty("testModel", &model);
1948 ctxt->setContextProperty("delegateWidth", delegateWidth);
1949 ctxt->setContextProperty("delegateHeight", delegateHeight);
1950 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
1952 QObject *object = canvas->rootObject();
1953 object->setProperty("width", canvas->width());
1954 object->setProperty("height", canvas->height());
1955 qApp->processEvents();
1957 QList<QPair<QString, QString> > items;
1958 for (int i=0; i<itemsToAdd; i++)
1959 items << qMakePair(QString("value %1").arg(i), QString::number(i));
1960 model.addItems(items);
1962 qApp->processEvents();
1964 QVariantList result = object->property("addedDelegates").toList();
1965 QCOMPARE(result.count(), items.count());
1966 for (int i=0; i<items.count(); i++)
1967 QCOMPARE(result[i].toString(), items[i].first);
1972 void tst_QDeclarativeGridView::onAdd_data()
1974 QTest::addColumn<int>("initialItemCount");
1975 QTest::addColumn<int>("itemsToAdd");
1977 QTest::newRow("0, add 1") << 0 << 1;
1978 QTest::newRow("0, add 2") << 0 << 2;
1979 QTest::newRow("0, add 10") << 0 << 10;
1981 QTest::newRow("1, add 1") << 1 << 1;
1982 QTest::newRow("1, add 2") << 1 << 2;
1983 QTest::newRow("1, add 10") << 1 << 10;
1985 QTest::newRow("5, add 1") << 5 << 1;
1986 QTest::newRow("5, add 2") << 5 << 2;
1987 QTest::newRow("5, add 10") << 5 << 10;
1990 void tst_QDeclarativeGridView::onRemove()
1992 QFETCH(int, initialItemCount);
1993 QFETCH(int, indexToRemove);
1994 QFETCH(int, removeCount);
1996 const int delegateWidth = 50;
1997 const int delegateHeight = 100;
1999 for (int i=0; i<initialItemCount; i++)
2000 model.addItem(QString("value %1").arg(i), "dummy value");
2002 QDeclarativeView *canvas = createView();
2003 QDeclarativeContext *ctxt = canvas->rootContext();
2004 ctxt->setContextProperty("testModel", &model);
2005 ctxt->setContextProperty("delegateWidth", delegateWidth);
2006 ctxt->setContextProperty("delegateHeight", delegateHeight);
2007 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
2008 QObject *object = canvas->rootObject();
2010 qApp->processEvents();
2012 model.removeItems(indexToRemove, removeCount);
2013 qApp->processEvents();
2014 QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
2019 void tst_QDeclarativeGridView::onRemove_data()
2021 QTest::addColumn<int>("initialItemCount");
2022 QTest::addColumn<int>("indexToRemove");
2023 QTest::addColumn<int>("removeCount");
2025 QTest::newRow("remove first") << 1 << 0 << 1;
2026 QTest::newRow("two items, remove first") << 2 << 0 << 1;
2027 QTest::newRow("two items, remove last") << 2 << 1 << 1;
2028 QTest::newRow("two items, remove all") << 2 << 0 << 2;
2030 QTest::newRow("four items, remove first") << 4 << 0 << 1;
2031 QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
2032 QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
2033 QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
2034 QTest::newRow("four items, remove last") << 4 << 3 << 1;
2035 QTest::newRow("four items, remove all") << 4 << 0 << 4;
2037 QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
2038 QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
2039 QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
2042 void tst_QDeclarativeGridView::testQtQuick11Attributes()
2044 QFETCH(QString, code);
2045 QFETCH(QString, warning);
2046 QFETCH(QString, error);
2048 QDeclarativeEngine engine;
2051 QDeclarativeComponent valid(&engine);
2052 valid.setData("import QtQuick 1.1; GridView { " + code.toUtf8() + " }", QUrl(""));
2053 obj = valid.create();
2055 QVERIFY(valid.errorString().isEmpty());
2058 QDeclarativeComponent invalid(&engine);
2059 invalid.setData("import QtQuick 1.0; GridView { " + code.toUtf8() + " }", QUrl(""));
2060 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2061 obj = invalid.create();
2062 QCOMPARE(invalid.errorString(), error);
2066 void tst_QDeclarativeGridView::testQtQuick11Attributes_data()
2068 QTest::addColumn<QString>("code");
2069 QTest::addColumn<QString>("warning");
2070 QTest::addColumn<QString>("error");
2072 QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()"
2073 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning"
2076 QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()"
2077 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd"
2081 void tst_QDeclarativeGridView::contentPosJump()
2083 QDeclarativeView *canvas = createView();
2086 for (int i = 0; i < 100; i++)
2087 model.addItem("Item" + QString::number(i), "");
2089 QDeclarativeContext *ctxt = canvas->rootContext();
2090 ctxt->setContextProperty("testModel", &model);
2091 ctxt->setContextProperty("testRightToLeft", QVariant(false));
2092 ctxt->setContextProperty("testTopToBottom", QVariant(false));
2094 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
2095 qApp->processEvents();
2097 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
2098 QVERIFY(gridview != 0);
2100 QDeclarativeItem *contentItem = gridview->contentItem();
2101 QVERIFY(contentItem != 0);
2103 // Test jumping more than a page of items.
2104 gridview->setContentY(500);
2106 // Confirm items positioned correctly
2107 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2108 for (int i = 24; i < model.count() && i < itemCount; ++i) {
2109 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2110 if (!item) qWarning() << "Item" << i << "not found";
2112 QVERIFY(item->x() == (i%3)*80);
2113 QVERIFY(item->y() == (i/3)*60);
2116 gridview->setContentY(-100);
2117 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2118 QVERIFY(itemCount < 15);
2119 // Confirm items positioned correctly
2120 for (int i = 0; i < model.count() && i < itemCount; ++i) {
2121 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2122 if (!item) qWarning() << "Item" << i << "not found";
2124 QVERIFY(item->x() == (i%3)*80);
2125 QVERIFY(item->y() == (i/3)*60);
2131 QDeclarativeView *tst_QDeclarativeGridView::createView()
2133 QDeclarativeView *canvas = new QDeclarativeView(0);
2134 canvas->setFixedSize(240,320);
2140 Find an item with the specified objectName. If index is supplied then the
2141 item must also evaluate the {index} expression equal to index
2143 template<typename T>
2144 T *tst_QDeclarativeGridView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
2146 const QMetaObject &mo = T::staticMetaObject;
2147 //qDebug() << parent->childItems().count() << "children";
2148 for (int i = 0; i < parent->childItems().count(); ++i) {
2149 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2152 //qDebug() << "try" << item;
2153 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2155 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2157 if (context->contextProperty("index").toInt() == index) {
2158 return static_cast<T*>(item);
2162 return static_cast<T*>(item);
2165 item = findItem<T>(item, objectName, index);
2167 return static_cast<T*>(item);
2173 template<typename T>
2174 QList<T*> tst_QDeclarativeGridView::findItems(QGraphicsObject *parent, const QString &objectName)
2177 const QMetaObject &mo = T::staticMetaObject;
2178 //qDebug() << parent->childItems().count() << "children";
2179 for (int i = 0; i < parent->childItems().count(); ++i) {
2180 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2183 //qDebug() << "try" << item;
2184 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2185 items.append(static_cast<T*>(item));
2186 //qDebug() << " found:" << item;
2188 items += findItems<T>(item, objectName);
2194 void tst_QDeclarativeGridView::dumpTree(QDeclarativeItem *parent, int depth)
2196 static QString padding(" ");
2197 for (int i = 0; i < parent->childItems().count(); ++i) {
2198 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2201 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2202 qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
2203 dumpTree(item, depth+1);
2208 QTEST_MAIN(tst_QDeclarativeGridView)
2210 #include "tst_qdeclarativegridview.moc"