1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <QtQuick1/qdeclarativeview.h>
44 #include <QtDeclarative/qdeclarativeengine.h>
45 #include <QtDeclarative/qdeclarativecomponent.h>
46 #include <QtDeclarative/qdeclarativecontext.h>
47 #include <QtDeclarative/qdeclarativeexpression.h>
48 #include <QtQuick1/private/qdeclarativepathview_p.h>
49 #include <QtQuick1/private/qdeclarativepath_p.h>
50 #include <QtQuick1/private/qdeclarativetext_p.h>
51 #include <QtQuick1/private/qdeclarativerectangle_p.h>
52 #include <QtDeclarative/private/qdeclarativevaluetype_p.h>
53 #include <QAbstractListModel>
54 #include <QStringListModel>
55 #include <QStandardItemModel>
58 static void initStandardTreeModel(QStandardItemModel *model)
61 item = new QStandardItem(QLatin1String("Row 1 Item"));
62 model->insertRow(0, item);
64 item = new QStandardItem(QLatin1String("Row 2 Item"));
65 item->setCheckable(true);
66 model->insertRow(1, item);
68 QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
69 item->setChild(0, childItem);
71 item = new QStandardItem(QLatin1String("Row 3 Item"));
72 item->setIcon(QIcon());
73 model->insertRow(2, item);
77 class tst_QDeclarative1PathView : public QObject
81 tst_QDeclarative1PathView();
91 void setCurrentIndex();
93 void propertyChanges();
95 void componentChanges();
97 void pathUpdateOnStartChanged();
102 void visualDataModel();
103 void undefinedPath();
106 void changePreferredHighlight();
109 QDeclarativeView *createView();
111 T *findItem(QGraphicsObject *parent, const QString &objectName, int index=-1);
113 QList<T*> findItems(QGraphicsObject *parent, const QString &objectName);
116 class TestObject : public QObject
120 Q_PROPERTY(bool error READ error WRITE setError)
121 Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
122 Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged)
125 TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {}
127 bool error() const { return mError; }
128 void setError(bool err) { mError = err; }
130 bool useModel() const { return mUseModel; }
131 void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
133 int pathItemCount() const { return mPathItemCount; }
134 void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); }
137 void useModelChanged();
138 void pathItemCountChanged();
146 class TestModel : public QAbstractListModel
149 enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
151 TestModel(QObject *parent=0) : QAbstractListModel(parent) {
152 QHash<int, QByteArray> roles;
153 roles[Name] = "name";
154 roles[Number] = "number";
158 int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
159 QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
162 rv = list.at(index.row()).first;
163 else if (role == Number)
164 rv = list.at(index.row()).second;
169 int count() const { return rowCount(); }
170 QString name(int index) const { return list.at(index).first; }
171 QString number(int index) const { return list.at(index).second; }
173 void addItem(const QString &name, const QString &number) {
174 beginInsertRows(QModelIndex(), list.count(), list.count());
175 list.append(QPair<QString,QString>(name, number));
179 void insertItem(int index, const QString &name, const QString &number) {
180 beginInsertRows(QModelIndex(), index, index);
181 list.insert(index, QPair<QString,QString>(name, number));
185 void removeItem(int index) {
186 beginRemoveRows(QModelIndex(), index, index);
187 list.removeAt(index);
191 void moveItem(int from, int to) {
192 beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
197 void modifyItem(int idx, const QString &name, const QString &number) {
198 list[idx] = QPair<QString,QString>(name, number);
199 emit dataChanged(index(idx,0), index(idx,0));
203 QList<QPair<QString,QString> > list;
207 tst_QDeclarative1PathView::tst_QDeclarative1PathView()
211 void tst_QDeclarative1PathView::initValues()
213 QDeclarativeEngine engine;
214 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview1.qml"));
215 QDeclarative1PathView *obj = qobject_cast<QDeclarative1PathView*>(c.create());
218 QVERIFY(obj->path() == 0);
219 QVERIFY(obj->delegate() == 0);
220 QCOMPARE(obj->model(), QVariant());
221 QCOMPARE(obj->currentIndex(), 0);
222 QCOMPARE(obj->offset(), 0.);
223 QCOMPARE(obj->preferredHighlightBegin(), 0.);
224 QCOMPARE(obj->dragMargin(), 0.);
225 QCOMPARE(obj->count(), 0);
226 QCOMPARE(obj->pathItemCount(), -1);
229 void tst_QDeclarative1PathView::items()
231 QDeclarativeView *canvas = createView();
234 model.addItem("Fred", "12345");
235 model.addItem("John", "2345");
236 model.addItem("Bob", "54321");
237 model.addItem("Bill", "4321");
239 QDeclarativeContext *ctxt = canvas->rootContext();
240 ctxt->setContextProperty("testModel", &model);
242 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
243 qApp->processEvents();
245 QDeclarative1PathView *pathview = findItem<QDeclarative1PathView>(canvas->rootObject(), "view");
246 QVERIFY(pathview != 0);
248 QCOMPARE(pathview->count(), model.count());
249 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
250 QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight
252 for (int i = 0; i < model.count(); ++i) {
253 QDeclarative1Text *name = findItem<QDeclarative1Text>(pathview, "textName", i);
255 QCOMPARE(name->text(), model.name(i));
256 QDeclarative1Text *number = findItem<QDeclarative1Text>(pathview, "textNumber", i);
257 QVERIFY(number != 0);
258 QCOMPARE(number->text(), model.number(i));
261 QDeclarative1Path *path = qobject_cast<QDeclarative1Path*>(pathview->path());
264 QVERIFY(pathview->highlightItem());
265 QPointF start = path->pointAt(0.0);
267 offset.setX(pathview->highlightItem()->width()/2);
268 offset.setY(pathview->highlightItem()->height()/2);
269 QCOMPARE(pathview->highlightItem()->pos() + offset, start);
274 void tst_QDeclarative1PathView::pathview2()
276 QDeclarativeEngine engine;
277 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview2.qml"));
278 QDeclarative1PathView *obj = qobject_cast<QDeclarative1PathView*>(c.create());
281 QVERIFY(obj->path() != 0);
282 QVERIFY(obj->delegate() != 0);
283 QVERIFY(obj->model() != QVariant());
284 QCOMPARE(obj->currentIndex(), 0);
285 QCOMPARE(obj->offset(), 0.);
286 QCOMPARE(obj->preferredHighlightBegin(), 0.);
287 QCOMPARE(obj->dragMargin(), 0.);
288 QCOMPARE(obj->count(), 8);
289 QCOMPARE(obj->pathItemCount(), 10);
292 void tst_QDeclarative1PathView::pathview3()
294 QDeclarativeEngine engine;
295 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview3.qml"));
296 QDeclarative1PathView *obj = qobject_cast<QDeclarative1PathView*>(c.create());
299 QVERIFY(obj->path() != 0);
300 QVERIFY(obj->delegate() != 0);
301 QVERIFY(obj->model() != QVariant());
302 QCOMPARE(obj->currentIndex(), 0);
303 QCOMPARE(obj->offset(), 1.0);
304 QCOMPARE(obj->preferredHighlightBegin(), 0.5);
305 QCOMPARE(obj->dragMargin(), 24.);
306 QCOMPARE(obj->count(), 8);
307 QCOMPARE(obj->pathItemCount(), 4);
310 void tst_QDeclarative1PathView::path()
312 QDeclarativeEngine engine;
313 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathtest.qml"));
314 QDeclarative1Path *obj = qobject_cast<QDeclarative1Path*>(c.create());
317 QCOMPARE(obj->startX(), 120.);
318 QCOMPARE(obj->startY(), 100.);
319 QVERIFY(obj->path() != QPainterPath());
321 QDeclarativeListReference list(obj, "pathElements");
322 QCOMPARE(list.count(), 5);
324 QDeclarative1PathAttribute* attr = qobject_cast<QDeclarative1PathAttribute*>(list.at(0));
326 QCOMPARE(attr->name(), QString("scale"));
327 QCOMPARE(attr->value(), 1.0);
329 QDeclarative1PathQuad* quad = qobject_cast<QDeclarative1PathQuad*>(list.at(1));
331 QCOMPARE(quad->x(), 120.);
332 QCOMPARE(quad->y(), 25.);
333 QCOMPARE(quad->controlX(), 260.);
334 QCOMPARE(quad->controlY(), 75.);
336 QDeclarative1PathPercent* perc = qobject_cast<QDeclarative1PathPercent*>(list.at(2));
338 QCOMPARE(perc->value(), 0.3);
340 QDeclarative1PathLine* line = qobject_cast<QDeclarative1PathLine*>(list.at(3));
342 QCOMPARE(line->x(), 120.);
343 QCOMPARE(line->y(), 100.);
345 QDeclarative1PathCubic* cubic = qobject_cast<QDeclarative1PathCubic*>(list.at(4));
347 QCOMPARE(cubic->x(), 180.);
348 QCOMPARE(cubic->y(), 0.);
349 QCOMPARE(cubic->control1X(), -10.);
350 QCOMPARE(cubic->control1Y(), 90.);
351 QCOMPARE(cubic->control2X(), 210.);
352 QCOMPARE(cubic->control2Y(), 90.);
355 void tst_QDeclarative1PathView::dataModel()
357 QDeclarativeView *canvas = createView();
359 QDeclarativeContext *ctxt = canvas->rootContext();
360 TestObject *testObject = new TestObject;
361 ctxt->setContextProperty("testObject", testObject);
364 model.addItem("red", "1");
365 model.addItem("green", "2");
366 model.addItem("blue", "3");
367 model.addItem("purple", "4");
368 model.addItem("gray", "5");
369 model.addItem("brown", "6");
370 model.addItem("yellow", "7");
371 model.addItem("thistle", "8");
372 model.addItem("cyan", "9");
373 model.addItem("peachpuff", "10");
374 model.addItem("powderblue", "11");
375 model.addItem("gold", "12");
376 model.addItem("sandybrown", "13");
378 ctxt->setContextProperty("testData", &model);
380 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/datamodel.qml"));
381 qApp->processEvents();
383 QDeclarative1PathView *pathview = qobject_cast<QDeclarative1PathView*>(canvas->rootObject());
384 QVERIFY(pathview != 0);
386 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
387 QVERIFY(testObject->error() == false);
389 QDeclarativeItem *item = findItem<QDeclarativeItem>(pathview, "wrapper", 0);
391 QCOMPARE(item->x(), 110.0);
392 QCOMPARE(item->y(), 10.0);
394 model.insertItem(4, "orange", "10");
397 QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
398 QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 14);
400 QVERIFY(pathview->currentIndex() == 0);
402 QDeclarative1Text *text = findItem<QDeclarative1Text>(pathview, "myText", 4);
404 QCOMPARE(text->text(), model.name(4));
407 QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
408 text = findItem<QDeclarative1Text>(pathview, "myText", 2);
410 QCOMPARE(text->text(), model.name(2));
412 testObject->setPathItemCount(5);
413 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
414 QVERIFY(testObject->error() == false);
416 QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
418 QDeclarative1Rectangle *testItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 4);
419 QVERIFY(testItem != 0);
420 testItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 5);
421 QVERIFY(testItem == 0);
423 pathview->setCurrentIndex(1);
425 model.insertItem(2, "pink", "2");
428 QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
429 QVERIFY(pathview->currentIndex() == 1);
431 text = findItem<QDeclarative1Text>(pathview, "myText", 2);
433 QCOMPARE(text->text(), model.name(2));
436 QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
437 text = findItem<QDeclarative1Text>(pathview, "myText", 3);
439 QCOMPARE(text->text(), model.name(3));
441 model.moveItem(3, 5);
442 QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
443 QList<QDeclarativeItem*> items = findItems<QDeclarativeItem>(pathview, "wrapper");
444 foreach (QDeclarativeItem *item, items) {
445 QVERIFY(item->property("onPath").toBool());
449 pathview->setOffset(7);
450 pathview->setOffset(0);
451 QCOMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5);
453 pathview->setCurrentIndex(model.count()-1);
454 model.removeItem(model.count()-1);
455 QCOMPARE(pathview->currentIndex(), model.count()-1);
458 // Confirm that the target offset is adjusted when removing items
459 pathview->setCurrentIndex(model.count()-1);
460 QTRY_COMPARE(pathview->offset(), 1.);
461 pathview->setCurrentIndex(model.count()-5);
462 model.removeItem(model.count()-1);
463 model.removeItem(model.count()-1);
464 model.removeItem(model.count()-1);
465 QTRY_COMPARE(pathview->offset(), 2.);
471 void tst_QDeclarative1PathView::pathMoved()
473 QDeclarativeView *canvas = createView();
476 model.addItem("Ben", "12345");
477 model.addItem("Bohn", "2345");
478 model.addItem("Bob", "54321");
479 model.addItem("Bill", "4321");
481 QDeclarativeContext *ctxt = canvas->rootContext();
482 ctxt->setContextProperty("testModel", &model);
484 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
485 qApp->processEvents();
487 QDeclarative1PathView *pathview = findItem<QDeclarative1PathView>(canvas->rootObject(), "view");
488 QVERIFY(pathview != 0);
490 QDeclarative1Rectangle *firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 0);
492 QDeclarative1Path *path = qobject_cast<QDeclarative1Path*>(pathview->path());
494 QPointF start = path->pointAt(0.0);
495 QPointF offset;//Center of item is at point, but pos is from corner
496 offset.setX(firstItem->width()/2);
497 offset.setY(firstItem->height()/2);
498 QCOMPARE(firstItem->pos() + offset, start);
499 pathview->setOffset(1.0);
501 for(int i=0; i<model.count(); i++){
502 QDeclarative1Rectangle *curItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", i);
503 QPointF itemPos(path->pointAt(0.25 + i*0.25));
504 QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y())));
507 pathview->setOffset(0.0);
508 QCOMPARE(firstItem->pos() + offset, start);
510 // Change delegate size
511 pathview->setOffset(0.1);
512 pathview->setOffset(0.0);
513 canvas->rootObject()->setProperty("delegateWidth", 30);
514 QCOMPARE(firstItem->width(), 30.0);
515 offset.setX(firstItem->width()/2);
516 QTRY_COMPARE(firstItem->pos() + offset, start);
518 // Change delegate scale
519 pathview->setOffset(0.1);
520 pathview->setOffset(0.0);
521 canvas->rootObject()->setProperty("delegateScale", 1.2);
522 QTRY_COMPARE(firstItem->pos() + offset, start);
527 void tst_QDeclarative1PathView::setCurrentIndex()
529 QDeclarativeView *canvas = createView();
532 model.addItem("Ben", "12345");
533 model.addItem("Bohn", "2345");
534 model.addItem("Bob", "54321");
535 model.addItem("Bill", "4321");
537 QDeclarativeContext *ctxt = canvas->rootContext();
538 ctxt->setContextProperty("testModel", &model);
540 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
541 qApp->processEvents();
543 QDeclarative1PathView *pathview = findItem<QDeclarative1PathView>(canvas->rootObject(), "view");
544 QVERIFY(pathview != 0);
546 QDeclarative1Rectangle *firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 0);
548 QDeclarative1Path *path = qobject_cast<QDeclarative1Path*>(pathview->path());
550 QPointF start = path->pointAt(0.0);
551 QPointF offset;//Center of item is at point, but pos is from corner
552 offset.setX(firstItem->width()/2);
553 offset.setY(firstItem->height()/2);
554 QCOMPARE(firstItem->pos() + offset, start);
555 QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0);
556 QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0);
558 pathview->setCurrentIndex(2);
560 firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 2);
561 QTRY_COMPARE(firstItem->pos() + offset, start);
562 QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2);
563 QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2);
565 pathview->decrementCurrentIndex();
566 QTRY_COMPARE(pathview->currentIndex(), 1);
567 firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 1);
569 QTRY_COMPARE(firstItem->pos() + offset, start);
571 pathview->decrementCurrentIndex();
572 QTRY_COMPARE(pathview->currentIndex(), 0);
573 firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 0);
575 QTRY_COMPARE(firstItem->pos() + offset, start);
577 pathview->decrementCurrentIndex();
578 QTRY_COMPARE(pathview->currentIndex(), 3);
579 firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 3);
581 QTRY_COMPARE(firstItem->pos() + offset, start);
583 pathview->incrementCurrentIndex();
584 QTRY_COMPARE(pathview->currentIndex(), 0);
585 firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 0);
587 QTRY_COMPARE(firstItem->pos() + offset, start);
592 void tst_QDeclarative1PathView::resetModel()
594 QDeclarativeView *canvas = createView();
597 strings << "one" << "two" << "three";
598 QStringListModel model(strings);
600 QDeclarativeContext *ctxt = canvas->rootContext();
601 ctxt->setContextProperty("testModel", &model);
603 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaypath.qml"));
604 qApp->processEvents();
606 QDeclarative1PathView *pathview = findItem<QDeclarative1PathView>(canvas->rootObject(), "view");
607 QVERIFY(pathview != 0);
609 QCOMPARE(pathview->count(), model.rowCount());
611 for (int i = 0; i < model.rowCount(); ++i) {
612 QDeclarative1Text *display = findItem<QDeclarative1Text>(pathview, "displayText", i);
613 QVERIFY(display != 0);
614 QCOMPARE(display->text(), strings.at(i));
618 strings << "four" << "five" << "six" << "seven";
619 model.setStringList(strings);
621 QCOMPARE(pathview->count(), model.rowCount());
623 for (int i = 0; i < model.rowCount(); ++i) {
624 QDeclarative1Text *display = findItem<QDeclarative1Text>(pathview, "displayText", i);
625 QVERIFY(display != 0);
626 QCOMPARE(display->text(), strings.at(i));
632 void tst_QDeclarative1PathView::propertyChanges()
634 QDeclarativeView *canvas = createView();
636 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
638 QDeclarative1PathView *pathView = canvas->rootObject()->findChild<QDeclarative1PathView*>("pathView");
641 QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged()));
642 QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged()));
644 QCOMPARE(pathView->preferredHighlightBegin(), 0.1);
645 QCOMPARE(pathView->dragMargin(), 5.0);
647 pathView->setPreferredHighlightBegin(0.4);
648 pathView->setPreferredHighlightEnd(0.4);
649 pathView->setDragMargin(20.0);
651 QCOMPARE(pathView->preferredHighlightBegin(), 0.4);
652 QCOMPARE(pathView->preferredHighlightEnd(), 0.4);
653 QCOMPARE(pathView->dragMargin(), 20.0);
655 QCOMPARE(snapPositionSpy.count(), 1);
656 QCOMPARE(dragMarginSpy.count(), 1);
658 pathView->setPreferredHighlightBegin(0.4);
659 pathView->setPreferredHighlightEnd(0.4);
660 pathView->setDragMargin(20.0);
662 QCOMPARE(snapPositionSpy.count(), 1);
663 QCOMPARE(dragMarginSpy.count(), 1);
667 void tst_QDeclarative1PathView::pathChanges()
669 QDeclarativeView *canvas = createView();
671 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
673 QDeclarative1PathView *pathView = canvas->rootObject()->findChild<QDeclarative1PathView*>("pathView");
676 QDeclarative1Path *path = canvas->rootObject()->findChild<QDeclarative1Path*>("path");
679 QSignalSpy startXSpy(path, SIGNAL(startXChanged()));
680 QSignalSpy startYSpy(path, SIGNAL(startYChanged()));
682 QCOMPARE(path->startX(), 220.0);
683 QCOMPARE(path->startY(), 200.0);
685 path->setStartX(240.0);
686 path->setStartY(220.0);
688 QCOMPARE(path->startX(), 240.0);
689 QCOMPARE(path->startY(), 220.0);
691 QCOMPARE(startXSpy.count(),1);
692 QCOMPARE(startYSpy.count(),1);
694 path->setStartX(240);
695 path->setStartY(220);
697 QCOMPARE(startXSpy.count(),1);
698 QCOMPARE(startYSpy.count(),1);
700 QDeclarative1Path *alternatePath = canvas->rootObject()->findChild<QDeclarative1Path*>("alternatePath");
701 QVERIFY(alternatePath);
703 QSignalSpy pathSpy(pathView, SIGNAL(pathChanged()));
705 QCOMPARE(pathView->path(), path);
707 pathView->setPath(alternatePath);
708 QCOMPARE(pathView->path(), alternatePath);
709 QCOMPARE(pathSpy.count(),1);
711 pathView->setPath(alternatePath);
712 QCOMPARE(pathSpy.count(),1);
714 QDeclarative1PathAttribute *pathAttribute = canvas->rootObject()->findChild<QDeclarative1PathAttribute*>("pathAttribute");
715 QVERIFY(pathAttribute);
717 QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged()));
718 QCOMPARE(pathAttribute->name(), QString("opacity"));
720 pathAttribute->setName("scale");
721 QCOMPARE(pathAttribute->name(), QString("scale"));
722 QCOMPARE(nameSpy.count(),1);
724 pathAttribute->setName("scale");
725 QCOMPARE(nameSpy.count(),1);
729 void tst_QDeclarative1PathView::componentChanges()
731 QDeclarativeView *canvas = createView();
733 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
735 QDeclarative1PathView *pathView = canvas->rootObject()->findChild<QDeclarative1PathView*>("pathView");
738 QDeclarativeComponent delegateComponent(canvas->engine());
739 delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
741 QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged()));
743 pathView->setDelegate(&delegateComponent);
744 QCOMPARE(pathView->delegate(), &delegateComponent);
745 QCOMPARE(delegateSpy.count(),1);
747 pathView->setDelegate(&delegateComponent);
748 QCOMPARE(delegateSpy.count(),1);
752 void tst_QDeclarative1PathView::modelChanges()
754 QDeclarativeView *canvas = createView();
756 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
758 QDeclarative1PathView *pathView = canvas->rootObject()->findChild<QDeclarative1PathView*>("pathView");
761 // QDeclarative1ListModel *alternateModel = canvas->rootObject()->findChild<QDeclarative1ListModel*>("alternateModel");
762 QObject *alternateModel = canvas->rootObject()->findChild<QObject*>("alternateModel");
763 QVERIFY(alternateModel);
764 QVariant modelVariant = QVariant::fromValue(alternateModel);
765 QSignalSpy modelSpy(pathView, SIGNAL(modelChanged()));
767 pathView->setModel(modelVariant);
768 QCOMPARE(pathView->model(), modelVariant);
769 QCOMPARE(modelSpy.count(),1);
771 pathView->setModel(modelVariant);
772 QCOMPARE(modelSpy.count(),1);
774 pathView->setModel(QVariant());
775 QCOMPARE(modelSpy.count(),2);
780 void tst_QDeclarative1PathView::pathUpdateOnStartChanged()
782 QDeclarativeView *canvas = createView();
784 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathUpdateOnStartChanged.qml"));
786 QDeclarative1PathView *pathView = canvas->rootObject()->findChild<QDeclarative1PathView*>("pathView");
789 QDeclarative1Path *path = canvas->rootObject()->findChild<QDeclarative1Path*>("path");
791 QCOMPARE(path->startX(), 400.0);
792 QCOMPARE(path->startY(), 300.0);
794 QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "wrapper", 0);
796 QCOMPARE(item->x(), path->startX() - item->width() / 2.0);
797 QCOMPARE(item->y(), path->startY() - item->height() / 2.0);
802 void tst_QDeclarative1PathView::package()
804 QDeclarativeView *canvas = createView();
806 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview_package.qml"));
808 QDeclarative1PathView *pathView = canvas->rootObject()->findChild<QDeclarative1PathView*>("photoPathView");
811 QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "pathItem");
813 QVERIFY(item->scale() != 1.0);
819 void tst_QDeclarative1PathView::emptyModel()
821 QDeclarativeView *canvas = createView();
823 QStringListModel model;
825 QDeclarativeContext *ctxt = canvas->rootContext();
826 ctxt->setContextProperty("emptyModel", &model);
828 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/emptymodel.qml"));
829 qApp->processEvents();
831 QDeclarative1PathView *pathview = qobject_cast<QDeclarative1PathView*>(canvas->rootObject());
832 QVERIFY(pathview != 0);
834 QCOMPARE(pathview->offset(), qreal(0.0));
839 void tst_QDeclarative1PathView::closed()
841 QDeclarativeEngine engine;
844 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/openPath.qml"));
845 QDeclarative1Path *obj = qobject_cast<QDeclarative1Path*>(c.create());
847 QCOMPARE(obj->isClosed(), false);
852 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/closedPath.qml"));
853 QDeclarative1Path *obj = qobject_cast<QDeclarative1Path*>(c.create());
855 QCOMPARE(obj->isClosed(), true);
861 void tst_QDeclarative1PathView::pathUpdate()
863 QDeclarativeView *canvas = createView();
865 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathUpdate.qml"));
867 QDeclarative1PathView *pathView = canvas->rootObject()->findChild<QDeclarative1PathView*>("pathView");
870 QDeclarativeItem *item = findItem<QDeclarativeItem>(pathView, "wrapper", 0);
872 QCOMPARE(item->x(), 150.0);
877 void tst_QDeclarative1PathView::visualDataModel()
879 QDeclarativeEngine engine;
880 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/vdm.qml"));
882 QDeclarative1PathView *obj = qobject_cast<QDeclarative1PathView*>(c.create());
885 QCOMPARE(obj->count(), 3);
890 void tst_QDeclarative1PathView::undefinedPath()
892 QDeclarativeEngine engine;
893 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/undefinedpath.qml"));
895 QDeclarative1PathView *obj = qobject_cast<QDeclarative1PathView*>(c.create());
898 QCOMPARE(obj->count(), 3);
903 void tst_QDeclarative1PathView::mouseDrag()
905 QDeclarativeView *canvas = createView();
906 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragpath.qml"));
908 QApplication::setActiveWindow(canvas);
909 QTest::qWaitForWindowShown(canvas);
910 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
912 QDeclarative1PathView *pathview = qobject_cast<QDeclarative1PathView*>(canvas->rootObject());
913 QVERIFY(pathview != 0);
915 int current = pathview->currentIndex();
917 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(10,100)));
920 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(30,100)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
921 QApplication::sendEvent(canvas->viewport(), &mv);
924 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(90,100)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
925 QApplication::sendEvent(canvas->viewport(), &mv);
928 QVERIFY(pathview->currentIndex() != current);
930 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(40,100)));
935 void tst_QDeclarative1PathView::treeModel()
937 QDeclarativeView *canvas = createView();
939 QStandardItemModel model;
940 initStandardTreeModel(&model);
941 canvas->engine()->rootContext()->setContextProperty("myModel", &model);
943 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/treemodel.qml"));
945 QDeclarative1PathView *pathview = qobject_cast<QDeclarative1PathView*>(canvas->rootObject());
946 QVERIFY(pathview != 0);
947 QCOMPARE(pathview->count(), 3);
949 QDeclarative1Text *item = findItem<QDeclarative1Text>(pathview, "wrapper", 0);
951 QCOMPARE(item->text(), QLatin1String("Row 1 Item"));
953 QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1)));
954 QCOMPARE(pathview->count(), 1);
956 QTRY_VERIFY(item = findItem<QDeclarative1Text>(pathview, "wrapper", 0));
957 QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item"));
962 void tst_QDeclarative1PathView::changePreferredHighlight()
964 QDeclarativeView *canvas = createView();
965 canvas->setFixedSize(400,200);
966 canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragpath.qml"));
968 QApplication::setActiveWindow(canvas);
969 QTest::qWaitForWindowShown(canvas);
970 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
972 QDeclarative1PathView *pathview = qobject_cast<QDeclarative1PathView*>(canvas->rootObject());
973 QVERIFY(pathview != 0);
975 int current = pathview->currentIndex();
976 QCOMPARE(current, 0);
978 QDeclarative1Rectangle *firstItem = findItem<QDeclarative1Rectangle>(pathview, "wrapper", 0);
980 QDeclarative1Path *path = qobject_cast<QDeclarative1Path*>(pathview->path());
982 QPointF start = path->pointAt(0.5);
983 start.setX(qRound(start.x()));
984 start.setY(qRound(start.y()));
985 QPointF offset;//Center of item is at point, but pos is from corner
986 offset.setX(firstItem->width()/2);
987 offset.setY(firstItem->height()/2);
988 QTRY_COMPARE(firstItem->pos() + offset, start);
990 pathview->setPreferredHighlightBegin(0.8);
991 pathview->setPreferredHighlightEnd(0.8);
992 start = path->pointAt(0.8);
993 start.setX(qRound(start.x()));
994 start.setY(qRound(start.y()));
995 QTRY_COMPARE(firstItem->pos() + offset, start);
996 QCOMPARE(pathview->currentIndex(), 0);
1001 QDeclarativeView *tst_QDeclarative1PathView::createView()
1003 QDeclarativeView *canvas = new QDeclarativeView(0);
1004 canvas->setFixedSize(240,320);
1010 Find an item with the specified objectName. If index is supplied then the
1011 item must also evaluate the {index} expression equal to index
1013 template<typename T>
1014 T *tst_QDeclarative1PathView::findItem(QGraphicsObject *parent, const QString &objectName, int index)
1016 const QMetaObject &mo = T::staticMetaObject;
1017 //qDebug() << parent->childItems().count() << "children";
1018 for (int i = 0; i < parent->childItems().count(); ++i) {
1019 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
1022 //qDebug() << "try" << item;
1023 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
1025 QDeclarativeExpression e(qmlContext(item), item, "index");
1026 if (e.evaluate().toInt() == index)
1027 return static_cast<T*>(item);
1029 return static_cast<T*>(item);
1032 item = findItem<T>(item, objectName, index);
1034 return static_cast<T*>(item);
1040 template<typename T>
1041 QList<T*> tst_QDeclarative1PathView::findItems(QGraphicsObject *parent, const QString &objectName)
1044 const QMetaObject &mo = T::staticMetaObject;
1045 //qDebug() << parent->QGraphicsObject::children().count() << "children";
1046 for (int i = 0; i < parent->childItems().count(); ++i) {
1047 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
1050 //qDebug() << "try" << item;
1051 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
1052 items.append(static_cast<T*>(item));
1053 items += findItems<T>(item, objectName);
1059 QTEST_MAIN(tst_QDeclarative1PathView)
1061 #include "tst_qdeclarativepathview.moc"