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(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
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));
237 // set an empty model and confirm that items are destroyed
239 ctxt->setContextProperty("testModel", &model2);
241 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
242 QTRY_VERIFY(itemCount == 0);
247 void tst_QDeclarativeGridView::changed()
249 QDeclarativeView *canvas = createView();
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");
260 QDeclarativeContext *ctxt = canvas->rootContext();
261 ctxt->setContextProperty("testModel", &model);
262 ctxt->setContextProperty("testRightToLeft", QVariant(false));
263 ctxt->setContextProperty("testTopToBottom", QVariant(false));
265 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
266 qApp->processEvents();
268 QDeclarativeFlickable *gridview = findItem<QDeclarativeFlickable>(canvas->rootObject(), "grid");
269 QTRY_VERIFY(gridview != 0);
271 QDeclarativeItem *contentItem = gridview->contentItem();
272 QTRY_VERIFY(contentItem != 0);
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));
285 void tst_QDeclarativeGridView::inserted()
287 QDeclarativeView *canvas = createView();
290 model.addItem("Fred", "12345");
291 model.addItem("John", "2345");
292 model.addItem("Bob", "54321");
294 QDeclarativeContext *ctxt = canvas->rootContext();
295 ctxt->setContextProperty("testModel", &model);
296 ctxt->setContextProperty("testRightToLeft", QVariant(false));
297 ctxt->setContextProperty("testTopToBottom", QVariant(false));
299 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
300 qApp->processEvents();
302 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
303 QTRY_VERIFY(gridview != 0);
305 QDeclarativeItem *contentItem = gridview->contentItem();
306 QTRY_VERIFY(contentItem != 0);
308 model.insertItem(1, "Will", "9876");
309 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
311 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
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));
320 // Checks that onAdd is called
321 int added = canvas->rootObject()->property("added").toInt();
322 QTRY_COMPARE(added, 1);
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);
331 model.insertItem(0, "Foo", "1111"); // zero index, and current item
333 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
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));
342 QTRY_COMPARE(gridview->currentIndex(), 1);
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);
351 for (int i = model.count(); i < 30; ++i)
352 model.insertItem(i, "Hello", QString::number(i));
354 gridview->setContentY(120);
356 // Insert item outside visible area
357 model.insertItem(1, "Hello", "1324");
359 QTRY_VERIFY(gridview->contentY() == 120);
364 void tst_QDeclarativeGridView::removed()
366 QDeclarativeView *canvas = createView();
369 for (int i = 0; i < 40; i++)
370 model.addItem("Item" + QString::number(i), "");
372 QDeclarativeContext *ctxt = canvas->rootContext();
373 ctxt->setContextProperty("testModel", &model);
374 ctxt->setContextProperty("testRightToLeft", QVariant(false));
375 ctxt->setContextProperty("testTopToBottom", QVariant(false));
377 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
378 qApp->processEvents();
380 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
381 QTRY_VERIFY(gridview != 0);
383 QDeclarativeItem *contentItem = gridview->contentItem();
384 QTRY_VERIFY(contentItem != 0);
387 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
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));
396 // Checks that onRemove is called
397 QString removed = canvas->rootObject()->property("removed").toString();
398 QTRY_COMPARE(removed, QString("Item1"));
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";
406 QTRY_VERIFY(item->x() == (i%3)*80);
407 QTRY_VERIFY(item->y() == (i/3)*60);
410 // Remove first item (which is the current item);
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));
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";
426 QTRY_VERIFY(item->x() == (i%3)*80);
427 QTRY_VERIFY(item->y() == (i/3)*60);
430 // Remove items not visible
431 model.removeItem(25);
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";
439 QTRY_VERIFY(item->x() == (i%3)*80);
440 QTRY_VERIFY(item->y() == (i/3)*60);
443 // Remove items before visible
444 gridview->setContentY(120);
445 gridview->setCurrentIndex(10);
447 // Setting currentIndex above shouldn't cause view to scroll
448 QTRY_COMPARE(gridview->contentY(), 120.0);
452 // Confirm items positioned correctly
453 for (int i = 6; i < 18; ++i) {
454 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
455 if (!item) qWarning() << "Item" << i << "not found";
457 QTRY_VERIFY(item->x() == (i%3)*80);
458 QTRY_VERIFY(item->y() == (i/3)*60);
461 // Remove currentIndex
462 QDeclarativeItem *oldCurrent = gridview->currentItem();
465 QTRY_COMPARE(gridview->currentIndex(), 9);
466 QTRY_VERIFY(gridview->currentItem() != oldCurrent);
468 gridview->setContentY(0);
469 // let transitions settle.
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";
478 QTRY_VERIFY(item->x() == (i%3)*80);
479 QTRY_VERIFY(item->y() == (i/3)*60);
482 // remove item outside current view.
483 gridview->setCurrentIndex(32);
484 gridview->setContentY(240);
486 model.removeItem(30);
487 QTRY_VERIFY(gridview->currentIndex() == 31);
489 // remove current item beyond visible items.
490 gridview->setCurrentIndex(20);
491 gridview->setContentY(0);
492 model.removeItem(20);
494 QTRY_COMPARE(gridview->currentIndex(), 20);
495 QTRY_VERIFY(gridview->currentItem() != 0);
497 // remove item before current, but visible
498 gridview->setCurrentIndex(8);
499 gridview->setContentY(240);
500 oldCurrent = gridview->currentItem();
503 QTRY_COMPARE(gridview->currentIndex(), 7);
504 QTRY_VERIFY(gridview->currentItem() == oldCurrent);
509 void tst_QDeclarativeGridView::clear()
511 QDeclarativeView *canvas = createView();
514 for (int i = 0; i < 30; i++)
515 model.addItem("Item" + QString::number(i), "");
517 QDeclarativeContext *ctxt = canvas->rootContext();
518 ctxt->setContextProperty("testModel", &model);
519 ctxt->setContextProperty("testRightToLeft", QVariant(false));
520 ctxt->setContextProperty("testTopToBottom", QVariant(false));
522 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
523 qApp->processEvents();
525 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
526 QVERIFY(gridview != 0);
528 QDeclarativeItem *contentItem = gridview->contentItem();
529 QVERIFY(contentItem != 0);
533 QVERIFY(gridview->count() == 0);
534 QVERIFY(gridview->currentItem() == 0);
535 QVERIFY(gridview->contentY() == 0);
536 QVERIFY(gridview->currentIndex() == -1);
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);
547 void tst_QDeclarativeGridView::moved()
549 QDeclarativeView *canvas = createView();
552 for (int i = 0; i < 30; i++)
553 model.addItem("Item" + QString::number(i), "");
555 QDeclarativeContext *ctxt = canvas->rootContext();
556 ctxt->setContextProperty("testModel", &model);
557 ctxt->setContextProperty("testRightToLeft", QVariant(false));
558 ctxt->setContextProperty("testTopToBottom", QVariant(false));
560 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
561 qApp->processEvents();
563 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
564 QTRY_VERIFY(gridview != 0);
566 QDeclarativeItem *contentItem = gridview->contentItem();
567 QTRY_VERIFY(contentItem != 0);
569 model.moveItem(1, 8);
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));
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));
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";
591 QTRY_VERIFY(item->x() == (i%3)*80);
592 QTRY_VERIFY(item->y() == (i/3)*60);
595 gridview->setContentY(120);
597 // move outside visible area
598 model.moveItem(1, 25);
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";
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));
616 // move from outside visible into visible
617 model.moveItem(28, 8);
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";
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));
634 // ensure content position is stable
635 gridview->setContentY(0);
636 model.moveItem(10, 0);
637 QTRY_VERIFY(gridview->contentY() == 0);
642 void tst_QDeclarativeGridView::currentIndex()
645 for (int i = 0; i < 60; i++)
646 model.addItem("Item" + QString::number(i), QString::number(i));
648 QDeclarativeView *canvas = new QDeclarativeView(0);
649 canvas->setFixedSize(240,320);
651 QDeclarativeContext *ctxt = canvas->rootContext();
652 ctxt->setContextProperty("testModel", &model);
654 QString filename(SRCDIR "/data/gridview-initCurrent.qml");
655 canvas->setSource(QUrl::fromLocalFile(filename));
657 qApp->processEvents();
659 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
660 QVERIFY(gridview != 0);
662 QDeclarativeItem *contentItem = gridview->contentItem();
663 QVERIFY(contentItem != 0);
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);
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);
681 gridview->setCurrentIndex(0);
682 QCOMPARE(gridview->currentIndex(), 0);
683 // confirm that the velocity is updated
684 QTRY_VERIFY(gridview->verticalVelocity() != 0.0);
686 gridview->moveCurrentIndexUp();
687 QCOMPARE(gridview->currentIndex(), 0);
689 gridview->moveCurrentIndexLeft();
690 QCOMPARE(gridview->currentIndex(), 0);
692 gridview->setCurrentIndex(model.count()-1);
693 QCOMPARE(gridview->currentIndex(), model.count()-1);
695 gridview->moveCurrentIndexRight();
696 QCOMPARE(gridview->currentIndex(), model.count()-1);
698 gridview->moveCurrentIndexDown();
699 QCOMPARE(gridview->currentIndex(), model.count()-1);
702 gridview->setWrapEnabled(true);
704 gridview->setCurrentIndex(0);
705 QCOMPARE(gridview->currentIndex(), 0);
707 gridview->moveCurrentIndexLeft();
708 QCOMPARE(gridview->currentIndex(), model.count()-1);
710 QTRY_COMPARE(gridview->contentY(), 880.0);
712 gridview->moveCurrentIndexRight();
713 QCOMPARE(gridview->currentIndex(), 0);
715 QTRY_COMPARE(gridview->contentY(), 0.0);
719 qApp->setActiveWindow(canvas);
721 // to be safe and avoid failing setFocus with window managers
722 qt_x11_wait_for_window_manager(canvas);
724 QTRY_VERIFY(canvas->hasFocus());
725 QTRY_VERIFY(canvas->scene()->hasFocus());
726 qApp->processEvents();
728 QTest::keyClick(canvas, Qt::Key_Down);
729 QCOMPARE(gridview->currentIndex(), 3);
731 QTest::keyClick(canvas, Qt::Key_Up);
732 QCOMPARE(gridview->currentIndex(), 0);
734 gridview->setFlow(QDeclarativeGridView::TopToBottom);
736 qApp->setActiveWindow(canvas);
738 // to be safe and avoid failing setFocus with window managers
739 qt_x11_wait_for_window_manager(canvas);
741 QTRY_VERIFY(canvas->hasFocus());
742 QTRY_VERIFY(canvas->scene()->hasFocus());
743 qApp->processEvents();
745 QTest::keyClick(canvas, Qt::Key_Right);
746 QCOMPARE(gridview->currentIndex(), 5);
748 QTest::keyClick(canvas, Qt::Key_Left);
749 QCOMPARE(gridview->currentIndex(), 0);
751 QTest::keyClick(canvas, Qt::Key_Down);
752 QCOMPARE(gridview->currentIndex(), 1);
754 QTest::keyClick(canvas, Qt::Key_Up);
755 QCOMPARE(gridview->currentIndex(), 0);
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();
765 gridview->setCurrentIndex(5);
766 QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
767 QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
769 // insert item before currentIndex
770 gridview->setCurrentIndex(28);
771 model.insertItem(0, "Foo", "1111");
772 QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
774 // check removing highlight by setting currentIndex to -1;
775 gridview->setCurrentIndex(-1);
777 QCOMPARE(gridview->currentIndex(), -1);
778 QVERIFY(!gridview->highlightItem());
779 QVERIFY(!gridview->currentItem());
781 gridview->setHighlightFollowsCurrentItem(true);
783 gridview->setFlow(QDeclarativeGridView::LeftToRight);
784 gridview->setLayoutDirection(Qt::RightToLeft);
786 qApp->setActiveWindow(canvas);
788 // to be safe and avoid failing setFocus with window managers
789 qt_x11_wait_for_window_manager(canvas);
791 QTRY_VERIFY(canvas->hasFocus());
792 QTRY_VERIFY(canvas->scene()->hasFocus());
793 qApp->processEvents();
795 gridview->setCurrentIndex(35);
797 QTest::keyClick(canvas, Qt::Key_Right);
798 QCOMPARE(gridview->currentIndex(), 34);
800 QTest::keyClick(canvas, Qt::Key_Down);
801 QCOMPARE(gridview->currentIndex(), 37);
803 QTest::keyClick(canvas, Qt::Key_Up);
804 QCOMPARE(gridview->currentIndex(), 34);
806 QTest::keyClick(canvas, Qt::Key_Left);
807 QCOMPARE(gridview->currentIndex(), 35);
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();
817 gridview->setCurrentIndex(5);
818 QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
819 QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
821 // insert item before currentIndex
822 gridview->setCurrentIndex(28);
823 model.insertItem(0, "Foo", "1111");
824 QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
826 // check removing highlight by setting currentIndex to -1;
827 gridview->setCurrentIndex(-1);
829 QCOMPARE(gridview->currentIndex(), -1);
830 QVERIFY(!gridview->highlightItem());
831 QVERIFY(!gridview->currentItem());
836 void tst_QDeclarativeGridView::noCurrentIndex()
839 for (int i = 0; i < 60; i++)
840 model.addItem("Item" + QString::number(i), QString::number(i));
842 QDeclarativeView *canvas = new QDeclarativeView(0);
843 canvas->setFixedSize(240,320);
845 QDeclarativeContext *ctxt = canvas->rootContext();
846 ctxt->setContextProperty("testModel", &model);
848 QString filename(SRCDIR "/data/gridview-noCurrent.qml");
849 canvas->setSource(QUrl::fromLocalFile(filename));
851 qApp->processEvents();
853 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
854 QVERIFY(gridview != 0);
856 QDeclarativeItem *contentItem = gridview->contentItem();
857 QVERIFY(contentItem != 0);
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);
865 gridview->setCurrentIndex(5);
866 QCOMPARE(gridview->currentIndex(), 5);
867 QVERIFY(gridview->currentItem());
868 QVERIFY(gridview->highlightItem());
871 void tst_QDeclarativeGridView::changeFlow()
873 QDeclarativeView *canvas = createView();
876 for (int i = 0; i < 30; i++)
877 model.addItem("Item" + QString::number(i), QString::number(i));
879 QDeclarativeContext *ctxt = canvas->rootContext();
880 ctxt->setContextProperty("testModel", &model);
881 ctxt->setContextProperty("testRightToLeft", QVariant(false));
882 ctxt->setContextProperty("testTopToBottom", QVariant(false));
884 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
885 qApp->processEvents();
887 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
888 QTRY_VERIFY(gridview != 0);
890 QDeclarativeItem *contentItem = gridview->contentItem();
891 QTRY_VERIFY(contentItem != 0);
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";
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));
909 ctxt->setContextProperty("testTopToBottom", QVariant(true));
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";
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));
927 ctxt->setContextProperty("testRightToLeft", QVariant(true));
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";
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));
944 gridview->setContentX(100);
945 QTRY_COMPARE(gridview->contentX(), 100.);
946 ctxt->setContextProperty("testTopToBottom", QVariant(false));
947 QTRY_COMPARE(gridview->contentX(), 0.);
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";
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));
968 void tst_QDeclarativeGridView::defaultValues()
970 QDeclarativeEngine engine;
971 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview3.qml"));
972 QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(c.create());
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);
991 void tst_QDeclarativeGridView::properties()
993 QDeclarativeEngine engine;
994 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview2.qml"));
995 QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(c.create());
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);
1014 void tst_QDeclarativeGridView::propertyChanges()
1016 QDeclarativeView *canvas = createView();
1017 QTRY_VERIFY(canvas);
1018 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1020 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
1021 QTRY_VERIFY(gridView);
1023 QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged()));
1024 QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged()));
1025 QSignalSpy layoutSpy(gridView, SIGNAL(layoutDirectionChanged()));
1026 QSignalSpy flowSpy(gridView, SIGNAL(flowChanged()));
1028 QTRY_COMPARE(gridView->isWrapEnabled(), true);
1029 QTRY_COMPARE(gridView->cacheBuffer(), 10);
1030 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::LeftToRight);
1032 gridView->setWrapEnabled(false);
1033 gridView->setCacheBuffer(3);
1034 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1036 QTRY_COMPARE(gridView->isWrapEnabled(), false);
1037 QTRY_COMPARE(gridView->cacheBuffer(), 3);
1038 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::TopToBottom);
1040 QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1041 QTRY_COMPARE(cacheBufferSpy.count(),1);
1042 QTRY_COMPARE(flowSpy.count(),1);
1044 gridView->setWrapEnabled(false);
1045 gridView->setCacheBuffer(3);
1046 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1048 QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1049 QTRY_COMPARE(cacheBufferSpy.count(),1);
1050 QTRY_COMPARE(flowSpy.count(),1);
1052 gridView->setFlow(QDeclarativeGridView::LeftToRight);
1053 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::LeftToRight);
1055 gridView->setWrapEnabled(true);
1056 gridView->setCacheBuffer(5);
1057 gridView->setLayoutDirection(Qt::RightToLeft);
1059 QTRY_COMPARE(gridView->isWrapEnabled(), true);
1060 QTRY_COMPARE(gridView->cacheBuffer(), 5);
1061 QTRY_COMPARE(gridView->layoutDirection(), Qt::RightToLeft);
1063 QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
1064 QTRY_COMPARE(cacheBufferSpy.count(),2);
1065 QTRY_COMPARE(layoutSpy.count(),1);
1066 QTRY_COMPARE(flowSpy.count(),2);
1068 gridView->setWrapEnabled(true);
1069 gridView->setCacheBuffer(5);
1070 gridView->setLayoutDirection(Qt::RightToLeft);
1072 QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
1073 QTRY_COMPARE(cacheBufferSpy.count(),2);
1074 QTRY_COMPARE(layoutSpy.count(),1);
1075 QTRY_COMPARE(flowSpy.count(),2);
1077 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1078 QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::TopToBottom);
1079 QTRY_COMPARE(flowSpy.count(),3);
1081 gridView->setFlow(QDeclarativeGridView::TopToBottom);
1082 QTRY_COMPARE(flowSpy.count(),3);
1087 void tst_QDeclarativeGridView::componentChanges()
1089 QDeclarativeView *canvas = createView();
1090 QTRY_VERIFY(canvas);
1091 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1093 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
1094 QTRY_VERIFY(gridView);
1096 QDeclarativeComponent component(canvas->engine());
1097 component.setData("import QtQuick 1.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
1099 QDeclarativeComponent delegateComponent(canvas->engine());
1100 delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
1102 QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged()));
1103 QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged()));
1104 QSignalSpy headerSpy(gridView, SIGNAL(headerChanged()));
1105 QSignalSpy footerSpy(gridView, SIGNAL(footerChanged()));
1107 gridView->setHighlight(&component);
1108 gridView->setDelegate(&delegateComponent);
1109 gridView->setHeader(&component);
1110 gridView->setFooter(&component);
1112 QTRY_COMPARE(gridView->highlight(), &component);
1113 QTRY_COMPARE(gridView->delegate(), &delegateComponent);
1114 QTRY_COMPARE(gridView->header(), &component);
1115 QTRY_COMPARE(gridView->footer(), &component);
1117 QTRY_COMPARE(highlightSpy.count(),1);
1118 QTRY_COMPARE(delegateSpy.count(),1);
1119 QTRY_COMPARE(headerSpy.count(),1);
1120 QTRY_COMPARE(footerSpy.count(),1);
1122 gridView->setHighlight(&component);
1123 gridView->setDelegate(&delegateComponent);
1124 gridView->setHeader(&component);
1125 gridView->setFooter(&component);
1127 QTRY_COMPARE(highlightSpy.count(),1);
1128 QTRY_COMPARE(delegateSpy.count(),1);
1129 QTRY_COMPARE(headerSpy.count(),1);
1130 QTRY_COMPARE(footerSpy.count(),1);
1135 void tst_QDeclarativeGridView::modelChanges()
1137 QDeclarativeView *canvas = createView();
1138 QTRY_VERIFY(canvas);
1139 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1141 QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
1142 QTRY_VERIFY(gridView);
1144 QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
1145 QTRY_VERIFY(alternateModel);
1146 QVariant modelVariant = QVariant::fromValue(alternateModel);
1147 QSignalSpy modelSpy(gridView, SIGNAL(modelChanged()));
1149 gridView->setModel(modelVariant);
1150 QTRY_COMPARE(gridView->model(), modelVariant);
1151 QTRY_COMPARE(modelSpy.count(),1);
1153 gridView->setModel(modelVariant);
1154 QTRY_COMPARE(modelSpy.count(),1);
1156 gridView->setModel(QVariant());
1157 QTRY_COMPARE(modelSpy.count(),2);
1161 void tst_QDeclarativeGridView::positionViewAtIndex()
1163 QDeclarativeView *canvas = createView();
1166 for (int i = 0; i < 40; i++)
1167 model.addItem("Item" + QString::number(i), "");
1169 QDeclarativeContext *ctxt = canvas->rootContext();
1170 ctxt->setContextProperty("testModel", &model);
1171 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1172 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1174 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1175 qApp->processEvents();
1177 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1178 QTRY_VERIFY(gridview != 0);
1180 QDeclarativeItem *contentItem = gridview->contentItem();
1181 QTRY_VERIFY(contentItem != 0);
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";
1189 QTRY_COMPARE(item->x(), (i%3)*80.);
1190 QTRY_COMPARE(item->y(), (i/3)*60.);
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.);
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";
1204 QTRY_COMPARE(item->x(), (i%3)*80.);
1205 QTRY_COMPARE(item->y(), (i/3)*60.);
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.);
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";
1219 QTRY_COMPARE(item->x(), (i%3)*80.);
1220 QTRY_COMPARE(item->y(), (i/3)*60.);
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.);
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";
1234 QTRY_COMPARE(item->x(), (i%3)*80.);
1235 QTRY_COMPARE(item->y(), (i/3)*60.);
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.);
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";
1251 QTRY_COMPARE(item->x(), (i%3)*80.);
1252 QTRY_COMPARE(item->y(), (i/3)*60.);
1256 gridview->positionViewAtIndex(30, QDeclarativeGridView::End);
1257 QTRY_COMPARE(gridview->contentY(), 340.);
1259 // Position in Center
1260 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1261 QTRY_COMPARE(gridview->contentY(), 170.);
1263 // Ensure at least partially visible
1264 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1265 QTRY_COMPARE(gridview->contentY(), 170.);
1267 gridview->setContentY(302);
1268 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1269 QTRY_COMPARE(gridview->contentY(), 302.);
1271 gridview->setContentY(360);
1272 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1273 QTRY_COMPARE(gridview->contentY(), 300.);
1275 gridview->setContentY(60);
1276 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1277 QTRY_COMPARE(gridview->contentY(), 60.);
1279 gridview->setContentY(20);
1280 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1281 QTRY_COMPARE(gridview->contentY(), 100.);
1283 // Ensure completely visible
1284 gridview->setContentY(120);
1285 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1286 QTRY_COMPARE(gridview->contentY(), 120.);
1288 gridview->setContentY(302);
1289 gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain);
1290 QTRY_COMPARE(gridview->contentY(), 300.);
1292 gridview->setContentY(60);
1293 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1294 QTRY_COMPARE(gridview->contentY(), 100.);
1296 // Test for Top To Bottom layout
1297 ctxt->setContextProperty("testTopToBottom", QVariant(true));
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";
1305 QTRY_COMPARE(item->x(), (i/5)*80.);
1306 QTRY_COMPARE(item->y(), (i%5)*60.);
1310 gridview->positionViewAtIndex(30, QDeclarativeGridView::End);
1311 QTRY_COMPARE(gridview->contentX(), 320.);
1312 QTRY_COMPARE(gridview->contentY(), 0.);
1314 // Position in Center
1315 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1316 QTRY_COMPARE(gridview->contentX(), 160.);
1318 // Ensure at least partially visible
1319 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1320 QTRY_COMPARE(gridview->contentX(), 160.);
1322 gridview->setContentX(170);
1323 gridview->positionViewAtIndex(25, QDeclarativeGridView::Visible);
1324 QTRY_COMPARE(gridview->contentX(), 170.);
1326 gridview->positionViewAtIndex(30, QDeclarativeGridView::Visible);
1327 QTRY_COMPARE(gridview->contentX(), 320.);
1329 gridview->setContentX(170);
1330 gridview->positionViewAtIndex(25, QDeclarativeGridView::Contain);
1331 QTRY_COMPARE(gridview->contentX(), 240.);
1333 // positionViewAtBeginning
1334 gridview->positionViewAtBeginning();
1335 QTRY_COMPARE(gridview->contentX(), 0.);
1337 gridview->setContentX(80);
1338 canvas->rootObject()->setProperty("showHeader", true);
1339 gridview->positionViewAtBeginning();
1340 QTRY_COMPARE(gridview->contentX(), -30.);
1342 // positionViewAtEnd
1343 gridview->positionViewAtEnd();
1344 QTRY_COMPARE(gridview->contentX(), 430.);
1346 gridview->setContentX(80);
1347 canvas->rootObject()->setProperty("showFooter", true);
1348 gridview->positionViewAtEnd();
1349 QTRY_COMPARE(gridview->contentX(), 460.);
1354 void tst_QDeclarativeGridView::snapping()
1356 QDeclarativeView *canvas = createView();
1359 for (int i = 0; i < 40; i++)
1360 model.addItem("Item" + QString::number(i), "");
1362 QDeclarativeContext *ctxt = canvas->rootContext();
1363 ctxt->setContextProperty("testModel", &model);
1364 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1365 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1367 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1368 qApp->processEvents();
1370 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1371 QTRY_VERIFY(gridview != 0);
1373 gridview->setHeight(220);
1374 QCOMPARE(gridview->height(), 220.);
1376 gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible);
1377 QCOMPARE(gridview->contentY(), 80.);
1379 gridview->setContentY(0);
1380 QCOMPARE(gridview->contentY(), 0.);
1382 gridview->setSnapMode(QDeclarativeGridView::SnapToRow);
1383 QCOMPARE(gridview->snapMode(), QDeclarativeGridView::SnapToRow);
1385 gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible);
1386 QCOMPARE(gridview->contentY(), 60.);
1388 gridview->positionViewAtIndex(15, QDeclarativeGridView::End);
1389 QCOMPARE(gridview->contentY(), 120.);
1395 void tst_QDeclarativeGridView::mirroring()
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);
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();
1408 QList<QString> objectNames;
1409 objectNames << "item1" << "item2"; // << "item3"
1411 gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1412 gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
1413 QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection());
1416 foreach(const QString objectName, objectNames)
1417 QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1419 gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1420 gridviewB->setProperty("layoutDirection", Qt::LeftToRight);
1423 foreach(const QString objectName, objectNames)
1424 QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1426 QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection());
1427 QDeclarativeItemPrivate::get(gridviewB)->setLayoutMirror(true);
1428 QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection());
1430 // LTR != LTR+mirror
1431 foreach(const QString objectName, objectNames)
1432 QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1434 gridviewA->setProperty("layoutDirection", Qt::RightToLeft);
1436 // RTL == LTR+mirror
1437 foreach(const QString objectName, objectNames)
1438 QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1440 gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
1442 // RTL != RTL+mirror
1443 foreach(const QString objectName, objectNames)
1444 QVERIFY(findItem<QDeclarativeItem>(gridviewA, objectName)->x() != findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1446 gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
1448 // LTR == RTL+mirror
1449 foreach(const QString objectName, objectNames)
1450 QCOMPARE(findItem<QDeclarativeItem>(gridviewA, objectName)->x(), findItem<QDeclarativeItem>(gridviewB, objectName)->x());
1456 void tst_QDeclarativeGridView::positionViewAtIndex_rightToLeft()
1458 QDeclarativeView *canvas = createView();
1461 for (int i = 0; i < 40; i++)
1462 model.addItem("Item" + QString::number(i), "");
1464 QDeclarativeContext *ctxt = canvas->rootContext();
1465 ctxt->setContextProperty("testModel", &model);
1466 ctxt->setContextProperty("testTopToBottom", QVariant(true));
1467 ctxt->setContextProperty("testRightToLeft", QVariant(true));
1469 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1470 qApp->processEvents();
1472 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1473 QTRY_VERIFY(gridview != 0);
1475 QDeclarativeItem *contentItem = gridview->contentItem();
1476 QTRY_VERIFY(contentItem != 0);
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";
1484 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1485 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1488 // Position on a currently visible item
1489 gridview->positionViewAtIndex(6, QDeclarativeGridView::Beginning);
1490 QTRY_COMPARE(gridview->contentX(), -320.);
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";
1498 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1499 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1502 // Position on an item beyond the visible items
1503 gridview->positionViewAtIndex(21, QDeclarativeGridView::Beginning);
1504 QTRY_COMPARE(gridview->contentX(), -560.);
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";
1512 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1513 QTRY_COMPARE(item->y(), qreal((i%5)*60));
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.);
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";
1526 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1527 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1530 // Position at the beginning again
1531 gridview->positionViewAtIndex(0, QDeclarativeGridView::Beginning);
1532 QTRY_COMPARE(gridview->contentX(), -240.);
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";
1540 QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
1541 QTRY_COMPARE(item->y(), qreal((i%5)*60));
1545 gridview->positionViewAtIndex(30, QDeclarativeGridView::End);
1546 QTRY_COMPARE(gridview->contentX(), -560.);
1548 // Position in Center
1549 gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
1550 QTRY_COMPARE(gridview->contentX(), -400.);
1552 // Ensure at least partially visible
1553 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1554 QTRY_COMPARE(gridview->contentX(), -400.);
1556 gridview->setContentX(-555.);
1557 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1558 QTRY_COMPARE(gridview->contentX(), -555.);
1560 gridview->setContentX(-239);
1561 gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
1562 QTRY_COMPARE(gridview->contentX(), -320.);
1564 gridview->setContentX(-239);
1565 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1566 QTRY_COMPARE(gridview->contentX(), -400.);
1568 gridview->setContentX(-640);
1569 gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
1570 QTRY_COMPARE(gridview->contentX(), -560.);
1572 // Ensure completely visible
1573 gridview->setContentX(-400);
1574 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1575 QTRY_COMPARE(gridview->contentX(), -400.);
1577 gridview->setContentX(-315);
1578 gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain);
1579 QTRY_COMPARE(gridview->contentX(), -320.);
1581 gridview->setContentX(-640);
1582 gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
1583 QTRY_COMPARE(gridview->contentX(), -560.);
1588 void tst_QDeclarativeGridView::resetModel()
1590 QDeclarativeView *canvas = createView();
1592 QStringList strings;
1593 strings << "one" << "two" << "three";
1594 QStringListModel model(strings);
1596 QDeclarativeContext *ctxt = canvas->rootContext();
1597 ctxt->setContextProperty("testModel", &model);
1599 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaygrid.qml"));
1600 qApp->processEvents();
1602 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1603 QTRY_VERIFY(gridview != 0);
1605 QDeclarativeItem *contentItem = gridview->contentItem();
1606 QTRY_VERIFY(contentItem != 0);
1608 QTRY_COMPARE(gridview->count(), model.rowCount());
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));
1617 strings << "four" << "five" << "six" << "seven";
1618 model.setStringList(strings);
1620 QTRY_COMPARE(gridview->count(), model.rowCount());
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));
1629 void tst_QDeclarativeGridView::enforceRange()
1631 QDeclarativeView *canvas = createView();
1634 for (int i = 0; i < 30; i++)
1635 model.addItem("Item" + QString::number(i), "");
1637 QDeclarativeContext *ctxt = canvas->rootContext();
1638 ctxt->setContextProperty("testModel", &model);
1639 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1640 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1642 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1643 qApp->processEvents();
1644 QVERIFY(canvas->rootObject() != 0);
1646 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1647 QTRY_VERIFY(gridview != 0);
1649 QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1650 QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1651 QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarativeGridView::StrictlyEnforceRange);
1653 QDeclarativeItem *contentItem = gridview->contentItem();
1654 QTRY_VERIFY(contentItem != 0);
1656 // view should be positioned at the top of the range.
1657 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1659 QTRY_COMPARE(gridview->contentY(), -100.0);
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));
1668 // Check currentIndex is updated when contentItem moves
1669 gridview->setContentY(0);
1670 QTRY_COMPARE(gridview->currentIndex(), 2);
1672 gridview->setCurrentIndex(5);
1673 QTRY_COMPARE(gridview->contentY(), 100.);
1676 for (int i = 0; i < 5; i++)
1677 model2.addItem("Item" + QString::number(i), "");
1679 ctxt->setContextProperty("testModel", &model2);
1680 QCOMPARE(gridview->count(), 5);
1685 void tst_QDeclarativeGridView::enforceRange_rightToLeft()
1687 QDeclarativeView *canvas = createView();
1690 for (int i = 0; i < 30; i++)
1691 model.addItem("Item" + QString::number(i), "");
1693 QDeclarativeContext *ctxt = canvas->rootContext();
1694 ctxt->setContextProperty("testModel", &model);
1695 ctxt->setContextProperty("testRightToLeft", QVariant(true));
1696 ctxt->setContextProperty("testTopToBottom", QVariant(true));
1698 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
1699 qApp->processEvents();
1700 QVERIFY(canvas->rootObject() != 0);
1702 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1703 QTRY_VERIFY(gridview != 0);
1705 QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
1706 QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
1707 QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarativeGridView::StrictlyEnforceRange);
1709 QDeclarativeItem *contentItem = gridview->contentItem();
1710 QTRY_VERIFY(contentItem != 0);
1712 // view should be positioned at the top of the range.
1713 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1715 QTRY_COMPARE(gridview->contentX(), -100.);
1716 QTRY_COMPARE(gridview->contentY(), 0.0);
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));
1725 // Check currentIndex is updated when contentItem moves
1726 gridview->setContentX(-200);
1727 QTRY_COMPARE(gridview->currentIndex(), 3);
1729 gridview->setCurrentIndex(7);
1730 QTRY_COMPARE(gridview->contentX(), -300.);
1731 QTRY_COMPARE(gridview->contentY(), 0.0);
1734 for (int i = 0; i < 5; i++)
1735 model2.addItem("Item" + QString::number(i), "");
1737 ctxt->setContextProperty("testModel", &model2);
1738 QCOMPARE(gridview->count(), 5);
1743 void tst_QDeclarativeGridView::QTBUG_8456()
1745 QDeclarativeView *canvas = createView();
1747 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/setindex.qml"));
1748 qApp->processEvents();
1750 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1751 QTRY_VERIFY(gridview != 0);
1753 QTRY_COMPARE(gridview->currentIndex(), 0);
1756 void tst_QDeclarativeGridView::manualHighlight()
1758 QDeclarativeView *canvas = createView();
1760 QString filename(SRCDIR "/data/manual-highlight.qml");
1761 canvas->setSource(QUrl::fromLocalFile(filename));
1763 qApp->processEvents();
1765 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1766 QTRY_VERIFY(gridview != 0);
1768 QDeclarativeItem *contentItem = gridview->contentItem();
1769 QTRY_VERIFY(contentItem != 0);
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());
1776 gridview->setCurrentIndex(2);
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());
1783 gridview->positionViewAtIndex(8, QDeclarativeGridView::Contain);
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());
1790 gridview->setFlow(QDeclarativeGridView::TopToBottom);
1791 QTRY_COMPARE(gridview->flow(), QDeclarativeGridView::TopToBottom);
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());
1800 void tst_QDeclarativeGridView::footer()
1802 QDeclarativeView *canvas = createView();
1805 for (int i = 0; i < 7; i++)
1806 model.addItem("Item" + QString::number(i), "");
1808 QDeclarativeContext *ctxt = canvas->rootContext();
1809 ctxt->setContextProperty("testModel", &model);
1811 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/footer.qml"));
1812 qApp->processEvents();
1814 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1815 QTRY_VERIFY(gridview != 0);
1817 QDeclarativeItem *contentItem = gridview->contentItem();
1818 QTRY_VERIFY(contentItem != 0);
1820 QDeclarativeText *footer = findItem<QDeclarativeText>(contentItem, "footer");
1823 QCOMPARE(footer->y(), 180.0);
1824 QCOMPARE(footer->height(), 30.0);
1826 model.removeItem(2);
1827 QTRY_COMPARE(footer->y(), 120.0);
1830 QTRY_COMPARE(footer->y(), 0.0);
1832 for (int i = 0; i < 30; i++)
1833 model.addItem("Item" + QString::number(i), "");
1835 QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
1837 footer = findItem<QDeclarativeText>(contentItem, "footer");
1839 footer = findItem<QDeclarativeText>(contentItem, "footer2");
1842 QCOMPARE(footer->y(), 600.0);
1843 QCOMPARE(footer->height(), 20.0);
1844 QCOMPARE(gridview->contentY(), 0.0);
1847 void tst_QDeclarativeGridView::header()
1849 QDeclarativeView *canvas = createView();
1852 for (int i = 0; i < 30; i++)
1853 model.addItem("Item" + QString::number(i), "");
1855 QDeclarativeContext *ctxt = canvas->rootContext();
1856 ctxt->setContextProperty("testModel", &model);
1858 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
1859 qApp->processEvents();
1861 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1862 QTRY_VERIFY(gridview != 0);
1864 QDeclarativeItem *contentItem = gridview->contentItem();
1865 QTRY_VERIFY(contentItem != 0);
1867 QDeclarativeText *header = findItem<QDeclarativeText>(contentItem, "header");
1870 QCOMPARE(header->y(), 0.0);
1871 QCOMPARE(header->height(), 30.0);
1872 QCOMPARE(gridview->contentY(), 0.0);
1874 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1876 QCOMPARE(item->y(), 30.0);
1879 QTRY_COMPARE(header->y(), 0.0);
1881 for (int i = 0; i < 30; i++)
1882 model.addItem("Item" + QString::number(i), "");
1884 QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
1886 header = findItem<QDeclarativeText>(contentItem, "header");
1888 header = findItem<QDeclarativeText>(contentItem, "header2");
1891 QCOMPARE(header->y(), 10.0);
1892 QCOMPARE(header->height(), 20.0);
1893 QCOMPARE(gridview->contentY(), 10.0);
1896 void tst_QDeclarativeGridView::indexAt()
1898 QDeclarativeView *canvas = createView();
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");
1909 QDeclarativeContext *ctxt = canvas->rootContext();
1910 ctxt->setContextProperty("testModel", &model);
1911 ctxt->setContextProperty("testRightToLeft", QVariant(false));
1912 ctxt->setContextProperty("testTopToBottom", QVariant(false));
1914 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
1915 qApp->processEvents();
1917 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
1918 QTRY_VERIFY(gridview != 0);
1920 QDeclarativeItem *contentItem = gridview->contentItem();
1921 QTRY_VERIFY(contentItem != 0);
1923 QTRY_COMPARE(gridview->count(), model.count());
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);
1934 void tst_QDeclarativeGridView::onAdd()
1936 QFETCH(int, initialItemCount);
1937 QFETCH(int, itemsToAdd);
1939 const int delegateWidth = 50;
1940 const int delegateHeight = 100;
1942 QDeclarativeView *canvas = createView();
1943 canvas->setFixedSize(5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit
1945 // these initial items should not trigger GridView.onAdd
1946 for (int i=0; i<initialItemCount; i++)
1947 model.addItem("dummy value", "dummy value");
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"));
1955 QObject *object = canvas->rootObject();
1956 object->setProperty("width", canvas->width());
1957 object->setProperty("height", canvas->height());
1958 qApp->processEvents();
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);
1965 qApp->processEvents();
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);
1975 void tst_QDeclarativeGridView::onAdd_data()
1977 QTest::addColumn<int>("initialItemCount");
1978 QTest::addColumn<int>("itemsToAdd");
1980 QTest::newRow("0, add 1") << 0 << 1;
1981 QTest::newRow("0, add 2") << 0 << 2;
1982 QTest::newRow("0, add 10") << 0 << 10;
1984 QTest::newRow("1, add 1") << 1 << 1;
1985 QTest::newRow("1, add 2") << 1 << 2;
1986 QTest::newRow("1, add 10") << 1 << 10;
1988 QTest::newRow("5, add 1") << 5 << 1;
1989 QTest::newRow("5, add 2") << 5 << 2;
1990 QTest::newRow("5, add 10") << 5 << 10;
1993 void tst_QDeclarativeGridView::onRemove()
1995 QFETCH(int, initialItemCount);
1996 QFETCH(int, indexToRemove);
1997 QFETCH(int, removeCount);
1999 const int delegateWidth = 50;
2000 const int delegateHeight = 100;
2002 for (int i=0; i<initialItemCount; i++)
2003 model.addItem(QString("value %1").arg(i), "dummy value");
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();
2013 qApp->processEvents();
2015 model.removeItems(indexToRemove, removeCount);
2016 qApp->processEvents();
2017 QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
2022 void tst_QDeclarativeGridView::onRemove_data()
2024 QTest::addColumn<int>("initialItemCount");
2025 QTest::addColumn<int>("indexToRemove");
2026 QTest::addColumn<int>("removeCount");
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;
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;
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;
2045 void tst_QDeclarativeGridView::testQtQuick11Attributes()
2047 QFETCH(QString, code);
2048 QFETCH(QString, warning);
2049 QFETCH(QString, error);
2051 QDeclarativeEngine engine;
2054 QDeclarativeComponent valid(&engine);
2055 valid.setData("import QtQuick 1.1; GridView { " + code.toUtf8() + " }", QUrl(""));
2056 obj = valid.create();
2058 QVERIFY(valid.errorString().isEmpty());
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);
2069 void tst_QDeclarativeGridView::testQtQuick11Attributes_data()
2071 QTest::addColumn<QString>("code");
2072 QTest::addColumn<QString>("warning");
2073 QTest::addColumn<QString>("error");
2075 QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()"
2076 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning"
2079 QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()"
2080 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd"
2084 void tst_QDeclarativeGridView::contentPosJump()
2086 QDeclarativeView *canvas = createView();
2089 for (int i = 0; i < 100; i++)
2090 model.addItem("Item" + QString::number(i), "");
2092 QDeclarativeContext *ctxt = canvas->rootContext();
2093 ctxt->setContextProperty("testModel", &model);
2094 ctxt->setContextProperty("testRightToLeft", QVariant(false));
2095 ctxt->setContextProperty("testTopToBottom", QVariant(false));
2097 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
2098 qApp->processEvents();
2100 QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
2101 QVERIFY(gridview != 0);
2103 QDeclarativeItem *contentItem = gridview->contentItem();
2104 QVERIFY(contentItem != 0);
2106 // Test jumping more than a page of items.
2107 gridview->setContentY(500);
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";
2115 QVERIFY(item->x() == (i%3)*80);
2116 QVERIFY(item->y() == (i/3)*60);
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";
2127 QVERIFY(item->x() == (i%3)*80);
2128 QVERIFY(item->y() == (i/3)*60);
2134 QDeclarativeView *tst_QDeclarativeGridView::createView()
2136 QDeclarativeView *canvas = new QDeclarativeView(0);
2137 canvas->setFixedSize(240,320);
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
2146 template<typename T>
2147 T *tst_QDeclarativeGridView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
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));
2155 //qDebug() << "try" << item;
2156 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2158 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2160 if (context->contextProperty("index").toInt() == index) {
2161 return static_cast<T*>(item);
2165 return static_cast<T*>(item);
2168 item = findItem<T>(item, objectName, index);
2170 return static_cast<T*>(item);
2176 template<typename T>
2177 QList<T*> tst_QDeclarativeGridView::findItems(QGraphicsObject *parent, const QString &objectName)
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));
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;
2191 items += findItems<T>(item, objectName);
2197 void tst_QDeclarativeGridView::dumpTree(QDeclarativeItem *parent, int depth)
2199 static QString padding(" ");
2200 for (int i = 0; i < parent->childItems().count(); ++i) {
2201 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2204 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
2205 qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
2206 dumpTree(item, depth+1);
2211 QTEST_MAIN(tst_QDeclarativeGridView)
2213 #include "tst_qdeclarativegridview.moc"