1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include <QtTest/QSignalSpy>
43 #include <QStandardItemModel>
44 #include <QtDeclarative/qdeclarativeengine.h>
45 #include <QtDeclarative/qdeclarativecomponent.h>
46 #include <QtDeclarative/qdeclarativecontext.h>
47 #include <QtDeclarative/qdeclarativeexpression.h>
48 #include <QtDeclarative/qdeclarativeview.h>
49 #include <private/qdeclarativelistview_p.h>
50 #include <private/qdeclarativetext_p.h>
51 #include <private/qdeclarativevisualitemmodel_p.h>
52 #include <private/qdeclarativevaluetype_p.h>
56 // In Symbian OS test data is located in applications private dir
60 static void initStandardTreeModel(QStandardItemModel *model)
63 item = new QStandardItem(QLatin1String("Row 1 Item"));
64 model->insertRow(0, item);
66 item = new QStandardItem(QLatin1String("Row 2 Item"));
67 item->setCheckable(true);
68 model->insertRow(1, item);
70 QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
71 item->setChild(0, childItem);
73 item = new QStandardItem(QLatin1String("Row 3 Item"));
74 item->setIcon(QIcon());
75 model->insertRow(2, item);
78 class SingleRoleModel : public QAbstractListModel
83 SingleRoleModel(QObject *parent = 0) {
84 QHash<int, QByteArray> roles;
85 roles.insert(Qt::DisplayRole , "name");
87 list << "one" << "two" << "three" << "four";
91 void set(int idx, QString string) {
93 emit dataChanged(index(idx,0), index(idx,0));
97 int rowCount(const QModelIndex &parent = QModelIndex()) const {
100 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
101 if (role == Qt::DisplayRole)
102 return list.at(index.row());
111 class tst_qdeclarativevisualdatamodel : public QObject
115 tst_qdeclarativevisualdatamodel();
121 void objectListModel();
123 void modelProperties();
127 QDeclarativeEngine engine;
129 T *findItem(QGraphicsObject *parent, const QString &objectName, int index);
132 class DataObject : public QObject
136 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
137 Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
140 DataObject(QObject *parent=0) : QObject(parent) {}
141 DataObject(const QString &name, const QString &color, QObject *parent=0)
142 : QObject(parent), m_name(name), m_color(color) { }
145 QString name() const { return m_name; }
146 void setName(const QString &name) {
147 if (name != m_name) {
153 QString color() const { return m_color; }
154 void setColor(const QString &color) {
155 if (color != m_color) {
170 tst_qdeclarativevisualdatamodel::tst_qdeclarativevisualdatamodel()
174 void tst_qdeclarativevisualdatamodel::rootIndex()
176 QDeclarativeEngine engine;
177 QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/visualdatamodel.qml"));
179 QStandardItemModel model;
180 initStandardTreeModel(&model);
182 engine.rootContext()->setContextProperty("myModel", &model);
184 QDeclarativeVisualDataModel *obj = qobject_cast<QDeclarativeVisualDataModel*>(c.create());
187 QMetaObject::invokeMethod(obj, "setRoot");
188 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
190 QMetaObject::invokeMethod(obj, "setRootToParent");
191 QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
196 void tst_qdeclarativevisualdatamodel::updateLayout()
198 QDeclarativeView view;
200 QStandardItemModel model;
201 initStandardTreeModel(&model);
203 view.rootContext()->setContextProperty("myModel", &model);
205 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml"));
207 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
208 QVERIFY(listview != 0);
210 QDeclarativeItem *contentItem = listview->contentItem();
211 QVERIFY(contentItem != 0);
213 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "display", 0);
215 QCOMPARE(name->text(), QString("Row 1 Item"));
216 name = findItem<QDeclarativeText>(contentItem, "display", 1);
218 QCOMPARE(name->text(), QString("Row 2 Item"));
219 name = findItem<QDeclarativeText>(contentItem, "display", 2);
221 QCOMPARE(name->text(), QString("Row 3 Item"));
223 model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
225 name = findItem<QDeclarativeText>(contentItem, "display", 0);
227 QCOMPARE(name->text(), QString("Row 3 Item"));
228 name = findItem<QDeclarativeText>(contentItem, "display", 1);
230 QCOMPARE(name->text(), QString("Row 2 Item"));
231 name = findItem<QDeclarativeText>(contentItem, "display", 2);
233 QCOMPARE(name->text(), QString("Row 1 Item"));
236 void tst_qdeclarativevisualdatamodel::childChanged()
238 QDeclarativeView view;
240 QStandardItemModel model;
241 initStandardTreeModel(&model);
243 view.rootContext()->setContextProperty("myModel", &model);
245 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml"));
247 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
248 QVERIFY(listview != 0);
250 QDeclarativeItem *contentItem = listview->contentItem();
251 QVERIFY(contentItem != 0);
253 QDeclarativeVisualDataModel *vdm = listview->findChild<QDeclarativeVisualDataModel*>("visualModel");
254 vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
256 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "display", 0);
258 QCOMPARE(name->text(), QString("Row 2 Child Item"));
260 model.item(1,0)->child(0,0)->setText("Row 2 updated child");
262 name = findItem<QDeclarativeText>(contentItem, "display", 0);
264 QCOMPARE(name->text(), QString("Row 2 updated child"));
266 model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
269 name = findItem<QDeclarativeText>(contentItem, "display", 1);
271 QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
273 model.item(1,0)->takeRow(1);
274 name = findItem<QDeclarativeText>(contentItem, "display", 1);
277 vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
279 name = findItem<QDeclarativeText>(contentItem, "display", 0);
281 QCOMPARE(name->text(), QString("Row 1 Item"));
282 name = findItem<QDeclarativeText>(contentItem, "display", 1);
284 QCOMPARE(name->text(), QString("Row 2 Item"));
285 name = findItem<QDeclarativeText>(contentItem, "display", 2);
287 QCOMPARE(name->text(), QString("Row 3 Item"));
290 void tst_qdeclarativevisualdatamodel::objectListModel()
292 QDeclarativeView view;
294 QList<QObject*> dataList;
295 dataList.append(new DataObject("Item 1", "red"));
296 dataList.append(new DataObject("Item 2", "green"));
297 dataList.append(new DataObject("Item 3", "blue"));
298 dataList.append(new DataObject("Item 4", "yellow"));
300 QDeclarativeContext *ctxt = view.rootContext();
301 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
303 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/objectlist.qml"));
305 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
306 QVERIFY(listview != 0);
308 QDeclarativeItem *contentItem = listview->contentItem();
309 QVERIFY(contentItem != 0);
311 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "name", 0);
312 QCOMPARE(name->text(), QString("Item 1"));
314 QDeclarativeText *section = findItem<QDeclarativeText>(contentItem, "section", 0);
315 QCOMPARE(section->text(), QString("Item 1"));
317 dataList[0]->setProperty("name", QLatin1String("Changed"));
318 QCOMPARE(name->text(), QString("Changed"));
321 void tst_qdeclarativevisualdatamodel::singleRole()
324 QDeclarativeView view;
326 SingleRoleModel model;
328 QDeclarativeContext *ctxt = view.rootContext();
329 ctxt->setContextProperty("myModel", &model);
331 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/singlerole1.qml"));
333 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
334 QVERIFY(listview != 0);
336 QDeclarativeItem *contentItem = listview->contentItem();
337 QVERIFY(contentItem != 0);
339 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "name", 1);
340 QCOMPARE(name->text(), QString("two"));
342 model.set(1, "Changed");
343 QCOMPARE(name->text(), QString("Changed"));
346 QDeclarativeView view;
348 SingleRoleModel model;
350 QDeclarativeContext *ctxt = view.rootContext();
351 ctxt->setContextProperty("myModel", &model);
353 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/singlerole2.qml"));
355 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
356 QVERIFY(listview != 0);
358 QDeclarativeItem *contentItem = listview->contentItem();
359 QVERIFY(contentItem != 0);
361 QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "name", 1);
362 QCOMPARE(name->text(), QString("two"));
364 model.set(1, "Changed");
365 QCOMPARE(name->text(), QString("Changed"));
369 void tst_qdeclarativevisualdatamodel::modelProperties()
372 QDeclarativeView view;
374 SingleRoleModel model;
376 QDeclarativeContext *ctxt = view.rootContext();
377 ctxt->setContextProperty("myModel", &model);
379 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/modelproperties.qml"));
381 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
382 QVERIFY(listview != 0);
384 QDeclarativeItem *contentItem = listview->contentItem();
385 QVERIFY(contentItem != 0);
387 QDeclarativeItem *delegate = findItem<QDeclarativeItem>(contentItem, "delegate", 1);
388 QCOMPARE(delegate->property("test1").toString(),QString("two"));
389 QCOMPARE(delegate->property("test2").toString(),QString("two"));
390 QCOMPARE(delegate->property("test3").toString(),QString("two"));
391 QCOMPARE(delegate->property("test4").toString(),QString("two"));
392 QVERIFY(!delegate->property("test9").isValid());
393 QCOMPARE(delegate->property("test5").toString(),QString(""));
394 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
395 QCOMPARE(delegate->property("test7").toInt(),1);
396 QCOMPARE(delegate->property("test8").toInt(),1);
400 QDeclarativeView view;
402 QList<QObject*> dataList;
403 dataList.append(new DataObject("Item 1", "red"));
404 dataList.append(new DataObject("Item 2", "green"));
405 dataList.append(new DataObject("Item 3", "blue"));
406 dataList.append(new DataObject("Item 4", "yellow"));
408 QDeclarativeContext *ctxt = view.rootContext();
409 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
411 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/modelproperties.qml"));
413 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
414 QVERIFY(listview != 0);
416 QDeclarativeItem *contentItem = listview->contentItem();
417 QVERIFY(contentItem != 0);
419 QDeclarativeItem *delegate = findItem<QDeclarativeItem>(contentItem, "delegate", 1);
420 QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
421 QEXPECT_FAIL("", "QTBUG-13576", Continue);
422 QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
423 QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
424 QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
425 QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
426 QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
427 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
428 QCOMPARE(delegate->property("test7").toInt(),1);
429 QCOMPARE(delegate->property("test8").toInt(),1);
433 QDeclarativeView view;
435 QStandardItemModel model;
436 initStandardTreeModel(&model);
438 view.rootContext()->setContextProperty("myModel", &model);
440 QUrl source(QUrl::fromLocalFile(SRCDIR "/data/modelproperties2.qml"));
442 //3 items, 3 warnings each
443 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
444 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
445 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
446 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":9: ReferenceError: Can't find variable: modelData");
447 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":9: ReferenceError: Can't find variable: modelData");
448 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":9: ReferenceError: Can't find variable: modelData");
449 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":15: TypeError: Result of expression 'model.modelData' [undefined] is not an object.");
450 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":15: TypeError: Result of expression 'model.modelData' [undefined] is not an object.");
451 QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":15: TypeError: Result of expression 'model.modelData' [undefined] is not an object.");
453 view.setSource(source);
455 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
456 QVERIFY(listview != 0);
458 QDeclarativeItem *contentItem = listview->contentItem();
459 QVERIFY(contentItem != 0);
461 QDeclarativeItem *delegate = findItem<QDeclarativeItem>(contentItem, "delegate", 1);
462 QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
463 QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
464 QVERIFY(!delegate->property("test3").isValid());
465 QVERIFY(!delegate->property("test4").isValid());
466 QVERIFY(!delegate->property("test5").isValid());
467 QVERIFY(!delegate->property("test9").isValid());
468 QVERIFY(delegate->property("test6").value<QObject*>() != 0);
469 QCOMPARE(delegate->property("test7").toInt(),1);
470 QCOMPARE(delegate->property("test8").toInt(),1);
473 //### should also test QStringList and QVariantList
476 void tst_qdeclarativevisualdatamodel::noDelegate()
478 QDeclarativeView view;
480 QStandardItemModel model;
481 initStandardTreeModel(&model);
483 view.rootContext()->setContextProperty("myModel", &model);
485 view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml"));
487 QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject());
488 QVERIFY(listview != 0);
490 QDeclarativeVisualDataModel *vdm = listview->findChild<QDeclarativeVisualDataModel*>("visualModel");
492 QCOMPARE(vdm->count(), 3);
495 QCOMPARE(vdm->count(), 0);
500 T *tst_qdeclarativevisualdatamodel::findItem(QGraphicsObject *parent, const QString &objectName, int index)
502 const QMetaObject &mo = T::staticMetaObject;
503 //qDebug() << parent->childItems().count() << "children";
504 for (int i = 0; i < parent->childItems().count(); ++i) {
505 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
508 //qDebug() << "try" << item;
509 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
511 QDeclarativeExpression e(qmlContext(item), item, "index");
512 if (e.evaluate().toInt() == index)
513 return static_cast<T*>(item);
515 return static_cast<T*>(item);
518 item = findItem<T>(item, objectName, index);
520 return static_cast<T*>(item);
526 QTEST_MAIN(tst_qdeclarativevisualdatamodel)
528 #include "tst_qdeclarativevisualdatamodel.moc"