tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** 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
       
    14 ** this package.
       
    15 **
       
    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.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtTest/QtTest>
       
    43 #include <QtGui/qstringlistmodel.h>
       
    44 #include <QtDeclarative/qdeclarativeview.h>
       
    45 #include <QtDeclarative/qdeclarativeengine.h>
       
    46 #include <QtDeclarative/qdeclarativecomponent.h>
       
    47 #include <QtDeclarative/qdeclarativecontext.h>
       
    48 #include <QtDeclarative/qdeclarativeexpression.h>
       
    49 #include <QtDeclarative/private/qlistmodelinterface_p.h>
       
    50 #include <QtDeclarative/private/qdeclarativegridview_p.h>
       
    51 #include <QtDeclarative/private/qdeclarativetext_p.h>
       
    52 #include <QtDeclarative/private/qdeclarativelistmodel_p.h>
       
    53 #include "../../../shared/util.h"
       
    54 
       
    55 class tst_QDeclarativeGridView : public QObject
       
    56 {
       
    57     Q_OBJECT
       
    58 public:
       
    59     tst_QDeclarativeGridView();
       
    60 
       
    61 private slots:
       
    62     void items();
       
    63     void changed();
       
    64     void inserted();
       
    65     void removed();
       
    66     void moved();
       
    67     void changeFlow();
       
    68     void currentIndex();
       
    69     void defaultValues();
       
    70     void properties();
       
    71     void propertyChanges();
       
    72     void componentChanges();
       
    73     void modelChanges();
       
    74     void positionViewAtIndex();
       
    75     void resetModel();
       
    76     void enforceRange();
       
    77     void QTBUG_8456();
       
    78     void manualHighlight();
       
    79 
       
    80 private:
       
    81     QDeclarativeView *createView();
       
    82     template<typename T>
       
    83     T *findItem(QGraphicsObject *parent, const QString &id, int index=-1);
       
    84     template<typename T>
       
    85     QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
       
    86     void dumpTree(QDeclarativeItem *parent, int depth = 0);
       
    87 };
       
    88 
       
    89 class TestModel : public QAbstractListModel
       
    90 {
       
    91 public:
       
    92     enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
       
    93 
       
    94     TestModel(QObject *parent=0) : QAbstractListModel(parent) {
       
    95         QHash<int, QByteArray> roles;
       
    96         roles[Name] = "name";
       
    97         roles[Number] = "number";
       
    98         setRoleNames(roles);
       
    99     }
       
   100 
       
   101     int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
       
   102     QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
       
   103         QVariant rv;
       
   104         if (role == Name)
       
   105             rv = list.at(index.row()).first;
       
   106         else if (role == Number)
       
   107             rv = list.at(index.row()).second;
       
   108 
       
   109         return rv;
       
   110     }
       
   111 
       
   112     int count() const { return rowCount(); }
       
   113     QString name(int index) const { return list.at(index).first; }
       
   114     QString number(int index) const { return list.at(index).second; }
       
   115 
       
   116     void addItem(const QString &name, const QString &number) {
       
   117         emit beginInsertRows(QModelIndex(), list.count(), list.count());
       
   118         list.append(QPair<QString,QString>(name, number));
       
   119         emit endInsertRows();
       
   120     }
       
   121 
       
   122     void insertItem(int index, const QString &name, const QString &number) {
       
   123         emit beginInsertRows(QModelIndex(), index, index);
       
   124         list.insert(index, QPair<QString,QString>(name, number));
       
   125         emit endInsertRows();
       
   126     }
       
   127 
       
   128     void removeItem(int index) {
       
   129         emit beginRemoveRows(QModelIndex(), index, index);
       
   130         list.removeAt(index);
       
   131         emit endRemoveRows();
       
   132     }
       
   133 
       
   134     void moveItem(int from, int to) {
       
   135         emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
       
   136         list.move(from, to);
       
   137         emit endMoveRows();
       
   138     }
       
   139 
       
   140     void modifyItem(int idx, const QString &name, const QString &number) {
       
   141         list[idx] = QPair<QString,QString>(name, number);
       
   142         emit dataChanged(index(idx,0), index(idx,0));
       
   143     }
       
   144 
       
   145 private:
       
   146     QList<QPair<QString,QString> > list;
       
   147 };
       
   148 
       
   149 tst_QDeclarativeGridView::tst_QDeclarativeGridView()
       
   150 {
       
   151 }
       
   152 
       
   153 void tst_QDeclarativeGridView::items()
       
   154 {
       
   155     QDeclarativeView *canvas = createView();
       
   156 
       
   157     TestModel model;
       
   158     model.addItem("Fred", "12345");
       
   159     model.addItem("John", "2345");
       
   160     model.addItem("Bob", "54321");
       
   161     model.addItem("Billy", "22345");
       
   162     model.addItem("Sam", "2945");
       
   163     model.addItem("Ben", "04321");
       
   164     model.addItem("Jim", "0780");
       
   165 
       
   166     QDeclarativeContext *ctxt = canvas->rootContext();
       
   167     ctxt->setContextProperty("testModel", &model);
       
   168     ctxt->setContextProperty("testTopToBottom", QVariant(false));
       
   169 
       
   170     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
       
   171     qApp->processEvents();
       
   172 
       
   173     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
   174     QTRY_VERIFY(gridview != 0);
       
   175 
       
   176     QDeclarativeItem *viewport = gridview->viewport();
       
   177     QTRY_VERIFY(viewport != 0);
       
   178 
       
   179     QTRY_COMPARE(gridview->count(), model.count());
       
   180     QTRY_COMPARE(viewport->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
       
   181 
       
   182     for (int i = 0; i < model.count(); ++i) {
       
   183         QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", i);
       
   184         QTRY_VERIFY(name != 0);
       
   185         QTRY_COMPARE(name->text(), model.name(i));
       
   186         QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", i);
       
   187         QTRY_VERIFY(number != 0);
       
   188         QTRY_COMPARE(number->text(), model.number(i));
       
   189     }
       
   190 
       
   191     // set an empty model and confirm that items are destroyed
       
   192     TestModel model2;
       
   193     ctxt->setContextProperty("testModel", &model2);
       
   194 
       
   195     int itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   196     QTRY_VERIFY(itemCount == 0);
       
   197 
       
   198     delete canvas;
       
   199 }
       
   200 
       
   201 void tst_QDeclarativeGridView::changed()
       
   202 {
       
   203     QDeclarativeView *canvas = createView();
       
   204 
       
   205     TestModel model;
       
   206     model.addItem("Fred", "12345");
       
   207     model.addItem("John", "2345");
       
   208     model.addItem("Bob", "54321");
       
   209     model.addItem("Billy", "22345");
       
   210     model.addItem("Sam", "2945");
       
   211     model.addItem("Ben", "04321");
       
   212     model.addItem("Jim", "0780");
       
   213 
       
   214     QDeclarativeContext *ctxt = canvas->rootContext();
       
   215     ctxt->setContextProperty("testModel", &model);
       
   216     ctxt->setContextProperty("testTopToBottom", QVariant(false));
       
   217 
       
   218     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
       
   219     qApp->processEvents();
       
   220 
       
   221     QDeclarativeFlickable *gridview = findItem<QDeclarativeFlickable>(canvas->rootObject(), "grid");
       
   222     QTRY_VERIFY(gridview != 0);
       
   223 
       
   224     QDeclarativeItem *viewport = gridview->viewport();
       
   225     QTRY_VERIFY(viewport != 0);
       
   226 
       
   227     model.modifyItem(1, "Will", "9876");
       
   228     QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", 1);
       
   229     QTRY_VERIFY(name != 0);
       
   230     QTRY_COMPARE(name->text(), model.name(1));
       
   231     QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", 1);
       
   232     QTRY_VERIFY(number != 0);
       
   233     QTRY_COMPARE(number->text(), model.number(1));
       
   234 
       
   235     delete canvas;
       
   236 }
       
   237 
       
   238 void tst_QDeclarativeGridView::inserted()
       
   239 {
       
   240     QDeclarativeView *canvas = createView();
       
   241 
       
   242     TestModel model;
       
   243     model.addItem("Fred", "12345");
       
   244     model.addItem("John", "2345");
       
   245     model.addItem("Bob", "54321");
       
   246 
       
   247     QDeclarativeContext *ctxt = canvas->rootContext();
       
   248     ctxt->setContextProperty("testModel", &model);
       
   249     ctxt->setContextProperty("testTopToBottom", QVariant(false));
       
   250 
       
   251     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
       
   252     qApp->processEvents();
       
   253 
       
   254     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
   255     QTRY_VERIFY(gridview != 0);
       
   256 
       
   257     QDeclarativeItem *viewport = gridview->viewport();
       
   258     QTRY_VERIFY(viewport != 0);
       
   259 
       
   260     model.insertItem(1, "Will", "9876");
       
   261 
       
   262     QTRY_COMPARE(viewport->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
       
   263 
       
   264     QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", 1);
       
   265     QTRY_VERIFY(name != 0);
       
   266     QTRY_COMPARE(name->text(), model.name(1));
       
   267     QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", 1);
       
   268     QTRY_VERIFY(number != 0);
       
   269     QTRY_COMPARE(number->text(), model.number(1));
       
   270 
       
   271     // Checks that onAdd is called
       
   272     int added = canvas->rootObject()->property("added").toInt();
       
   273     QTRY_COMPARE(added, 1);
       
   274 
       
   275     // Confirm items positioned correctly
       
   276     for (int i = 0; i < model.count(); ++i) {
       
   277         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   278         QTRY_COMPARE(item->x(), (i%3)*80.0);
       
   279         QTRY_COMPARE(item->y(), (i/3)*60.0);
       
   280     }
       
   281 
       
   282     model.insertItem(0, "Foo", "1111"); // zero index, and current item
       
   283 
       
   284     QTRY_COMPARE(viewport->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
       
   285 
       
   286     name = findItem<QDeclarativeText>(viewport, "textName", 0);
       
   287     QTRY_VERIFY(name != 0);
       
   288     QTRY_COMPARE(name->text(), model.name(0));
       
   289     number = findItem<QDeclarativeText>(viewport, "textNumber", 0);
       
   290     QTRY_VERIFY(number != 0);
       
   291     QTRY_COMPARE(number->text(), model.number(0));
       
   292 
       
   293     QTRY_COMPARE(gridview->currentIndex(), 1);
       
   294 
       
   295     // Confirm items positioned correctly
       
   296     for (int i = 0; i < model.count(); ++i) {
       
   297         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   298         QTRY_VERIFY(item->x() == (i%3)*80);
       
   299         QTRY_VERIFY(item->y() == (i/3)*60);
       
   300     }
       
   301 
       
   302     for (int i = model.count(); i < 30; ++i)
       
   303         model.insertItem(i, "Hello", QString::number(i));
       
   304 
       
   305     gridview->setContentY(120);
       
   306 
       
   307     // Insert item outside visible area
       
   308     model.insertItem(1, "Hello", "1324");
       
   309 
       
   310     QTRY_VERIFY(gridview->contentY() == 120);
       
   311 
       
   312     delete canvas;
       
   313 }
       
   314 
       
   315 void tst_QDeclarativeGridView::removed()
       
   316 {
       
   317     QDeclarativeView *canvas = createView();
       
   318 
       
   319     TestModel model;
       
   320     for (int i = 0; i < 40; i++)
       
   321         model.addItem("Item" + QString::number(i), "");
       
   322 
       
   323     QDeclarativeContext *ctxt = canvas->rootContext();
       
   324     ctxt->setContextProperty("testModel", &model);
       
   325     ctxt->setContextProperty("testTopToBottom", QVariant(false));
       
   326 
       
   327     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
       
   328     qApp->processEvents();
       
   329 
       
   330     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
   331     QTRY_VERIFY(gridview != 0);
       
   332 
       
   333     QDeclarativeItem *viewport = gridview->viewport();
       
   334     QTRY_VERIFY(viewport != 0);
       
   335 
       
   336     model.removeItem(1);
       
   337 
       
   338     QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", 1);
       
   339     QTRY_VERIFY(name != 0);
       
   340     QTRY_COMPARE(name->text(), model.name(1));
       
   341     QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", 1);
       
   342     QTRY_VERIFY(number != 0);
       
   343     QTRY_COMPARE(number->text(), model.number(1));
       
   344 
       
   345     // Checks that onRemove is called
       
   346     QString removed = canvas->rootObject()->property("removed").toString();
       
   347     QTRY_COMPARE(removed, QString("Item1"));
       
   348 
       
   349     // Confirm items positioned correctly
       
   350     int itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   351     for (int i = 0; i < model.count() && i < itemCount; ++i) {
       
   352         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   353         if (!item) qWarning() << "Item" << i << "not found";
       
   354         QTRY_VERIFY(item);
       
   355         QTRY_VERIFY(item->x() == (i%3)*80);
       
   356         QTRY_VERIFY(item->y() == (i/3)*60);
       
   357     }
       
   358 
       
   359     // Remove first item (which is the current item);
       
   360     model.removeItem(0);
       
   361 
       
   362     name = findItem<QDeclarativeText>(viewport, "textName", 0);
       
   363     QTRY_VERIFY(name != 0);
       
   364     QTRY_COMPARE(name->text(), model.name(0));
       
   365     number = findItem<QDeclarativeText>(viewport, "textNumber", 0);
       
   366     QTRY_VERIFY(number != 0);
       
   367     QTRY_COMPARE(number->text(), model.number(0));
       
   368 
       
   369     // Confirm items positioned correctly
       
   370     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   371     for (int i = 0; i < model.count() && i < itemCount; ++i) {
       
   372         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   373         if (!item) qWarning() << "Item" << i << "not found";
       
   374         QTRY_VERIFY(item);
       
   375         QTRY_VERIFY(item->x() == (i%3)*80);
       
   376         QTRY_VERIFY(item->y() == (i/3)*60);
       
   377     }
       
   378 
       
   379     // Remove items not visible
       
   380     model.removeItem(25);
       
   381 
       
   382     // Confirm items positioned correctly
       
   383     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   384     for (int i = 0; i < model.count() && i < itemCount; ++i) {
       
   385         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   386         if (!item) qWarning() << "Item" << i << "not found";
       
   387         QTRY_VERIFY(item);
       
   388         QTRY_VERIFY(item->x() == (i%3)*80);
       
   389         QTRY_VERIFY(item->y() == (i/3)*60);
       
   390     }
       
   391 
       
   392     // Remove items before visible
       
   393     gridview->setContentY(120);
       
   394     gridview->setCurrentIndex(10);
       
   395 
       
   396     // Setting currentIndex above shouldn't cause view to scroll
       
   397     QTRY_COMPARE(gridview->contentY(), 120.0);
       
   398 
       
   399     model.removeItem(1);
       
   400 
       
   401     // Confirm items positioned correctly
       
   402     for (int i = 6; i < 18; ++i) {
       
   403         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   404         if (!item) qWarning() << "Item" << i << "not found";
       
   405         QTRY_VERIFY(item);
       
   406         QTRY_VERIFY(item->x() == (i%3)*80);
       
   407         QTRY_VERIFY(item->y() == (i/3)*60);
       
   408     }
       
   409 
       
   410     // Remove currentIndex
       
   411     QDeclarativeItem *oldCurrent = gridview->currentItem();
       
   412     model.removeItem(9);
       
   413 
       
   414     QTRY_COMPARE(gridview->currentIndex(), 9);
       
   415     QTRY_VERIFY(gridview->currentItem() != oldCurrent);
       
   416 
       
   417     gridview->setContentY(0);
       
   418     // let transitions settle.
       
   419     QTest::qWait(100);
       
   420 
       
   421     // Confirm items positioned correctly
       
   422     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   423     for (int i = 0; i < model.count() && i < itemCount; ++i) {
       
   424         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   425         if (!item) qWarning() << "Item" << i << "not found";
       
   426         QTRY_VERIFY(item);
       
   427         QTRY_VERIFY(item->x() == (i%3)*80);
       
   428         QTRY_VERIFY(item->y() == (i/3)*60);
       
   429     }
       
   430 
       
   431     // remove item outside current view.
       
   432     gridview->setCurrentIndex(32);
       
   433     gridview->setContentY(240);
       
   434 
       
   435     model.removeItem(30);
       
   436     QTRY_VERIFY(gridview->currentIndex() == 31);
       
   437 
       
   438     // remove current item beyond visible items.
       
   439     gridview->setCurrentIndex(20);
       
   440     gridview->setContentY(0);
       
   441     model.removeItem(20);
       
   442 
       
   443     QTRY_COMPARE(gridview->currentIndex(), 20);
       
   444     QTRY_VERIFY(gridview->currentItem() != 0);
       
   445 
       
   446     // remove item before current, but visible
       
   447     gridview->setCurrentIndex(8);
       
   448     gridview->setContentY(240);
       
   449     oldCurrent = gridview->currentItem();
       
   450     model.removeItem(6);
       
   451 
       
   452     QTRY_COMPARE(gridview->currentIndex(), 7);
       
   453     QTRY_VERIFY(gridview->currentItem() == oldCurrent);
       
   454 
       
   455     delete canvas;
       
   456 }
       
   457 
       
   458 void tst_QDeclarativeGridView::moved()
       
   459 {
       
   460     QDeclarativeView *canvas = createView();
       
   461 
       
   462     TestModel model;
       
   463     for (int i = 0; i < 30; i++)
       
   464         model.addItem("Item" + QString::number(i), "");
       
   465 
       
   466     QDeclarativeContext *ctxt = canvas->rootContext();
       
   467     ctxt->setContextProperty("testModel", &model);
       
   468     ctxt->setContextProperty("testTopToBottom", QVariant(false));
       
   469 
       
   470     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
       
   471     qApp->processEvents();
       
   472 
       
   473     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
   474     QTRY_VERIFY(gridview != 0);
       
   475 
       
   476     QDeclarativeItem *viewport = gridview->viewport();
       
   477     QTRY_VERIFY(viewport != 0);
       
   478 
       
   479     model.moveItem(1, 8);
       
   480 
       
   481     QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", 1);
       
   482     QTRY_VERIFY(name != 0);
       
   483     QTRY_COMPARE(name->text(), model.name(1));
       
   484     QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", 1);
       
   485     QTRY_VERIFY(number != 0);
       
   486     QTRY_COMPARE(number->text(), model.number(1));
       
   487 
       
   488     name = findItem<QDeclarativeText>(viewport, "textName", 8);
       
   489     QTRY_VERIFY(name != 0);
       
   490     QTRY_COMPARE(name->text(), model.name(8));
       
   491     number = findItem<QDeclarativeText>(viewport, "textNumber", 8);
       
   492     QTRY_VERIFY(number != 0);
       
   493     QTRY_COMPARE(number->text(), model.number(8));
       
   494 
       
   495     // Confirm items positioned correctly
       
   496     int itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   497     for (int i = 0; i < model.count() && i < itemCount; ++i) {
       
   498         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   499         if (!item) qWarning() << "Item" << i << "not found";
       
   500         QTRY_VERIFY(item);
       
   501         QTRY_VERIFY(item->x() == (i%3)*80);
       
   502         QTRY_VERIFY(item->y() == (i/3)*60);
       
   503     }
       
   504 
       
   505     gridview->setContentY(120);
       
   506 
       
   507     // move outside visible area
       
   508     model.moveItem(1, 25);
       
   509 
       
   510     // Confirm items positioned correctly and indexes correct
       
   511     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count()-1;
       
   512     for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
       
   513         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   514         if (!item) qWarning() << "Item" << i << "not found";
       
   515         QTRY_VERIFY(item);
       
   516         QTRY_COMPARE(item->x(), qreal((i%3)*80));
       
   517         QTRY_COMPARE(item->y(), qreal((i/3)*60));
       
   518         name = findItem<QDeclarativeText>(viewport, "textName", i);
       
   519         QTRY_VERIFY(name != 0);
       
   520         QTRY_COMPARE(name->text(), model.name(i));
       
   521         number = findItem<QDeclarativeText>(viewport, "textNumber", i);
       
   522         QTRY_VERIFY(number != 0);
       
   523         QTRY_COMPARE(number->text(), model.number(i));
       
   524     }
       
   525 
       
   526     // move from outside visible into visible
       
   527     model.moveItem(28, 8);
       
   528 
       
   529     // Confirm items positioned correctly and indexes correct
       
   530     for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) {
       
   531         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   532         if (!item) qWarning() << "Item" << i << "not found";
       
   533         QTRY_VERIFY(item);
       
   534         QTRY_VERIFY(item->x() == (i%3)*80);
       
   535         QTRY_VERIFY(item->y() == (i/3)*60);
       
   536         name = findItem<QDeclarativeText>(viewport, "textName", i);
       
   537         QTRY_VERIFY(name != 0);
       
   538         QTRY_COMPARE(name->text(), model.name(i));
       
   539         number = findItem<QDeclarativeText>(viewport, "textNumber", i);
       
   540         QTRY_VERIFY(number != 0);
       
   541         QTRY_COMPARE(number->text(), model.number(i));
       
   542     }
       
   543 
       
   544     // ensure content position is stable
       
   545     gridview->setContentY(0);
       
   546     model.moveItem(10, 0);
       
   547     QTRY_VERIFY(gridview->contentY() == 0);
       
   548 
       
   549     delete canvas;
       
   550 }
       
   551 
       
   552 void tst_QDeclarativeGridView::currentIndex()
       
   553 {
       
   554     TestModel model;
       
   555     for (int i = 0; i < 30; i++)
       
   556         model.addItem("Item" + QString::number(i), QString::number(i));
       
   557 
       
   558     QDeclarativeView *canvas = new QDeclarativeView(0);
       
   559     canvas->setFixedSize(240,320);
       
   560 
       
   561     QDeclarativeContext *ctxt = canvas->rootContext();
       
   562     ctxt->setContextProperty("testModel", &model);
       
   563 
       
   564     QString filename(SRCDIR "/data/gridview-initCurrent.qml");
       
   565     canvas->setSource(QUrl::fromLocalFile(filename));
       
   566 
       
   567     qApp->processEvents();
       
   568 
       
   569     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
   570     QTRY_VERIFY(gridview != 0);
       
   571 
       
   572     QDeclarativeItem *viewport = gridview->viewport();
       
   573     QTRY_VERIFY(viewport != 0);
       
   574 
       
   575     // current item should be third item
       
   576     QTRY_COMPARE(gridview->currentIndex(), 5);
       
   577     QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(viewport, "wrapper", 5));
       
   578     QTRY_COMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y());
       
   579 
       
   580     gridview->moveCurrentIndexRight();
       
   581     QTRY_COMPARE(gridview->currentIndex(), 6);
       
   582     gridview->moveCurrentIndexDown();
       
   583     QTRY_COMPARE(gridview->currentIndex(), 9);
       
   584     gridview->moveCurrentIndexUp();
       
   585     QTRY_COMPARE(gridview->currentIndex(), 6);
       
   586     gridview->moveCurrentIndexLeft();
       
   587     QTRY_COMPARE(gridview->currentIndex(), 5);
       
   588 
       
   589     // no wrap
       
   590     gridview->setCurrentIndex(0);
       
   591     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   592 
       
   593     gridview->moveCurrentIndexUp();
       
   594     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   595 
       
   596     gridview->moveCurrentIndexLeft();
       
   597     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   598 
       
   599     gridview->setCurrentIndex(model.count()-1);
       
   600     QTRY_COMPARE(gridview->currentIndex(), model.count()-1);
       
   601 
       
   602     gridview->moveCurrentIndexRight();
       
   603     QTRY_COMPARE(gridview->currentIndex(), model.count()-1);
       
   604 
       
   605     gridview->moveCurrentIndexDown();
       
   606     QTRY_COMPARE(gridview->currentIndex(), model.count()-1);
       
   607 
       
   608     // with wrap
       
   609     gridview->setWrapEnabled(true);
       
   610 
       
   611     gridview->setCurrentIndex(0);
       
   612     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   613 
       
   614     gridview->moveCurrentIndexLeft();
       
   615     QTRY_COMPARE(gridview->currentIndex(), model.count()-1);
       
   616 
       
   617     QTRY_COMPARE(gridview->contentY(), 279.0);
       
   618 
       
   619     gridview->moveCurrentIndexRight();
       
   620     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   621 
       
   622     QTRY_COMPARE(gridview->contentY(), 0.0);
       
   623 
       
   624     // Test keys
       
   625     canvas->show();
       
   626     qApp->setActiveWindow(canvas);
       
   627 #ifdef Q_WS_X11
       
   628     // to be safe and avoid failing setFocus with window managers
       
   629     qt_x11_wait_for_window_manager(canvas);
       
   630 #endif
       
   631     QTRY_VERIFY(canvas->hasFocus());
       
   632     QTRY_VERIFY(canvas->scene()->hasFocus());
       
   633     qApp->processEvents();
       
   634 
       
   635     QTest::keyClick(canvas, Qt::Key_Down);
       
   636     QTRY_COMPARE(gridview->currentIndex(), 3);
       
   637 
       
   638     QTest::keyClick(canvas, Qt::Key_Up);
       
   639     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   640 
       
   641     gridview->setFlow(QDeclarativeGridView::TopToBottom);
       
   642 
       
   643     QTest::keyClick(canvas, Qt::Key_Right);
       
   644     QTRY_COMPARE(gridview->currentIndex(), 5);
       
   645 
       
   646     QTest::keyClick(canvas, Qt::Key_Left);
       
   647     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   648 
       
   649     QTest::keyClick(canvas, Qt::Key_Down);
       
   650     QTRY_COMPARE(gridview->currentIndex(), 1);
       
   651 
       
   652     QTest::keyClick(canvas, Qt::Key_Up);
       
   653     QTRY_COMPARE(gridview->currentIndex(), 0);
       
   654 
       
   655 
       
   656     // turn off auto highlight
       
   657     gridview->setHighlightFollowsCurrentItem(false);
       
   658     QTRY_VERIFY(gridview->highlightFollowsCurrentItem() == false);
       
   659     QTRY_VERIFY(gridview->highlightItem());
       
   660     qreal hlPosX = gridview->highlightItem()->x();
       
   661     qreal hlPosY = gridview->highlightItem()->y();
       
   662 
       
   663     gridview->setCurrentIndex(5);
       
   664     QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
       
   665     QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
       
   666 
       
   667     // insert item before currentIndex
       
   668     gridview->setCurrentIndex(28);
       
   669     model.insertItem(0, "Foo", "1111");
       
   670     QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
       
   671 
       
   672     delete canvas;
       
   673 }
       
   674 
       
   675 void tst_QDeclarativeGridView::changeFlow()
       
   676 {
       
   677     QDeclarativeView *canvas = createView();
       
   678 
       
   679     TestModel model;
       
   680     for (int i = 0; i < 30; i++)
       
   681         model.addItem("Item" + QString::number(i), QString::number(i));
       
   682 
       
   683     QDeclarativeContext *ctxt = canvas->rootContext();
       
   684     ctxt->setContextProperty("testModel", &model);
       
   685     ctxt->setContextProperty("testTopToBottom", QVariant(false));
       
   686 
       
   687     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
       
   688     qApp->processEvents();
       
   689 
       
   690     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
   691     QTRY_VERIFY(gridview != 0);
       
   692 
       
   693     QDeclarativeItem *viewport = gridview->viewport();
       
   694     QTRY_VERIFY(viewport != 0);
       
   695 
       
   696     // Confirm items positioned correctly and indexes correct
       
   697     int itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   698     for (int i = 0; i < model.count() && i < itemCount; ++i) {
       
   699         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   700         if (!item) qWarning() << "Item" << i << "not found";
       
   701         QTRY_VERIFY(item);
       
   702         QTRY_COMPARE(item->x(), qreal((i%3)*80));
       
   703         QTRY_COMPARE(item->y(), qreal((i/3)*60));
       
   704         QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", i);
       
   705         QTRY_VERIFY(name != 0);
       
   706         QTRY_COMPARE(name->text(), model.name(i));
       
   707         QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", i);
       
   708         QTRY_VERIFY(number != 0);
       
   709         QTRY_COMPARE(number->text(), model.number(i));
       
   710     }
       
   711 
       
   712     ctxt->setContextProperty("testTopToBottom", QVariant(true));
       
   713 
       
   714     // Confirm items positioned correctly and indexes correct
       
   715     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   716     for (int i = 0; i < model.count() && i < itemCount; ++i) {
       
   717         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   718         if (!item) qWarning() << "Item" << i << "not found";
       
   719         QTRY_VERIFY(item);
       
   720         QTRY_COMPARE(item->x(), qreal((i/5)*80));
       
   721         QTRY_COMPARE(item->y(), qreal((i%5)*60));
       
   722         QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", i);
       
   723         QTRY_VERIFY(name != 0);
       
   724         QTRY_COMPARE(name->text(), model.name(i));
       
   725         QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", i);
       
   726         QTRY_VERIFY(number != 0);
       
   727         QTRY_COMPARE(number->text(), model.number(i));
       
   728     }
       
   729 
       
   730     delete canvas;
       
   731 }
       
   732 
       
   733 void tst_QDeclarativeGridView::defaultValues()
       
   734 {
       
   735     QDeclarativeEngine engine;
       
   736     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview3.qml"));
       
   737     QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(c.create());
       
   738 
       
   739     QTRY_VERIFY(obj != 0);
       
   740     QTRY_VERIFY(obj->model() == QVariant());
       
   741     QTRY_VERIFY(obj->delegate() == 0);
       
   742     QTRY_COMPARE(obj->currentIndex(), -1);
       
   743     QTRY_VERIFY(obj->currentItem() == 0);
       
   744     QTRY_COMPARE(obj->count(), 0);
       
   745     QTRY_VERIFY(obj->highlight() == 0);
       
   746     QTRY_VERIFY(obj->highlightItem() == 0);
       
   747     QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true);
       
   748     QTRY_VERIFY(obj->flow() == 0);
       
   749     QTRY_COMPARE(obj->isWrapEnabled(), false);
       
   750     QTRY_COMPARE(obj->cacheBuffer(), 0);
       
   751     QTRY_COMPARE(obj->cellWidth(), 100); //### Should 100 be the default?
       
   752     QTRY_COMPARE(obj->cellHeight(), 100);
       
   753     delete obj;
       
   754 }
       
   755 
       
   756 void tst_QDeclarativeGridView::properties()
       
   757 {
       
   758     QDeclarativeEngine engine;
       
   759     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview2.qml"));
       
   760     QDeclarativeGridView *obj = qobject_cast<QDeclarativeGridView*>(c.create());
       
   761 
       
   762     QTRY_VERIFY(obj != 0);
       
   763     QTRY_VERIFY(obj->model() != QVariant());
       
   764     QTRY_VERIFY(obj->delegate() != 0);
       
   765     QTRY_COMPARE(obj->currentIndex(), 0);
       
   766     QTRY_VERIFY(obj->currentItem() != 0);
       
   767     QTRY_COMPARE(obj->count(), 4);
       
   768     QTRY_VERIFY(obj->highlight() != 0);
       
   769     QTRY_VERIFY(obj->highlightItem() != 0);
       
   770     QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false);
       
   771     QTRY_VERIFY(obj->flow() == 0);
       
   772     QTRY_COMPARE(obj->isWrapEnabled(), true);
       
   773     QTRY_COMPARE(obj->cacheBuffer(), 200);
       
   774     QTRY_COMPARE(obj->cellWidth(), 100);
       
   775     QTRY_COMPARE(obj->cellHeight(), 100);
       
   776     delete obj;
       
   777 }
       
   778 
       
   779 void tst_QDeclarativeGridView::propertyChanges()
       
   780 {
       
   781     QDeclarativeView *canvas = createView();
       
   782     QTRY_VERIFY(canvas);
       
   783     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
       
   784 
       
   785     QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
       
   786     QTRY_VERIFY(gridView);
       
   787 
       
   788     QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged()));
       
   789     QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged()));
       
   790     QSignalSpy flowSpy(gridView, SIGNAL(flowChanged()));
       
   791 
       
   792     QTRY_COMPARE(gridView->isWrapEnabled(), true);
       
   793     QTRY_COMPARE(gridView->cacheBuffer(), 10);
       
   794     QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::LeftToRight);
       
   795 
       
   796     gridView->setWrapEnabled(false);
       
   797     gridView->setCacheBuffer(3);
       
   798     gridView->setFlow(QDeclarativeGridView::TopToBottom);
       
   799 
       
   800     QTRY_COMPARE(gridView->isWrapEnabled(), false);
       
   801     QTRY_COMPARE(gridView->cacheBuffer(), 3);
       
   802     QTRY_COMPARE(gridView->flow(), QDeclarativeGridView::TopToBottom);
       
   803 
       
   804     QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
       
   805     QTRY_COMPARE(cacheBufferSpy.count(),1);
       
   806     QTRY_COMPARE(flowSpy.count(),1);
       
   807 
       
   808     gridView->setWrapEnabled(false);
       
   809     gridView->setCacheBuffer(3);
       
   810     gridView->setFlow(QDeclarativeGridView::TopToBottom);
       
   811 
       
   812     QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
       
   813     QTRY_COMPARE(cacheBufferSpy.count(),1);
       
   814     QTRY_COMPARE(flowSpy.count(),1);
       
   815 
       
   816     delete canvas;
       
   817 }
       
   818 
       
   819 void tst_QDeclarativeGridView::componentChanges()
       
   820 {
       
   821     QDeclarativeView *canvas = createView();
       
   822     QTRY_VERIFY(canvas);
       
   823     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
       
   824 
       
   825     QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
       
   826     QTRY_VERIFY(gridView);
       
   827 
       
   828     QDeclarativeComponent component(canvas->engine());
       
   829     component.setData("import Qt 4.7; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
       
   830 
       
   831     QDeclarativeComponent delegateComponent(canvas->engine());
       
   832     delegateComponent.setData("import Qt 4.7; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
       
   833 
       
   834     QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged()));
       
   835     QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged()));
       
   836 
       
   837     gridView->setHighlight(&component);
       
   838     gridView->setDelegate(&delegateComponent);
       
   839 
       
   840     QTRY_COMPARE(gridView->highlight(), &component);
       
   841     QTRY_COMPARE(gridView->delegate(), &delegateComponent);
       
   842 
       
   843     QTRY_COMPARE(highlightSpy.count(),1);
       
   844     QTRY_COMPARE(delegateSpy.count(),1);
       
   845 
       
   846     gridView->setHighlight(&component);
       
   847     gridView->setDelegate(&delegateComponent);
       
   848 
       
   849     QTRY_COMPARE(highlightSpy.count(),1);
       
   850     QTRY_COMPARE(delegateSpy.count(),1);
       
   851     delete canvas;
       
   852 }
       
   853 
       
   854 void tst_QDeclarativeGridView::modelChanges()
       
   855 {
       
   856     QDeclarativeView *canvas = createView();
       
   857     QTRY_VERIFY(canvas);
       
   858     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
       
   859 
       
   860     QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView");
       
   861     QTRY_VERIFY(gridView);
       
   862 
       
   863     QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
       
   864     QTRY_VERIFY(alternateModel);
       
   865     QVariant modelVariant = QVariant::fromValue(alternateModel);
       
   866     QSignalSpy modelSpy(gridView, SIGNAL(modelChanged()));
       
   867 
       
   868     gridView->setModel(modelVariant);
       
   869     QTRY_COMPARE(gridView->model(), modelVariant);
       
   870     QTRY_COMPARE(modelSpy.count(),1);
       
   871 
       
   872     gridView->setModel(modelVariant);
       
   873     QTRY_COMPARE(modelSpy.count(),1);
       
   874 
       
   875     gridView->setModel(QVariant());
       
   876     QTRY_COMPARE(modelSpy.count(),2);
       
   877     delete canvas;
       
   878 }
       
   879 
       
   880 void tst_QDeclarativeGridView::positionViewAtIndex()
       
   881 {
       
   882     QDeclarativeView *canvas = createView();
       
   883 
       
   884     TestModel model;
       
   885     for (int i = 0; i < 40; i++)
       
   886         model.addItem("Item" + QString::number(i), "");
       
   887 
       
   888     QDeclarativeContext *ctxt = canvas->rootContext();
       
   889     ctxt->setContextProperty("testModel", &model);
       
   890     ctxt->setContextProperty("testTopToBottom", QVariant(false));
       
   891 
       
   892     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
       
   893     qApp->processEvents();
       
   894 
       
   895     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
   896     QTRY_VERIFY(gridview != 0);
       
   897 
       
   898     QDeclarativeItem *viewport = gridview->viewport();
       
   899     QTRY_VERIFY(viewport != 0);
       
   900 
       
   901     // Confirm items positioned correctly
       
   902     int itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   903     for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
       
   904         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   905         if (!item) qWarning() << "Item" << i << "not found";
       
   906         QTRY_VERIFY(item);
       
   907         QTRY_COMPARE(item->x(), (i%3)*80.);
       
   908         QTRY_COMPARE(item->y(), (i/3)*60.);
       
   909     }
       
   910 
       
   911     // Position on a currently visible item
       
   912     gridview->positionViewAtIndex(4, QDeclarativeGridView::Beginning);
       
   913     QTRY_COMPARE(gridview->contentY(), 60.);
       
   914 
       
   915     // Confirm items positioned correctly
       
   916     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   917     for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
       
   918         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   919         if (!item) qWarning() << "Item" << i << "not found";
       
   920         QTRY_VERIFY(item);
       
   921         QTRY_COMPARE(item->x(), (i%3)*80.);
       
   922         QTRY_COMPARE(item->y(), (i/3)*60.);
       
   923     }
       
   924 
       
   925     // Position on an item beyond the visible items
       
   926     gridview->positionViewAtIndex(21, QDeclarativeGridView::Beginning);
       
   927     QTRY_COMPARE(gridview->contentY(), 420.);
       
   928 
       
   929     // Confirm items positioned correctly
       
   930     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   931     for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
       
   932         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   933         if (!item) qWarning() << "Item" << i << "not found";
       
   934         QTRY_VERIFY(item);
       
   935         QTRY_COMPARE(item->x(), (i%3)*80.);
       
   936         QTRY_COMPARE(item->y(), (i/3)*60.);
       
   937     }
       
   938 
       
   939     // Position on an item that would leave empty space if positioned at the top
       
   940     gridview->positionViewAtIndex(31, QDeclarativeGridView::Beginning);
       
   941     QTRY_COMPARE(gridview->contentY(), 520.);
       
   942 
       
   943     // Confirm items positioned correctly
       
   944     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   945     for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
       
   946         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   947         if (!item) qWarning() << "Item" << i << "not found";
       
   948         QTRY_VERIFY(item);
       
   949         QTRY_COMPARE(item->x(), (i%3)*80.);
       
   950         QTRY_COMPARE(item->y(), (i/3)*60.);
       
   951     }
       
   952 
       
   953     // Position at the beginning again
       
   954     gridview->positionViewAtIndex(0, QDeclarativeGridView::Beginning);
       
   955     QTRY_COMPARE(gridview->contentY(), 0.);
       
   956 
       
   957     // Confirm items positioned correctly
       
   958     itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count();
       
   959     for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
       
   960         QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i);
       
   961         if (!item) qWarning() << "Item" << i << "not found";
       
   962         QTRY_VERIFY(item);
       
   963         QTRY_COMPARE(item->x(), (i%3)*80.);
       
   964         QTRY_COMPARE(item->y(), (i/3)*60.);
       
   965     }
       
   966 
       
   967     // Position at End
       
   968     gridview->positionViewAtIndex(30, QDeclarativeGridView::End);
       
   969     QTRY_COMPARE(gridview->contentY(), 340.);
       
   970 
       
   971     // Position in Center
       
   972     gridview->positionViewAtIndex(15, QDeclarativeGridView::Center);
       
   973     QTRY_COMPARE(gridview->contentY(), 170.);
       
   974 
       
   975     // Ensure at least partially visible
       
   976     gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
       
   977     QTRY_COMPARE(gridview->contentY(), 170.);
       
   978 
       
   979     gridview->setContentY(302);
       
   980     gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
       
   981     QTRY_COMPARE(gridview->contentY(), 302.);
       
   982 
       
   983     gridview->setContentY(360);
       
   984     gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible);
       
   985     QTRY_COMPARE(gridview->contentY(), 300.);
       
   986 
       
   987     gridview->setContentY(60);
       
   988     gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
       
   989     QTRY_COMPARE(gridview->contentY(), 60.);
       
   990 
       
   991     gridview->setContentY(20);
       
   992     gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible);
       
   993     QTRY_COMPARE(gridview->contentY(), 100.);
       
   994 
       
   995     // Ensure completely visible
       
   996     gridview->setContentY(120);
       
   997     gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
       
   998     QTRY_COMPARE(gridview->contentY(), 120.);
       
   999 
       
  1000     gridview->setContentY(302);
       
  1001     gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain);
       
  1002     QTRY_COMPARE(gridview->contentY(), 300.);
       
  1003 
       
  1004     gridview->setContentY(60);
       
  1005     gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain);
       
  1006     QTRY_COMPARE(gridview->contentY(), 100.);
       
  1007 
       
  1008     delete canvas;
       
  1009 }
       
  1010 
       
  1011 void tst_QDeclarativeGridView::resetModel()
       
  1012 {
       
  1013     QDeclarativeView *canvas = createView();
       
  1014 
       
  1015     QStringList strings;
       
  1016     strings << "one" << "two" << "three";
       
  1017     QStringListModel model(strings);
       
  1018 
       
  1019     QDeclarativeContext *ctxt = canvas->rootContext();
       
  1020     ctxt->setContextProperty("testModel", &model);
       
  1021 
       
  1022     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaygrid.qml"));
       
  1023     qApp->processEvents();
       
  1024 
       
  1025     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
  1026     QTRY_VERIFY(gridview != 0);
       
  1027 
       
  1028     QDeclarativeItem *viewport = gridview->viewport();
       
  1029     QTRY_VERIFY(viewport != 0);
       
  1030 
       
  1031     QTRY_COMPARE(gridview->count(), model.rowCount());
       
  1032 
       
  1033     for (int i = 0; i < model.rowCount(); ++i) {
       
  1034         QDeclarativeText *display = findItem<QDeclarativeText>(viewport, "displayText", i);
       
  1035         QTRY_VERIFY(display != 0);
       
  1036         QTRY_COMPARE(display->text(), strings.at(i));
       
  1037     }
       
  1038 
       
  1039     strings.clear();
       
  1040     strings << "four" << "five" << "six" << "seven";
       
  1041     model.setStringList(strings);
       
  1042 
       
  1043     QTRY_COMPARE(gridview->count(), model.rowCount());
       
  1044 
       
  1045     for (int i = 0; i < model.rowCount(); ++i) {
       
  1046         QDeclarativeText *display = findItem<QDeclarativeText>(viewport, "displayText", i);
       
  1047         QTRY_VERIFY(display != 0);
       
  1048         QTRY_COMPARE(display->text(), strings.at(i));
       
  1049     }
       
  1050 }
       
  1051 
       
  1052 void tst_QDeclarativeGridView::enforceRange()
       
  1053 {
       
  1054     QDeclarativeView *canvas = createView();
       
  1055 
       
  1056     TestModel model;
       
  1057     for (int i = 0; i < 30; i++)
       
  1058         model.addItem("Item" + QString::number(i), "");
       
  1059 
       
  1060     QDeclarativeContext *ctxt = canvas->rootContext();
       
  1061     ctxt->setContextProperty("testModel", &model);
       
  1062 
       
  1063     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
       
  1064     qApp->processEvents();
       
  1065 
       
  1066     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
  1067     QTRY_VERIFY(gridview != 0);
       
  1068 
       
  1069     QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
       
  1070     QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
       
  1071     QTRY_COMPARE(gridview->highlightRangeMode(), QDeclarativeGridView::StrictlyEnforceRange);
       
  1072 
       
  1073     QDeclarativeItem *viewport = gridview->viewport();
       
  1074     QTRY_VERIFY(viewport != 0);
       
  1075 
       
  1076     // view should be positioned at the top of the range.
       
  1077     QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", 0);
       
  1078     QTRY_VERIFY(item);
       
  1079     QTRY_COMPARE(gridview->contentY(), -100.0);
       
  1080 
       
  1081     QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", 0);
       
  1082     QTRY_VERIFY(name != 0);
       
  1083     QTRY_COMPARE(name->text(), model.name(0));
       
  1084     QDeclarativeText *number = findItem<QDeclarativeText>(viewport, "textNumber", 0);
       
  1085     QTRY_VERIFY(number != 0);
       
  1086     QTRY_COMPARE(number->text(), model.number(0));
       
  1087 
       
  1088     // Check currentIndex is updated when viewport moves
       
  1089     gridview->setContentY(0);
       
  1090     QTRY_COMPARE(gridview->currentIndex(), 2);
       
  1091 
       
  1092     gridview->setCurrentIndex(5);
       
  1093     QTRY_COMPARE(gridview->contentY(), 100.);
       
  1094 
       
  1095     delete canvas;
       
  1096 }
       
  1097 
       
  1098 void tst_QDeclarativeGridView::QTBUG_8456()
       
  1099 {
       
  1100     QDeclarativeView *canvas = createView();
       
  1101 
       
  1102     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/setindex.qml"));
       
  1103     qApp->processEvents();
       
  1104 
       
  1105     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
  1106     QTRY_VERIFY(gridview != 0);
       
  1107 
       
  1108     QTRY_COMPARE(gridview->currentIndex(), 0);
       
  1109 }
       
  1110 
       
  1111 void tst_QDeclarativeGridView::manualHighlight()
       
  1112 {
       
  1113     QDeclarativeView *canvas = createView();
       
  1114 
       
  1115     QString filename(SRCDIR "/data/manual-highlight.qml");
       
  1116     canvas->setSource(QUrl::fromLocalFile(filename));
       
  1117 
       
  1118     qApp->processEvents();
       
  1119 
       
  1120     QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid");
       
  1121     QTRY_VERIFY(gridview != 0);
       
  1122 
       
  1123     QDeclarativeItem *viewport = gridview->viewport();
       
  1124     QTRY_VERIFY(viewport != 0);
       
  1125 
       
  1126     QTRY_COMPARE(gridview->currentIndex(), 0);
       
  1127     QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(viewport, "wrapper", 0));
       
  1128     QTRY_COMPARE(gridview->highlightItem()->y(), gridview->currentItem()->y());
       
  1129     QTRY_COMPARE(gridview->highlightItem()->x(), gridview->currentItem()->x());
       
  1130 
       
  1131     gridview->setCurrentIndex(2);
       
  1132 
       
  1133     QTRY_COMPARE(gridview->currentIndex(), 2);
       
  1134     QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(viewport, "wrapper", 2));
       
  1135     QTRY_COMPARE(gridview->highlightItem()->y(), gridview->currentItem()->y());
       
  1136     QTRY_COMPARE(gridview->highlightItem()->x(), gridview->currentItem()->x());
       
  1137 }
       
  1138 
       
  1139 
       
  1140 QDeclarativeView *tst_QDeclarativeGridView::createView()
       
  1141 {
       
  1142     QDeclarativeView *canvas = new QDeclarativeView(0);
       
  1143     canvas->setFixedSize(240,320);
       
  1144 
       
  1145     return canvas;
       
  1146 }
       
  1147 
       
  1148 /*
       
  1149    Find an item with the specified objectName.  If index is supplied then the
       
  1150    item must also evaluate the {index} expression equal to index
       
  1151 */
       
  1152 template<typename T>
       
  1153 T *tst_QDeclarativeGridView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
       
  1154 {
       
  1155     const QMetaObject &mo = T::staticMetaObject;
       
  1156     //qDebug() << parent->childItems().count() << "children";
       
  1157     for (int i = 0; i < parent->childItems().count(); ++i) {
       
  1158         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
       
  1159         if(!item)
       
  1160             continue;
       
  1161         //qDebug() << "try" << item;
       
  1162         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
       
  1163             if (index != -1) {
       
  1164                 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
       
  1165                 if (context) {
       
  1166                     if (context->contextProperty("index").toInt() == index) {
       
  1167                         return static_cast<T*>(item);
       
  1168                     }
       
  1169                 }
       
  1170             } else {
       
  1171                 return static_cast<T*>(item);
       
  1172             }
       
  1173         }
       
  1174         item = findItem<T>(item, objectName, index);
       
  1175         if (item)
       
  1176             return static_cast<T*>(item);
       
  1177     }
       
  1178 
       
  1179     return 0;
       
  1180 }
       
  1181 
       
  1182 template<typename T>
       
  1183 QList<T*> tst_QDeclarativeGridView::findItems(QGraphicsObject *parent, const QString &objectName)
       
  1184 {
       
  1185     QList<T*> items;
       
  1186     const QMetaObject &mo = T::staticMetaObject;
       
  1187     //qDebug() << parent->childItems().count() << "children";
       
  1188     for (int i = 0; i < parent->childItems().count(); ++i) {
       
  1189         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
       
  1190         if(!item)
       
  1191             continue;
       
  1192         //qDebug() << "try" << item;
       
  1193         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
       
  1194             items.append(static_cast<T*>(item));
       
  1195             //qDebug() << " found:" << item;
       
  1196         }
       
  1197         items += findItems<T>(item, objectName);
       
  1198     }
       
  1199 
       
  1200     return items;
       
  1201 }
       
  1202 
       
  1203 void tst_QDeclarativeGridView::dumpTree(QDeclarativeItem *parent, int depth)
       
  1204 {
       
  1205     static QString padding("                       ");
       
  1206     for (int i = 0; i < parent->childItems().count(); ++i) {
       
  1207         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
       
  1208         if(!item)
       
  1209             continue;
       
  1210         QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
       
  1211         qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
       
  1212         dumpTree(item, depth+1);
       
  1213     }
       
  1214 }
       
  1215 
       
  1216 
       
  1217 QTEST_MAIN(tst_QDeclarativeGridView)
       
  1218 
       
  1219 #include "tst_qdeclarativegridview.moc"