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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <QtWidgets/QStringListModel>
44 #include <QtQuick1/qdeclarativeview.h>
45 #include <QtDeclarative/qdeclarativeengine.h>
46 #include <QtDeclarative/qdeclarativecontext.h>
47 #include <QtDeclarative/qdeclarativeexpression.h>
48 #include <QtQuick1/private/qdeclarativeitem_p.h>
49 #include <QtQuick1/private/qdeclarativelistview_p.h>
50 #include <QtQuick1/private/qdeclarativetext_p.h>
51 #include <QtQuick1/private/qdeclarativevisualitemmodel_p.h>
52 #include <QtDeclarative/private/qlistmodelinterface_p.h>
53 #include "../../../shared/util.h"
54 #include "incrementalmodel.h"
57 // In Symbian OS test data is located in applications private dir
61 class tst_QDeclarative1ListView : public QObject
65 tst_QDeclarative1ListView();
68 // Test both QListModelInterface and QAbstractItemModel model types
69 void qListModelInterface_items();
70 void qAbstractItemModel_items();
72 void qListModelInterface_changed();
73 void qAbstractItemModel_changed();
75 void qListModelInterface_inserted();
76 void qAbstractItemModel_inserted();
78 void qListModelInterface_removed();
79 void qAbstractItemModel_removed();
81 void qListModelInterface_moved();
82 void qAbstractItemModel_moved();
84 void qListModelInterface_clear();
85 void qAbstractItemModel_clear();
89 void noCurrentIndex();
93 void sectionsDelegate();
95 void positionViewAtIndex();
97 void propertyChanges();
98 void componentChanges();
101 void manualHighlight();
107 void sizeLessThan1();
109 void resizeDelegate();
112 void incrementalModel();
116 void onRemove_data();
117 void testQtQuick11Attributes();
118 void testQtQuick11Attributes_data();
120 void test_mirroring();
121 void orientationChange();
122 void contentPosJump();
125 template <class T> void items();
126 template <class T> void changed();
127 template <class T> void inserted();
128 template <class T> void removed(bool animated);
129 template <class T> void moved();
130 template <class T> void clear();
131 QDeclarativeView *createView();
133 T *findItem(QGraphicsObject *parent, const QString &id, int index=-1);
135 QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
136 void dumpTree(QDeclarativeItem *parent, int depth = 0);
139 class TestObject : public QObject
143 Q_PROPERTY(bool error READ error WRITE setError NOTIFY changedError)
144 Q_PROPERTY(bool animate READ animate NOTIFY changedAnim)
145 Q_PROPERTY(bool invalidHighlight READ invalidHighlight NOTIFY changedHl)
146 Q_PROPERTY(int cacheBuffer READ cacheBuffer NOTIFY changedCacheBuffer)
149 TestObject(QObject *parent = 0)
150 : QObject(parent), mError(true), mAnimate(false), mInvalidHighlight(false)
153 bool error() const { return mError; }
154 void setError(bool err) { mError = err; emit changedError(); }
156 bool animate() const { return mAnimate; }
157 void setAnimate(bool anim) { mAnimate = anim; emit changedAnim(); }
159 bool invalidHighlight() const { return mInvalidHighlight; }
160 void setInvalidHighlight(bool invalid) { mInvalidHighlight = invalid; emit changedHl(); }
162 int cacheBuffer() const { return mCacheBuffer; }
163 void setCacheBuffer(int buffer) { mCacheBuffer = buffer; emit changedCacheBuffer(); }
169 void changedCacheBuffer();
174 bool mInvalidHighlight;
178 class TestModel : public QListModelInterface
182 TestModel(QObject *parent = 0) : QListModelInterface(parent) {}
185 enum Roles { Name, Number };
187 QString name(int index) const { return list.at(index).first; }
188 QString number(int index) const { return list.at(index).second; }
190 int count() const { return list.count(); }
192 QList<int> roles() const { return QList<int>() << Name << Number; }
193 QString toString(int role) const {
204 QVariant data(int index, int role) const
207 return list.at(index).first;
209 return list.at(index).second;
212 QHash<int, QVariant> data(int index, const QList<int> &roles) const {
213 QHash<int,QVariant> returnHash;
215 for (int i = 0; i < roles.size(); ++i) {
216 int role = roles.at(i);
220 info = list.at(index).first;
223 info = list.at(index).second;
228 returnHash.insert(role, info);
233 void addItem(const QString &name, const QString &number) {
234 list.append(QPair<QString,QString>(name, number));
235 emit itemsInserted(list.count()-1, 1);
238 void insertItem(int index, const QString &name, const QString &number) {
239 list.insert(index, QPair<QString,QString>(name, number));
240 emit itemsInserted(index, 1);
243 void removeItem(int index) {
244 list.removeAt(index);
245 emit itemsRemoved(index, 1);
248 void removeItems(int index, int count) {
251 list.removeAt(index);
252 emit itemsRemoved(index, count);
255 void moveItem(int from, int to) {
257 emit itemsMoved(from, to, 1);
260 void modifyItem(int index, const QString &name, const QString &number) {
261 list[index] = QPair<QString,QString>(name, number);
262 emit itemsChanged(index, 1, roles());
266 int count = list.count();
268 emit itemsRemoved(0, count);
272 QList<QPair<QString,QString> > list;
276 class TestModel2 : public QAbstractListModel
279 enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
281 TestModel2(QObject *parent=0) : QAbstractListModel(parent) {
282 QHash<int, QByteArray> roles;
283 roles[Name] = "name";
284 roles[Number] = "number";
288 int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
289 QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
292 rv = list.at(index.row()).first;
293 else if (role == Number)
294 rv = list.at(index.row()).second;
299 int count() const { return rowCount(); }
300 QString name(int index) const { return list.at(index).first; }
301 QString number(int index) const { return list.at(index).second; }
303 void addItem(const QString &name, const QString &number) {
304 emit beginInsertRows(QModelIndex(), list.count(), list.count());
305 list.append(QPair<QString,QString>(name, number));
306 emit endInsertRows();
309 void addItems(const QList<QPair<QString, QString> > &items) {
310 emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
311 for (int i=0; i<items.count(); i++)
312 list.append(QPair<QString,QString>(items[i].first, items[i].second));
313 emit endInsertRows();
316 void insertItem(int index, const QString &name, const QString &number) {
317 emit beginInsertRows(QModelIndex(), index, index);
318 list.insert(index, QPair<QString,QString>(name, number));
319 emit endInsertRows();
322 void removeItem(int index) {
323 emit beginRemoveRows(QModelIndex(), index, index);
324 list.removeAt(index);
325 emit endRemoveRows();
328 void removeItems(int index, int count) {
329 emit beginRemoveRows(QModelIndex(), index, index+count-1);
331 list.removeAt(index);
332 emit endRemoveRows();
335 void moveItem(int from, int to) {
336 emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
341 void modifyItem(int idx, const QString &name, const QString &number) {
342 list[idx] = QPair<QString,QString>(name, number);
343 emit dataChanged(index(idx,0), index(idx,0));
347 int count = list.count();
348 emit beginRemoveRows(QModelIndex(), 0, count-1);
350 emit endRemoveRows();
354 QList<QPair<QString,QString> > list;
357 tst_QDeclarative1ListView::tst_QDeclarative1ListView()
362 void tst_QDeclarative1ListView::items()
364 QDeclarativeView *canvas = createView();
367 model.addItem("Fred", "12345");
368 model.addItem("John", "2345");
369 model.addItem("Bob", "54321");
371 QDeclarativeContext *ctxt = canvas->rootContext();
372 ctxt->setContextProperty("testModel", &model);
374 TestObject *testObject = new TestObject;
375 ctxt->setContextProperty("testObject", testObject);
377 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
378 qApp->processEvents();
380 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
381 QTRY_VERIFY(listview != 0);
383 QDeclarativeItem *contentItem = listview->contentItem();
384 QTRY_VERIFY(contentItem != 0);
386 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
387 QTRY_VERIFY(testObject->error() == false);
389 QTRY_VERIFY(listview->highlightItem() != 0);
390 QTRY_COMPARE(listview->count(), model.count());
391 QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
392 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
394 // current item should be first item
395 QTRY_COMPARE(listview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
397 for (int i = 0; i < model.count(); ++i) {
398 QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", i);
399 QTRY_VERIFY(name != 0);
400 QTRY_COMPARE(name->text(), model.name(i));
401 QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
402 QTRY_VERIFY(number != 0);
403 QTRY_COMPARE(number->text(), model.number(i));
406 // switch to other delegate
407 testObject->setAnimate(true);
408 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
409 QTRY_VERIFY(testObject->error() == false);
410 QTRY_VERIFY(listview->currentItem());
412 // set invalid highlight
413 testObject->setInvalidHighlight(true);
414 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
415 QTRY_VERIFY(testObject->error() == false);
416 QTRY_VERIFY(listview->currentItem());
417 QTRY_VERIFY(listview->highlightItem() == 0);
419 // back to normal highlight
420 testObject->setInvalidHighlight(false);
421 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
422 QTRY_VERIFY(testObject->error() == false);
423 QTRY_VERIFY(listview->currentItem());
424 QTRY_VERIFY(listview->highlightItem() != 0);
426 // set an empty model and confirm that items are destroyed
428 ctxt->setContextProperty("testModel", &model2);
430 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
431 QTRY_VERIFY(itemCount == 0);
433 QTRY_COMPARE(listview->highlightResizeSpeed(), 1000.0);
434 QTRY_COMPARE(listview->highlightMoveSpeed(), 1000.0);
442 void tst_QDeclarative1ListView::changed()
444 QDeclarativeView *canvas = createView();
447 model.addItem("Fred", "12345");
448 model.addItem("John", "2345");
449 model.addItem("Bob", "54321");
451 QDeclarativeContext *ctxt = canvas->rootContext();
452 ctxt->setContextProperty("testModel", &model);
454 TestObject *testObject = new TestObject;
455 ctxt->setContextProperty("testObject", testObject);
457 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
458 qApp->processEvents();
460 QDeclarative1Flickable *listview = findItem<QDeclarative1Flickable>(canvas->rootObject(), "list");
461 QTRY_VERIFY(listview != 0);
463 QDeclarativeItem *contentItem = listview->contentItem();
464 QTRY_VERIFY(contentItem != 0);
466 model.modifyItem(1, "Will", "9876");
467 QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
468 QTRY_VERIFY(name != 0);
469 QTRY_COMPARE(name->text(), model.name(1));
470 QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
471 QTRY_VERIFY(number != 0);
472 QTRY_COMPARE(number->text(), model.number(1));
479 void tst_QDeclarative1ListView::inserted()
481 QDeclarativeView *canvas = createView();
484 model.addItem("Fred", "12345");
485 model.addItem("John", "2345");
486 model.addItem("Bob", "54321");
488 QDeclarativeContext *ctxt = canvas->rootContext();
489 ctxt->setContextProperty("testModel", &model);
491 TestObject *testObject = new TestObject;
492 ctxt->setContextProperty("testObject", testObject);
494 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
495 qApp->processEvents();
497 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
498 QTRY_VERIFY(listview != 0);
500 QDeclarativeItem *contentItem = listview->contentItem();
501 QTRY_VERIFY(contentItem != 0);
503 model.insertItem(1, "Will", "9876");
505 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
507 QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
508 QTRY_VERIFY(name != 0);
509 QTRY_COMPARE(name->text(), model.name(1));
510 QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
511 QTRY_VERIFY(number != 0);
512 QTRY_COMPARE(number->text(), model.number(1));
514 // Confirm items positioned correctly
515 for (int i = 0; i < model.count(); ++i) {
516 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
517 QTRY_COMPARE(item->y(), i*20.0);
520 model.insertItem(0, "Foo", "1111"); // zero index, and current item
522 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
523 QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
525 name = findItem<QDeclarative1Text>(contentItem, "textName", 0);
526 QTRY_VERIFY(name != 0);
527 QTRY_COMPARE(name->text(), model.name(0));
528 number = findItem<QDeclarative1Text>(contentItem, "textNumber", 0);
529 QTRY_VERIFY(number != 0);
530 QTRY_COMPARE(number->text(), model.number(0));
532 QTRY_COMPARE(listview->currentIndex(), 1);
534 // Confirm items positioned correctly
535 for (int i = 0; i < model.count(); ++i) {
536 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
537 QTRY_COMPARE(item->y(), i*20.0);
540 for (int i = model.count(); i < 30; ++i)
541 model.insertItem(i, "Hello", QString::number(i));
543 listview->setContentY(80);
545 // Insert item outside visible area
546 model.insertItem(1, "Hello", "1324");
548 QTRY_VERIFY(listview->contentY() == 80);
550 // Confirm items positioned correctly
551 for (int i = 5; i < 5+15; ++i) {
552 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
553 if (!item) qWarning() << "Item" << i << "not found";
555 QTRY_COMPARE(item->y(), i*20.0 - 20.0);
558 // QTRY_COMPARE(listview->contentItemHeight(), model.count() * 20.0);
562 model.insertItem(0, "Hello", "1234");
563 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
565 QCOMPARE(item->y(), 0.);
566 QVERIFY(listview->contentY() == 0);
573 void tst_QDeclarative1ListView::removed(bool animated)
575 QDeclarativeView *canvas = createView();
578 for (int i = 0; i < 50; i++)
579 model.addItem("Item" + QString::number(i), "");
581 QDeclarativeContext *ctxt = canvas->rootContext();
582 ctxt->setContextProperty("testModel", &model);
584 TestObject *testObject = new TestObject;
585 testObject->setAnimate(animated);
586 ctxt->setContextProperty("testObject", testObject);
588 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
589 qApp->processEvents();
591 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
592 QTRY_VERIFY(listview != 0);
594 QDeclarativeItem *contentItem = listview->contentItem();
595 QTRY_VERIFY(contentItem != 0);
598 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
600 QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
601 QTRY_VERIFY(name != 0);
602 QTRY_COMPARE(name->text(), model.name(1));
603 QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
604 QTRY_VERIFY(number != 0);
605 QTRY_COMPARE(number->text(), model.number(1));
607 // Confirm items positioned correctly
608 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
609 for (int i = 0; i < model.count() && i < itemCount; ++i) {
610 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
611 if (!item) qWarning() << "Item" << i << "not found";
613 QTRY_VERIFY(item->y() == i*20);
616 // Remove first item (which is the current item);
617 model.removeItem(0); // post: top item starts at 20
621 name = findItem<QDeclarative1Text>(contentItem, "textName", 0);
622 QTRY_VERIFY(name != 0);
623 QTRY_COMPARE(name->text(), model.name(0));
624 number = findItem<QDeclarative1Text>(contentItem, "textNumber", 0);
625 QTRY_VERIFY(number != 0);
626 QTRY_COMPARE(number->text(), model.number(0));
628 // Confirm items positioned correctly
629 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
630 for (int i = 0; i < model.count() && i < itemCount; ++i) {
631 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
632 if (!item) qWarning() << "Item" << i << "not found";
634 QTRY_COMPARE(item->y(),i*20.0 + 20.0);
637 // Remove items not visible
638 model.removeItem(18);
639 qApp->processEvents();
641 // Confirm items positioned correctly
642 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
643 for (int i = 0; i < model.count() && i < itemCount; ++i) {
644 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
645 if (!item) qWarning() << "Item" << i << "not found";
647 QTRY_COMPARE(item->y(),i*20.0+20.0);
650 // Remove items before visible
651 listview->setContentY(80);
652 listview->setCurrentIndex(10);
654 model.removeItem(1); // post: top item will be at 40
655 qApp->processEvents();
657 // Confirm items positioned correctly
658 for (int i = 2; i < 18; ++i) {
659 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
660 if (!item) qWarning() << "Item" << i << "not found";
662 QTRY_COMPARE(item->y(),40+i*20.0);
665 // Remove current index
666 QTRY_VERIFY(listview->currentIndex() == 9);
667 QDeclarativeItem *oldCurrent = listview->currentItem();
670 QTRY_COMPARE(listview->currentIndex(), 9);
671 QTRY_VERIFY(listview->currentItem() != oldCurrent);
673 listview->setContentY(40); // That's the top now
674 // let transitions settle.
677 // Confirm items positioned correctly
678 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
679 for (int i = 0; i < model.count() && i < itemCount; ++i) {
680 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
681 if (!item) qWarning() << "Item" << i << "not found";
683 QTRY_COMPARE(item->y(),40+i*20.0);
686 // remove current item beyond visible items.
687 listview->setCurrentIndex(20);
688 listview->setContentY(40);
689 model.removeItem(20);
691 QTRY_COMPARE(listview->currentIndex(), 20);
692 QTRY_VERIFY(listview->currentItem() != 0);
694 // remove item before current, but visible
695 listview->setCurrentIndex(8);
696 oldCurrent = listview->currentItem();
699 QTRY_COMPARE(listview->currentIndex(), 7);
700 QTRY_VERIFY(listview->currentItem() == oldCurrent);
702 listview->setContentY(80);
705 // remove all visible items
706 model.removeItems(1, 18);
709 // Confirm items positioned correctly
710 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
711 for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
712 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i+2);
713 if (!item) qWarning() << "Item" << i+2 << "not found";
715 QTRY_COMPARE(item->y(),80+i*20.0);
718 model.removeItems(1, 17);
719 // QTest::qWait(300);
721 model.removeItems(2, 1);
722 model.addItem("New", "1");
724 QTRY_VERIFY(name = findItem<QDeclarative1Text>(contentItem, "textName", model.count()-1));
725 QCOMPARE(name->text(), QString("New"));
727 // Add some more items so that we don't run out
729 for (int i = 0; i < 50; i++)
730 model.addItem("Item" + QString::number(i), "");
733 listview->setCurrentIndex(0);
734 listview->setContentY(30);
736 QTRY_VERIFY(name = findItem<QDeclarative1Text>(contentItem, "textName", 0));
738 // QTBUG-19198 move to end and remove all visible items one at a time.
739 listview->positionViewAtEnd();
740 for (int i = 0; i < 18; ++i)
741 model.removeItems(model.count() - 1, 1);
742 QTRY_VERIFY(findItems<QDeclarativeItem>(contentItem, "wrapper").count() > 16);
749 void tst_QDeclarative1ListView::clear()
751 QDeclarativeView *canvas = createView();
754 for (int i = 0; i < 30; i++)
755 model.addItem("Item" + QString::number(i), "");
757 QDeclarativeContext *ctxt = canvas->rootContext();
758 ctxt->setContextProperty("testModel", &model);
760 TestObject *testObject = new TestObject;
761 ctxt->setContextProperty("testObject", testObject);
763 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
764 qApp->processEvents();
766 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
767 QTRY_VERIFY(listview != 0);
769 QDeclarativeItem *contentItem = listview->contentItem();
770 QTRY_VERIFY(contentItem != 0);
774 QTRY_VERIFY(listview->count() == 0);
775 QTRY_VERIFY(listview->currentItem() == 0);
776 QTRY_VERIFY(listview->contentY() == 0);
777 QVERIFY(listview->currentIndex() == -1);
779 // confirm sanity when adding an item to cleared list
780 model.addItem("New", "1");
781 QTRY_VERIFY(listview->count() == 1);
782 QVERIFY(listview->currentItem() != 0);
783 QVERIFY(listview->currentIndex() == 0);
791 void tst_QDeclarative1ListView::moved()
793 QDeclarativeView *canvas = createView();
796 for (int i = 0; i < 30; i++)
797 model.addItem("Item" + QString::number(i), "");
799 QDeclarativeContext *ctxt = canvas->rootContext();
800 ctxt->setContextProperty("testModel", &model);
802 TestObject *testObject = new TestObject;
803 ctxt->setContextProperty("testObject", testObject);
805 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
806 qApp->processEvents();
808 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
809 QTRY_VERIFY(listview != 0);
811 QDeclarativeItem *contentItem = listview->contentItem();
812 QTRY_VERIFY(contentItem != 0);
814 model.moveItem(1, 4);
816 QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 1);
817 QTRY_VERIFY(name != 0);
818 QTRY_COMPARE(name->text(), model.name(1));
819 QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 1);
820 QTRY_VERIFY(number != 0);
821 QTRY_COMPARE(number->text(), model.number(1));
823 name = findItem<QDeclarative1Text>(contentItem, "textName", 4);
824 QTRY_VERIFY(name != 0);
825 QTRY_COMPARE(name->text(), model.name(4));
826 number = findItem<QDeclarative1Text>(contentItem, "textNumber", 4);
827 QTRY_VERIFY(number != 0);
828 QTRY_COMPARE(number->text(), model.number(4));
830 // Confirm items positioned correctly
831 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
832 for (int i = 0; i < model.count() && i < itemCount; ++i) {
833 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
834 if (!item) qWarning() << "Item" << i << "not found";
836 QTRY_VERIFY(item->y() == i*20);
839 listview->setContentY(80);
841 // move outside visible area
842 model.moveItem(1, 18);
844 // Confirm items positioned correctly and indexes correct
845 for (int i = 3; i < model.count() && i < itemCount; ++i) {
846 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
847 if (!item) qWarning() << "Item" << i << "not found";
849 QTRY_COMPARE(item->y(), i*20.0 + 20);
850 name = findItem<QDeclarative1Text>(contentItem, "textName", i);
851 QTRY_VERIFY(name != 0);
852 QTRY_COMPARE(name->text(), model.name(i));
853 number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
854 QTRY_VERIFY(number != 0);
855 QTRY_COMPARE(number->text(), model.number(i));
858 // move from outside visible into visible
859 model.moveItem(20, 4);
861 // Confirm items positioned correctly and indexes correct
862 for (int i = 3; i < model.count() && i < itemCount; ++i) {
863 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
864 if (!item) qWarning() << "Item" << i << "not found";
866 QTRY_COMPARE(item->y(), i*20.0 + 20);
867 name = findItem<QDeclarative1Text>(contentItem, "textName", i);
868 QTRY_VERIFY(name != 0);
869 QTRY_COMPARE(name->text(), model.name(i));
870 number = findItem<QDeclarative1Text>(contentItem, "textNumber", i);
871 QTRY_VERIFY(number != 0);
872 QTRY_COMPARE(number->text(), model.number(i));
879 void tst_QDeclarative1ListView::enforceRange()
881 QDeclarativeView *canvas = createView();
884 for (int i = 0; i < 30; i++)
885 model.addItem("Item" + QString::number(i), "");
887 QDeclarativeContext *ctxt = canvas->rootContext();
888 ctxt->setContextProperty("testModel", &model);
890 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-enforcerange.qml"));
891 qApp->processEvents();
893 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
894 QTRY_VERIFY(listview != 0);
896 QTRY_COMPARE(listview->preferredHighlightBegin(), 100.0);
897 QTRY_COMPARE(listview->preferredHighlightEnd(), 100.0);
898 QTRY_COMPARE(listview->highlightRangeMode(), QDeclarative1ListView::StrictlyEnforceRange);
900 QDeclarativeItem *contentItem = listview->contentItem();
901 QTRY_VERIFY(contentItem != 0);
903 // view should be positioned at the top of the range.
904 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
906 QTRY_COMPARE(listview->contentY(), -100.0);
908 QDeclarative1Text *name = findItem<QDeclarative1Text>(contentItem, "textName", 0);
909 QTRY_VERIFY(name != 0);
910 QTRY_COMPARE(name->text(), model.name(0));
911 QDeclarative1Text *number = findItem<QDeclarative1Text>(contentItem, "textNumber", 0);
912 QTRY_VERIFY(number != 0);
913 QTRY_COMPARE(number->text(), model.number(0));
915 // Check currentIndex is updated when contentItem moves
916 listview->setContentY(20);
918 QTRY_COMPARE(listview->currentIndex(), 6);
922 for (int i = 0; i < 5; i++)
923 model2.addItem("Item" + QString::number(i), "");
925 ctxt->setContextProperty("testModel", &model2);
926 QCOMPARE(listview->count(), 5);
931 void tst_QDeclarative1ListView::spacing()
933 QDeclarativeView *canvas = createView();
936 for (int i = 0; i < 30; i++)
937 model.addItem("Item" + QString::number(i), "");
939 QDeclarativeContext *ctxt = canvas->rootContext();
940 ctxt->setContextProperty("testModel", &model);
942 TestObject *testObject = new TestObject;
943 ctxt->setContextProperty("testObject", testObject);
945 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
946 qApp->processEvents();
948 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
949 QTRY_VERIFY(listview != 0);
951 QDeclarativeItem *contentItem = listview->contentItem();
952 QTRY_VERIFY(contentItem != 0);
954 // Confirm items positioned correctly
955 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
956 for (int i = 0; i < model.count() && i < itemCount; ++i) {
957 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
958 if (!item) qWarning() << "Item" << i << "not found";
960 QTRY_VERIFY(item->y() == i*20);
963 listview->setSpacing(10);
964 QTRY_VERIFY(listview->spacing() == 10);
966 // Confirm items positioned correctly
967 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
968 for (int i = 0; i < model.count() && i < itemCount; ++i) {
969 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
970 if (!item) qWarning() << "Item" << i << "not found";
972 QTRY_VERIFY(item->y() == i*30);
975 listview->setSpacing(0);
977 // Confirm items positioned correctly
978 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
979 for (int i = 0; i < model.count() && i < itemCount; ++i) {
980 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
981 if (!item) qWarning() << "Item" << i << "not found";
983 QTRY_COMPARE(item->y(), i*20.0);
990 void tst_QDeclarative1ListView::sections()
992 QDeclarativeView *canvas = createView();
995 for (int i = 0; i < 30; i++)
996 model.addItem("Item" + QString::number(i), QString::number(i/5));
998 QDeclarativeContext *ctxt = canvas->rootContext();
999 ctxt->setContextProperty("testModel", &model);
1001 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-sections.qml"));
1002 qApp->processEvents();
1004 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1005 QTRY_VERIFY(listview != 0);
1007 QDeclarativeItem *contentItem = listview->contentItem();
1008 QTRY_VERIFY(contentItem != 0);
1010 // Confirm items positioned correctly
1011 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1012 for (int i = 0; i < model.count() && i < itemCount; ++i) {
1013 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1015 QTRY_COMPARE(item->y(), qreal(i*20 + ((i+4)/5) * 20));
1016 QDeclarative1Text *next = findItem<QDeclarative1Text>(item, "nextSection");
1017 QCOMPARE(next->text().toInt(), (i+1)/5);
1020 QSignalSpy currentSectionChangedSpy(listview, SIGNAL(currentSectionChanged()));
1022 // Remove section boundary
1023 model.removeItem(5);
1025 // New section header created
1026 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 5);
1028 QTRY_COMPARE(item->height(), 40.0);
1030 model.insertItem(3, "New Item", "0");
1032 // Section header moved
1033 item = findItem<QDeclarativeItem>(contentItem, "wrapper", 5);
1035 QTRY_COMPARE(item->height(), 20.0);
1037 item = findItem<QDeclarativeItem>(contentItem, "wrapper", 6);
1039 QTRY_COMPARE(item->height(), 40.0);
1041 // insert item which will become a section header
1042 model.insertItem(6, "Replace header", "1");
1044 item = findItem<QDeclarativeItem>(contentItem, "wrapper", 6);
1046 QTRY_COMPARE(item->height(), 40.0);
1048 item = findItem<QDeclarativeItem>(contentItem, "wrapper", 7);
1050 QTRY_COMPARE(item->height(), 20.0);
1052 QTRY_COMPARE(listview->currentSection(), QString("0"));
1054 listview->setContentY(140);
1055 QTRY_COMPARE(listview->currentSection(), QString("1"));
1057 QTRY_COMPARE(currentSectionChangedSpy.count(), 1);
1059 listview->setContentY(20);
1060 QTRY_COMPARE(listview->currentSection(), QString("0"));
1062 QTRY_COMPARE(currentSectionChangedSpy.count(), 2);
1064 item = findItem<QDeclarativeItem>(contentItem, "wrapper", 1);
1066 QTRY_COMPARE(item->height(), 20.0);
1068 // check that headers change when item changes
1069 listview->setContentY(0);
1070 model.modifyItem(0, "changed", "2");
1072 item = findItem<QDeclarativeItem>(contentItem, "wrapper", 1);
1074 QTRY_COMPARE(item->height(), 40.0);
1079 void tst_QDeclarative1ListView::sectionsDelegate()
1081 QDeclarativeView *canvas = createView();
1084 for (int i = 0; i < 30; i++)
1085 model.addItem("Item" + QString::number(i), QString::number(i/5));
1087 QDeclarativeContext *ctxt = canvas->rootContext();
1088 ctxt->setContextProperty("testModel", &model);
1090 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-sections_delegate.qml"));
1091 qApp->processEvents();
1093 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1094 QTRY_VERIFY(listview != 0);
1096 QDeclarativeItem *contentItem = listview->contentItem();
1097 QTRY_VERIFY(contentItem != 0);
1099 // Confirm items positioned correctly
1100 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1101 for (int i = 0; i < model.count() && i < itemCount; ++i) {
1102 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1104 QTRY_COMPARE(item->y(), qreal(i*20 + ((i+5)/5) * 20));
1105 QDeclarative1Text *next = findItem<QDeclarative1Text>(item, "nextSection");
1106 QCOMPARE(next->text().toInt(), (i+1)/5);
1109 for (int i = 0; i < 3; ++i) {
1110 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "sect_" + QString::number(i));
1112 QTRY_COMPARE(item->y(), qreal(i*20*6));
1115 model.modifyItem(0, "One", "aaa");
1116 model.modifyItem(1, "Two", "aaa");
1117 model.modifyItem(2, "Three", "aaa");
1118 model.modifyItem(3, "Four", "aaa");
1119 model.modifyItem(4, "Five", "aaa");
1121 for (int i = 0; i < 3; ++i) {
1122 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem,
1123 "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
1125 QTRY_COMPARE(item->y(), qreal(i*20*6));
1128 // remove section boundary
1129 model.removeItem(5);
1130 qApp->processEvents();
1131 for (int i = 0; i < 3; ++i) {
1132 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem,
1133 "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
1138 QList<QDeclarativeItem*> items = findItems<QDeclarativeItem>(contentItem, "sect_1");
1139 QCOMPARE(items.count(), 1);
1142 model.modifyItem(0, "One", "aaa");
1143 model.modifyItem(1, "One", "aaa");
1144 model.modifyItem(2, "One", "aaa");
1145 model.modifyItem(3, "Four", "aaa");
1146 model.modifyItem(4, "Four", "aaa");
1147 model.modifyItem(5, "Four", "aaa");
1148 model.modifyItem(6, "Five", "aaa");
1149 model.modifyItem(7, "Five", "aaa");
1150 model.modifyItem(8, "Five", "aaa");
1151 model.modifyItem(9, "Two", "aaa");
1152 model.modifyItem(10, "Two", "aaa");
1153 model.modifyItem(11, "Two", "aaa");
1154 QTRY_COMPARE(findItems<QDeclarativeItem>(contentItem, "sect_aaa").count(), 1);
1155 canvas->rootObject()->setProperty("sectionProperty", "name");
1156 // ensure view has settled.
1157 QTRY_COMPARE(findItems<QDeclarativeItem>(contentItem, "sect_Four").count(), 1);
1158 for (int i = 0; i < 4; ++i) {
1159 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem,
1160 "sect_" + model.name(i*3));
1162 QTRY_COMPARE(item->y(), qreal(i*20*4));
1166 model.removeItems(10, 20);
1167 // ensure view has settled.
1168 QTRY_COMPARE(findItems<QDeclarativeItem>(contentItem, "wrapper").count(), 10);
1169 // Drag view up beyond bounds
1170 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20,20)));
1172 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,0)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1173 QApplication::sendEvent(canvas->viewport(), &mv);
1176 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,-50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1177 QApplication::sendEvent(canvas->viewport(), &mv);
1180 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,-200)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1181 QApplication::sendEvent(canvas->viewport(), &mv);
1183 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20,-200)));
1184 // view should settle back at 0
1185 QTRY_COMPARE(listview->contentY(), 0.0);
1190 void tst_QDeclarative1ListView::currentIndex()
1193 for (int i = 0; i < 30; i++)
1194 model.addItem("Item" + QString::number(i), QString::number(i));
1196 QDeclarativeView *canvas = new QDeclarativeView(0);
1197 canvas->setFixedSize(240,320);
1199 QDeclarativeContext *ctxt = canvas->rootContext();
1200 ctxt->setContextProperty("testModel", &model);
1201 ctxt->setContextProperty("testWrap", QVariant(false));
1203 QString filename(SRCDIR "/data/listview-initCurrent.qml");
1204 canvas->setSource(QUrl::fromLocalFile(filename));
1206 qApp->processEvents();
1208 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1209 QTRY_VERIFY(listview != 0);
1211 QDeclarativeItem *contentItem = listview->contentItem();
1212 QTRY_VERIFY(contentItem != 0);
1214 // current item should be 20th item at startup
1215 // and current item should be in view
1216 QCOMPARE(listview->currentIndex(), 20);
1217 QCOMPARE(listview->contentY(), 100.0);
1218 QCOMPARE(listview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 20));
1219 QCOMPARE(listview->highlightItem()->y(), listview->currentItem()->y());
1222 listview->setCurrentIndex(0);
1223 QCOMPARE(listview->currentIndex(), 0);
1224 // confirm that the velocity is updated
1225 QTRY_VERIFY(listview->verticalVelocity() != 0.0);
1227 listview->incrementCurrentIndex();
1228 QCOMPARE(listview->currentIndex(), 1);
1229 listview->decrementCurrentIndex();
1230 QCOMPARE(listview->currentIndex(), 0);
1232 listview->decrementCurrentIndex();
1233 QCOMPARE(listview->currentIndex(), 0);
1236 ctxt->setContextProperty("testWrap", QVariant(true));
1237 QVERIFY(listview->isWrapEnabled());
1239 listview->decrementCurrentIndex();
1240 QCOMPARE(listview->currentIndex(), model.count()-1);
1242 QTRY_COMPARE(listview->contentY(), 280.0);
1244 listview->incrementCurrentIndex();
1245 QCOMPARE(listview->currentIndex(), 0);
1247 QTRY_COMPARE(listview->contentY(), 0.0);
1251 qApp->setActiveWindow(canvas);
1253 // to be safe and avoid failing setFocus with window managers
1254 qt_x11_wait_for_window_manager(canvas);
1256 QTRY_VERIFY(canvas->hasFocus());
1257 QTRY_VERIFY(canvas->scene()->hasFocus());
1258 qApp->processEvents();
1260 QTest::keyClick(canvas, Qt::Key_Down);
1261 QCOMPARE(listview->currentIndex(), 1);
1263 QTest::keyClick(canvas, Qt::Key_Up);
1264 QCOMPARE(listview->currentIndex(), 0);
1266 // turn off auto highlight
1267 listview->setHighlightFollowsCurrentItem(false);
1268 QVERIFY(listview->highlightFollowsCurrentItem() == false);
1270 QVERIFY(listview->highlightItem());
1271 qreal hlPos = listview->highlightItem()->y();
1273 listview->setCurrentIndex(4);
1274 QTRY_COMPARE(listview->highlightItem()->y(), hlPos);
1276 // insert item before currentIndex
1277 listview->setCurrentIndex(28);
1278 model.insertItem(0, "Foo", "1111");
1279 QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
1281 // check removing highlight by setting currentIndex to -1;
1282 listview->setCurrentIndex(-1);
1284 QCOMPARE(listview->currentIndex(), -1);
1285 QVERIFY(!listview->highlightItem());
1286 QVERIFY(!listview->currentItem());
1291 void tst_QDeclarative1ListView::noCurrentIndex()
1294 for (int i = 0; i < 30; i++)
1295 model.addItem("Item" + QString::number(i), QString::number(i));
1297 QDeclarativeView *canvas = new QDeclarativeView(0);
1298 canvas->setFixedSize(240,320);
1300 QDeclarativeContext *ctxt = canvas->rootContext();
1301 ctxt->setContextProperty("testModel", &model);
1303 QString filename(SRCDIR "/data/listview-noCurrent.qml");
1304 canvas->setSource(QUrl::fromLocalFile(filename));
1306 qApp->processEvents();
1308 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1309 QTRY_VERIFY(listview != 0);
1311 QDeclarativeItem *contentItem = listview->contentItem();
1312 QTRY_VERIFY(contentItem != 0);
1314 // current index should be -1 at startup
1315 // and we should not have a currentItem or highlightItem
1316 QCOMPARE(listview->currentIndex(), -1);
1317 QCOMPARE(listview->contentY(), 0.0);
1318 QVERIFY(!listview->highlightItem());
1319 QVERIFY(!listview->currentItem());
1321 listview->setCurrentIndex(2);
1322 QCOMPARE(listview->currentIndex(), 2);
1323 QVERIFY(listview->highlightItem());
1324 QVERIFY(listview->currentItem());
1329 void tst_QDeclarative1ListView::itemList()
1331 QDeclarativeView *canvas = createView();
1333 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/itemlist.qml"));
1334 qApp->processEvents();
1336 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "view");
1337 QTRY_VERIFY(listview != 0);
1339 QDeclarativeItem *contentItem = listview->contentItem();
1340 QTRY_VERIFY(contentItem != 0);
1342 QDeclarative1VisualItemModel *model = canvas->rootObject()->findChild<QDeclarative1VisualItemModel*>("itemModel");
1343 QTRY_VERIFY(model != 0);
1345 QTRY_VERIFY(model->count() == 3);
1346 QTRY_COMPARE(listview->currentIndex(), 0);
1348 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "item1");
1350 QTRY_COMPARE(item->x(), 0.0);
1351 QCOMPARE(item->height(), listview->height());
1353 QDeclarative1Text *text = findItem<QDeclarative1Text>(contentItem, "text1");
1355 QTRY_COMPARE(text->text(), QLatin1String("index: 0"));
1357 listview->setCurrentIndex(2);
1359 item = findItem<QDeclarativeItem>(contentItem, "item3");
1361 QTRY_COMPARE(item->x(), 480.0);
1363 text = findItem<QDeclarative1Text>(contentItem, "text3");
1365 QTRY_COMPARE(text->text(), QLatin1String("index: 2"));
1370 void tst_QDeclarative1ListView::cacheBuffer()
1372 QDeclarativeView *canvas = createView();
1375 for (int i = 0; i < 30; i++)
1376 model.addItem("Item" + QString::number(i), "");
1378 QDeclarativeContext *ctxt = canvas->rootContext();
1379 ctxt->setContextProperty("testModel", &model);
1381 TestObject *testObject = new TestObject;
1382 ctxt->setContextProperty("testObject", testObject);
1384 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
1385 qApp->processEvents();
1387 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1388 QTRY_VERIFY(listview != 0);
1390 QDeclarativeItem *contentItem = listview->contentItem();
1391 QTRY_VERIFY(contentItem != 0);
1392 QTRY_VERIFY(listview->delegate() != 0);
1393 QTRY_VERIFY(listview->model() != 0);
1394 QTRY_VERIFY(listview->highlight() != 0);
1396 // Confirm items positioned correctly
1397 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1398 for (int i = 0; i < model.count() && i < itemCount; ++i) {
1399 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1400 if (!item) qWarning() << "Item" << i << "not found";
1402 QTRY_VERIFY(item->y() == i*20);
1405 testObject->setCacheBuffer(400);
1406 QTRY_VERIFY(listview->cacheBuffer() == 400);
1408 int newItemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1409 QTRY_VERIFY(newItemCount > itemCount);
1411 // Confirm items positioned correctly
1412 for (int i = 0; i < model.count() && i < newItemCount; ++i) {
1413 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1414 if (!item) qWarning() << "Item" << i << "not found";
1416 QTRY_VERIFY(item->y() == i*20);
1423 void tst_QDeclarative1ListView::positionViewAtIndex()
1425 QDeclarativeView *canvas = createView();
1428 for (int i = 0; i < 40; i++)
1429 model.addItem("Item" + QString::number(i), "");
1431 QDeclarativeContext *ctxt = canvas->rootContext();
1432 ctxt->setContextProperty("testModel", &model);
1434 TestObject *testObject = new TestObject;
1435 ctxt->setContextProperty("testObject", testObject);
1437 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
1438 qApp->processEvents();
1440 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1441 QTRY_VERIFY(listview != 0);
1443 QDeclarativeItem *contentItem = listview->contentItem();
1444 QTRY_VERIFY(contentItem != 0);
1446 // Confirm items positioned correctly
1447 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1448 for (int i = 0; i < model.count() && i < itemCount; ++i) {
1449 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1450 if (!item) qWarning() << "Item" << i << "not found";
1452 QTRY_COMPARE(item->y(), i*20.);
1455 // Position on a currently visible item
1456 listview->positionViewAtIndex(3, QDeclarative1ListView::Beginning);
1457 QTRY_COMPARE(listview->contentY(), 60.);
1459 // Confirm items positioned correctly
1460 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1461 for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
1462 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1463 if (!item) qWarning() << "Item" << i << "not found";
1465 QTRY_COMPARE(item->y(), i*20.);
1468 // Position on an item beyond the visible items
1469 listview->positionViewAtIndex(22, QDeclarative1ListView::Beginning);
1470 QTRY_COMPARE(listview->contentY(), 440.);
1472 // Confirm items positioned correctly
1473 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1474 for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
1475 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1476 if (!item) qWarning() << "Item" << i << "not found";
1478 QTRY_COMPARE(item->y(), i*20.);
1481 // Position on an item that would leave empty space if positioned at the top
1482 listview->positionViewAtIndex(28, QDeclarative1ListView::Beginning);
1483 QTRY_COMPARE(listview->contentY(), 480.);
1485 // Confirm items positioned correctly
1486 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1487 for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
1488 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1489 if (!item) qWarning() << "Item" << i << "not found";
1491 QTRY_COMPARE(item->y(), i*20.);
1494 // Position at the beginning again
1495 listview->positionViewAtIndex(0, QDeclarative1ListView::Beginning);
1496 QTRY_COMPARE(listview->contentY(), 0.);
1498 // Confirm items positioned correctly
1499 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1500 for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
1501 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1502 if (!item) qWarning() << "Item" << i << "not found";
1504 QTRY_COMPARE(item->y(), i*20.);
1507 // Position at End using last index
1508 listview->positionViewAtIndex(model.count()-1, QDeclarative1ListView::End);
1509 QTRY_COMPARE(listview->contentY(), 480.);
1511 // Confirm items positioned correctly
1512 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1513 for (int i = 24; i < model.count(); ++i) {
1514 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1515 if (!item) qWarning() << "Item" << i << "not found";
1517 QTRY_COMPARE(item->y(), i*20.);
1521 listview->positionViewAtIndex(20, QDeclarative1ListView::End);
1522 QTRY_COMPARE(listview->contentY(), 100.);
1524 // Position in Center
1525 listview->positionViewAtIndex(15, QDeclarative1ListView::Center);
1526 QTRY_COMPARE(listview->contentY(), 150.);
1528 // Ensure at least partially visible
1529 listview->positionViewAtIndex(15, QDeclarative1ListView::Visible);
1530 QTRY_COMPARE(listview->contentY(), 150.);
1532 listview->setContentY(302);
1533 listview->positionViewAtIndex(15, QDeclarative1ListView::Visible);
1534 QTRY_COMPARE(listview->contentY(), 302.);
1536 listview->setContentY(320);
1537 listview->positionViewAtIndex(15, QDeclarative1ListView::Visible);
1538 QTRY_COMPARE(listview->contentY(), 300.);
1540 listview->setContentY(85);
1541 listview->positionViewAtIndex(20, QDeclarative1ListView::Visible);
1542 QTRY_COMPARE(listview->contentY(), 85.);
1544 listview->setContentY(75);
1545 listview->positionViewAtIndex(20, QDeclarative1ListView::Visible);
1546 QTRY_COMPARE(listview->contentY(), 100.);
1548 // Ensure completely visible
1549 listview->setContentY(120);
1550 listview->positionViewAtIndex(20, QDeclarative1ListView::Contain);
1551 QTRY_COMPARE(listview->contentY(), 120.);
1553 listview->setContentY(302);
1554 listview->positionViewAtIndex(15, QDeclarative1ListView::Contain);
1555 QTRY_COMPARE(listview->contentY(), 300.);
1557 listview->setContentY(85);
1558 listview->positionViewAtIndex(20, QDeclarative1ListView::Contain);
1559 QTRY_COMPARE(listview->contentY(), 100.);
1561 // positionAtBeginnging
1562 listview->positionViewAtBeginning();
1563 QTRY_COMPARE(listview->contentY(), 0.);
1565 listview->setContentY(80);
1566 canvas->rootObject()->setProperty("showHeader", true);
1567 listview->positionViewAtBeginning();
1568 QTRY_COMPARE(listview->contentY(), -30.);
1571 listview->positionViewAtEnd();
1572 QTRY_COMPARE(listview->contentY(), 480.); // 40*20 - 320
1574 listview->setContentY(80);
1575 canvas->rootObject()->setProperty("showFooter", true);
1576 listview->positionViewAtEnd();
1577 QTRY_COMPARE(listview->contentY(), 510.);
1583 void tst_QDeclarative1ListView::resetModel()
1585 QDeclarativeView *canvas = createView();
1587 QStringList strings;
1588 strings << "one" << "two" << "three";
1589 QStringListModel model(strings);
1591 QDeclarativeContext *ctxt = canvas->rootContext();
1592 ctxt->setContextProperty("testModel", &model);
1594 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaylist.qml"));
1595 qApp->processEvents();
1597 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1598 QTRY_VERIFY(listview != 0);
1600 QDeclarativeItem *contentItem = listview->contentItem();
1601 QTRY_VERIFY(contentItem != 0);
1603 QTRY_COMPARE(listview->count(), model.rowCount());
1605 for (int i = 0; i < model.rowCount(); ++i) {
1606 QDeclarative1Text *display = findItem<QDeclarative1Text>(contentItem, "displayText", i);
1607 QTRY_VERIFY(display != 0);
1608 QTRY_COMPARE(display->text(), strings.at(i));
1612 strings << "four" << "five" << "six" << "seven";
1613 model.setStringList(strings);
1615 QTRY_COMPARE(listview->count(), model.rowCount());
1617 for (int i = 0; i < model.rowCount(); ++i) {
1618 QDeclarative1Text *display = findItem<QDeclarative1Text>(contentItem, "displayText", i);
1619 QTRY_VERIFY(display != 0);
1620 QTRY_COMPARE(display->text(), strings.at(i));
1626 void tst_QDeclarative1ListView::propertyChanges()
1628 QDeclarativeView *canvas = createView();
1629 QTRY_VERIFY(canvas);
1630 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1632 QDeclarative1ListView *listView = canvas->rootObject()->findChild<QDeclarative1ListView*>("listView");
1633 QTRY_VERIFY(listView);
1635 QSignalSpy highlightFollowsCurrentItemSpy(listView, SIGNAL(highlightFollowsCurrentItemChanged()));
1636 QSignalSpy preferredHighlightBeginSpy(listView, SIGNAL(preferredHighlightBeginChanged()));
1637 QSignalSpy preferredHighlightEndSpy(listView, SIGNAL(preferredHighlightEndChanged()));
1638 QSignalSpy highlightRangeModeSpy(listView, SIGNAL(highlightRangeModeChanged()));
1639 QSignalSpy keyNavigationWrapsSpy(listView, SIGNAL(keyNavigationWrapsChanged()));
1640 QSignalSpy cacheBufferSpy(listView, SIGNAL(cacheBufferChanged()));
1641 QSignalSpy snapModeSpy(listView, SIGNAL(snapModeChanged()));
1643 QTRY_COMPARE(listView->highlightFollowsCurrentItem(), true);
1644 QTRY_COMPARE(listView->preferredHighlightBegin(), 0.0);
1645 QTRY_COMPARE(listView->preferredHighlightEnd(), 0.0);
1646 QTRY_COMPARE(listView->highlightRangeMode(), QDeclarative1ListView::ApplyRange);
1647 QTRY_COMPARE(listView->isWrapEnabled(), true);
1648 QTRY_COMPARE(listView->cacheBuffer(), 10);
1649 QTRY_COMPARE(listView->snapMode(), QDeclarative1ListView::SnapToItem);
1651 listView->setHighlightFollowsCurrentItem(false);
1652 listView->setPreferredHighlightBegin(1.0);
1653 listView->setPreferredHighlightEnd(1.0);
1654 listView->setHighlightRangeMode(QDeclarative1ListView::StrictlyEnforceRange);
1655 listView->setWrapEnabled(false);
1656 listView->setCacheBuffer(3);
1657 listView->setSnapMode(QDeclarative1ListView::SnapOneItem);
1659 QTRY_COMPARE(listView->highlightFollowsCurrentItem(), false);
1660 QTRY_COMPARE(listView->preferredHighlightBegin(), 1.0);
1661 QTRY_COMPARE(listView->preferredHighlightEnd(), 1.0);
1662 QTRY_COMPARE(listView->highlightRangeMode(), QDeclarative1ListView::StrictlyEnforceRange);
1663 QTRY_COMPARE(listView->isWrapEnabled(), false);
1664 QTRY_COMPARE(listView->cacheBuffer(), 3);
1665 QTRY_COMPARE(listView->snapMode(), QDeclarative1ListView::SnapOneItem);
1667 QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1);
1668 QTRY_COMPARE(preferredHighlightBeginSpy.count(),1);
1669 QTRY_COMPARE(preferredHighlightEndSpy.count(),1);
1670 QTRY_COMPARE(highlightRangeModeSpy.count(),1);
1671 QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1672 QTRY_COMPARE(cacheBufferSpy.count(),1);
1673 QTRY_COMPARE(snapModeSpy.count(),1);
1675 listView->setHighlightFollowsCurrentItem(false);
1676 listView->setPreferredHighlightBegin(1.0);
1677 listView->setPreferredHighlightEnd(1.0);
1678 listView->setHighlightRangeMode(QDeclarative1ListView::StrictlyEnforceRange);
1679 listView->setWrapEnabled(false);
1680 listView->setCacheBuffer(3);
1681 listView->setSnapMode(QDeclarative1ListView::SnapOneItem);
1683 QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1);
1684 QTRY_COMPARE(preferredHighlightBeginSpy.count(),1);
1685 QTRY_COMPARE(preferredHighlightEndSpy.count(),1);
1686 QTRY_COMPARE(highlightRangeModeSpy.count(),1);
1687 QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
1688 QTRY_COMPARE(cacheBufferSpy.count(),1);
1689 QTRY_COMPARE(snapModeSpy.count(),1);
1694 void tst_QDeclarative1ListView::componentChanges()
1696 QDeclarativeView *canvas = createView();
1697 QTRY_VERIFY(canvas);
1698 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1700 QDeclarative1ListView *listView = canvas->rootObject()->findChild<QDeclarative1ListView*>("listView");
1701 QTRY_VERIFY(listView);
1703 QDeclarativeComponent component(canvas->engine());
1704 component.setData("import QtQuick 1.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
1706 QDeclarativeComponent delegateComponent(canvas->engine());
1707 delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
1709 QSignalSpy highlightSpy(listView, SIGNAL(highlightChanged()));
1710 QSignalSpy delegateSpy(listView, SIGNAL(delegateChanged()));
1711 QSignalSpy headerSpy(listView, SIGNAL(headerChanged()));
1712 QSignalSpy footerSpy(listView, SIGNAL(footerChanged()));
1714 listView->setHighlight(&component);
1715 listView->setHeader(&component);
1716 listView->setFooter(&component);
1717 listView->setDelegate(&delegateComponent);
1719 QTRY_COMPARE(listView->highlight(), &component);
1720 QTRY_COMPARE(listView->header(), &component);
1721 QTRY_COMPARE(listView->footer(), &component);
1722 QTRY_COMPARE(listView->delegate(), &delegateComponent);
1724 QTRY_COMPARE(highlightSpy.count(),1);
1725 QTRY_COMPARE(delegateSpy.count(),1);
1726 QTRY_COMPARE(headerSpy.count(),1);
1727 QTRY_COMPARE(footerSpy.count(),1);
1729 listView->setHighlight(&component);
1730 listView->setHeader(&component);
1731 listView->setFooter(&component);
1732 listView->setDelegate(&delegateComponent);
1734 QTRY_COMPARE(highlightSpy.count(),1);
1735 QTRY_COMPARE(delegateSpy.count(),1);
1736 QTRY_COMPARE(headerSpy.count(),1);
1737 QTRY_COMPARE(footerSpy.count(),1);
1742 void tst_QDeclarative1ListView::modelChanges()
1744 QDeclarativeView *canvas = createView();
1745 QTRY_VERIFY(canvas);
1746 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
1748 QDeclarative1ListView *listView = canvas->rootObject()->findChild<QDeclarative1ListView*>("listView");
1749 QTRY_VERIFY(listView);
1751 QObject *alternateModel = canvas->rootObject()->findChild<QObject*>("alternateModel");
1752 QTRY_VERIFY(alternateModel);
1753 QVariant modelVariant = QVariant::fromValue(alternateModel);
1754 QSignalSpy modelSpy(listView, SIGNAL(modelChanged()));
1756 listView->setModel(modelVariant);
1757 QTRY_COMPARE(listView->model(), modelVariant);
1758 QTRY_COMPARE(modelSpy.count(),1);
1760 listView->setModel(modelVariant);
1761 QTRY_COMPARE(modelSpy.count(),1);
1763 listView->setModel(QVariant());
1764 QTRY_COMPARE(modelSpy.count(),2);
1769 void tst_QDeclarative1ListView::QTBUG_9791()
1771 QDeclarativeView *canvas = createView();
1773 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/strictlyenforcerange.qml"));
1774 qApp->processEvents();
1776 QDeclarative1ListView *listview = qobject_cast<QDeclarative1ListView*>(canvas->rootObject());
1777 QTRY_VERIFY(listview != 0);
1779 QDeclarativeItem *contentItem = listview->contentItem();
1780 QTRY_VERIFY(contentItem != 0);
1781 QTRY_VERIFY(listview->delegate() != 0);
1782 QTRY_VERIFY(listview->model() != 0);
1784 QMetaObject::invokeMethod(listview, "fillModel");
1785 qApp->processEvents();
1787 // Confirm items positioned correctly
1788 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1789 QCOMPARE(itemCount, 3);
1791 for (int i = 0; i < itemCount; ++i) {
1792 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1793 if (!item) qWarning() << "Item" << i << "not found";
1795 QTRY_COMPARE(item->x(), i*300.0);
1798 // check that view is positioned correctly
1799 QTRY_COMPARE(listview->contentX(), 590.0);
1804 void tst_QDeclarative1ListView::manualHighlight()
1806 QDeclarativeView *canvas = new QDeclarativeView(0);
1807 canvas->setFixedSize(240,320);
1809 QString filename(SRCDIR "/data/manual-highlight.qml");
1810 canvas->setSource(QUrl::fromLocalFile(filename));
1812 qApp->processEvents();
1814 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1815 QTRY_VERIFY(listview != 0);
1817 QDeclarativeItem *contentItem = listview->contentItem();
1818 QTRY_VERIFY(contentItem != 0);
1820 QTRY_COMPARE(listview->currentIndex(), 0);
1821 QTRY_COMPARE(listview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0));
1822 QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
1824 listview->setCurrentIndex(2);
1826 QTRY_COMPARE(listview->currentIndex(), 2);
1827 QTRY_COMPARE(listview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2));
1828 QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
1831 listview->positionViewAtIndex(3, QDeclarative1ListView::Contain);
1833 QTRY_COMPARE(listview->currentIndex(), 2);
1834 QTRY_COMPARE(listview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2));
1835 QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
1840 void tst_QDeclarative1ListView::QTBUG_11105()
1842 QDeclarativeView *canvas = createView();
1845 for (int i = 0; i < 30; i++)
1846 model.addItem("Item" + QString::number(i), "");
1848 QDeclarativeContext *ctxt = canvas->rootContext();
1849 ctxt->setContextProperty("testModel", &model);
1851 TestObject *testObject = new TestObject;
1852 ctxt->setContextProperty("testObject", testObject);
1854 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
1855 qApp->processEvents();
1857 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1858 QTRY_VERIFY(listview != 0);
1860 QDeclarativeItem *contentItem = listview->contentItem();
1861 QTRY_VERIFY(contentItem != 0);
1863 // Confirm items positioned correctly
1864 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1865 for (int i = 0; i < model.count() && i < itemCount; ++i) {
1866 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
1867 if (!item) qWarning() << "Item" << i << "not found";
1869 QTRY_VERIFY(item->y() == i*20);
1872 listview->positionViewAtIndex(20, QDeclarative1ListView::Beginning);
1873 QCOMPARE(listview->contentY(), 280.);
1876 for (int i = 0; i < 5; i++)
1877 model2.addItem("Item" + QString::number(i), "");
1879 ctxt->setContextProperty("testModel", &model2);
1881 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
1882 QCOMPARE(itemCount, 5);
1888 void tst_QDeclarative1ListView::header()
1891 QDeclarativeView *canvas = createView();
1894 for (int i = 0; i < 30; i++)
1895 model.addItem("Item" + QString::number(i), "");
1897 QDeclarativeContext *ctxt = canvas->rootContext();
1898 ctxt->setContextProperty("testModel", &model);
1900 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
1901 qApp->processEvents();
1903 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1904 QTRY_VERIFY(listview != 0);
1906 QDeclarativeItem *contentItem = listview->contentItem();
1907 QTRY_VERIFY(contentItem != 0);
1909 QDeclarative1Text *header = findItem<QDeclarative1Text>(contentItem, "header");
1911 QCOMPARE(header->y(), 0.0);
1912 QCOMPARE(header->height(), 20.0);
1914 QCOMPARE(listview->contentY(), 0.0);
1917 QTRY_COMPARE(header->y(), 0.0);
1919 for (int i = 0; i < 30; i++)
1920 model.addItem("Item" + QString::number(i), "");
1922 QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
1924 header = findItem<QDeclarative1Text>(contentItem, "header");
1926 header = findItem<QDeclarative1Text>(contentItem, "header2");
1929 QCOMPARE(header->y(), 10.0);
1930 QCOMPARE(header->height(), 10.0);
1931 QCOMPARE(listview->contentY(), 10.0);
1936 QDeclarativeView *canvas = createView();
1940 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header1.qml"));
1941 qApp->processEvents();
1943 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1944 QTRY_VERIFY(listview != 0);
1946 QDeclarativeItem *contentItem = listview->contentItem();
1947 QTRY_VERIFY(contentItem != 0);
1949 QDeclarative1Text *header = findItem<QDeclarative1Text>(contentItem, "header");
1951 QCOMPARE(header->y(), 0.0);
1953 QCOMPARE(listview->contentY(), 0.0);
1956 QTRY_COMPARE(header->y(), 0.0);
1962 QDeclarativeView *canvas = createView();
1966 QDeclarativeContext *ctxt = canvas->rootContext();
1967 ctxt->setContextProperty("testModel", &model);
1969 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
1970 qApp->processEvents();
1972 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
1973 QTRY_VERIFY(listview != 0);
1975 QDeclarativeItem *contentItem = listview->contentItem();
1976 QTRY_VERIFY(contentItem != 0);
1978 QDeclarative1Text *header = findItem<QDeclarative1Text>(contentItem, "header");
1981 header->setHeight(500);
1983 model.addItem("Item 0", "");
1985 header->setHeight(40);
1986 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0);
1988 QTRY_VERIFY(header->y() + header->height() == item->y());
1994 void tst_QDeclarative1ListView::footer()
1996 QDeclarativeView *canvas = createView();
1999 for (int i = 0; i < 3; i++)
2000 model.addItem("Item" + QString::number(i), "");
2002 QDeclarativeContext *ctxt = canvas->rootContext();
2003 ctxt->setContextProperty("testModel", &model);
2005 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/footer.qml"));
2006 qApp->processEvents();
2008 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
2009 QTRY_VERIFY(listview != 0);
2011 QDeclarativeItem *contentItem = listview->contentItem();
2012 QTRY_VERIFY(contentItem != 0);
2014 QDeclarative1Text *footer = findItem<QDeclarative1Text>(contentItem, "footer");
2016 QCOMPARE(footer->y(), 60.0);
2017 QCOMPARE(footer->height(), 30.0);
2019 model.removeItem(1);
2020 QTRY_COMPARE(footer->y(), 40.0);
2023 QTRY_COMPARE(footer->y(), 0.0);
2025 for (int i = 0; i < 30; i++)
2026 model.addItem("Item" + QString::number(i), "");
2028 QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
2030 footer = findItem<QDeclarative1Text>(contentItem, "footer");
2032 footer = findItem<QDeclarative1Text>(contentItem, "footer2");
2035 QCOMPARE(footer->y(), 600.0);
2036 QCOMPARE(footer->height(), 20.0);
2037 QCOMPARE(listview->contentY(), 0.0);
2042 class LVAccessor : public QDeclarative1ListView
2045 qreal minY() const { return minYExtent(); }
2046 qreal maxY() const { return maxYExtent(); }
2047 qreal minX() const { return minXExtent(); }
2048 qreal maxX() const { return maxXExtent(); }
2051 void tst_QDeclarative1ListView::headerFooter()
2055 QDeclarativeView *canvas = createView();
2058 QDeclarativeContext *ctxt = canvas->rootContext();
2059 ctxt->setContextProperty("testModel", &model);
2061 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/headerfooter.qml"));
2062 qApp->processEvents();
2064 QDeclarative1ListView *listview = qobject_cast<QDeclarative1ListView*>(canvas->rootObject());
2065 QTRY_VERIFY(listview != 0);
2067 QDeclarativeItem *contentItem = listview->contentItem();
2068 QTRY_VERIFY(contentItem != 0);
2070 QDeclarativeItem *header = findItem<QDeclarativeItem>(contentItem, "header");
2072 QCOMPARE(header->y(), 0.0);
2074 QDeclarativeItem *footer = findItem<QDeclarativeItem>(contentItem, "footer");
2076 QCOMPARE(footer->y(), 20.0);
2078 QVERIFY(static_cast<LVAccessor*>(listview)->minY() == 0);
2079 QVERIFY(static_cast<LVAccessor*>(listview)->maxY() == 0);
2085 QDeclarativeView *canvas = createView();
2088 QDeclarativeContext *ctxt = canvas->rootContext();
2089 ctxt->setContextProperty("testModel", &model);
2091 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/headerfooter.qml"));
2092 canvas->rootObject()->setProperty("horizontal", true);
2093 qApp->processEvents();
2095 QDeclarative1ListView *listview = qobject_cast<QDeclarative1ListView*>(canvas->rootObject());
2096 QTRY_VERIFY(listview != 0);
2098 QDeclarativeItem *contentItem = listview->contentItem();
2099 QTRY_VERIFY(contentItem != 0);
2101 QDeclarativeItem *header = findItem<QDeclarativeItem>(contentItem, "header");
2103 QCOMPARE(header->x(), 0.0);
2105 QDeclarativeItem *footer = findItem<QDeclarativeItem>(contentItem, "footer");
2107 QCOMPARE(footer->x(), 20.0);
2109 QVERIFY(static_cast<LVAccessor*>(listview)->minX() == 0);
2110 QVERIFY(static_cast<LVAccessor*>(listview)->maxX() == 0);
2116 QDeclarativeView *canvas = createView();
2119 QDeclarativeContext *ctxt = canvas->rootContext();
2120 ctxt->setContextProperty("testModel", &model);
2122 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/headerfooter.qml"));
2123 canvas->rootObject()->setProperty("horizontal", true);
2124 canvas->rootObject()->setProperty("rtl", true);
2125 qApp->processEvents();
2127 QDeclarative1ListView *listview = qobject_cast<QDeclarative1ListView*>(canvas->rootObject());
2128 QTRY_VERIFY(listview != 0);
2130 QDeclarativeItem *contentItem = listview->contentItem();
2131 QTRY_VERIFY(contentItem != 0);
2133 QDeclarativeItem *header = findItem<QDeclarativeItem>(contentItem, "header");
2135 QCOMPARE(header->x(), -20.0);
2137 QDeclarativeItem *footer = findItem<QDeclarativeItem>(contentItem, "footer");
2139 QCOMPARE(footer->x(), -50.0);
2141 QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), 240.);
2142 QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), 240.);
2148 void tst_QDeclarative1ListView::resizeView()
2150 QDeclarativeView *canvas = createView();
2153 for (int i = 0; i < 40; i++)
2154 model.addItem("Item" + QString::number(i), "");
2156 QDeclarativeContext *ctxt = canvas->rootContext();
2157 ctxt->setContextProperty("testModel", &model);
2159 TestObject *testObject = new TestObject;
2160 ctxt->setContextProperty("testObject", testObject);
2162 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
2163 qApp->processEvents();
2165 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
2166 QTRY_VERIFY(listview != 0);
2168 QDeclarativeItem *contentItem = listview->contentItem();
2169 QTRY_VERIFY(contentItem != 0);
2171 // Confirm items positioned correctly
2172 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2173 for (int i = 0; i < model.count() && i < itemCount; ++i) {
2174 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2175 if (!item) qWarning() << "Item" << i << "not found";
2177 QTRY_COMPARE(item->y(), i*20.);
2180 QVariant heightRatio;
2181 QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
2182 QCOMPARE(heightRatio.toReal(), 0.4);
2184 listview->setHeight(200);
2186 QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
2187 QCOMPARE(heightRatio.toReal(), 0.25);
2193 void tst_QDeclarative1ListView::sizeLessThan1()
2195 QDeclarativeView *canvas = createView();
2198 for (int i = 0; i < 30; i++)
2199 model.addItem("Item" + QString::number(i), "");
2201 QDeclarativeContext *ctxt = canvas->rootContext();
2202 ctxt->setContextProperty("testModel", &model);
2204 TestObject *testObject = new TestObject;
2205 ctxt->setContextProperty("testObject", testObject);
2207 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/sizelessthan1.qml"));
2208 qApp->processEvents();
2210 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
2211 QTRY_VERIFY(listview != 0);
2213 QDeclarativeItem *contentItem = listview->contentItem();
2214 QTRY_VERIFY(contentItem != 0);
2216 // Confirm items positioned correctly
2217 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2218 for (int i = 0; i < model.count() && i < itemCount; ++i) {
2219 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2220 if (!item) qWarning() << "Item" << i << "not found";
2222 QTRY_COMPARE(item->y(), i*0.5);
2229 void tst_QDeclarative1ListView::QTBUG_14821()
2231 QDeclarativeView *canvas = createView();
2233 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtbug14821.qml"));
2234 qApp->processEvents();
2236 QDeclarative1ListView *listview = qobject_cast<QDeclarative1ListView*>(canvas->rootObject());
2237 QVERIFY(listview != 0);
2239 QDeclarativeItem *contentItem = listview->contentItem();
2240 QVERIFY(contentItem != 0);
2242 listview->decrementCurrentIndex();
2243 QCOMPARE(listview->currentIndex(), 99);
2245 listview->incrementCurrentIndex();
2246 QCOMPARE(listview->currentIndex(), 0);
2251 void tst_QDeclarative1ListView::resizeDelegate()
2253 QDeclarativeView *canvas = createView();
2255 QStringList strings;
2256 for (int i = 0; i < 30; ++i)
2257 strings << QString::number(i);
2258 QStringListModel model(strings);
2260 QDeclarativeContext *ctxt = canvas->rootContext();
2261 ctxt->setContextProperty("testModel", &model);
2263 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaylist.qml"));
2264 qApp->processEvents();
2266 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
2267 QTRY_VERIFY(listview != 0);
2269 QDeclarativeItem *contentItem = listview->contentItem();
2270 QTRY_VERIFY(contentItem != 0);
2272 QTRY_COMPARE(listview->count(), model.rowCount());
2274 listview->setCurrentIndex(25);
2275 listview->setContentY(0);
2277 for (int i = 0; i < 16; ++i) {
2278 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2280 QCOMPARE(item->y(), i*20.0);
2283 QCOMPARE(listview->currentItem()->y(), 500.0);
2284 QTRY_COMPARE(listview->highlightItem()->y(), 500.0);
2286 canvas->rootObject()->setProperty("delegateHeight", 30);
2287 qApp->processEvents();
2289 for (int i = 0; i < 11; ++i) {
2290 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2292 QTRY_COMPARE(item->y(), i*30.0);
2295 QTRY_COMPARE(listview->currentItem()->y(), 750.0);
2296 QTRY_COMPARE(listview->highlightItem()->y(), 750.0);
2298 listview->setCurrentIndex(1);
2299 listview->positionViewAtIndex(25, QDeclarative1ListView::Beginning);
2300 listview->positionViewAtIndex(5, QDeclarative1ListView::Beginning);
2302 for (int i = 5; i < 16; ++i) {
2303 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2305 QCOMPARE(item->y(), i*30.0);
2308 QTRY_COMPARE(listview->currentItem()->y(), 30.0);
2309 QTRY_COMPARE(listview->highlightItem()->y(), 30.0);
2311 canvas->rootObject()->setProperty("delegateHeight", 20);
2312 qApp->processEvents();
2314 for (int i = 5; i < 11; ++i) {
2315 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2317 QTRY_COMPARE(item->y(), 150 + (i-5)*20.0);
2320 QTRY_COMPARE(listview->currentItem()->y(), 70.0);
2321 QTRY_COMPARE(listview->highlightItem()->y(), 70.0);
2326 void tst_QDeclarative1ListView::QTBUG_16037()
2328 QDeclarativeView *canvas = createView();
2330 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtbug16037.qml"));
2331 qApp->processEvents();
2333 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "listview");
2334 QTRY_VERIFY(listview != 0);
2336 QVERIFY(listview->contentHeight() <= 0.0);
2338 QMetaObject::invokeMethod(canvas->rootObject(), "setModel");
2340 QTRY_COMPARE(listview->contentHeight(), 80.0);
2345 void tst_QDeclarative1ListView::indexAt()
2347 QDeclarativeView *canvas = createView();
2350 for (int i = 0; i < 30; i++)
2351 model.addItem("Item" + QString::number(i), "");
2353 QDeclarativeContext *ctxt = canvas->rootContext();
2354 ctxt->setContextProperty("testModel", &model);
2356 TestObject *testObject = new TestObject;
2357 ctxt->setContextProperty("testObject", testObject);
2359 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
2360 qApp->processEvents();
2362 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
2363 QTRY_VERIFY(listview != 0);
2365 QDeclarativeItem *contentItem = listview->contentItem();
2366 QTRY_VERIFY(contentItem != 0);
2368 QCOMPARE(listview->indexAt(0,0), 0);
2369 QCOMPARE(listview->indexAt(0,19), 0);
2370 QCOMPARE(listview->indexAt(239,19), 0);
2371 QCOMPARE(listview->indexAt(0,20), 1);
2372 QCOMPARE(listview->indexAt(240,20), -1);
2378 void tst_QDeclarative1ListView::incrementalModel()
2380 QDeclarativeView *canvas = createView();
2382 IncrementalModel model;
2383 QDeclarativeContext *ctxt = canvas->rootContext();
2384 ctxt->setContextProperty("testModel", &model);
2386 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaylist.qml"));
2387 qApp->processEvents();
2389 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
2390 QTRY_VERIFY(listview != 0);
2392 QDeclarativeItem *contentItem = listview->contentItem();
2393 QTRY_VERIFY(contentItem != 0);
2395 QTRY_COMPARE(listview->count(), 20);
2397 listview->positionViewAtIndex(10, QDeclarative1ListView::Beginning);
2399 QTRY_COMPARE(listview->count(), 25);
2404 void tst_QDeclarative1ListView::onAdd()
2406 QFETCH(int, initialItemCount);
2407 QFETCH(int, itemsToAdd);
2409 const int delegateHeight = 10;
2412 // these initial items should not trigger ListView.onAdd
2413 for (int i=0; i<initialItemCount; i++)
2414 model.addItem("dummy value", "dummy value");
2416 QDeclarativeView *canvas = createView();
2417 canvas->setFixedSize(200, delegateHeight * (initialItemCount + itemsToAdd));
2418 QDeclarativeContext *ctxt = canvas->rootContext();
2419 ctxt->setContextProperty("testModel", &model);
2420 ctxt->setContextProperty("delegateHeight", delegateHeight);
2421 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
2423 QObject *object = canvas->rootObject();
2424 object->setProperty("width", canvas->width());
2425 object->setProperty("height", canvas->height());
2426 qApp->processEvents();
2428 QList<QPair<QString, QString> > items;
2429 for (int i=0; i<itemsToAdd; i++)
2430 items << qMakePair(QString("value %1").arg(i), QString::number(i));
2431 model.addItems(items);
2433 qApp->processEvents();
2435 QVariantList result = object->property("addedDelegates").toList();
2436 QCOMPARE(result.count(), items.count());
2437 for (int i=0; i<items.count(); i++)
2438 QCOMPARE(result[i].toString(), items[i].first);
2443 void tst_QDeclarative1ListView::onAdd_data()
2445 QTest::addColumn<int>("initialItemCount");
2446 QTest::addColumn<int>("itemsToAdd");
2448 QTest::newRow("0, add 1") << 0 << 1;
2449 QTest::newRow("0, add 2") << 0 << 2;
2450 QTest::newRow("0, add 10") << 0 << 10;
2452 QTest::newRow("1, add 1") << 1 << 1;
2453 QTest::newRow("1, add 2") << 1 << 2;
2454 QTest::newRow("1, add 10") << 1 << 10;
2456 QTest::newRow("5, add 1") << 5 << 1;
2457 QTest::newRow("5, add 2") << 5 << 2;
2458 QTest::newRow("5, add 10") << 5 << 10;
2461 void tst_QDeclarative1ListView::onRemove()
2463 QFETCH(int, initialItemCount);
2464 QFETCH(int, indexToRemove);
2465 QFETCH(int, removeCount);
2467 const int delegateHeight = 10;
2469 for (int i=0; i<initialItemCount; i++)
2470 model.addItem(QString("value %1").arg(i), "dummy value");
2472 QDeclarativeView *canvas = createView();
2473 QDeclarativeContext *ctxt = canvas->rootContext();
2474 ctxt->setContextProperty("testModel", &model);
2475 ctxt->setContextProperty("delegateHeight", delegateHeight);
2476 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
2477 QObject *object = canvas->rootObject();
2479 qApp->processEvents();
2481 model.removeItems(indexToRemove, removeCount);
2482 qApp->processEvents();
2483 QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
2488 void tst_QDeclarative1ListView::onRemove_data()
2490 QTest::addColumn<int>("initialItemCount");
2491 QTest::addColumn<int>("indexToRemove");
2492 QTest::addColumn<int>("removeCount");
2494 QTest::newRow("remove first") << 1 << 0 << 1;
2495 QTest::newRow("two items, remove first") << 2 << 0 << 1;
2496 QTest::newRow("two items, remove last") << 2 << 1 << 1;
2497 QTest::newRow("two items, remove all") << 2 << 0 << 2;
2499 QTest::newRow("four items, remove first") << 4 << 0 << 1;
2500 QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
2501 QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
2502 QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
2503 QTest::newRow("four items, remove last") << 4 << 3 << 1;
2504 QTest::newRow("four items, remove all") << 4 << 0 << 4;
2506 QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
2507 QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
2508 QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
2511 void tst_QDeclarative1ListView::testQtQuick11Attributes()
2513 QFETCH(QString, code);
2514 QFETCH(QString, warning);
2515 QFETCH(QString, error);
2517 QDeclarativeEngine engine;
2520 QDeclarativeComponent valid(&engine);
2521 valid.setData("import QtQuick 1.1; ListView { " + code.toUtf8() + " }", QUrl(""));
2522 obj = valid.create();
2524 QVERIFY(valid.errorString().isEmpty());
2527 QDeclarativeComponent invalid(&engine);
2528 invalid.setData("import QtQuick 1.0; ListView { " + code.toUtf8() + " }", QUrl(""));
2529 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2530 obj = invalid.create();
2531 QCOMPARE(invalid.errorString(), error);
2535 void tst_QDeclarative1ListView::testQtQuick11Attributes_data()
2537 QTest::addColumn<QString>("code");
2538 QTest::addColumn<QString>("warning");
2539 QTest::addColumn<QString>("error");
2541 QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()"
2542 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning"
2545 QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()"
2546 << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd"
2550 void tst_QDeclarative1ListView::rightToLeft()
2552 QDeclarativeView *canvas = createView();
2553 canvas->setFixedSize(640,320);
2554 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/rightToLeft.qml"));
2555 qApp->processEvents();
2557 QVERIFY(canvas->rootObject() != 0);
2558 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "view");
2559 QTRY_VERIFY(listview != 0);
2561 QDeclarativeItem *contentItem = listview->contentItem();
2562 QTRY_VERIFY(contentItem != 0);
2564 QDeclarative1VisualItemModel *model = canvas->rootObject()->findChild<QDeclarative1VisualItemModel*>("itemModel");
2565 QTRY_VERIFY(model != 0);
2567 QTRY_VERIFY(model->count() == 3);
2568 QTRY_COMPARE(listview->currentIndex(), 0);
2570 // initial position at first item, right edge aligned
2571 QCOMPARE(listview->contentX(), -640.);
2573 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "item1");
2575 QTRY_COMPARE(item->x(), -100.0);
2576 QCOMPARE(item->height(), listview->height());
2578 QDeclarative1Text *text = findItem<QDeclarative1Text>(contentItem, "text1");
2580 QTRY_COMPARE(text->text(), QLatin1String("index: 0"));
2582 listview->setCurrentIndex(2);
2584 item = findItem<QDeclarativeItem>(contentItem, "item3");
2586 QTRY_COMPARE(item->x(), -540.0);
2588 text = findItem<QDeclarative1Text>(contentItem, "text3");
2590 QTRY_COMPARE(text->text(), QLatin1String("index: 2"));
2592 QCOMPARE(listview->contentX(), -640.);
2594 // Ensure resizing maintains position relative to right edge
2595 qobject_cast<QDeclarativeItem*>(canvas->rootObject())->setWidth(600);
2596 QTRY_COMPARE(listview->contentX(), -600.);
2601 void tst_QDeclarative1ListView::test_mirroring()
2603 QDeclarativeView *canvasA = createView();
2604 canvasA->setSource(QUrl::fromLocalFile(SRCDIR "/data/rightToLeft.qml"));
2605 QDeclarative1ListView *listviewA = findItem<QDeclarative1ListView>(canvasA->rootObject(), "view");
2606 QTRY_VERIFY(listviewA != 0);
2608 QDeclarativeView *canvasB = createView();
2609 canvasB->setSource(QUrl::fromLocalFile(SRCDIR "/data/rightToLeft.qml"));
2610 QDeclarative1ListView *listviewB = findItem<QDeclarative1ListView>(canvasB->rootObject(), "view");
2611 QTRY_VERIFY(listviewA != 0);
2612 qApp->processEvents();
2614 QList<QString> objectNames;
2615 objectNames << "item1" << "item2"; // << "item3"
2617 listviewA->setProperty("layoutDirection", Qt::LeftToRight);
2618 listviewB->setProperty("layoutDirection", Qt::RightToLeft);
2619 QCOMPARE(listviewA->layoutDirection(), listviewA->effectiveLayoutDirection());
2622 foreach(const QString objectName, objectNames)
2623 QVERIFY(findItem<QDeclarativeItem>(listviewA, objectName)->x() != findItem<QDeclarativeItem>(listviewB, objectName)->x());
2625 listviewA->setProperty("layoutDirection", Qt::LeftToRight);
2626 listviewB->setProperty("layoutDirection", Qt::LeftToRight);
2629 foreach(const QString objectName, objectNames)
2630 QCOMPARE(findItem<QDeclarativeItem>(listviewA, objectName)->x(), findItem<QDeclarativeItem>(listviewB, objectName)->x());
2632 QVERIFY(listviewB->layoutDirection() == listviewB->effectiveLayoutDirection());
2633 QDeclarativeItemPrivate::get(listviewB)->setLayoutMirror(true);
2634 QVERIFY(listviewB->layoutDirection() != listviewB->effectiveLayoutDirection());
2636 // LTR != LTR+mirror
2637 foreach(const QString objectName, objectNames)
2638 QVERIFY(findItem<QDeclarativeItem>(listviewA, objectName)->x() != findItem<QDeclarativeItem>(listviewB, objectName)->x());
2640 listviewA->setProperty("layoutDirection", Qt::RightToLeft);
2642 // RTL == LTR+mirror
2643 foreach(const QString objectName, objectNames)
2644 QCOMPARE(findItem<QDeclarativeItem>(listviewA, objectName)->x(), findItem<QDeclarativeItem>(listviewB, objectName)->x());
2646 listviewB->setProperty("layoutDirection", Qt::RightToLeft);
2648 // RTL != RTL+mirror
2649 foreach(const QString objectName, objectNames)
2650 QVERIFY(findItem<QDeclarativeItem>(listviewA, objectName)->x() != findItem<QDeclarativeItem>(listviewB, objectName)->x());
2652 listviewA->setProperty("layoutDirection", Qt::LeftToRight);
2654 // LTR == RTL+mirror
2655 foreach(const QString objectName, objectNames)
2656 QCOMPARE(findItem<QDeclarativeItem>(listviewA, objectName)->x(), findItem<QDeclarativeItem>(listviewB, objectName)->x());
2662 void tst_QDeclarative1ListView::orientationChange()
2664 QDeclarativeView *canvas = createView();
2666 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/orientchange.qml"));
2667 qApp->processEvents();
2669 QDeclarative1ListView *listview = qobject_cast<QDeclarative1ListView*>(canvas->rootObject());
2670 QVERIFY(listview != 0);
2672 QDeclarativeItem *contentItem = listview->contentItem();
2673 QVERIFY(contentItem != 0);
2675 listview->positionViewAtIndex(50, QDeclarative1ListView::Beginning);
2677 // Confirm items positioned correctly
2678 for (int i = 50; i < 54; ++i) {
2679 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2681 QCOMPARE(item->y(), i*80.0);
2684 listview->setOrientation(QDeclarative1ListView::Horizontal);
2685 QCOMPARE(listview->contentY(), 0.);
2687 // Confirm items positioned correctly
2688 for (int i = 0; i < 3; ++i) {
2689 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2691 QCOMPARE(item->x(), i*80.0);
2694 listview->positionViewAtIndex(50, QDeclarative1ListView::Beginning);
2695 listview->setOrientation(QDeclarative1ListView::Vertical);
2696 QCOMPARE(listview->contentX(), 0.);
2698 // Confirm items positioned correctly
2699 for (int i = 0; i < 4; ++i) {
2700 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2702 QCOMPARE(item->y(), i*80.0);
2708 void tst_QDeclarative1ListView::contentPosJump()
2710 QDeclarativeView *canvas = createView();
2713 for (int i = 0; i < 50; i++)
2714 model.addItem("Item" + QString::number(i), "");
2716 QDeclarativeContext *ctxt = canvas->rootContext();
2717 ctxt->setContextProperty("testModel", &model);
2719 TestObject *testObject = new TestObject;
2720 ctxt->setContextProperty("testObject", testObject);
2722 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
2723 qApp->processEvents();
2725 QDeclarative1ListView *listview = findItem<QDeclarative1ListView>(canvas->rootObject(), "list");
2726 QTRY_VERIFY(listview != 0);
2728 QDeclarativeItem *contentItem = listview->contentItem();
2729 QTRY_VERIFY(contentItem != 0);
2731 // Confirm items positioned correctly
2732 int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2733 for (int i = 0; i < model.count() && i < itemCount; ++i) {
2734 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2735 if (!item) qWarning() << "Item" << i << "not found";
2737 QTRY_VERIFY(item->y() == i*20);
2740 // Test jumping more than a page of items.
2741 listview->setContentY(500);
2742 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2743 for (int i = 25; i < model.count() && i < itemCount; ++i) {
2744 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2745 if (!item) qWarning() << "Item" << i << "not found";
2747 QTRY_VERIFY(item->y() == i*20);
2750 listview->setContentY(-100);
2751 itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
2752 QVERIFY(itemCount < 20);
2753 for (int i = 0; i < model.count() && i < itemCount; ++i) {
2754 QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
2755 if (!item) qWarning() << "Item" << i << "not found";
2757 QTRY_VERIFY(item->y() == i*20);
2763 void tst_QDeclarative1ListView::qListModelInterface_items()
2768 void tst_QDeclarative1ListView::qAbstractItemModel_items()
2770 items<TestModel2>();
2773 void tst_QDeclarative1ListView::qListModelInterface_changed()
2775 changed<TestModel>();
2778 void tst_QDeclarative1ListView::qAbstractItemModel_changed()
2780 changed<TestModel2>();
2783 void tst_QDeclarative1ListView::qListModelInterface_inserted()
2785 inserted<TestModel>();
2788 void tst_QDeclarative1ListView::qAbstractItemModel_inserted()
2790 inserted<TestModel2>();
2793 void tst_QDeclarative1ListView::qListModelInterface_removed()
2795 removed<TestModel>(false);
2796 removed<TestModel>(true);
2799 void tst_QDeclarative1ListView::qAbstractItemModel_removed()
2801 removed<TestModel2>(false);
2802 removed<TestModel2>(true);
2805 void tst_QDeclarative1ListView::qListModelInterface_moved()
2810 void tst_QDeclarative1ListView::qAbstractItemModel_moved()
2812 moved<TestModel2>();
2815 void tst_QDeclarative1ListView::qListModelInterface_clear()
2820 void tst_QDeclarative1ListView::qAbstractItemModel_clear()
2822 clear<TestModel2>();
2825 QDeclarativeView *tst_QDeclarative1ListView::createView()
2827 QDeclarativeView *canvas = new QDeclarativeView(0);
2828 canvas->setFixedSize(240,320);
2834 Find an item with the specified objectName. If index is supplied then the
2835 item must also evaluate the {index} expression equal to index
2837 template<typename T>
2838 T *tst_QDeclarative1ListView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
2840 const QMetaObject &mo = T::staticMetaObject;
2841 //qDebug() << parent->childItems().count() << "children";
2842 for (int i = 0; i < parent->childItems().count(); ++i) {
2843 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2846 //qDebug() << "try" << item;
2847 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
2849 QDeclarativeExpression e(qmlContext(item), item, "index");
2850 if (e.evaluate().toInt() == index)
2851 return static_cast<T*>(item);
2853 return static_cast<T*>(item);
2856 item = findItem<T>(item, objectName, index);
2858 return static_cast<T*>(item);
2864 template<typename T>
2865 QList<T*> tst_QDeclarative1ListView::findItems(QGraphicsObject *parent, const QString &objectName)
2868 const QMetaObject &mo = T::staticMetaObject;
2869 //qDebug() << parent->childItems().count() << "children";
2870 for (int i = 0; i < parent->childItems().count(); ++i) {
2871 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2872 if(!item || !item->isVisible())
2874 //qDebug() << "try" << item;
2875 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
2876 items.append(static_cast<T*>(item));
2877 items += findItems<T>(item, objectName);
2883 void tst_QDeclarative1ListView::dumpTree(QDeclarativeItem *parent, int depth)
2885 static QString padding(" ");
2886 for (int i = 0; i < parent->childItems().count(); ++i) {
2887 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
2890 qDebug() << padding.left(depth*2) << item;
2891 dumpTree(item, depth+1);
2896 QTEST_MAIN(tst_QDeclarative1ListView)
2898 #include "tst_qdeclarativelistview.moc"