tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.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 <QtDeclarative/qdeclarativeview.h>
       
    44 #include <QtDeclarative/qdeclarativeengine.h>
       
    45 #include <QtDeclarative/qdeclarativecomponent.h>
       
    46 #include <QtDeclarative/qdeclarativecontext.h>
       
    47 #include <QtDeclarative/qdeclarativeexpression.h>
       
    48 #include <QtDeclarative/private/qdeclarativepathview_p.h>
       
    49 #include <QtDeclarative/private/qdeclarativepath_p.h>
       
    50 #include <QtDeclarative/private/qdeclarativetext_p.h>
       
    51 #include <QtDeclarative/private/qdeclarativerectangle_p.h>
       
    52 #include <QtDeclarative/private/qdeclarativelistmodel_p.h>
       
    53 #include <QtDeclarative/private/qdeclarativevaluetype_p.h>
       
    54 #include <QAbstractListModel>
       
    55 #include <QStringListModel>
       
    56 #include <QFile>
       
    57 
       
    58 #include "../../../shared/util.h"
       
    59 
       
    60 class tst_QDeclarativePathView : public QObject
       
    61 {
       
    62     Q_OBJECT
       
    63 public:
       
    64     tst_QDeclarativePathView();
       
    65 
       
    66 private slots:
       
    67     void initValues();
       
    68     void items();
       
    69     void dataModel();
       
    70     void pathview2();
       
    71     void pathview3();
       
    72     void path();
       
    73     void pathMoved();
       
    74     void setCurrentIndex();
       
    75     void resetModel();
       
    76     void propertyChanges();
       
    77     void pathChanges();
       
    78     void componentChanges();
       
    79     void modelChanges();
       
    80     void pathUpdateOnStartChanged();
       
    81     void package();
       
    82 
       
    83 
       
    84 private:
       
    85     QDeclarativeView *createView();
       
    86     template<typename T>
       
    87     T *findItem(QGraphicsObject *parent, const QString &objectName, int index=-1);
       
    88     template<typename T>
       
    89     QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
       
    90 };
       
    91 
       
    92 class TestObject : public QObject
       
    93 {
       
    94     Q_OBJECT
       
    95 
       
    96     Q_PROPERTY(bool error READ error WRITE setError)
       
    97     Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
       
    98     Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged)
       
    99 
       
   100 public:
       
   101     TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {}
       
   102 
       
   103     bool error() const { return mError; }
       
   104     void setError(bool err) { mError = err; }
       
   105 
       
   106     bool useModel() const { return mUseModel; }
       
   107     void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
       
   108 
       
   109     int pathItemCount() const { return mPathItemCount; }
       
   110     void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); }
       
   111 
       
   112 signals:
       
   113     void useModelChanged();
       
   114     void pathItemCountChanged();
       
   115 
       
   116 private:
       
   117     bool mError;
       
   118     bool mUseModel;
       
   119     int mPathItemCount;
       
   120 };
       
   121 
       
   122 class TestModel : public QAbstractListModel
       
   123 {
       
   124 public:
       
   125     enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
       
   126 
       
   127     TestModel(QObject *parent=0) : QAbstractListModel(parent) {
       
   128         QHash<int, QByteArray> roles;
       
   129         roles[Name] = "name";
       
   130         roles[Number] = "number";
       
   131         setRoleNames(roles);
       
   132     }
       
   133 
       
   134     int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
       
   135     QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
       
   136         QVariant rv;
       
   137         if (role == Name)
       
   138             rv = list.at(index.row()).first;
       
   139         else if (role == Number)
       
   140             rv = list.at(index.row()).second;
       
   141 
       
   142         return rv;
       
   143     }
       
   144 
       
   145     int count() const { return rowCount(); }
       
   146     QString name(int index) const { return list.at(index).first; }
       
   147     QString number(int index) const { return list.at(index).second; }
       
   148 
       
   149     void addItem(const QString &name, const QString &number) {
       
   150         emit beginInsertRows(QModelIndex(), list.count(), list.count());
       
   151         list.append(QPair<QString,QString>(name, number));
       
   152         emit endInsertRows();
       
   153     }
       
   154 
       
   155     void insertItem(int index, const QString &name, const QString &number) {
       
   156         emit beginInsertRows(QModelIndex(), index, index);
       
   157         list.insert(index, QPair<QString,QString>(name, number));
       
   158         emit endInsertRows();
       
   159     }
       
   160 
       
   161     void removeItem(int index) {
       
   162         emit beginRemoveRows(QModelIndex(), index, index);
       
   163         list.removeAt(index);
       
   164         emit endRemoveRows();
       
   165     }
       
   166 
       
   167     void moveItem(int from, int to) {
       
   168         emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
       
   169         list.move(from, to);
       
   170         emit endMoveRows();
       
   171     }
       
   172 
       
   173     void modifyItem(int idx, const QString &name, const QString &number) {
       
   174         list[idx] = QPair<QString,QString>(name, number);
       
   175         emit dataChanged(index(idx,0), index(idx,0));
       
   176     }
       
   177 
       
   178 private:
       
   179     QList<QPair<QString,QString> > list;
       
   180 };
       
   181 
       
   182 
       
   183 tst_QDeclarativePathView::tst_QDeclarativePathView()
       
   184 {
       
   185 }
       
   186 
       
   187 void tst_QDeclarativePathView::initValues()
       
   188 {
       
   189     QDeclarativeEngine engine;
       
   190     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview1.qml"));
       
   191     QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
       
   192 
       
   193     QVERIFY(obj != 0);
       
   194     QVERIFY(obj->path() == 0);
       
   195     QVERIFY(obj->delegate() == 0);
       
   196     QCOMPARE(obj->model(), QVariant());
       
   197     QCOMPARE(obj->currentIndex(), 0);
       
   198     QCOMPARE(obj->offset(), 0.);
       
   199     QCOMPARE(obj->preferredHighlightBegin(), 0.);
       
   200     QCOMPARE(obj->dragMargin(), 0.);
       
   201     QCOMPARE(obj->count(), 0);
       
   202     QCOMPARE(obj->pathItemCount(), -1);
       
   203 }
       
   204 
       
   205 void tst_QDeclarativePathView::items()
       
   206 {
       
   207     QDeclarativeView *canvas = createView();
       
   208 
       
   209     TestModel model;
       
   210     model.addItem("Fred", "12345");
       
   211     model.addItem("John", "2345");
       
   212     model.addItem("Bob", "54321");
       
   213     model.addItem("Bill", "4321");
       
   214 
       
   215     QDeclarativeContext *ctxt = canvas->rootContext();
       
   216     ctxt->setContextProperty("testModel", &model);
       
   217 
       
   218     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
       
   219     qApp->processEvents();
       
   220 
       
   221     QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
       
   222     QVERIFY(pathview != 0);
       
   223 
       
   224     QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight
       
   225 
       
   226     for (int i = 0; i < model.count(); ++i) {
       
   227         QDeclarativeText *name = findItem<QDeclarativeText>(pathview, "textName", i);
       
   228         QVERIFY(name != 0);
       
   229         QCOMPARE(name->text(), model.name(i));
       
   230         QDeclarativeText *number = findItem<QDeclarativeText>(pathview, "textNumber", i);
       
   231         QVERIFY(number != 0);
       
   232         QCOMPARE(number->text(), model.number(i));
       
   233     }
       
   234 
       
   235     QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
       
   236     QVERIFY(path);
       
   237 
       
   238     QVERIFY(pathview->highlightItem());
       
   239     QPointF start = path->pointAt(0.0);
       
   240     QPointF offset;
       
   241     offset.setX(pathview->highlightItem()->width()/2);
       
   242     offset.setY(pathview->highlightItem()->height()/2);
       
   243     QCOMPARE(pathview->highlightItem()->pos() + offset, start);
       
   244 
       
   245     delete canvas;
       
   246 }
       
   247 
       
   248 void tst_QDeclarativePathView::pathview2()
       
   249 {
       
   250     QDeclarativeEngine engine;
       
   251     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview2.qml"));
       
   252     QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
       
   253 
       
   254     QVERIFY(obj != 0);
       
   255     QVERIFY(obj->path() != 0);
       
   256     QVERIFY(obj->delegate() != 0);
       
   257     QVERIFY(obj->model() != QVariant());
       
   258     QCOMPARE(obj->currentIndex(), 0);
       
   259     QCOMPARE(obj->offset(), 0.);
       
   260     QCOMPARE(obj->preferredHighlightBegin(), 0.);
       
   261     QCOMPARE(obj->dragMargin(), 0.);
       
   262     QCOMPARE(obj->count(), 8);
       
   263     QCOMPARE(obj->pathItemCount(), 10);
       
   264 }
       
   265 
       
   266 void tst_QDeclarativePathView::pathview3()
       
   267 {
       
   268     QDeclarativeEngine engine;
       
   269     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview3.qml"));
       
   270     QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
       
   271 
       
   272     QVERIFY(obj != 0);
       
   273     QVERIFY(obj->path() != 0);
       
   274     QVERIFY(obj->delegate() != 0);
       
   275     QVERIFY(obj->model() != QVariant());
       
   276     QCOMPARE(obj->currentIndex(), 0);
       
   277     QCOMPARE(obj->offset(), 1.0);
       
   278     QCOMPARE(obj->preferredHighlightBegin(), 0.5);
       
   279     QCOMPARE(obj->dragMargin(), 24.);
       
   280     QCOMPARE(obj->count(), 8);
       
   281     QCOMPARE(obj->pathItemCount(), 4);
       
   282 }
       
   283 
       
   284 void tst_QDeclarativePathView::path()
       
   285 {
       
   286     QDeclarativeEngine engine;
       
   287     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathtest.qml"));
       
   288     QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
       
   289 
       
   290     QVERIFY(obj != 0);
       
   291     QCOMPARE(obj->startX(), 120.);
       
   292     QCOMPARE(obj->startY(), 100.);
       
   293     QVERIFY(obj->path() != QPainterPath());
       
   294 
       
   295     QDeclarativeListReference list(obj, "pathElements");
       
   296     QCOMPARE(list.count(), 5);
       
   297 
       
   298     QDeclarativePathAttribute* attr = qobject_cast<QDeclarativePathAttribute*>(list.at(0));
       
   299     QVERIFY(attr != 0);
       
   300     QCOMPARE(attr->name(), QString("scale"));
       
   301     QCOMPARE(attr->value(), 1.0);
       
   302 
       
   303     QDeclarativePathQuad* quad = qobject_cast<QDeclarativePathQuad*>(list.at(1));
       
   304     QVERIFY(quad != 0);
       
   305     QCOMPARE(quad->x(), 120.);
       
   306     QCOMPARE(quad->y(), 25.);
       
   307     QCOMPARE(quad->controlX(), 260.);
       
   308     QCOMPARE(quad->controlY(), 75.);
       
   309 
       
   310     QDeclarativePathPercent* perc = qobject_cast<QDeclarativePathPercent*>(list.at(2));
       
   311     QVERIFY(perc != 0);
       
   312     QCOMPARE(perc->value(), 0.3);
       
   313 
       
   314     QDeclarativePathLine* line = qobject_cast<QDeclarativePathLine*>(list.at(3));
       
   315     QVERIFY(line != 0);
       
   316     QCOMPARE(line->x(), 120.);
       
   317     QCOMPARE(line->y(), 100.);
       
   318 
       
   319     QDeclarativePathCubic* cubic = qobject_cast<QDeclarativePathCubic*>(list.at(4));
       
   320     QVERIFY(cubic != 0);
       
   321     QCOMPARE(cubic->x(), 180.);
       
   322     QCOMPARE(cubic->y(), 0.);
       
   323     QCOMPARE(cubic->control1X(), -10.);
       
   324     QCOMPARE(cubic->control1Y(), 90.);
       
   325     QCOMPARE(cubic->control2X(), 210.);
       
   326     QCOMPARE(cubic->control2Y(), 90.);
       
   327 }
       
   328 
       
   329 void tst_QDeclarativePathView::dataModel()
       
   330 {
       
   331     QDeclarativeView *canvas = createView();
       
   332 
       
   333     QDeclarativeContext *ctxt = canvas->rootContext();
       
   334     TestObject *testObject = new TestObject;
       
   335     ctxt->setContextProperty("testObject", testObject);
       
   336 
       
   337     TestModel model;
       
   338     model.addItem("red", "1");
       
   339     model.addItem("green", "2");
       
   340     model.addItem("blue", "3");
       
   341     model.addItem("purple", "4");
       
   342     model.addItem("gray", "5");
       
   343     model.addItem("brown", "6");
       
   344     model.addItem("yellow", "7");
       
   345     model.addItem("thistle", "8");
       
   346     model.addItem("cyan", "9");
       
   347 
       
   348     ctxt->setContextProperty("testData", &model);
       
   349 
       
   350     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/datamodel.qml"));
       
   351     qApp->processEvents();
       
   352 
       
   353     QDeclarativePathView *pathview = qobject_cast<QDeclarativePathView*>(canvas->rootObject());
       
   354     QVERIFY(pathview != 0);
       
   355 
       
   356     QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
       
   357     QVERIFY(testObject->error() == false);
       
   358 
       
   359     QDeclarativeItem *item = findItem<QDeclarativeItem>(pathview, "wrapper", 0);
       
   360     QVERIFY(item);
       
   361     QCOMPARE(item->x(), 110.0);
       
   362     QCOMPARE(item->y(), 10.0);
       
   363 
       
   364     model.insertItem(4, "orange", "10");
       
   365 
       
   366     int itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count();
       
   367     QCOMPARE(itemCount, 10);
       
   368 
       
   369     QDeclarativeText *text = findItem<QDeclarativeText>(pathview, "myText", 4);
       
   370     QVERIFY(text);
       
   371     QCOMPARE(text->text(), model.name(4));
       
   372 
       
   373     model.removeItem(2);
       
   374     text = findItem<QDeclarativeText>(pathview, "myText", 2);
       
   375     QVERIFY(text);
       
   376     QCOMPARE(text->text(), model.name(2));
       
   377 
       
   378     testObject->setPathItemCount(5);
       
   379     QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
       
   380     QVERIFY(testObject->error() == false);
       
   381 
       
   382     itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count();
       
   383     QCOMPARE(itemCount, 5);
       
   384 
       
   385     QDeclarativeRectangle *testItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 4);
       
   386     QVERIFY(testItem != 0);
       
   387     testItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 5);
       
   388     QVERIFY(testItem == 0);
       
   389 
       
   390     model.insertItem(2, "pink", "2");
       
   391 
       
   392     itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count();
       
   393     QCOMPARE(itemCount, 5);
       
   394 
       
   395     text = findItem<QDeclarativeText>(pathview, "myText", 2);
       
   396     QVERIFY(text);
       
   397     QCOMPARE(text->text(), model.name(2));
       
   398 
       
   399     model.removeItem(3);
       
   400     itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count();
       
   401     QCOMPARE(itemCount, 5);
       
   402     text = findItem<QDeclarativeText>(pathview, "myText", 3);
       
   403     QVERIFY(text);
       
   404     QCOMPARE(text->text(), model.name(3));
       
   405 
       
   406     delete canvas;
       
   407 }
       
   408 
       
   409 void tst_QDeclarativePathView::pathMoved()
       
   410 {
       
   411     QDeclarativeView *canvas = createView();
       
   412 
       
   413     TestModel model;
       
   414     model.addItem("Ben", "12345");
       
   415     model.addItem("Bohn", "2345");
       
   416     model.addItem("Bob", "54321");
       
   417     model.addItem("Bill", "4321");
       
   418 
       
   419     QDeclarativeContext *ctxt = canvas->rootContext();
       
   420     ctxt->setContextProperty("testModel", &model);
       
   421 
       
   422     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
       
   423     qApp->processEvents();
       
   424 
       
   425     QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
       
   426     QVERIFY(pathview != 0);
       
   427 
       
   428     QDeclarativeRectangle *firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
       
   429     QVERIFY(firstItem);
       
   430     QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
       
   431     QVERIFY(path);
       
   432     QPointF start = path->pointAt(0.0);
       
   433     QPointF offset;//Center of item is at point, but pos is from corner
       
   434     offset.setX(firstItem->width()/2);
       
   435     offset.setY(firstItem->height()/2);
       
   436     QCOMPARE(firstItem->pos() + offset, start);
       
   437     pathview->setOffset(1.0);
       
   438 
       
   439     for(int i=0; i<model.count(); i++){
       
   440         QDeclarativeRectangle *curItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", i);
       
   441         QPointF itemPos(path->pointAt(0.25 + i*0.25));
       
   442         QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y())));
       
   443     }
       
   444 
       
   445     pathview->setOffset(0.0);
       
   446     QCOMPARE(firstItem->pos() + offset, start);
       
   447 
       
   448     delete canvas;
       
   449 }
       
   450 
       
   451 void tst_QDeclarativePathView::setCurrentIndex()
       
   452 {
       
   453     QDeclarativeView *canvas = createView();
       
   454 
       
   455     TestModel model;
       
   456     model.addItem("Ben", "12345");
       
   457     model.addItem("Bohn", "2345");
       
   458     model.addItem("Bob", "54321");
       
   459     model.addItem("Bill", "4321");
       
   460 
       
   461     QDeclarativeContext *ctxt = canvas->rootContext();
       
   462     ctxt->setContextProperty("testModel", &model);
       
   463 
       
   464     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
       
   465     qApp->processEvents();
       
   466 
       
   467     QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
       
   468     QVERIFY(pathview != 0);
       
   469 
       
   470     QDeclarativeRectangle *firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
       
   471     QVERIFY(firstItem);
       
   472     QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
       
   473     QVERIFY(path);
       
   474     QPointF start = path->pointAt(0.0);
       
   475     QPointF offset;//Center of item is at point, but pos is from corner
       
   476     offset.setX(firstItem->width()/2);
       
   477     offset.setY(firstItem->height()/2);
       
   478     QCOMPARE(firstItem->pos() + offset, start);
       
   479     QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0);
       
   480     QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0);
       
   481 
       
   482     pathview->setCurrentIndex(2);
       
   483 
       
   484     firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 2);
       
   485     QTRY_COMPARE(firstItem->pos() + offset, start);
       
   486     QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2);
       
   487     QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2);
       
   488 
       
   489     pathview->decrementCurrentIndex();
       
   490     QTRY_COMPARE(pathview->currentIndex(), 1);
       
   491     firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 1);
       
   492     QVERIFY(firstItem);
       
   493     QTRY_COMPARE(firstItem->pos() + offset, start);
       
   494 
       
   495     pathview->decrementCurrentIndex();
       
   496     QTRY_COMPARE(pathview->currentIndex(), 0);
       
   497     firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
       
   498     QVERIFY(firstItem);
       
   499     QTRY_COMPARE(firstItem->pos() + offset, start);
       
   500 
       
   501     pathview->decrementCurrentIndex();
       
   502     QTRY_COMPARE(pathview->currentIndex(), 3);
       
   503     firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 3);
       
   504     QVERIFY(firstItem);
       
   505     QTRY_COMPARE(firstItem->pos() + offset, start);
       
   506 
       
   507     pathview->incrementCurrentIndex();
       
   508     QTRY_COMPARE(pathview->currentIndex(), 0);
       
   509     firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
       
   510     QVERIFY(firstItem);
       
   511     QTRY_COMPARE(firstItem->pos() + offset, start);
       
   512 
       
   513     delete canvas;
       
   514 }
       
   515 
       
   516 void tst_QDeclarativePathView::resetModel()
       
   517 {
       
   518     QDeclarativeView *canvas = createView();
       
   519 
       
   520     QStringList strings;
       
   521     strings << "one" << "two" << "three";
       
   522     QStringListModel model(strings);
       
   523 
       
   524     QDeclarativeContext *ctxt = canvas->rootContext();
       
   525     ctxt->setContextProperty("testModel", &model);
       
   526 
       
   527     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaypath.qml"));
       
   528     qApp->processEvents();
       
   529 
       
   530     QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
       
   531     QVERIFY(pathview != 0);
       
   532 
       
   533     QCOMPARE(pathview->count(), model.rowCount());
       
   534 
       
   535     for (int i = 0; i < model.rowCount(); ++i) {
       
   536         QDeclarativeText *display = findItem<QDeclarativeText>(pathview, "displayText", i);
       
   537         QVERIFY(display != 0);
       
   538         QCOMPARE(display->text(), strings.at(i));
       
   539     }
       
   540 
       
   541     strings.clear();
       
   542     strings << "four" << "five" << "six" << "seven";
       
   543     model.setStringList(strings);
       
   544 
       
   545     QCOMPARE(pathview->count(), model.rowCount());
       
   546 
       
   547     for (int i = 0; i < model.rowCount(); ++i) {
       
   548         QDeclarativeText *display = findItem<QDeclarativeText>(pathview, "displayText", i);
       
   549         QVERIFY(display != 0);
       
   550         QCOMPARE(display->text(), strings.at(i));
       
   551     }
       
   552 }
       
   553 
       
   554 void tst_QDeclarativePathView::propertyChanges()
       
   555 {
       
   556     QDeclarativeView *canvas = createView();
       
   557     QVERIFY(canvas);
       
   558     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
       
   559 
       
   560     QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
       
   561     QVERIFY(pathView);
       
   562 
       
   563     QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged()));
       
   564     QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged()));
       
   565 
       
   566     QCOMPARE(pathView->preferredHighlightBegin(), 0.1);
       
   567     QCOMPARE(pathView->dragMargin(), 5.0);
       
   568 
       
   569     pathView->setPreferredHighlightBegin(0.4);
       
   570     pathView->setPreferredHighlightEnd(0.4);
       
   571     pathView->setDragMargin(20.0);
       
   572 
       
   573     QCOMPARE(pathView->preferredHighlightBegin(), 0.4);
       
   574     QCOMPARE(pathView->preferredHighlightEnd(), 0.4);
       
   575     QCOMPARE(pathView->dragMargin(), 20.0);
       
   576 
       
   577     QCOMPARE(snapPositionSpy.count(), 1);
       
   578     QCOMPARE(dragMarginSpy.count(), 1);
       
   579 
       
   580     pathView->setPreferredHighlightBegin(0.4);
       
   581     pathView->setPreferredHighlightEnd(0.4);
       
   582     pathView->setDragMargin(20.0);
       
   583 
       
   584     QCOMPARE(snapPositionSpy.count(), 1);
       
   585     QCOMPARE(dragMarginSpy.count(), 1);
       
   586     delete canvas;
       
   587 }
       
   588 
       
   589 void tst_QDeclarativePathView::pathChanges()
       
   590 {
       
   591     QDeclarativeView *canvas = createView();
       
   592     QVERIFY(canvas);
       
   593     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
       
   594 
       
   595     QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
       
   596     QVERIFY(pathView);
       
   597 
       
   598     QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
       
   599     QVERIFY(path);
       
   600 
       
   601     QSignalSpy startXSpy(path, SIGNAL(startXChanged()));
       
   602     QSignalSpy startYSpy(path, SIGNAL(startYChanged()));
       
   603 
       
   604     QCOMPARE(path->startX(), 220.0);
       
   605     QCOMPARE(path->startY(), 200.0);
       
   606 
       
   607     path->setStartX(240.0);
       
   608     path->setStartY(220.0);
       
   609 
       
   610     QCOMPARE(path->startX(), 240.0);
       
   611     QCOMPARE(path->startY(), 220.0);
       
   612 
       
   613     QCOMPARE(startXSpy.count(),1);
       
   614     QCOMPARE(startYSpy.count(),1);
       
   615 
       
   616     path->setStartX(240);
       
   617     path->setStartY(220);
       
   618 
       
   619     QCOMPARE(startXSpy.count(),1);
       
   620     QCOMPARE(startYSpy.count(),1);
       
   621 
       
   622     QDeclarativePath *alternatePath = canvas->rootObject()->findChild<QDeclarativePath*>("alternatePath");
       
   623     QVERIFY(alternatePath);
       
   624 
       
   625     QSignalSpy pathSpy(pathView, SIGNAL(pathChanged()));
       
   626 
       
   627     QCOMPARE(pathView->path(), path);
       
   628 
       
   629     pathView->setPath(alternatePath);
       
   630     QCOMPARE(pathView->path(), alternatePath);
       
   631     QCOMPARE(pathSpy.count(),1);
       
   632 
       
   633     pathView->setPath(alternatePath);
       
   634     QCOMPARE(pathSpy.count(),1);
       
   635 
       
   636     QDeclarativePathAttribute *pathAttribute = canvas->rootObject()->findChild<QDeclarativePathAttribute*>("pathAttribute");
       
   637     QVERIFY(pathAttribute);
       
   638 
       
   639     QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged()));
       
   640     QCOMPARE(pathAttribute->name(), QString("opacity"));
       
   641 
       
   642     pathAttribute->setName("scale");
       
   643     QCOMPARE(pathAttribute->name(), QString("scale"));
       
   644     QCOMPARE(nameSpy.count(),1);
       
   645 
       
   646     pathAttribute->setName("scale");
       
   647     QCOMPARE(nameSpy.count(),1);
       
   648     delete canvas;
       
   649 }
       
   650 
       
   651 void tst_QDeclarativePathView::componentChanges()
       
   652 {
       
   653     QDeclarativeView *canvas = createView();
       
   654     QVERIFY(canvas);
       
   655     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
       
   656 
       
   657     QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
       
   658     QVERIFY(pathView);
       
   659 
       
   660     QDeclarativeComponent delegateComponent(canvas->engine());
       
   661     delegateComponent.setData("import Qt 4.7; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
       
   662 
       
   663     QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged()));
       
   664 
       
   665     pathView->setDelegate(&delegateComponent);
       
   666     QCOMPARE(pathView->delegate(), &delegateComponent);
       
   667     QCOMPARE(delegateSpy.count(),1);
       
   668 
       
   669     pathView->setDelegate(&delegateComponent);
       
   670     QCOMPARE(delegateSpy.count(),1);
       
   671     delete canvas;
       
   672 }
       
   673 
       
   674 void tst_QDeclarativePathView::modelChanges()
       
   675 {
       
   676     QDeclarativeView *canvas = createView();
       
   677     QVERIFY(canvas);
       
   678     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
       
   679 
       
   680     QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
       
   681     QVERIFY(pathView);
       
   682 
       
   683     QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
       
   684     QVERIFY(alternateModel);
       
   685     QVariant modelVariant = QVariant::fromValue(alternateModel);
       
   686     QSignalSpy modelSpy(pathView, SIGNAL(modelChanged()));
       
   687 
       
   688     pathView->setModel(modelVariant);
       
   689     QCOMPARE(pathView->model(), modelVariant);
       
   690     QCOMPARE(modelSpy.count(),1);
       
   691 
       
   692     pathView->setModel(modelVariant);
       
   693     QCOMPARE(modelSpy.count(),1);
       
   694 
       
   695     pathView->setModel(QVariant());
       
   696     QCOMPARE(modelSpy.count(),2);
       
   697 
       
   698     delete canvas;
       
   699 }
       
   700 
       
   701 void tst_QDeclarativePathView::pathUpdateOnStartChanged()
       
   702 {
       
   703     QDeclarativeView *canvas = createView();
       
   704     QVERIFY(canvas);
       
   705     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathUpdateOnStartChanged.qml"));
       
   706 
       
   707     QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
       
   708     QVERIFY(pathView);
       
   709 
       
   710     QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
       
   711     QVERIFY(path);
       
   712     QCOMPARE(path->startX(), 400.0);
       
   713     QCOMPARE(path->startY(), 300.0);
       
   714 
       
   715     QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "wrapper", 0);
       
   716     QVERIFY(item);
       
   717     QCOMPARE(item->x(), path->startX() - item->width() / 2.0);
       
   718     QCOMPARE(item->y(), path->startY() - item->height() / 2.0);
       
   719 
       
   720     delete canvas;
       
   721 }
       
   722 
       
   723 void tst_QDeclarativePathView::package()
       
   724 {
       
   725     QDeclarativeView *canvas = createView();
       
   726     QVERIFY(canvas);
       
   727     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview_package.qml"));
       
   728 
       
   729     QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("photoPathView");
       
   730     QVERIFY(pathView);
       
   731 
       
   732     QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "pathItem");
       
   733     QVERIFY(item);
       
   734     QVERIFY(item->scale() != 1.0);
       
   735 
       
   736     delete canvas;
       
   737 }
       
   738 
       
   739 QDeclarativeView *tst_QDeclarativePathView::createView()
       
   740 {
       
   741     QDeclarativeView *canvas = new QDeclarativeView(0);
       
   742     canvas->setFixedSize(240,320);
       
   743 
       
   744     return canvas;
       
   745 }
       
   746 
       
   747 /*
       
   748    Find an item with the specified objectName.  If index is supplied then the
       
   749    item must also evaluate the {index} expression equal to index
       
   750  */
       
   751 template<typename T>
       
   752 T *tst_QDeclarativePathView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
       
   753 {
       
   754     const QMetaObject &mo = T::staticMetaObject;
       
   755     //qDebug() << parent->childItems().count() << "children";
       
   756     for (int i = 0; i < parent->childItems().count(); ++i) {
       
   757         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
       
   758         if(!item)
       
   759             continue;
       
   760         //qDebug() << "try" << item;
       
   761         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
       
   762             if (index != -1) {
       
   763                 QDeclarativeExpression e(qmlContext(item), item, "index");
       
   764                 if (e.evaluate().toInt() == index)
       
   765                     return static_cast<T*>(item);
       
   766             } else {
       
   767                 return static_cast<T*>(item);
       
   768             }
       
   769         }
       
   770         item = findItem<T>(item, objectName, index);
       
   771         if (item)
       
   772             return static_cast<T*>(item);
       
   773     }
       
   774 
       
   775     return 0;
       
   776 }
       
   777 
       
   778 template<typename T>
       
   779 QList<T*> tst_QDeclarativePathView::findItems(QGraphicsObject *parent, const QString &objectName)
       
   780 {
       
   781     QList<T*> items;
       
   782     const QMetaObject &mo = T::staticMetaObject;
       
   783     //qDebug() << parent->QGraphicsObject::children().count() << "children";
       
   784     for (int i = 0; i < parent->childItems().count(); ++i) {
       
   785         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
       
   786         if(!item)
       
   787             continue;
       
   788         //qDebug() << "try" << item;
       
   789         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
       
   790             items.append(static_cast<T*>(item));
       
   791         items += findItems<T>(item, objectName);
       
   792     }
       
   793 
       
   794     return items;
       
   795 }
       
   796 
       
   797 QTEST_MAIN(tst_QDeclarativePathView)
       
   798 
       
   799 #include "tst_qdeclarativepathview.moc"