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 <QtQuick/qquickview.h>
44 #include <QtQml/qqmlengine.h>
45 #include <QtQml/qqmlcomponent.h>
46 #include <QtQml/qqmlcontext.h>
47 #include <QtQml/qqmlexpression.h>
48 #include <QtQml/qqmlincubator.h>
49 #include <QtQuick/private/qquickpathview_p.h>
50 #include <QtQuick/private/qquickpath_p.h>
51 #include <QtQuick/private/qquicktext_p.h>
52 #include <QtQuick/private/qquickrectangle_p.h>
53 #include <QtQml/private/qquicklistmodel_p.h>
54 #include <QtQml/private/qqmlvaluetype_p.h>
55 #include <QStringListModel>
56 #include <QStandardItemModel>
59 #include "../../shared/util.h"
60 #include "../shared/viewtestutil.h"
61 #include "../shared/visualtestutil.h"
63 using namespace QQuickViewTestUtil;
64 using namespace QQuickVisualTestUtil;
67 static void initStandardTreeModel(QStandardItemModel *model)
70 item = new QStandardItem(QLatin1String("Row 1 Item"));
71 model->insertRow(0, item);
73 item = new QStandardItem(QLatin1String("Row 2 Item"));
74 item->setCheckable(true);
75 model->insertRow(1, item);
77 QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
78 item->setChild(0, childItem);
80 item = new QStandardItem(QLatin1String("Row 3 Item"));
81 item->setIcon(QIcon());
82 model->insertRow(2, item);
86 class tst_QQuickPathView : public QQmlDataTest
98 void insertModel_data();
100 void removeModel_data();
102 void moveModel_data();
106 void setCurrentIndex();
108 void propertyChanges();
110 void componentChanges();
112 void pathUpdateOnStartChanged();
117 void visualDataModel();
118 void undefinedPath();
121 void changePreferredHighlight();
122 void missingPercent();
123 void creationContext();
124 void currentOffsetOnInsertion();
128 class TestObject : public QObject
132 Q_PROPERTY(bool error READ error WRITE setError)
133 Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
134 Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged)
137 TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {}
139 bool error() const { return mError; }
140 void setError(bool err) { mError = err; }
142 bool useModel() const { return mUseModel; }
143 void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
145 int pathItemCount() const { return mPathItemCount; }
146 void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); }
149 void useModelChanged();
150 void pathItemCountChanged();
158 tst_QQuickPathView::tst_QQuickPathView()
162 void tst_QQuickPathView::initValues()
165 QQmlComponent c(&engine, testFileUrl("pathview1.qml"));
166 QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
169 QVERIFY(obj->path() == 0);
170 QVERIFY(obj->delegate() == 0);
171 QCOMPARE(obj->model(), QVariant());
172 QCOMPARE(obj->currentIndex(), 0);
173 QCOMPARE(obj->offset(), 0.);
174 QCOMPARE(obj->preferredHighlightBegin(), 0.);
175 QCOMPARE(obj->dragMargin(), 0.);
176 QCOMPARE(obj->count(), 0);
177 QCOMPARE(obj->pathItemCount(), -1);
182 void tst_QQuickPathView::items()
184 QQuickView *canvas = createView();
187 model.addItem("Fred", "12345");
188 model.addItem("John", "2345");
189 model.addItem("Bob", "54321");
190 model.addItem("Bill", "4321");
192 QQmlContext *ctxt = canvas->rootContext();
193 ctxt->setContextProperty("testModel", &model);
195 canvas->setSource(testFileUrl("pathview0.qml"));
196 qApp->processEvents();
198 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
199 QVERIFY(pathview != 0);
201 QCOMPARE(pathview->count(), model.count());
202 QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
203 QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight
205 for (int i = 0; i < model.count(); ++i) {
206 QQuickText *name = findItem<QQuickText>(pathview, "textName", i);
208 QCOMPARE(name->text(), model.name(i));
209 QQuickText *number = findItem<QQuickText>(pathview, "textNumber", i);
210 QVERIFY(number != 0);
211 QCOMPARE(number->text(), model.number(i));
214 QQuickPath *path = qobject_cast<QQuickPath*>(pathview->path());
217 QVERIFY(pathview->highlightItem());
218 QPointF start = path->pointAt(0.0);
220 offset.setX(pathview->highlightItem()->width()/2);
221 offset.setY(pathview->highlightItem()->height()/2);
222 QCOMPARE(pathview->highlightItem()->pos() + offset, start);
227 void tst_QQuickPathView::pathview2()
230 QQmlComponent c(&engine, testFileUrl("pathview2.qml"));
231 QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
234 QVERIFY(obj->path() != 0);
235 QVERIFY(obj->delegate() != 0);
236 QVERIFY(obj->model() != QVariant());
237 QCOMPARE(obj->currentIndex(), 0);
238 QCOMPARE(obj->offset(), 0.);
239 QCOMPARE(obj->preferredHighlightBegin(), 0.);
240 QCOMPARE(obj->dragMargin(), 0.);
241 QCOMPARE(obj->count(), 8);
242 QCOMPARE(obj->pathItemCount(), 10);
247 void tst_QQuickPathView::pathview3()
250 QQmlComponent c(&engine, testFileUrl("pathview3.qml"));
251 QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
254 QVERIFY(obj->path() != 0);
255 QVERIFY(obj->delegate() != 0);
256 QVERIFY(obj->model() != QVariant());
257 QCOMPARE(obj->currentIndex(), 0);
258 QCOMPARE(obj->offset(), 1.0);
259 QCOMPARE(obj->preferredHighlightBegin(), 0.5);
260 QCOMPARE(obj->dragMargin(), 24.);
261 QCOMPARE(obj->count(), 8);
262 QCOMPARE(obj->pathItemCount(), 4);
267 void tst_QQuickPathView::insertModel_data()
269 QTest::addColumn<int>("mode");
270 QTest::addColumn<int>("idx");
271 QTest::addColumn<int>("count");
272 QTest::addColumn<qreal>("offset");
274 // We have 8 items, with currentIndex == 4
275 QTest::newRow("insert after current")
276 << int(QQuickPathView::StrictlyEnforceRange) << 6 << 1 << 5.;
277 QTest::newRow("insert before current")
278 << int(QQuickPathView::StrictlyEnforceRange) << 2 << 1 << 4.;
279 QTest::newRow("insert multiple after current")
280 << int(QQuickPathView::StrictlyEnforceRange) << 5 << 2 << 6.;
281 QTest::newRow("insert multiple before current")
282 << int(QQuickPathView::StrictlyEnforceRange) << 1 << 2 << 4.;
283 QTest::newRow("insert at end")
284 << int(QQuickPathView::StrictlyEnforceRange) << 8 << 1 << 5.;
285 QTest::newRow("insert at beginning")
286 << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 4.;
287 QTest::newRow("insert at current")
288 << int(QQuickPathView::StrictlyEnforceRange) << 4 << 1 << 4.;
290 QTest::newRow("no range - insert after current")
291 << int(QQuickPathView::NoHighlightRange) << 6 << 1 << 5.;
292 QTest::newRow("no range - insert before current")
293 << int(QQuickPathView::NoHighlightRange) << 2 << 1 << 4.;
294 QTest::newRow("no range - insert multiple after current")
295 << int(QQuickPathView::NoHighlightRange) << 5 << 2 << 6.;
296 QTest::newRow("no range - insert multiple before current")
297 << int(QQuickPathView::NoHighlightRange) << 1 << 2 << 4.;
298 QTest::newRow("no range - insert at end")
299 << int(QQuickPathView::NoHighlightRange) << 8 << 1 << 5.;
300 QTest::newRow("no range - insert at beginning")
301 << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 4.;
302 QTest::newRow("no range - insert at current")
303 << int(QQuickPathView::NoHighlightRange) << 4 << 1 << 4.;
306 void tst_QQuickPathView::insertModel()
311 QFETCH(qreal, offset);
313 QQuickView *canvas = createView();
317 model.addItem("Ben", "12345");
318 model.addItem("Bohn", "2345");
319 model.addItem("Bob", "54321");
320 model.addItem("Bill", "4321");
321 model.addItem("Jinny", "679");
322 model.addItem("Milly", "73378");
323 model.addItem("Jimmy", "3535");
324 model.addItem("Barb", "9039");
326 QQmlContext *ctxt = canvas->rootContext();
327 ctxt->setContextProperty("testModel", &model);
329 canvas->setSource(testFileUrl("pathview0.qml"));
330 qApp->processEvents();
332 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
333 QVERIFY(pathview != 0);
335 pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode);
337 pathview->setCurrentIndex(4);
338 if (mode == QQuickPathView::StrictlyEnforceRange)
339 QTRY_COMPARE(pathview->offset(), 4.0);
341 pathview->setOffset(4);
343 QList<QPair<QString, QString> > items;
344 for (int i = 0; i < count; ++i)
345 items.append(qMakePair(QString("New"), QString::number(i)));
347 model.insertItems(idx, items);
348 QTRY_COMPARE(pathview->offset(), offset);
353 void tst_QQuickPathView::removeModel_data()
355 QTest::addColumn<int>("mode");
356 QTest::addColumn<int>("idx");
357 QTest::addColumn<int>("count");
358 QTest::addColumn<qreal>("offset");
360 // We have 8 items, with currentIndex == 4
361 QTest::newRow("remove after current")
362 << int(QQuickPathView::StrictlyEnforceRange) << 6 << 1 << 3.;
363 QTest::newRow("remove before current")
364 << int(QQuickPathView::StrictlyEnforceRange) << 2 << 1 << 4.;
365 QTest::newRow("remove multiple after current")
366 << int(QQuickPathView::StrictlyEnforceRange) << 5 << 2 << 2.;
367 QTest::newRow("remove multiple before current")
368 << int(QQuickPathView::StrictlyEnforceRange) << 1 << 2 << 4.;
369 QTest::newRow("remove last")
370 << int(QQuickPathView::StrictlyEnforceRange) << 7 << 1 << 3.;
371 QTest::newRow("remove first")
372 << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 4.;
373 QTest::newRow("remove current")
374 << int(QQuickPathView::StrictlyEnforceRange) << 4 << 1 << 3.;
376 QTest::newRow("no range - remove after current")
377 << int(QQuickPathView::NoHighlightRange) << 6 << 1 << 3.;
378 QTest::newRow("no range - remove before current")
379 << int(QQuickPathView::NoHighlightRange) << 2 << 1 << 4.;
380 QTest::newRow("no range - remove multiple after current")
381 << int(QQuickPathView::NoHighlightRange) << 5 << 2 << 2.;
382 QTest::newRow("no range - remove multiple before current")
383 << int(QQuickPathView::NoHighlightRange) << 1 << 2 << 4.;
384 QTest::newRow("no range - remove last")
385 << int(QQuickPathView::NoHighlightRange) << 7 << 1 << 3.;
386 QTest::newRow("no range - remove first")
387 << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 4.;
388 QTest::newRow("no range - remove current offset")
389 << int(QQuickPathView::NoHighlightRange) << 4 << 1 << 4.;
392 void tst_QQuickPathView::removeModel()
397 QFETCH(qreal, offset);
399 QQuickView *canvas = createView();
403 model.addItem("Ben", "12345");
404 model.addItem("Bohn", "2345");
405 model.addItem("Bob", "54321");
406 model.addItem("Bill", "4321");
407 model.addItem("Jinny", "679");
408 model.addItem("Milly", "73378");
409 model.addItem("Jimmy", "3535");
410 model.addItem("Barb", "9039");
412 QQmlContext *ctxt = canvas->rootContext();
413 ctxt->setContextProperty("testModel", &model);
415 canvas->setSource(testFileUrl("pathview0.qml"));
416 qApp->processEvents();
418 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
419 QVERIFY(pathview != 0);
421 pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode);
423 pathview->setCurrentIndex(4);
424 if (mode == QQuickPathView::StrictlyEnforceRange)
425 QTRY_COMPARE(pathview->offset(), 4.0);
427 pathview->setOffset(4);
429 model.removeItems(idx, count);
430 QTRY_COMPARE(pathview->offset(), offset);
436 void tst_QQuickPathView::moveModel_data()
438 QTest::addColumn<int>("mode");
439 QTest::addColumn<int>("from");
440 QTest::addColumn<int>("to");
441 QTest::addColumn<int>("count");
442 QTest::addColumn<qreal>("offset");
444 // We have 8 items, with currentIndex == 4
445 QTest::newRow("move after current")
446 << int(QQuickPathView::StrictlyEnforceRange) << 5 << 6 << 1 << 4.;
447 QTest::newRow("move before current")
448 << int(QQuickPathView::StrictlyEnforceRange) << 2 << 3 << 1 << 4.;
449 QTest::newRow("move before current to after")
450 << int(QQuickPathView::StrictlyEnforceRange) << 2 << 6 << 1 << 5.;
451 QTest::newRow("move multiple after current")
452 << int(QQuickPathView::StrictlyEnforceRange) << 5 << 6 << 2 << 4.;
453 QTest::newRow("move multiple before current")
454 << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 2 << 4.;
455 QTest::newRow("move before current to end")
456 << int(QQuickPathView::StrictlyEnforceRange) << 2 << 7 << 1 << 5.;
457 QTest::newRow("move last to beginning")
458 << int(QQuickPathView::StrictlyEnforceRange) << 7 << 0 << 1 << 3.;
459 QTest::newRow("move current")
460 << int(QQuickPathView::StrictlyEnforceRange) << 4 << 6 << 1 << 2.;
462 QTest::newRow("no range - move after current")
463 << int(QQuickPathView::NoHighlightRange) << 5 << 6 << 1 << 4.;
464 QTest::newRow("no range - move before current")
465 << int(QQuickPathView::NoHighlightRange) << 2 << 3 << 1 << 4.;
466 QTest::newRow("no range - move before current to after")
467 << int(QQuickPathView::NoHighlightRange) << 2 << 6 << 1 << 5.;
468 QTest::newRow("no range - move multiple after current")
469 << int(QQuickPathView::NoHighlightRange) << 5 << 6 << 2 << 4.;
470 QTest::newRow("no range - move multiple before current")
471 << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 2 << 4.;
472 QTest::newRow("no range - move before current to end")
473 << int(QQuickPathView::NoHighlightRange) << 2 << 7 << 1 << 5.;
474 QTest::newRow("no range - move last to beginning")
475 << int(QQuickPathView::NoHighlightRange) << 7 << 0 << 1 << 3.;
476 QTest::newRow("no range - move current")
477 << int(QQuickPathView::NoHighlightRange) << 4 << 6 << 1 << 4.;
478 QTest::newRow("no range - move multiple incl. current")
479 << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 5 << 4.;
482 void tst_QQuickPathView::moveModel()
488 QFETCH(qreal, offset);
490 QQuickView *canvas = createView();
494 model.addItem("Ben", "12345");
495 model.addItem("Bohn", "2345");
496 model.addItem("Bob", "54321");
497 model.addItem("Bill", "4321");
498 model.addItem("Jinny", "679");
499 model.addItem("Milly", "73378");
500 model.addItem("Jimmy", "3535");
501 model.addItem("Barb", "9039");
503 QQmlContext *ctxt = canvas->rootContext();
504 ctxt->setContextProperty("testModel", &model);
506 canvas->setSource(testFileUrl("pathview0.qml"));
507 qApp->processEvents();
509 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
510 QVERIFY(pathview != 0);
512 pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode);
514 pathview->setCurrentIndex(4);
515 if (mode == QQuickPathView::StrictlyEnforceRange)
516 QTRY_COMPARE(pathview->offset(), 4.0);
518 pathview->setOffset(4);
520 model.moveItems(from, to, count);
521 QTRY_COMPARE(pathview->offset(), offset);
526 void tst_QQuickPathView::path()
529 QQmlComponent c(&engine, testFileUrl("pathtest.qml"));
530 QQuickPath *obj = qobject_cast<QQuickPath*>(c.create());
533 QCOMPARE(obj->startX(), 120.);
534 QCOMPARE(obj->startY(), 100.);
535 QVERIFY(obj->path() != QPainterPath());
537 QQmlListReference list(obj, "pathElements");
538 QCOMPARE(list.count(), 5);
540 QQuickPathAttribute* attr = qobject_cast<QQuickPathAttribute*>(list.at(0));
542 QCOMPARE(attr->name(), QString("scale"));
543 QCOMPARE(attr->value(), 1.0);
545 QQuickPathQuad* quad = qobject_cast<QQuickPathQuad*>(list.at(1));
547 QCOMPARE(quad->x(), 120.);
548 QCOMPARE(quad->y(), 25.);
549 QCOMPARE(quad->controlX(), 260.);
550 QCOMPARE(quad->controlY(), 75.);
552 QQuickPathPercent* perc = qobject_cast<QQuickPathPercent*>(list.at(2));
554 QCOMPARE(perc->value(), 0.3);
556 QQuickPathLine* line = qobject_cast<QQuickPathLine*>(list.at(3));
558 QCOMPARE(line->x(), 120.);
559 QCOMPARE(line->y(), 100.);
561 QQuickPathCubic* cubic = qobject_cast<QQuickPathCubic*>(list.at(4));
563 QCOMPARE(cubic->x(), 180.);
564 QCOMPARE(cubic->y(), 0.);
565 QCOMPARE(cubic->control1X(), -10.);
566 QCOMPARE(cubic->control1Y(), 90.);
567 QCOMPARE(cubic->control2X(), 210.);
568 QCOMPARE(cubic->control2Y(), 90.);
573 void tst_QQuickPathView::dataModel()
575 QQuickView *canvas = createView();
578 QQmlContext *ctxt = canvas->rootContext();
579 TestObject *testObject = new TestObject;
580 ctxt->setContextProperty("testObject", testObject);
583 model.addItem("red", "1");
584 model.addItem("green", "2");
585 model.addItem("blue", "3");
586 model.addItem("purple", "4");
587 model.addItem("gray", "5");
588 model.addItem("brown", "6");
589 model.addItem("yellow", "7");
590 model.addItem("thistle", "8");
591 model.addItem("cyan", "9");
592 model.addItem("peachpuff", "10");
593 model.addItem("powderblue", "11");
594 model.addItem("gold", "12");
595 model.addItem("sandybrown", "13");
597 ctxt->setContextProperty("testData", &model);
599 canvas->setSource(testFileUrl("datamodel.qml"));
600 qApp->processEvents();
602 QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
603 QVERIFY(pathview != 0);
605 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
606 QVERIFY(testObject->error() == false);
608 QQuickItem *item = findItem<QQuickItem>(pathview, "wrapper", 0);
610 QCOMPARE(item->x(), 110.0);
611 QCOMPARE(item->y(), 10.0);
613 model.insertItem(4, "orange", "10");
616 QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
617 QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 14);
619 QVERIFY(pathview->currentIndex() == 0);
620 QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 0));
622 QQuickText *text = findItem<QQuickText>(pathview, "myText", 4);
624 QCOMPARE(text->text(), model.name(4));
627 QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
628 text = findItem<QQuickText>(pathview, "myText", 2);
630 QCOMPARE(text->text(), model.name(2));
631 QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 0));
633 testObject->setPathItemCount(5);
634 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
635 QVERIFY(testObject->error() == false);
637 QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
639 QQuickRectangle *testItem = findItem<QQuickRectangle>(pathview, "wrapper", 4);
640 QVERIFY(testItem != 0);
641 testItem = findItem<QQuickRectangle>(pathview, "wrapper", 5);
642 QVERIFY(testItem == 0);
644 pathview->setCurrentIndex(1);
645 QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
648 model.insertItem(2, "pink", "2");
651 QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
652 QVERIFY(pathview->currentIndex() == 1);
653 QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
655 text = findItem<QQuickText>(pathview, "myText", 2);
657 QCOMPARE(text->text(), model.name(2));
660 QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
661 text = findItem<QQuickText>(pathview, "myText", 3);
663 QCOMPARE(text->text(), model.name(3));
664 QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
666 model.moveItem(3, 5);
667 QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
668 QList<QQuickItem*> items = findItems<QQuickItem>(pathview, "wrapper");
669 foreach (QQuickItem *item, items) {
670 QVERIFY(item->property("onPath").toBool());
672 QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
675 pathview->setOffset(7);
676 pathview->setOffset(0);
677 QCOMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
679 pathview->setCurrentIndex(model.count()-1);
680 model.removeItem(model.count()-1);
681 QCOMPARE(pathview->currentIndex(), model.count()-1);
687 void tst_QQuickPathView::pathMoved()
689 QQuickView *canvas = createView();
693 model.addItem("Ben", "12345");
694 model.addItem("Bohn", "2345");
695 model.addItem("Bob", "54321");
696 model.addItem("Bill", "4321");
698 QQmlContext *ctxt = canvas->rootContext();
699 ctxt->setContextProperty("testModel", &model);
701 canvas->setSource(testFileUrl("pathview0.qml"));
702 qApp->processEvents();
704 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
705 QVERIFY(pathview != 0);
707 QQuickRectangle *firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
709 QQuickPath *path = qobject_cast<QQuickPath*>(pathview->path());
711 QPointF start = path->pointAt(0.0);
712 QPointF offset;//Center of item is at point, but pos is from corner
713 offset.setX(firstItem->width()/2);
714 offset.setY(firstItem->height()/2);
715 QTRY_COMPARE(firstItem->pos() + offset, start);
716 pathview->setOffset(1.0);
718 for (int i=0; i<model.count(); i++) {
719 QQuickRectangle *curItem = findItem<QQuickRectangle>(pathview, "wrapper", i);
720 QPointF itemPos(path->pointAt(0.25 + i*0.25));
721 QCOMPARE(curItem->pos() + offset, QPointF(itemPos.x(), itemPos.y()));
724 pathview->setOffset(0.0);
725 QCOMPARE(firstItem->pos() + offset, start);
727 // Change delegate size
728 pathview->setOffset(0.1);
729 pathview->setOffset(0.0);
730 canvas->rootObject()->setProperty("delegateWidth", 30);
731 QCOMPARE(firstItem->width(), 30.0);
732 offset.setX(firstItem->width()/2);
733 QTRY_COMPARE(firstItem->pos() + offset, start);
735 // Change delegate scale
736 pathview->setOffset(0.1);
737 pathview->setOffset(0.0);
738 canvas->rootObject()->setProperty("delegateScale", 1.2);
739 QTRY_COMPARE(firstItem->pos() + offset, start);
744 void tst_QQuickPathView::setCurrentIndex()
746 QQuickView *canvas = createView();
750 model.addItem("Ben", "12345");
751 model.addItem("Bohn", "2345");
752 model.addItem("Bob", "54321");
753 model.addItem("Bill", "4321");
755 QQmlContext *ctxt = canvas->rootContext();
756 ctxt->setContextProperty("testModel", &model);
758 canvas->setSource(testFileUrl("pathview0.qml"));
759 qApp->processEvents();
761 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
762 QVERIFY(pathview != 0);
764 QQuickRectangle *firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
766 QQuickPath *path = qobject_cast<QQuickPath*>(pathview->path());
768 QPointF start = path->pointAt(0.0);
769 QPointF offset;//Center of item is at point, but pos is from corner
770 offset.setX(firstItem->width()/2);
771 offset.setY(firstItem->height()/2);
772 QCOMPARE(firstItem->pos() + offset, start);
773 QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0);
774 QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0);
776 pathview->setCurrentIndex(2);
778 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 2);
779 QTRY_COMPARE(firstItem->pos() + offset, start);
780 QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2);
781 QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2);
782 QCOMPARE(pathview->currentItem(), firstItem);
783 QCOMPARE(firstItem->property("onPath"), QVariant(true));
785 pathview->decrementCurrentIndex();
786 QTRY_COMPARE(pathview->currentIndex(), 1);
787 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 1);
789 QTRY_COMPARE(firstItem->pos() + offset, start);
790 QCOMPARE(pathview->currentItem(), firstItem);
791 QCOMPARE(firstItem->property("onPath"), QVariant(true));
793 pathview->decrementCurrentIndex();
794 QTRY_COMPARE(pathview->currentIndex(), 0);
795 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
797 QTRY_COMPARE(firstItem->pos() + offset, start);
798 QCOMPARE(pathview->currentItem(), firstItem);
799 QCOMPARE(firstItem->property("onPath"), QVariant(true));
801 pathview->decrementCurrentIndex();
802 QTRY_COMPARE(pathview->currentIndex(), 3);
803 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 3);
805 QTRY_COMPARE(firstItem->pos() + offset, start);
806 QCOMPARE(pathview->currentItem(), firstItem);
807 QCOMPARE(firstItem->property("onPath"), QVariant(true));
809 pathview->incrementCurrentIndex();
810 QTRY_COMPARE(pathview->currentIndex(), 0);
811 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
813 QTRY_COMPARE(firstItem->pos() + offset, start);
814 QCOMPARE(pathview->currentItem(), firstItem);
815 QCOMPARE(firstItem->property("onPath"), QVariant(true));
817 // move an item, set move duration to 0, and change currentIndex to moved item. QTBUG-22786
818 model.moveItem(0, 3);
819 pathview->setHighlightMoveDuration(0);
820 pathview->setCurrentIndex(3);
821 QCOMPARE(pathview->currentIndex(), 3);
822 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 3);
824 QCOMPARE(pathview->currentItem(), firstItem);
825 QTRY_COMPARE(firstItem->pos() + offset, start);
826 model.moveItem(3, 0);
827 pathview->setCurrentIndex(0);
828 pathview->setHighlightMoveDuration(300);
830 // Check the current item is still created when outside the bounds of pathItemCount.
831 pathview->setPathItemCount(2);
832 pathview->setHighlightRangeMode(QQuickPathView::NoHighlightRange);
833 QVERIFY(findItem<QQuickRectangle>(pathview, "wrapper", 0));
834 QVERIFY(findItem<QQuickRectangle>(pathview, "wrapper", 1));
835 QVERIFY(!findItem<QQuickRectangle>(pathview, "wrapper", 2));
836 QVERIFY(!findItem<QQuickRectangle>(pathview, "wrapper", 3));
838 pathview->setCurrentIndex(2);
839 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 2);
840 QCOMPARE(pathview->currentItem(), firstItem);
841 QCOMPARE(firstItem->property("onPath"), QVariant(false));
843 pathview->decrementCurrentIndex();
844 QTRY_COMPARE(pathview->currentIndex(), 1);
845 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 1);
847 QCOMPARE(pathview->currentItem(), firstItem);
848 QCOMPARE(firstItem->property("onPath"), QVariant(true));
850 pathview->decrementCurrentIndex();
851 QTRY_COMPARE(pathview->currentIndex(), 0);
852 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
854 QCOMPARE(pathview->currentItem(), firstItem);
855 QCOMPARE(firstItem->property("onPath"), QVariant(true));
857 pathview->decrementCurrentIndex();
858 QTRY_COMPARE(pathview->currentIndex(), 3);
859 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 3);
861 QCOMPARE(pathview->currentItem(), firstItem);
862 QCOMPARE(firstItem->property("onPath"), QVariant(false));
864 pathview->incrementCurrentIndex();
865 QTRY_COMPARE(pathview->currentIndex(), 0);
866 firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
868 QCOMPARE(pathview->currentItem(), firstItem);
869 QCOMPARE(firstItem->property("onPath"), QVariant(true));
874 void tst_QQuickPathView::resetModel()
876 QQuickView *canvas = createView();
879 strings << "one" << "two" << "three";
880 QStringListModel model(strings);
882 QQmlContext *ctxt = canvas->rootContext();
883 ctxt->setContextProperty("testModel", &model);
885 canvas->setSource(testFileUrl("displaypath.qml"));
886 qApp->processEvents();
888 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
889 QVERIFY(pathview != 0);
891 QCOMPARE(pathview->count(), model.rowCount());
893 for (int i = 0; i < model.rowCount(); ++i) {
894 QQuickText *display = findItem<QQuickText>(pathview, "displayText", i);
895 QVERIFY(display != 0);
896 QCOMPARE(display->text(), strings.at(i));
900 strings << "four" << "five" << "six" << "seven";
901 model.setStringList(strings);
903 QCOMPARE(pathview->count(), model.rowCount());
905 for (int i = 0; i < model.rowCount(); ++i) {
906 QQuickText *display = findItem<QQuickText>(pathview, "displayText", i);
907 QVERIFY(display != 0);
908 QCOMPARE(display->text(), strings.at(i));
914 void tst_QQuickPathView::propertyChanges()
916 QQuickView *canvas = createView();
918 canvas->setSource(testFileUrl("propertychanges.qml"));
920 QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
923 QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged()));
924 QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged()));
926 QCOMPARE(pathView->preferredHighlightBegin(), 0.1);
927 QCOMPARE(pathView->dragMargin(), 5.0);
929 pathView->setPreferredHighlightBegin(0.4);
930 pathView->setPreferredHighlightEnd(0.4);
931 pathView->setDragMargin(20.0);
933 QCOMPARE(pathView->preferredHighlightBegin(), 0.4);
934 QCOMPARE(pathView->preferredHighlightEnd(), 0.4);
935 QCOMPARE(pathView->dragMargin(), 20.0);
937 QCOMPARE(snapPositionSpy.count(), 1);
938 QCOMPARE(dragMarginSpy.count(), 1);
940 pathView->setPreferredHighlightBegin(0.4);
941 pathView->setPreferredHighlightEnd(0.4);
942 pathView->setDragMargin(20.0);
944 QCOMPARE(snapPositionSpy.count(), 1);
945 QCOMPARE(dragMarginSpy.count(), 1);
949 void tst_QQuickPathView::pathChanges()
951 QQuickView *canvas = createView();
953 canvas->setSource(testFileUrl("propertychanges.qml"));
955 QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
958 QQuickPath *path = canvas->rootObject()->findChild<QQuickPath*>("path");
961 QSignalSpy startXSpy(path, SIGNAL(startXChanged()));
962 QSignalSpy startYSpy(path, SIGNAL(startYChanged()));
964 QCOMPARE(path->startX(), 220.0);
965 QCOMPARE(path->startY(), 200.0);
967 path->setStartX(240.0);
968 path->setStartY(220.0);
970 QCOMPARE(path->startX(), 240.0);
971 QCOMPARE(path->startY(), 220.0);
973 QCOMPARE(startXSpy.count(),1);
974 QCOMPARE(startYSpy.count(),1);
976 path->setStartX(240);
977 path->setStartY(220);
979 QCOMPARE(startXSpy.count(),1);
980 QCOMPARE(startYSpy.count(),1);
982 QQuickPath *alternatePath = canvas->rootObject()->findChild<QQuickPath*>("alternatePath");
983 QVERIFY(alternatePath);
985 QSignalSpy pathSpy(pathView, SIGNAL(pathChanged()));
987 QCOMPARE(pathView->path(), path);
989 pathView->setPath(alternatePath);
990 QCOMPARE(pathView->path(), alternatePath);
991 QCOMPARE(pathSpy.count(),1);
993 pathView->setPath(alternatePath);
994 QCOMPARE(pathSpy.count(),1);
996 QQuickPathAttribute *pathAttribute = canvas->rootObject()->findChild<QQuickPathAttribute*>("pathAttribute");
997 QVERIFY(pathAttribute);
999 QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged()));
1000 QCOMPARE(pathAttribute->name(), QString("opacity"));
1002 pathAttribute->setName("scale");
1003 QCOMPARE(pathAttribute->name(), QString("scale"));
1004 QCOMPARE(nameSpy.count(),1);
1006 pathAttribute->setName("scale");
1007 QCOMPARE(nameSpy.count(),1);
1011 void tst_QQuickPathView::componentChanges()
1013 QQuickView *canvas = createView();
1015 canvas->setSource(testFileUrl("propertychanges.qml"));
1017 QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
1020 QQmlComponent delegateComponent(canvas->engine());
1021 delegateComponent.setData("import QtQuick 2.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
1023 QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged()));
1025 pathView->setDelegate(&delegateComponent);
1026 QCOMPARE(pathView->delegate(), &delegateComponent);
1027 QCOMPARE(delegateSpy.count(),1);
1029 pathView->setDelegate(&delegateComponent);
1030 QCOMPARE(delegateSpy.count(),1);
1034 void tst_QQuickPathView::modelChanges()
1036 QQuickView *canvas = createView();
1038 canvas->setSource(testFileUrl("propertychanges.qml"));
1040 QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
1043 QQuickListModel *alternateModel = canvas->rootObject()->findChild<QQuickListModel*>("alternateModel");
1044 QVERIFY(alternateModel);
1045 QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
1046 QSignalSpy modelSpy(pathView, SIGNAL(modelChanged()));
1048 pathView->setModel(modelVariant);
1049 QCOMPARE(pathView->model(), modelVariant);
1050 QCOMPARE(modelSpy.count(),1);
1052 pathView->setModel(modelVariant);
1053 QCOMPARE(modelSpy.count(),1);
1055 pathView->setModel(QVariant());
1056 QCOMPARE(modelSpy.count(),2);
1061 void tst_QQuickPathView::pathUpdateOnStartChanged()
1063 QQuickView *canvas = createView();
1065 canvas->setSource(testFileUrl("pathUpdateOnStartChanged.qml"));
1067 QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
1070 QQuickPath *path = canvas->rootObject()->findChild<QQuickPath*>("path");
1072 QCOMPARE(path->startX(), 400.0);
1073 QCOMPARE(path->startY(), 300.0);
1075 QQuickItem *item = findItem<QQuickItem>(pathView, "wrapper", 0);
1077 QCOMPARE(item->x(), path->startX() - item->width() / 2.0);
1078 QCOMPARE(item->y(), path->startY() - item->height() / 2.0);
1083 void tst_QQuickPathView::package()
1085 QQuickView *canvas = createView();
1087 canvas->setSource(testFileUrl("pathview_package.qml"));
1089 QTest::qWaitForWindowShown(canvas);
1091 QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("photoPathView");
1095 QSKIP("QTBUG-21590 view does not reliably receive polish without a running animation");
1098 QQuickItem *item = findItem<QQuickItem>(pathView, "pathItem");
1100 QVERIFY(item->scale() != 1.0);
1106 void tst_QQuickPathView::emptyModel()
1108 QQuickView *canvas = createView();
1110 QStringListModel model;
1112 QQmlContext *ctxt = canvas->rootContext();
1113 ctxt->setContextProperty("emptyModel", &model);
1115 canvas->setSource(testFileUrl("emptymodel.qml"));
1116 qApp->processEvents();
1118 QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
1119 QVERIFY(pathview != 0);
1121 QCOMPARE(pathview->offset(), qreal(0.0));
1126 void tst_QQuickPathView::closed()
1131 QQmlComponent c(&engine, testFileUrl("openPath.qml"));
1132 QQuickPath *obj = qobject_cast<QQuickPath*>(c.create());
1134 QCOMPARE(obj->isClosed(), false);
1139 QQmlComponent c(&engine, testFileUrl("closedPath.qml"));
1140 QQuickPath *obj = qobject_cast<QQuickPath*>(c.create());
1142 QCOMPARE(obj->isClosed(), true);
1148 void tst_QQuickPathView::pathUpdate()
1150 QQuickView *canvas = createView();
1152 canvas->setSource(testFileUrl("pathUpdate.qml"));
1154 QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
1157 QQuickItem *item = findItem<QQuickItem>(pathView, "wrapper", 0);
1159 QCOMPARE(item->x(), 150.0);
1164 void tst_QQuickPathView::visualDataModel()
1167 QQmlComponent c(&engine, testFileUrl("vdm.qml"));
1169 QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
1172 QCOMPARE(obj->count(), 3);
1177 void tst_QQuickPathView::undefinedPath()
1181 // QPainterPath warnings are only received if QT_NO_DEBUG is not defined
1182 if (QLibraryInfo::isDebugBuild()) {
1183 QString warning1("QPainterPath::moveTo: Adding point where x or y is NaN or Inf, ignoring call");
1184 QTest::ignoreMessage(QtWarningMsg,qPrintable(warning1));
1186 QString warning2("QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call");
1187 QTest::ignoreMessage(QtWarningMsg,qPrintable(warning2));
1190 QQmlComponent c(&engine, testFileUrl("undefinedpath.qml"));
1192 QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
1195 QCOMPARE(obj->count(), 3);
1200 void tst_QQuickPathView::mouseDrag()
1202 QQuickView *canvas = createView();
1203 canvas->setSource(testFileUrl("dragpath.qml"));
1205 canvas->requestActivateWindow();
1206 QTest::qWaitForWindowShown(canvas);
1207 QTRY_COMPARE(canvas, qGuiApp->focusWindow());
1209 QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
1210 QVERIFY(pathview != 0);
1212 int current = pathview->currentIndex();
1214 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10,100));
1218 QMouseEvent mv(QEvent::MouseMove, QPoint(30,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1219 QGuiApplication::sendEvent(canvas, &mv);
1222 QMouseEvent mv(QEvent::MouseMove, QPoint(90,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1223 QGuiApplication::sendEvent(canvas, &mv);
1226 QVERIFY(pathview->currentIndex() != current);
1228 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100));
1233 void tst_QQuickPathView::treeModel()
1235 QQuickView *canvas = createView();
1238 QStandardItemModel model;
1239 initStandardTreeModel(&model);
1240 canvas->engine()->rootContext()->setContextProperty("myModel", &model);
1242 canvas->setSource(testFileUrl("treemodel.qml"));
1244 QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
1245 QVERIFY(pathview != 0);
1246 QCOMPARE(pathview->count(), 3);
1248 QQuickText *item = findItem<QQuickText>(pathview, "wrapper", 0);
1250 QCOMPARE(item->text(), QLatin1String("Row 1 Item"));
1252 QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1)));
1253 QCOMPARE(pathview->count(), 1);
1255 QTRY_VERIFY(item = findItem<QQuickText>(pathview, "wrapper", 0));
1256 QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item"));
1261 void tst_QQuickPathView::changePreferredHighlight()
1263 QQuickView *canvas = createView();
1264 canvas->setGeometry(0,0,400,200);
1265 canvas->setSource(testFileUrl("dragpath.qml"));
1267 canvas->requestActivateWindow();
1268 QTest::qWaitForWindowShown(canvas);
1269 QTRY_COMPARE(canvas, qGuiApp->focusWindow());
1271 QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
1272 QVERIFY(pathview != 0);
1274 int current = pathview->currentIndex();
1275 QCOMPARE(current, 0);
1277 QQuickRectangle *firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
1279 QQuickPath *path = qobject_cast<QQuickPath*>(pathview->path());
1281 QPointF start = path->pointAt(0.5);
1282 QPointF offset;//Center of item is at point, but pos is from corner
1283 offset.setX(firstItem->width()/2);
1284 offset.setY(firstItem->height()/2);
1285 QTRY_COMPARE(firstItem->pos() + offset, start);
1287 pathview->setPreferredHighlightBegin(0.8);
1288 pathview->setPreferredHighlightEnd(0.8);
1289 start = path->pointAt(0.8);
1290 QTRY_COMPARE(firstItem->pos() + offset, start);
1291 QCOMPARE(pathview->currentIndex(), 0);
1296 void tst_QQuickPathView::creationContext()
1299 canvas.setGeometry(0,0,240,320);
1300 canvas.setSource(testFileUrl("creationContext.qml"));
1302 QQuickItem *rootItem = qobject_cast<QQuickItem *>(canvas.rootObject());
1304 QVERIFY(rootItem->property("count").toInt() > 0);
1307 QVERIFY(item = findItem<QQuickItem>(rootItem, "listItem", 0));
1308 QCOMPARE(item->property("text").toString(), QString("Hello!"));
1312 void tst_QQuickPathView::currentOffsetOnInsertion()
1314 QQuickView *canvas = createView();
1319 QQmlContext *ctxt = canvas->rootContext();
1320 ctxt->setContextProperty("testModel", &model);
1322 canvas->setSource(testFileUrl("pathline.qml"));
1323 qApp->processEvents();
1325 QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
1326 QVERIFY(pathview != 0);
1328 pathview->setPreferredHighlightBegin(0.5);
1329 pathview->setPreferredHighlightEnd(0.5);
1331 QCOMPARE(pathview->count(), model.count());
1333 model.addItem("item0", "0");
1335 QCOMPARE(pathview->count(), model.count());
1337 QQuickRectangle *item = 0;
1338 QTRY_VERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 0));
1340 QQuickPath *path = qobject_cast<QQuickPath*>(pathview->path());
1343 QPointF start = path->pointAt(0.5);
1344 QPointF offset;//Center of item is at point, but pos is from corner
1345 offset.setX(item->width()/2);
1346 offset.setY(item->height()/2);
1347 QCOMPARE(item->pos() + offset, start);
1349 QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged()));
1351 // insert an item at the beginning
1352 model.insertItem(0, "item1", "1");
1353 qApp->processEvents();
1355 QCOMPARE(currentIndexSpy.count(), 1);
1357 // currentIndex is now 1
1358 QVERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 1));
1360 // verify that current item (item 1) is still at offset 0.5
1361 QCOMPARE(item->pos() + offset, start);
1363 // insert another item at the beginning
1364 model.insertItem(0, "item2", "2");
1365 qApp->processEvents();
1367 QCOMPARE(currentIndexSpy.count(), 2);
1369 // currentIndex is now 2
1370 QVERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 2));
1372 // verify that current item (item 2) is still at offset 0.5
1373 QCOMPARE(item->pos() + offset, start);
1375 // verify that remove before current maintains current item
1376 model.removeItem(0);
1377 qApp->processEvents();
1379 QCOMPARE(currentIndexSpy.count(), 3);
1381 // currentIndex is now 1
1382 QVERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 1));
1384 // verify that current item (item 1) is still at offset 0.5
1385 QCOMPARE(item->pos() + offset, start);
1390 void tst_QQuickPathView::asynchronous()
1392 QQuickView *canvas = createView();
1394 QQmlIncubationController controller;
1395 canvas->engine()->setIncubationController(&controller);
1397 canvas->setSource(testFileUrl("asyncloader.qml"));
1399 QQuickItem *rootObject = qobject_cast<QQuickItem*>(canvas->rootObject());
1400 QVERIFY(rootObject);
1402 QQuickPathView *pathview = 0;
1405 controller.incubateWhile(&b);
1406 pathview = rootObject->findChild<QQuickPathView*>("view");
1409 // items will be created one at a time
1410 for (int i = 0; i < 5; ++i) {
1411 QVERIFY(findItem<QQuickItem>(pathview, "wrapper", i) == 0);
1412 QQuickItem *item = 0;
1415 controller.incubateWhile(&b);
1416 item = findItem<QQuickItem>(pathview, "wrapper", i);
1422 controller.incubateWhile(&b);
1425 // verify positioning
1426 QQuickRectangle *firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
1428 QQuickPath *path = qobject_cast<QQuickPath*>(pathview->path());
1430 QPointF start = path->pointAt(0.0);
1431 QPointF offset;//Center of item is at point, but pos is from corner
1432 offset.setX(firstItem->width()/2);
1433 offset.setY(firstItem->height()/2);
1434 QTRY_COMPARE(firstItem->pos() + offset, start);
1435 pathview->setOffset(1.0);
1437 for (int i=0; i<5; i++) {
1438 QQuickItem *curItem = findItem<QQuickItem>(pathview, "wrapper", i);
1439 QPointF itemPos(path->pointAt(0.2 + i*0.2));
1440 QCOMPARE(curItem->pos() + offset, itemPos);
1446 void tst_QQuickPathView::missingPercent()
1449 QQmlComponent c(&engine, testFileUrl("missingPercent.qml"));
1450 QQuickPath *obj = qobject_cast<QQuickPath*>(c.create());
1452 QCOMPARE(obj->attributeAt("_qfx_percent", 1.0), qreal(1.0));
1456 QTEST_MAIN(tst_QQuickPathView)
1458 #include "tst_qquickpathview.moc"