aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit885735d011472bcfbb96e688d9e64553d7fe9d4b (patch)
tree734963625eba643bf11bc4870a4c407809a6400a /tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp')
-rw-r--r--tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp1061
1 files changed, 1061 insertions, 0 deletions
diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
new file mode 100644
index 0000000000..46c351985f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
@@ -0,0 +1,1061 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtDeclarative/qdeclarativeview.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/private/qdeclarativepathview_p.h>
+#include <QtDeclarative/private/qdeclarativepath_p.h>
+#include <QtDeclarative/private/qdeclarativetext_p.h>
+#include <QtDeclarative/private/qdeclarativerectangle_p.h>
+#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
+#include <QtDeclarative/private/qdeclarativevaluetype_p.h>
+#include <QAbstractListModel>
+#include <QStringListModel>
+#include <QStandardItemModel>
+#include <QFile>
+
+#include "../../../shared/util.h"
+
+#ifdef Q_OS_SYMBIAN
+// In Symbian OS test data is located in applications private dir
+#define SRCDIR "."
+#endif
+
+static void initStandardTreeModel(QStandardItemModel *model)
+{
+ QStandardItem *item;
+ item = new QStandardItem(QLatin1String("Row 1 Item"));
+ model->insertRow(0, item);
+
+ item = new QStandardItem(QLatin1String("Row 2 Item"));
+ item->setCheckable(true);
+ model->insertRow(1, item);
+
+ QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
+ item->setChild(0, childItem);
+
+ item = new QStandardItem(QLatin1String("Row 3 Item"));
+ item->setIcon(QIcon());
+ model->insertRow(2, item);
+}
+
+
+class tst_QDeclarativePathView : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QDeclarativePathView();
+
+private slots:
+ void initValues();
+ void items();
+ void dataModel();
+ void pathview2();
+ void pathview3();
+ void path();
+ void pathMoved();
+ void setCurrentIndex();
+ void resetModel();
+ void propertyChanges();
+ void pathChanges();
+ void componentChanges();
+ void modelChanges();
+ void pathUpdateOnStartChanged();
+ void package();
+ void emptyModel();
+ void closed();
+ void pathUpdate();
+ void visualDataModel();
+ void undefinedPath();
+ void mouseDrag();
+ void treeModel();
+ void changePreferredHighlight();
+
+private:
+ QDeclarativeView *createView();
+ template<typename T>
+ T *findItem(QGraphicsObject *parent, const QString &objectName, int index=-1);
+ template<typename T>
+ QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
+};
+
+class TestObject : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool error READ error WRITE setError)
+ Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
+ Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged)
+
+public:
+ TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {}
+
+ bool error() const { return mError; }
+ void setError(bool err) { mError = err; }
+
+ bool useModel() const { return mUseModel; }
+ void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
+
+ int pathItemCount() const { return mPathItemCount; }
+ void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); }
+
+signals:
+ void useModelChanged();
+ void pathItemCountChanged();
+
+private:
+ bool mError;
+ bool mUseModel;
+ int mPathItemCount;
+};
+
+class TestModel : public QAbstractListModel
+{
+public:
+ enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
+
+ TestModel(QObject *parent=0) : QAbstractListModel(parent) {
+ QHash<int, QByteArray> roles;
+ roles[Name] = "name";
+ roles[Number] = "number";
+ setRoleNames(roles);
+ }
+
+ int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
+ QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
+ QVariant rv;
+ if (role == Name)
+ rv = list.at(index.row()).first;
+ else if (role == Number)
+ rv = list.at(index.row()).second;
+
+ return rv;
+ }
+
+ int count() const { return rowCount(); }
+ QString name(int index) const { return list.at(index).first; }
+ QString number(int index) const { return list.at(index).second; }
+
+ void addItem(const QString &name, const QString &number) {
+ beginInsertRows(QModelIndex(), list.count(), list.count());
+ list.append(QPair<QString,QString>(name, number));
+ endInsertRows();
+ }
+
+ void insertItem(int index, const QString &name, const QString &number) {
+ beginInsertRows(QModelIndex(), index, index);
+ list.insert(index, QPair<QString,QString>(name, number));
+ endInsertRows();
+ }
+
+ void removeItem(int index) {
+ beginRemoveRows(QModelIndex(), index, index);
+ list.removeAt(index);
+ endRemoveRows();
+ }
+
+ void moveItem(int from, int to) {
+ beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
+ list.move(from, to);
+ endMoveRows();
+ }
+
+ void modifyItem(int idx, const QString &name, const QString &number) {
+ list[idx] = QPair<QString,QString>(name, number);
+ emit dataChanged(index(idx,0), index(idx,0));
+ }
+
+private:
+ QList<QPair<QString,QString> > list;
+};
+
+
+tst_QDeclarativePathView::tst_QDeclarativePathView()
+{
+}
+
+void tst_QDeclarativePathView::initValues()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview1.qml"));
+ QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
+
+ QVERIFY(obj != 0);
+ QVERIFY(obj->path() == 0);
+ QVERIFY(obj->delegate() == 0);
+ QCOMPARE(obj->model(), QVariant());
+ QCOMPARE(obj->currentIndex(), 0);
+ QCOMPARE(obj->offset(), 0.);
+ QCOMPARE(obj->preferredHighlightBegin(), 0.);
+ QCOMPARE(obj->dragMargin(), 0.);
+ QCOMPARE(obj->count(), 0);
+ QCOMPARE(obj->pathItemCount(), -1);
+}
+
+void tst_QDeclarativePathView::items()
+{
+ QDeclarativeView *canvas = createView();
+
+ TestModel model;
+ model.addItem("Fred", "12345");
+ model.addItem("John", "2345");
+ model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight
+
+ for (int i = 0; i < model.count(); ++i) {
+ QDeclarativeText *name = findItem<QDeclarativeText>(pathview, "textName", i);
+ QVERIFY(name != 0);
+ QCOMPARE(name->text(), model.name(i));
+ QDeclarativeText *number = findItem<QDeclarativeText>(pathview, "textNumber", i);
+ QVERIFY(number != 0);
+ QCOMPARE(number->text(), model.number(i));
+ }
+
+ QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+ QVERIFY(path);
+
+ QVERIFY(pathview->highlightItem());
+ QPointF start = path->pointAt(0.0);
+ QPointF offset;
+ offset.setX(pathview->highlightItem()->width()/2);
+ offset.setY(pathview->highlightItem()->height()/2);
+ QCOMPARE(pathview->highlightItem()->pos() + offset, start);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::pathview2()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview2.qml"));
+ QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
+
+ QVERIFY(obj != 0);
+ QVERIFY(obj->path() != 0);
+ QVERIFY(obj->delegate() != 0);
+ QVERIFY(obj->model() != QVariant());
+ QCOMPARE(obj->currentIndex(), 0);
+ QCOMPARE(obj->offset(), 0.);
+ QCOMPARE(obj->preferredHighlightBegin(), 0.);
+ QCOMPARE(obj->dragMargin(), 0.);
+ QCOMPARE(obj->count(), 8);
+ QCOMPARE(obj->pathItemCount(), 10);
+}
+
+void tst_QDeclarativePathView::pathview3()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview3.qml"));
+ QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
+
+ QVERIFY(obj != 0);
+ QVERIFY(obj->path() != 0);
+ QVERIFY(obj->delegate() != 0);
+ QVERIFY(obj->model() != QVariant());
+ QCOMPARE(obj->currentIndex(), 0);
+ QCOMPARE(obj->offset(), 1.0);
+ QCOMPARE(obj->preferredHighlightBegin(), 0.5);
+ QCOMPARE(obj->dragMargin(), 24.);
+ QCOMPARE(obj->count(), 8);
+ QCOMPARE(obj->pathItemCount(), 4);
+}
+
+void tst_QDeclarativePathView::path()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathtest.qml"));
+ QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
+
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->startX(), 120.);
+ QCOMPARE(obj->startY(), 100.);
+ QVERIFY(obj->path() != QPainterPath());
+
+ QDeclarativeListReference list(obj, "pathElements");
+ QCOMPARE(list.count(), 5);
+
+ QDeclarativePathAttribute* attr = qobject_cast<QDeclarativePathAttribute*>(list.at(0));
+ QVERIFY(attr != 0);
+ QCOMPARE(attr->name(), QString("scale"));
+ QCOMPARE(attr->value(), 1.0);
+
+ QDeclarativePathQuad* quad = qobject_cast<QDeclarativePathQuad*>(list.at(1));
+ QVERIFY(quad != 0);
+ QCOMPARE(quad->x(), 120.);
+ QCOMPARE(quad->y(), 25.);
+ QCOMPARE(quad->controlX(), 260.);
+ QCOMPARE(quad->controlY(), 75.);
+
+ QDeclarativePathPercent* perc = qobject_cast<QDeclarativePathPercent*>(list.at(2));
+ QVERIFY(perc != 0);
+ QCOMPARE(perc->value(), 0.3);
+
+ QDeclarativePathLine* line = qobject_cast<QDeclarativePathLine*>(list.at(3));
+ QVERIFY(line != 0);
+ QCOMPARE(line->x(), 120.);
+ QCOMPARE(line->y(), 100.);
+
+ QDeclarativePathCubic* cubic = qobject_cast<QDeclarativePathCubic*>(list.at(4));
+ QVERIFY(cubic != 0);
+ QCOMPARE(cubic->x(), 180.);
+ QCOMPARE(cubic->y(), 0.);
+ QCOMPARE(cubic->control1X(), -10.);
+ QCOMPARE(cubic->control1Y(), 90.);
+ QCOMPARE(cubic->control2X(), 210.);
+ QCOMPARE(cubic->control2Y(), 90.);
+}
+
+void tst_QDeclarativePathView::dataModel()
+{
+ QDeclarativeView *canvas = createView();
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ TestObject *testObject = new TestObject;
+ ctxt->setContextProperty("testObject", testObject);
+
+ TestModel model;
+ model.addItem("red", "1");
+ model.addItem("green", "2");
+ model.addItem("blue", "3");
+ model.addItem("purple", "4");
+ model.addItem("gray", "5");
+ model.addItem("brown", "6");
+ model.addItem("yellow", "7");
+ model.addItem("thistle", "8");
+ model.addItem("cyan", "9");
+ model.addItem("peachpuff", "10");
+ model.addItem("powderblue", "11");
+ model.addItem("gold", "12");
+ model.addItem("sandybrown", "13");
+
+ ctxt->setContextProperty("testData", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/datamodel.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = qobject_cast<QDeclarativePathView*>(canvas->rootObject());
+ QVERIFY(pathview != 0);
+
+ QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+ QVERIFY(testObject->error() == false);
+
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(pathview, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->x(), 110.0);
+ QCOMPARE(item->y(), 10.0);
+
+ model.insertItem(4, "orange", "10");
+ QTest::qWait(100);
+
+ QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 14);
+
+ QVERIFY(pathview->currentIndex() == 0);
+
+ QDeclarativeText *text = findItem<QDeclarativeText>(pathview, "myText", 4);
+ QVERIFY(text);
+ QCOMPARE(text->text(), model.name(4));
+
+ model.removeItem(2);
+ text = findItem<QDeclarativeText>(pathview, "myText", 2);
+ QVERIFY(text);
+ QCOMPARE(text->text(), model.name(2));
+
+ testObject->setPathItemCount(5);
+ QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+ QVERIFY(testObject->error() == false);
+
+ QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
+
+ QDeclarativeRectangle *testItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 4);
+ QVERIFY(testItem != 0);
+ testItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 5);
+ QVERIFY(testItem == 0);
+
+ pathview->setCurrentIndex(1);
+
+ model.insertItem(2, "pink", "2");
+ QTest::qWait(100);
+
+ QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
+ QVERIFY(pathview->currentIndex() == 1);
+
+ text = findItem<QDeclarativeText>(pathview, "myText", 2);
+ QVERIFY(text);
+ QCOMPARE(text->text(), model.name(2));
+
+ model.removeItem(3);
+ QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
+ text = findItem<QDeclarativeText>(pathview, "myText", 3);
+ QVERIFY(text);
+ QCOMPARE(text->text(), model.name(3));
+
+ model.moveItem(3, 5);
+ QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
+ QList<QDeclarativeItem*> items = findItems<QDeclarativeItem>(pathview, "wrapper");
+ foreach (QDeclarativeItem *item, items) {
+ QVERIFY(item->property("onPath").toBool());
+ }
+
+ // QTBUG-14199
+ pathview->setOffset(7);
+ pathview->setOffset(0);
+ QCOMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
+
+ pathview->setCurrentIndex(model.count()-1);
+ model.removeItem(model.count()-1);
+ QCOMPARE(pathview->currentIndex(), model.count()-1);
+
+ // QTBUG-18825
+ // Confirm that the target offset is adjusted when removing items
+ pathview->setCurrentIndex(model.count()-1);
+ QTRY_COMPARE(pathview->offset(), 1.);
+ pathview->setCurrentIndex(model.count()-5);
+ model.removeItem(model.count()-1);
+ model.removeItem(model.count()-1);
+ model.removeItem(model.count()-1);
+ QTRY_COMPARE(pathview->offset(), 2.);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::pathMoved()
+{
+ QDeclarativeView *canvas = createView();
+
+ TestModel model;
+ model.addItem("Ben", "12345");
+ model.addItem("Bohn", "2345");
+ model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ QDeclarativeRectangle *firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
+ QVERIFY(firstItem);
+ QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+ QVERIFY(path);
+ QPointF start = path->pointAt(0.0);
+ QPointF offset;//Center of item is at point, but pos is from corner
+ offset.setX(firstItem->width()/2);
+ offset.setY(firstItem->height()/2);
+ QCOMPARE(firstItem->pos() + offset, start);
+ pathview->setOffset(1.0);
+
+ for(int i=0; i<model.count(); i++){
+ QDeclarativeRectangle *curItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", i);
+ QPointF itemPos(path->pointAt(0.25 + i*0.25));
+ QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y())));
+ }
+
+ pathview->setOffset(0.0);
+ QCOMPARE(firstItem->pos() + offset, start);
+
+ // Change delegate size
+ pathview->setOffset(0.1);
+ pathview->setOffset(0.0);
+ canvas->rootObject()->setProperty("delegateWidth", 30);
+ QCOMPARE(firstItem->width(), 30.0);
+ offset.setX(firstItem->width()/2);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ // Change delegate scale
+ pathview->setOffset(0.1);
+ pathview->setOffset(0.0);
+ canvas->rootObject()->setProperty("delegateScale", 1.2);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::setCurrentIndex()
+{
+ QDeclarativeView *canvas = createView();
+
+ TestModel model;
+ model.addItem("Ben", "12345");
+ model.addItem("Bohn", "2345");
+ model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ QDeclarativeRectangle *firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
+ QVERIFY(firstItem);
+ QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+ QVERIFY(path);
+ QPointF start = path->pointAt(0.0);
+ QPointF offset;//Center of item is at point, but pos is from corner
+ offset.setX(firstItem->width()/2);
+ offset.setY(firstItem->height()/2);
+ QCOMPARE(firstItem->pos() + offset, start);
+ QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0);
+ QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0);
+
+ pathview->setCurrentIndex(2);
+
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 2);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+ QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2);
+ QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2);
+
+ pathview->decrementCurrentIndex();
+ QTRY_COMPARE(pathview->currentIndex(), 1);
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 1);
+ QVERIFY(firstItem);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ pathview->decrementCurrentIndex();
+ QTRY_COMPARE(pathview->currentIndex(), 0);
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
+ QVERIFY(firstItem);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ pathview->decrementCurrentIndex();
+ QTRY_COMPARE(pathview->currentIndex(), 3);
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 3);
+ QVERIFY(firstItem);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ pathview->incrementCurrentIndex();
+ QTRY_COMPARE(pathview->currentIndex(), 0);
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
+ QVERIFY(firstItem);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::resetModel()
+{
+ QDeclarativeView *canvas = createView();
+
+ QStringList strings;
+ strings << "one" << "two" << "three";
+ QStringListModel model(strings);
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaypath.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ QCOMPARE(pathview->count(), model.rowCount());
+
+ for (int i = 0; i < model.rowCount(); ++i) {
+ QDeclarativeText *display = findItem<QDeclarativeText>(pathview, "displayText", i);
+ QVERIFY(display != 0);
+ QCOMPARE(display->text(), strings.at(i));
+ }
+
+ strings.clear();
+ strings << "four" << "five" << "six" << "seven";
+ model.setStringList(strings);
+
+ QCOMPARE(pathview->count(), model.rowCount());
+
+ for (int i = 0; i < model.rowCount(); ++i) {
+ QDeclarativeText *display = findItem<QDeclarativeText>(pathview, "displayText", i);
+ QVERIFY(display != 0);
+ QCOMPARE(display->text(), strings.at(i));
+ }
+}
+
+void tst_QDeclarativePathView::propertyChanges()
+{
+ QDeclarativeView *canvas = createView();
+ QVERIFY(canvas);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+
+ QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
+ QVERIFY(pathView);
+
+ QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged()));
+ QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged()));
+
+ QCOMPARE(pathView->preferredHighlightBegin(), 0.1);
+ QCOMPARE(pathView->dragMargin(), 5.0);
+
+ pathView->setPreferredHighlightBegin(0.4);
+ pathView->setPreferredHighlightEnd(0.4);
+ pathView->setDragMargin(20.0);
+
+ QCOMPARE(pathView->preferredHighlightBegin(), 0.4);
+ QCOMPARE(pathView->preferredHighlightEnd(), 0.4);
+ QCOMPARE(pathView->dragMargin(), 20.0);
+
+ QCOMPARE(snapPositionSpy.count(), 1);
+ QCOMPARE(dragMarginSpy.count(), 1);
+
+ pathView->setPreferredHighlightBegin(0.4);
+ pathView->setPreferredHighlightEnd(0.4);
+ pathView->setDragMargin(20.0);
+
+ QCOMPARE(snapPositionSpy.count(), 1);
+ QCOMPARE(dragMarginSpy.count(), 1);
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::pathChanges()
+{
+ QDeclarativeView *canvas = createView();
+ QVERIFY(canvas);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+
+ QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
+ QVERIFY(pathView);
+
+ QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
+ QVERIFY(path);
+
+ QSignalSpy startXSpy(path, SIGNAL(startXChanged()));
+ QSignalSpy startYSpy(path, SIGNAL(startYChanged()));
+
+ QCOMPARE(path->startX(), 220.0);
+ QCOMPARE(path->startY(), 200.0);
+
+ path->setStartX(240.0);
+ path->setStartY(220.0);
+
+ QCOMPARE(path->startX(), 240.0);
+ QCOMPARE(path->startY(), 220.0);
+
+ QCOMPARE(startXSpy.count(),1);
+ QCOMPARE(startYSpy.count(),1);
+
+ path->setStartX(240);
+ path->setStartY(220);
+
+ QCOMPARE(startXSpy.count(),1);
+ QCOMPARE(startYSpy.count(),1);
+
+ QDeclarativePath *alternatePath = canvas->rootObject()->findChild<QDeclarativePath*>("alternatePath");
+ QVERIFY(alternatePath);
+
+ QSignalSpy pathSpy(pathView, SIGNAL(pathChanged()));
+
+ QCOMPARE(pathView->path(), path);
+
+ pathView->setPath(alternatePath);
+ QCOMPARE(pathView->path(), alternatePath);
+ QCOMPARE(pathSpy.count(),1);
+
+ pathView->setPath(alternatePath);
+ QCOMPARE(pathSpy.count(),1);
+
+ QDeclarativePathAttribute *pathAttribute = canvas->rootObject()->findChild<QDeclarativePathAttribute*>("pathAttribute");
+ QVERIFY(pathAttribute);
+
+ QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged()));
+ QCOMPARE(pathAttribute->name(), QString("opacity"));
+
+ pathAttribute->setName("scale");
+ QCOMPARE(pathAttribute->name(), QString("scale"));
+ QCOMPARE(nameSpy.count(),1);
+
+ pathAttribute->setName("scale");
+ QCOMPARE(nameSpy.count(),1);
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::componentChanges()
+{
+ QDeclarativeView *canvas = createView();
+ QVERIFY(canvas);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+
+ QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
+ QVERIFY(pathView);
+
+ QDeclarativeComponent delegateComponent(canvas->engine());
+ delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
+
+ QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged()));
+
+ pathView->setDelegate(&delegateComponent);
+ QCOMPARE(pathView->delegate(), &delegateComponent);
+ QCOMPARE(delegateSpy.count(),1);
+
+ pathView->setDelegate(&delegateComponent);
+ QCOMPARE(delegateSpy.count(),1);
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::modelChanges()
+{
+ QDeclarativeView *canvas = createView();
+ QVERIFY(canvas);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+
+ QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
+ QVERIFY(pathView);
+
+ QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
+ QVERIFY(alternateModel);
+ QVariant modelVariant = QVariant::fromValue(alternateModel);
+ QSignalSpy modelSpy(pathView, SIGNAL(modelChanged()));
+
+ pathView->setModel(modelVariant);
+ QCOMPARE(pathView->model(), modelVariant);
+ QCOMPARE(modelSpy.count(),1);
+
+ pathView->setModel(modelVariant);
+ QCOMPARE(modelSpy.count(),1);
+
+ pathView->setModel(QVariant());
+ QCOMPARE(modelSpy.count(),2);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::pathUpdateOnStartChanged()
+{
+ QDeclarativeView *canvas = createView();
+ QVERIFY(canvas);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathUpdateOnStartChanged.qml"));
+
+ QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
+ QVERIFY(pathView);
+
+ QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
+ QVERIFY(path);
+ QCOMPARE(path->startX(), 400.0);
+ QCOMPARE(path->startY(), 300.0);
+
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->x(), path->startX() - item->width() / 2.0);
+ QCOMPARE(item->y(), path->startY() - item->height() / 2.0);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::package()
+{
+ QDeclarativeView *canvas = createView();
+ QVERIFY(canvas);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview_package.qml"));
+
+ QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("photoPathView");
+ QVERIFY(pathView);
+
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "pathItem");
+ QVERIFY(item);
+ QVERIFY(item->scale() != 1.0);
+
+ delete canvas;
+}
+
+//QTBUG-13017
+void tst_QDeclarativePathView::emptyModel()
+{
+ QDeclarativeView *canvas = createView();
+
+ QStringListModel model;
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("emptyModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/emptymodel.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = qobject_cast<QDeclarativePathView*>(canvas->rootObject());
+ QVERIFY(pathview != 0);
+
+ QCOMPARE(pathview->offset(), qreal(0.0));
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::closed()
+{
+ QDeclarativeEngine engine;
+
+ {
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/openPath.qml"));
+ QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
+ QVERIFY(obj);
+ QCOMPARE(obj->isClosed(), false);
+ delete obj;
+ }
+
+ {
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/closedPath.qml"));
+ QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
+ QVERIFY(obj);
+ QCOMPARE(obj->isClosed(), true);
+ delete obj;
+ }
+}
+
+// QTBUG-14239
+void tst_QDeclarativePathView::pathUpdate()
+{
+ QDeclarativeView *canvas = createView();
+ QVERIFY(canvas);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathUpdate.qml"));
+
+ QDeclarativePathView *pathView = canvas->rootObject()->findChild<QDeclarativePathView*>("pathView");
+ QVERIFY(pathView);
+
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->x(), 150.0);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::visualDataModel()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/vdm.qml"));
+
+ QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
+ QVERIFY(obj != 0);
+
+ QCOMPARE(obj->count(), 3);
+
+ delete obj;
+}
+
+void tst_QDeclarativePathView::undefinedPath()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/undefinedpath.qml"));
+
+ QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
+ QVERIFY(obj != 0);
+
+ QCOMPARE(obj->count(), 3);
+
+ delete obj;
+}
+
+void tst_QDeclarativePathView::mouseDrag()
+{
+ QDeclarativeView *canvas = createView();
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragpath.qml"));
+ canvas->show();
+ QApplication::setActiveWindow(canvas);
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
+
+ QDeclarativePathView *pathview = qobject_cast<QDeclarativePathView*>(canvas->rootObject());
+ QVERIFY(pathview != 0);
+
+ int current = pathview->currentIndex();
+
+ QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(10,100)));
+
+ {
+ QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(30,100)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+ QApplication::sendEvent(canvas->viewport(), &mv);
+ }
+ {
+ QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(90,100)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+ QApplication::sendEvent(canvas->viewport(), &mv);
+ }
+
+ QVERIFY(pathview->currentIndex() != current);
+
+ QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(40,100)));
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::treeModel()
+{
+ QDeclarativeView *canvas = createView();
+
+ QStandardItemModel model;
+ initStandardTreeModel(&model);
+ canvas->engine()->rootContext()->setContextProperty("myModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/treemodel.qml"));
+
+ QDeclarativePathView *pathview = qobject_cast<QDeclarativePathView*>(canvas->rootObject());
+ QVERIFY(pathview != 0);
+ QCOMPARE(pathview->count(), 3);
+
+ QDeclarativeText *item = findItem<QDeclarativeText>(pathview, "wrapper", 0);
+ QVERIFY(item);
+ QCOMPARE(item->text(), QLatin1String("Row 1 Item"));
+
+ QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1)));
+ QCOMPARE(pathview->count(), 1);
+
+ QTRY_VERIFY(item = findItem<QDeclarativeText>(pathview, "wrapper", 0));
+ QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item"));
+
+ delete canvas;
+}
+
+void tst_QDeclarativePathView::changePreferredHighlight()
+{
+ QDeclarativeView *canvas = createView();
+ canvas->setFixedSize(400,200);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragpath.qml"));
+ canvas->show();
+ QApplication::setActiveWindow(canvas);
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
+
+ QDeclarativePathView *pathview = qobject_cast<QDeclarativePathView*>(canvas->rootObject());
+ QVERIFY(pathview != 0);
+
+ int current = pathview->currentIndex();
+ QCOMPARE(current, 0);
+
+ QDeclarativeRectangle *firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
+ QVERIFY(firstItem);
+ QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+ QVERIFY(path);
+ QPointF start = path->pointAt(0.5);
+ start.setX(qRound(start.x()));
+ start.setY(qRound(start.y()));
+ QPointF offset;//Center of item is at point, but pos is from corner
+ offset.setX(firstItem->width()/2);
+ offset.setY(firstItem->height()/2);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ pathview->setPreferredHighlightBegin(0.8);
+ pathview->setPreferredHighlightEnd(0.8);
+ start = path->pointAt(0.8);
+ start.setX(qRound(start.x()));
+ start.setY(qRound(start.y()));
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+ QCOMPARE(pathview->currentIndex(), 0);
+
+ delete canvas;
+}
+
+QDeclarativeView *tst_QDeclarativePathView::createView()
+{
+ QDeclarativeView *canvas = new QDeclarativeView(0);
+ canvas->setFixedSize(240,320);
+
+ return canvas;
+}
+
+/*
+ Find an item with the specified objectName. If index is supplied then the
+ item must also evaluate the {index} expression equal to index
+ */
+template<typename T>
+T *tst_QDeclarativePathView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
+{
+ const QMetaObject &mo = T::staticMetaObject;
+ //qDebug() << parent->childItems().count() << "children";
+ for (int i = 0; i < parent->childItems().count(); ++i) {
+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
+ if(!item)
+ continue;
+ //qDebug() << "try" << item;
+ if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+ if (index != -1) {
+ QDeclarativeExpression e(qmlContext(item), item, "index");
+ if (e.evaluate().toInt() == index)
+ return static_cast<T*>(item);
+ } else {
+ return static_cast<T*>(item);
+ }
+ }
+ item = findItem<T>(item, objectName, index);
+ if (item)
+ return static_cast<T*>(item);
+ }
+
+ return 0;
+}
+
+template<typename T>
+QList<T*> tst_QDeclarativePathView::findItems(QGraphicsObject *parent, const QString &objectName)
+{
+ QList<T*> items;
+ const QMetaObject &mo = T::staticMetaObject;
+ //qDebug() << parent->QGraphicsObject::children().count() << "children";
+ for (int i = 0; i < parent->childItems().count(); ++i) {
+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
+ if(!item)
+ continue;
+ //qDebug() << "try" << item;
+ if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
+ items.append(static_cast<T*>(item));
+ items += findItems<T>(item, objectName);
+ }
+
+ return items;
+}
+
+QTEST_MAIN(tst_QDeclarativePathView)
+
+#include "tst_qdeclarativepathview.moc"