aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@qt.io>2018-06-16 11:40:05 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2018-11-05 12:48:48 +0000
commit0477a057fd02050fd330760bf046f5e0e91a9331 (patch)
tree159df846e849db8ef6a91f53f29c399dd6fde63f
parent627226520a2bbb977ce32a21bdffd2004cb28796 (diff)
Move xmllistmodel to xmlpatternsv5.12.0-beta4
Latest changes moved to xmlpatterns: e08f9393acc6417598f328d7f4b7b082c5d57afa Change-Id: I7e3054a3f0f11833053746294e3b2b958047394d Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
-rw-r--r--src/imports/imports.pro1
-rw-r--r--src/imports/xmllistmodel/plugin.cpp67
-rw-r--r--src/imports/xmllistmodel/plugins.qmltypes59
-rw-r--r--src/imports/xmllistmodel/qmldir5
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp1238
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel_p.h219
-rw-r--r--src/imports/xmllistmodel/xmllistmodel.pro14
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qmltest/doc/qtqmltest.qdocconf2
-rw-r--r--src/quick/doc/qtquick.qdocconf2
-rw-r--r--src/quick/doc/snippets/qml/xmlrole.qml96
-rw-r--r--tests/auto/quick/examples/examples.pro1
-rw-r--r--tests/auto/quick/examples/tst_examples.cpp6
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/empty.xml0
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/get.qml61
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/groups.qml10
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/groups.xml18
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/model.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/model.xml54
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/model2.xml14
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml9
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/recipes.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/recipes.xml90
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml8
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml13
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/testtypes.qml8
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/unique.qml9
-rw-r--r--tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro16
-rw-r--r--tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp1011
-rw-r--r--tests/auto/quick/quick.pro6
32 files changed, 4 insertions, 3079 deletions
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index cf49deb03c..24e93fec1c 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -28,4 +28,3 @@ qtHaveModule(quick) {
qtConfig(quick-path):qtConfig(thread): SUBDIRS += shapes
}
-qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel
diff --git a/src/imports/xmllistmodel/plugin.cpp b/src/imports/xmllistmodel/plugin.cpp
deleted file mode 100644
index c5356b8534..0000000000
--- a/src/imports/xmllistmodel/plugin.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-
-#include "qqmlxmllistmodel_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QmlXmlListModelPlugin : public QQmlExtensionPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
-
-public:
- QmlXmlListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
- {
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.XmlListModel"));
- qmlRegisterType<QQuickXmlListModel>(uri,2,0,"XmlListModel");
- qmlRegisterType<QQuickXmlListModelRole>(uri,2,0,"XmlRole");
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
- }
-};
-
-QT_END_NAMESPACE
-
-#include "plugin.moc"
diff --git a/src/imports/xmllistmodel/plugins.qmltypes b/src/imports/xmllistmodel/plugins.qmltypes
deleted file mode 100644
index 951d0b6eeb..0000000000
--- a/src/imports/xmllistmodel/plugins.qmltypes
+++ /dev/null
@@ -1,59 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.XmlListModel 2.12'
-
-Module {
- dependencies: ["QtQuick 2.12"]
- Component {
- name: "QQuickXmlListModel"
- defaultProperty: "roles"
- prototype: "QAbstractListModel"
- exports: ["QtQuick.XmlListModel/XmlListModel 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "progress"; type: "double"; isReadonly: true }
- Property { name: "source"; type: "QUrl" }
- Property { name: "xml"; type: "string" }
- Property { name: "query"; type: "string" }
- Property { name: "namespaceDeclarations"; type: "string" }
- Property { name: "roles"; type: "QQuickXmlListModelRole"; isList: true; isReadonly: true }
- Property { name: "count"; type: "int"; isReadonly: true }
- Signal {
- name: "statusChanged"
- Parameter { type: "QQuickXmlListModel::Status" }
- }
- Signal {
- name: "progressChanged"
- Parameter { name: "progress"; type: "double" }
- }
- Method { name: "reload" }
- Method {
- name: "get"
- type: "QQmlV4Handle"
- Parameter { name: "index"; type: "int" }
- }
- Method { name: "errorString"; type: "string" }
- }
- Component {
- name: "QQuickXmlListModelRole"
- prototype: "QObject"
- exports: ["QtQuick.XmlListModel/XmlRole 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "name"; type: "string" }
- Property { name: "query"; type: "string" }
- Property { name: "isKey"; type: "bool" }
- }
-}
diff --git a/src/imports/xmllistmodel/qmldir b/src/imports/xmllistmodel/qmldir
deleted file mode 100644
index 1f17dbb112..0000000000
--- a/src/imports/xmllistmodel/qmldir
+++ /dev/null
@@ -1,5 +0,0 @@
-module QtQuick.XmlListModel
-plugin qmlxmllistmodelplugin
-classname QmlXmlListModelPlugin
-typeinfo plugins.qmltypes
-designersupported
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
deleted file mode 100644
index 470b419c1f..0000000000
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ /dev/null
@@ -1,1238 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlxmllistmodel_p.h"
-
-#include <qqmlcontext.h>
-#include <private/qqmlengine_p.h>
-#include <private/qv8engine_p.h>
-#include <private/qv4value_p.h>
-#include <private/qv4engine_p.h>
-#include <private/qv4object_p.h>
-
-#include <QDebug>
-#include <QStringList>
-#include <QMap>
-#include <QThread>
-#include <QXmlQuery>
-#include <QXmlResultItems>
-#include <QXmlNodeModelIndex>
-#include <QBuffer>
-#if QT_CONFIG(qml_network)
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#endif
-#include <QTimer>
-#include <QMutex>
-
-#include <private/qabstractitemmodel_p.h>
-
-Q_DECLARE_METATYPE(QQuickXmlQueryResult)
-
-QT_BEGIN_NAMESPACE
-
-using namespace QV4;
-
-typedef QPair<int, int> QQuickXmlListRange;
-
-#define XMLLISTMODEL_CLEAR_ID 0
-
-/*!
- \qmlmodule QtQuick.XmlListModel 2.\QtMinorVersion
- \title Qt Quick XmlListModel QML Types
- \ingroup qmlmodules
- \brief Provides QML types for creating models from XML data
-
- This QML module contains types for creating models from XML data.
-
- To use the types in this module, import the module with the following line:
-
- \qml \QtMinorVersion
- import QtQuick.XmlListModel 2.\1
- \endqml
-*/
-
-/*!
- \qmltype XmlRole
- \instantiates QQuickXmlListModelRole
- \inqmlmodule QtQuick.XmlListModel
- \brief For specifying a role to an XmlListModel.
- \ingroup qtquick-models
-
- \sa {Qt QML}
-*/
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlRole::name
-
- The name for the role. This name is used to access the model data for this role.
-
- For example, the following model has a role named "title", which can be accessed
- from the view's delegate:
-
- \qml
- XmlListModel {
- id: xmlModel
- // ...
- XmlRole {
- name: "title"
- query: "title/string()"
- }
- }
- \endqml
-
- \qml
- ListView {
- model: xmlModel
- delegate: Text { text: title }
- }
- \endqml
-*/
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlRole::query
- The relative XPath expression query for this role. The query must be relative; it cannot start
- with a '/'.
-
- For example, if there is an XML document like this:
-
- \quotefile qml/xmlrole.xml
- Here are some valid XPath expressions for XmlRole queries on this document:
-
- \snippet qml/xmlrole.qml 0
- \dots 4
- \snippet qml/xmlrole.qml 1
-
- Accessing the model data for the above roles from a delegate:
-
- \snippet qml/xmlrole.qml 2
-
- See the \l{http://www.w3.org/TR/xpath20/}{W3C XPath 2.0 specification} for more information.
-*/
-
-/*!
- \qmlproperty bool QtQuick.XmlListModel::XmlRole::isKey
- Defines whether this is a key role.
- Key roles are used to determine whether a set of values should
- be updated or added to the XML list model when XmlListModel::reload()
- is called.
-
- \sa XmlListModel
-*/
-
-struct XmlQueryJob
-{
- int queryId;
- QByteArray data;
- QString query;
- QString namespaces;
- QStringList roleQueries;
- QList<void*> roleQueryErrorId; // the ptr to send back if there is an error
- QStringList keyRoleQueries;
- QStringList keyRoleResultsCache;
- QString prefix;
-};
-
-
-class QQuickXmlQueryEngine;
-class QQuickXmlQueryThreadObject : public QObject
-{
- Q_OBJECT
-public:
- QQuickXmlQueryThreadObject(QQuickXmlQueryEngine *);
-
- void processJobs();
- bool event(QEvent *e) override;
-
-private:
- QQuickXmlQueryEngine *m_queryEngine;
-};
-
-
-class QQuickXmlQueryEngine : public QThread
-{
- Q_OBJECT
-public:
- QQuickXmlQueryEngine(QQmlEngine *eng);
- ~QQuickXmlQueryEngine();
-
- int doQuery(QString query, QString namespaces, QByteArray data, QList<QQuickXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache);
- void abort(int id);
-
- void processJobs();
-
- static QQuickXmlQueryEngine *instance(QQmlEngine *engine);
-
-signals:
- void queryCompleted(const QQuickXmlQueryResult &);
- void error(void*, const QString&);
-
-protected:
- void run() override;
-
-private:
- void processQuery(XmlQueryJob *job);
- void doQueryJob(XmlQueryJob *job, QQuickXmlQueryResult *currentResult);
- void doSubQueryJob(XmlQueryJob *job, QQuickXmlQueryResult *currentResult);
- void getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const;
- void addIndexToRangeList(QList<QQuickXmlListRange> *ranges, int index) const;
-
- QMutex m_mutex;
- QQuickXmlQueryThreadObject *m_threadObject;
- QList<XmlQueryJob> m_jobs;
- QSet<int> m_cancelledJobs;
- QAtomicInt m_queryIds;
-
- QQmlEngine *m_engine;
- QObject *m_eventLoopQuitHack;
-
- static QHash<QQmlEngine *,QQuickXmlQueryEngine*> queryEngines;
- static QMutex queryEnginesMutex;
-};
-QHash<QQmlEngine *,QQuickXmlQueryEngine*> QQuickXmlQueryEngine::queryEngines;
-QMutex QQuickXmlQueryEngine::queryEnginesMutex;
-
-
-QQuickXmlQueryThreadObject::QQuickXmlQueryThreadObject(QQuickXmlQueryEngine *e)
- : m_queryEngine(e)
-{
-}
-
-void QQuickXmlQueryThreadObject::processJobs()
-{
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
-}
-
-bool QQuickXmlQueryThreadObject::event(QEvent *e)
-{
- if (e->type() == QEvent::User) {
- m_queryEngine->processJobs();
- return true;
- } else {
- return QObject::event(e);
- }
-}
-
-
-
-QQuickXmlQueryEngine::QQuickXmlQueryEngine(QQmlEngine *eng)
-: QThread(eng), m_threadObject(0), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1), m_engine(eng), m_eventLoopQuitHack(0)
-{
- qRegisterMetaType<QQuickXmlQueryResult>("QQuickXmlQueryResult");
-
- m_eventLoopQuitHack = new QObject;
- m_eventLoopQuitHack->moveToThread(this);
- connect(m_eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
- start(QThread::IdlePriority);
-}
-
-QQuickXmlQueryEngine::~QQuickXmlQueryEngine()
-{
- queryEnginesMutex.lock();
- queryEngines.remove(m_engine);
- queryEnginesMutex.unlock();
-
- m_eventLoopQuitHack->deleteLater();
- wait();
-}
-
-int QQuickXmlQueryEngine::doQuery(QString query, QString namespaces, QByteArray data, QList<QQuickXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache) {
- {
- QMutexLocker m1(&m_mutex);
- m_queryIds.ref();
- if (m_queryIds.load() <= 0)
- m_queryIds.store(1);
- }
-
- XmlQueryJob job;
- job.queryId = m_queryIds.load();
- job.data = data;
- job.query = QLatin1String("doc($src)") + query;
- job.namespaces = namespaces;
- job.keyRoleResultsCache = keyRoleResultsCache;
-
- for (int i=0; i<roleObjects->count(); i++) {
- if (!roleObjects->at(i)->isValid()) {
- job.roleQueries << QString();
- continue;
- }
- job.roleQueries << roleObjects->at(i)->query();
- job.roleQueryErrorId << static_cast<void*>(roleObjects->at(i));
- if (roleObjects->at(i)->isKey())
- job.keyRoleQueries << job.roleQueries.last();
- }
-
- {
- QMutexLocker ml(&m_mutex);
- m_jobs.append(job);
- if (m_threadObject)
- m_threadObject->processJobs();
- }
-
- return job.queryId;
-}
-
-void QQuickXmlQueryEngine::abort(int id)
-{
- QMutexLocker ml(&m_mutex);
- if (id != -1)
- m_cancelledJobs.insert(id);
-}
-
-void QQuickXmlQueryEngine::run()
-{
- m_mutex.lock();
- m_threadObject = new QQuickXmlQueryThreadObject(this);
- m_mutex.unlock();
-
- processJobs();
- exec();
-
- delete m_threadObject;
- m_threadObject = 0;
-}
-
-void QQuickXmlQueryEngine::processJobs()
-{
- QMutexLocker locker(&m_mutex);
-
- while (true) {
- if (m_jobs.isEmpty())
- return;
-
- XmlQueryJob currentJob = m_jobs.takeLast();
- while (m_cancelledJobs.remove(currentJob.queryId)) {
- if (m_jobs.isEmpty())
- return;
- currentJob = m_jobs.takeLast();
- }
-
- locker.unlock();
- processQuery(&currentJob);
- locker.relock();
- }
-}
-
-QQuickXmlQueryEngine *QQuickXmlQueryEngine::instance(QQmlEngine *engine)
-{
- queryEnginesMutex.lock();
- QQuickXmlQueryEngine *queryEng = queryEngines.value(engine);
- if (!queryEng) {
- queryEng = new QQuickXmlQueryEngine(engine);
- queryEngines.insert(engine, queryEng);
- }
- queryEnginesMutex.unlock();
-
- return queryEng;
-}
-
-void QQuickXmlQueryEngine::processQuery(XmlQueryJob *job)
-{
- QQuickXmlQueryResult result;
- result.queryId = job->queryId;
- doQueryJob(job, &result);
- doSubQueryJob(job, &result);
-
- {
- QMutexLocker ml(&m_mutex);
- if (m_cancelledJobs.contains(job->queryId)) {
- m_cancelledJobs.remove(job->queryId);
- } else {
- emit queryCompleted(result);
- }
- }
-}
-
-void QQuickXmlQueryEngine::doQueryJob(XmlQueryJob *currentJob, QQuickXmlQueryResult *currentResult)
-{
- Q_ASSERT(currentJob->queryId != -1);
-
- QString r;
- QXmlQuery query;
- QBuffer buffer(&currentJob->data);
- buffer.open(QIODevice::ReadOnly);
- query.bindVariable(QLatin1String("src"), &buffer);
- query.setQuery(currentJob->namespaces + currentJob->query);
- query.evaluateTo(&r);
-
- //always need a single root element
- QByteArray xml = "<dummy:items xmlns:dummy=\"http://qtsotware.com/dummy\">\n" + r.toUtf8() + "</dummy:items>";
- QBuffer b(&xml);
- b.open(QIODevice::ReadOnly);
-
- QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + currentJob->namespaces;
- QString prefix = QLatin1String("doc($inputDocument)/dummy:items/*");
-
- //figure out how many items we are dealing with
- int count = -1;
- {
- QXmlResultItems result;
- QXmlQuery countquery;
- countquery.bindVariable(QLatin1String("inputDocument"), &b);
- countquery.setQuery(namespaces + QLatin1String("count(") + prefix + QLatin1Char(')'));
- countquery.evaluateTo(&result);
- QXmlItem item(result.next());
- if (item.isAtomicValue())
- count = item.toAtomicValue().toInt();
- }
-
- currentJob->data = xml;
- currentJob->prefix = namespaces + prefix + QLatin1Char('/');
- currentResult->size = (count > 0 ? count : 0);
-}
-
-void QQuickXmlQueryEngine::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const
-{
- const QStringList &keysQueries = currentJob.keyRoleQueries;
- QString keysQuery;
- if (keysQueries.count() == 1)
- keysQuery = currentJob.prefix + keysQueries[0];
- else if (keysQueries.count() > 1)
- keysQuery = currentJob.prefix + QLatin1String("concat(") + keysQueries.join(QLatin1Char(',')) + QLatin1Char(')');
-
- if (!keysQuery.isEmpty()) {
- query->setQuery(keysQuery);
- QXmlResultItems resultItems;
- query->evaluateTo(&resultItems);
- QXmlItem item(resultItems.next());
- while (!item.isNull()) {
- values->append(item.toAtomicValue().toString());
- item = resultItems.next();
- }
- }
-}
-
-void QQuickXmlQueryEngine::addIndexToRangeList(QList<QQuickXmlListRange> *ranges, int index) const {
- if (ranges->isEmpty())
- ranges->append(qMakePair(index, 1));
- else if (ranges->last().first + ranges->last().second == index)
- ranges->last().second += 1;
- else
- ranges->append(qMakePair(index, 1));
-}
-
-void QQuickXmlQueryEngine::doSubQueryJob(XmlQueryJob *currentJob, QQuickXmlQueryResult *currentResult)
-{
- Q_ASSERT(currentJob->queryId != -1);
-
- QBuffer b(&currentJob->data);
- b.open(QIODevice::ReadOnly);
-
- QXmlQuery subquery;
- subquery.bindVariable(QLatin1String("inputDocument"), &b);
-
- QStringList keyRoleResults;
- getValuesOfKeyRoles(*currentJob, &keyRoleResults, &subquery);
-
- // See if any values of key roles have been inserted or removed.
-
- if (currentJob->keyRoleResultsCache.isEmpty()) {
- currentResult->inserted << qMakePair(0, currentResult->size);
- } else {
- if (keyRoleResults != currentJob->keyRoleResultsCache) {
- QStringList temp;
- for (int i=0; i<currentJob->keyRoleResultsCache.count(); i++) {
- if (!keyRoleResults.contains(currentJob->keyRoleResultsCache[i]))
- addIndexToRangeList(&currentResult->removed, i);
- else
- temp << currentJob->keyRoleResultsCache[i];
- }
- for (int i=0; i<keyRoleResults.count(); i++) {
- if (temp.count() == i || keyRoleResults[i] != temp[i]) {
- temp.insert(i, keyRoleResults[i]);
- addIndexToRangeList(&currentResult->inserted, i);
- }
- }
- }
- }
- currentResult->keyRoleResultsCache = keyRoleResults;
-
- // Get the new values for each role.
- //### we might be able to condense even further (query for everything in one go)
- const QStringList &queries = currentJob->roleQueries;
- for (int i = 0; i < queries.size(); ++i) {
- QList<QVariant> resultList;
- if (!queries[i].isEmpty()) {
- subquery.setQuery(currentJob->prefix + QLatin1String("(let $v := string(") + queries[i] + QLatin1String(") return if ($v) then ") + queries[i] + QLatin1String(" else \"\")"));
- if (subquery.isValid()) {
- QXmlResultItems resultItems;
- subquery.evaluateTo(&resultItems);
- QXmlItem item(resultItems.next());
- while (!item.isNull()) {
- resultList << item.toAtomicValue(); //### we used to trim strings
- item = resultItems.next();
- }
- } else {
- emit error(currentJob->roleQueryErrorId.at(i), queries[i]);
- }
- }
- //### should warn here if things have gone wrong.
- while (resultList.count() < currentResult->size)
- resultList << QVariant();
- currentResult->data << resultList;
- b.seek(0);
- }
-
- //this method is much slower, but works better for incremental loading
- /*for (int j = 0; j < m_size; ++j) {
- QList<QVariant> resultList;
- for (int i = 0; i < m_roleObjects->size(); ++i) {
- QQuickXmlListModelRole *role = m_roleObjects->at(i);
- subquery.setQuery(m_prefix.arg(j+1) + role->query());
- if (role->isStringList()) {
- QStringList data;
- subquery.evaluateTo(&data);
- resultList << QVariant(data);
- //qDebug() << data;
- } else {
- QString s;
- subquery.evaluateTo(&s);
- if (role->isCData()) {
- //un-escape
- s.replace(QLatin1String("&lt;"), QLatin1String("<"));
- s.replace(QLatin1String("&gt;"), QLatin1String(">"));
- s.replace(QLatin1String("&amp;"), QLatin1String("&"));
- }
- resultList << s.trimmed();
- //qDebug() << s;
- }
- b.seek(0);
- }
- m_modelData << resultList;
- }*/
-}
-
-class QQuickXmlListModelPrivate : public QAbstractItemModelPrivate
-{
- Q_DECLARE_PUBLIC(QQuickXmlListModel)
-public:
- QQuickXmlListModelPrivate()
- : isComponentComplete(true), size(0), highestRole(Qt::UserRole)
-#if QT_CONFIG(qml_network)
- , reply(0)
-#endif
- , status(QQuickXmlListModel::Null), progress(0.0)
- , queryId(-1), roleObjects(), redirectCount(0) {}
-
-
- void notifyQueryStarted(bool remoteSource) {
- Q_Q(QQuickXmlListModel);
- progress = remoteSource ? 0.0 : 1.0;
- status = QQuickXmlListModel::Loading;
- errorString.clear();
- emit q->progressChanged(progress);
- emit q->statusChanged(status);
- }
-
-#if QT_CONFIG(qml_network)
- void deleteReply() {
- Q_Q(QQuickXmlListModel);
- if (reply) {
- QObject::disconnect(reply, 0, q, 0);
- reply->deleteLater();
- reply = 0;
- }
- }
-#endif
-
- bool isComponentComplete;
- QUrl src;
- QString xml;
- QString query;
- QString namespaces;
- int size;
- QList<int> roles;
- QStringList roleNames;
- int highestRole;
-
-#if QT_CONFIG(qml_network)
- QNetworkReply *reply;
-#endif
- QQuickXmlListModel::Status status;
- QString errorString;
- qreal progress;
- int queryId;
- QStringList keyRoleResultsCache;
- QList<QQuickXmlListModelRole *> roleObjects;
-
- static void append_role(QQmlListProperty<QQuickXmlListModelRole> *list, QQuickXmlListModelRole *role);
- static void clear_role(QQmlListProperty<QQuickXmlListModelRole> *list);
- QList<QList<QVariant> > data;
- int redirectCount;
-};
-
-
-void QQuickXmlListModelPrivate::append_role(QQmlListProperty<QQuickXmlListModelRole> *list, QQuickXmlListModelRole *role)
-{
- QQuickXmlListModel *_this = qobject_cast<QQuickXmlListModel *>(list->object);
- if (_this && role) {
- int i = _this->d_func()->roleObjects.count();
- _this->d_func()->roleObjects.append(role);
- if (_this->d_func()->roleNames.contains(role->name())) {
- qmlWarning(role) << QQuickXmlListModel::tr("\"%1\" duplicates a previous role name and will be disabled.").arg(role->name());
- return;
- }
- _this->d_func()->roles.insert(i, _this->d_func()->highestRole);
- _this->d_func()->roleNames.insert(i, role->name());
- ++_this->d_func()->highestRole;
- }
-}
-
-//### clear needs to invalidate any cached data (in data table) as well
-// (and the model should emit the appropriate signals)
-void QQuickXmlListModelPrivate::clear_role(QQmlListProperty<QQuickXmlListModelRole> *list)
-{
- QQuickXmlListModel *_this = static_cast<QQuickXmlListModel *>(list->object);
- _this->d_func()->roles.clear();
- _this->d_func()->roleNames.clear();
- _this->d_func()->roleObjects.clear();
-}
-
-/*!
- \qmltype XmlListModel
- \instantiates QQuickXmlListModel
- \inqmlmodule QtQuick.XmlListModel
- \brief For specifying a read-only model using XPath expressions.
- \ingroup qtquick-models
-
-
- To use this element, you will need to import the module with the following line:
- \code
- import QtQuick.XmlListModel 2.0
- \endcode
-
- XmlListModel is used to create a read-only model from XML data. It can be used as a data source
- for view elements (such as ListView, PathView, GridView) and other elements that interact with model
- data (such as \l Repeater).
-
- For example, if there is a XML document at http://www.mysite.com/feed.xml like this:
-
- \code
- <?xml version="1.0" encoding="utf-8"?>
- <rss version="2.0">
- ...
- <channel>
- <item>
- <title>A blog post</title>
- <pubDate>Sat, 07 Sep 2010 10:00:01 GMT</pubDate>
- </item>
- <item>
- <title>Another blog post</title>
- <pubDate>Sat, 07 Sep 2010 15:35:01 GMT</pubDate>
- </item>
- </channel>
- </rss>
- \endcode
-
- A XmlListModel could create a model from this data, like this:
-
- \qml
- import QtQuick 2.0
- import QtQuick.XmlListModel 2.0
-
- XmlListModel {
- id: xmlModel
- source: "http://www.mysite.com/feed.xml"
- query: "/rss/channel/item"
-
- XmlRole { name: "title"; query: "title/string()" }
- XmlRole { name: "pubDate"; query: "pubDate/string()" }
- }
- \endqml
-
- The \l {XmlListModel::query}{query} value of "/rss/channel/item" specifies that the XmlListModel should generate
- a model item for each \c <item> in the XML document.
-
- The XmlRole objects define the
- model item attributes. Here, each model item will have \c title and \c pubDate
- attributes that match the \c title and \c pubDate values of its corresponding \c <item>.
- (See \l XmlRole::query for more examples of valid XPath expressions for XmlRole.)
-
- The model could be used in a ListView, like this:
-
- \qml
- ListView {
- width: 180; height: 300
- model: xmlModel
- delegate: Text { text: title + ": " + pubDate }
- }
- \endqml
-
- \image qml-xmllistmodel-example.png
-
- The XmlListModel data is loaded asynchronously, and \l status
- is set to \c XmlListModel.Ready when loading is complete.
- Note this means when XmlListModel is used for a view, the view is not
- populated until the model is loaded.
-
-
- \section2 Using Key XML Roles
-
- You can define certain roles as "keys" so that when reload() is called,
- the model will only add and refresh data that contains new values for
- these keys.
-
- For example, if above role for "pubDate" was defined like this instead:
-
- \qml
- XmlRole { name: "pubDate"; query: "pubDate/string()"; isKey: true }
- \endqml
-
- Then when reload() is called, the model will only add and reload
- items with a "pubDate" value that is not already
- present in the model.
-
- This is useful when displaying the contents of XML documents that
- are incrementally updated (such as RSS feeds) to avoid repainting the
- entire contents of a model in a view.
-
- If multiple key roles are specified, the model only adds and reload items
- with a combined value of all key roles that is not already present in
- the model.
-
- \sa {Qt Quick Demo - RSS News}
-*/
-
-QQuickXmlListModel::QQuickXmlListModel(QObject *parent)
- : QAbstractListModel(*(new QQuickXmlListModelPrivate), parent)
-{
-}
-
-QQuickXmlListModel::~QQuickXmlListModel()
-{
-}
-
-/*!
- \qmlproperty list<XmlRole> QtQuick.XmlListModel::XmlListModel::roles
-
- The roles to make available for this model.
-*/
-QQmlListProperty<QQuickXmlListModelRole> QQuickXmlListModel::roleObjects()
-{
- Q_D(QQuickXmlListModel);
- QQmlListProperty<QQuickXmlListModelRole> list(this, d->roleObjects);
- list.append = &QQuickXmlListModelPrivate::append_role;
- list.clear = &QQuickXmlListModelPrivate::clear_role;
- return list;
-}
-
-QModelIndex QQuickXmlListModel::index(int row, int column, const QModelIndex &parent) const
-{
- Q_D(const QQuickXmlListModel);
- return !parent.isValid() && column == 0 && row >= 0 && row < d->size
- ? createIndex(row, column)
- : QModelIndex();
-}
-
-int QQuickXmlListModel::rowCount(const QModelIndex &parent) const
-{
- Q_D(const QQuickXmlListModel);
- return !parent.isValid() ? d->size : 0;
-}
-
-QVariant QQuickXmlListModel::data(const QModelIndex &index, int role) const
-{
- Q_D(const QQuickXmlListModel);
- const int roleIndex = d->roles.indexOf(role);
- return (roleIndex == -1 || !index.isValid())
- ? QVariant()
- : d->data.value(roleIndex).value(index.row());
-}
-
-QHash<int, QByteArray> QQuickXmlListModel::roleNames() const
-{
- Q_D(const QQuickXmlListModel);
- QHash<int,QByteArray> roleNames;
- for (int i = 0; i < d->roles.count(); ++i)
- roleNames.insert(d->roles.at(i), d->roleNames.at(i).toUtf8());
- return roleNames;
-}
-
-/*!
- \qmlproperty int QtQuick.XmlListModel::XmlListModel::count
- The number of data entries in the model.
-*/
-int QQuickXmlListModel::count() const
-{
- Q_D(const QQuickXmlListModel);
- return d->size;
-}
-
-/*!
- \qmlproperty url QtQuick.XmlListModel::XmlListModel::source
- The location of the XML data source.
-
- If both \c source and \l xml are set, \l xml is used.
-*/
-QUrl QQuickXmlListModel::source() const
-{
- Q_D(const QQuickXmlListModel);
- return d->src;
-}
-
-void QQuickXmlListModel::setSource(const QUrl &src)
-{
- Q_D(QQuickXmlListModel);
- if (d->src != src) {
- d->src = src;
- if (d->xml.isEmpty()) // src is only used if d->xml is not set
- reload();
- emit sourceChanged();
- }
-}
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlListModel::xml
- This property holds the XML data for this model, if set.
-
- The text is assumed to be UTF-8 encoded.
-
- If both \l source and \c xml are set, \c xml is used.
-*/
-QString QQuickXmlListModel::xml() const
-{
- Q_D(const QQuickXmlListModel);
- return d->xml;
-}
-
-void QQuickXmlListModel::setXml(const QString &xml)
-{
- Q_D(QQuickXmlListModel);
- if (d->xml != xml) {
- d->xml = xml;
- reload();
- emit xmlChanged();
- }
-}
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlListModel::query
- An absolute XPath query representing the base query for creating model items
- from this model's XmlRole objects. The query should start with '/' or '//'.
-*/
-QString QQuickXmlListModel::query() const
-{
- Q_D(const QQuickXmlListModel);
- return d->query;
-}
-
-void QQuickXmlListModel::setQuery(const QString &query)
-{
- Q_D(QQuickXmlListModel);
- if (!query.startsWith(QLatin1Char('/'))) {
- qmlWarning(this) << QCoreApplication::translate("QQuickXmlRoleList", "An XmlListModel query must start with '/' or \"//\"");
- return;
- }
-
- if (d->query != query) {
- d->query = query;
- reload();
- emit queryChanged();
- }
-}
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlListModel::namespaceDeclarations
- The namespace declarations to be used in the XPath queries.
-
- The namespaces should be declared as in XQuery. For example, if a requested document
- at http://mysite.com/feed.xml uses the namespace "http://www.w3.org/2005/Atom",
- this can be declared as the default namespace:
-
- \qml
- XmlListModel {
- source: "http://mysite.com/feed.xml"
- query: "/feed/entry"
- namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';"
-
- XmlRole { name: "title"; query: "title/string()" }
- }
- \endqml
-*/
-QString QQuickXmlListModel::namespaceDeclarations() const
-{
- Q_D(const QQuickXmlListModel);
- return d->namespaces;
-}
-
-void QQuickXmlListModel::setNamespaceDeclarations(const QString &declarations)
-{
- Q_D(QQuickXmlListModel);
- if (d->namespaces != declarations) {
- d->namespaces = declarations;
- reload();
- emit namespaceDeclarationsChanged();
- }
-}
-
-/*!
- \qmlmethod object QtQuick.XmlListModel::XmlListModel::get(int index)
-
- Returns the item at \a index in the model.
-
- For example, for a model like this:
-
- \qml
- XmlListModel {
- id: model
- source: "http://mysite.com/feed.xml"
- query: "/feed/entry"
- XmlRole { name: "title"; query: "title/string()" }
- }
- \endqml
-
- This will access the \c title value for the first item in the model:
-
- \js
- var title = model.get(0).title;
- \endjs
-*/
-QQmlV4Handle QQuickXmlListModel::get(int index) const
-{
- // Must be called with a context and handle scope
- Q_D(const QQuickXmlListModel);
-
- if (index < 0 || index >= count())
- return QQmlV4Handle(Encode::undefined());
-
- QQmlEngine *engine = qmlContext(this)->engine();
- ExecutionEngine *v4engine = engine->handle();
- Scope scope(v4engine);
- Scoped<Object> o(scope, v4engine->newObject());
- ScopedString name(scope);
- ScopedValue value(scope);
- for (int ii = 0; ii < d->roleObjects.count(); ++ii) {
- name = v4engine->newIdentifier(d->roleObjects[ii]->name());
- value = v4engine->fromVariant(d->data.value(ii).value(index));
- o->insertMember(name.getPointer(), value);
- }
-
- return QQmlV4Handle(o);
-}
-
-/*!
- \qmlproperty enumeration QtQuick.XmlListModel::XmlListModel::status
- Specifies the model loading status, which can be one of the following:
-
- \list
- \li XmlListModel.Null - No XML data has been set for this model.
- \li XmlListModel.Ready - The XML data has been loaded into the model.
- \li XmlListModel.Loading - The model is in the process of reading and loading XML data.
- \li XmlListModel.Error - An error occurred while the model was loading. See errorString() for details
- about the error.
- \endlist
-
- \sa progress
-
-*/
-QQuickXmlListModel::Status QQuickXmlListModel::status() const
-{
- Q_D(const QQuickXmlListModel);
- return d->status;
-}
-
-/*!
- \qmlproperty real QtQuick.XmlListModel::XmlListModel::progress
-
- This indicates the current progress of the downloading of the XML data
- source. This value ranges from 0.0 (no data downloaded) to
- 1.0 (all data downloaded). If the XML data is not from a remote source,
- the progress becomes 1.0 as soon as the data is read.
-
- Note that when the progress is 1.0, the XML data has been downloaded, but
- it is yet to be loaded into the model at this point. Use the status
- property to find out when the XML data has been read and loaded into
- the model.
-
- \sa status, source
-*/
-qreal QQuickXmlListModel::progress() const
-{
- Q_D(const QQuickXmlListModel);
- return d->progress;
-}
-
-/*!
- \qmlmethod QtQuick.XmlListModel::XmlListModel::errorString()
-
- Returns a string description of the last error that occurred
- if \l status is XmlListModel::Error.
-*/
-QString QQuickXmlListModel::errorString() const
-{
- Q_D(const QQuickXmlListModel);
- return d->errorString;
-}
-
-void QQuickXmlListModel::classBegin()
-{
- Q_D(QQuickXmlListModel);
- d->isComponentComplete = false;
-
- QQuickXmlQueryEngine *queryEngine = QQuickXmlQueryEngine::instance(qmlEngine(this));
- connect(queryEngine, SIGNAL(queryCompleted(QQuickXmlQueryResult)),
- SLOT(queryCompleted(QQuickXmlQueryResult)));
- connect(queryEngine, SIGNAL(error(void*,QString)),
- SLOT(queryError(void*,QString)));
-}
-
-void QQuickXmlListModel::componentComplete()
-{
- Q_D(QQuickXmlListModel);
- d->isComponentComplete = true;
- reload();
-}
-
-/*!
- \qmlmethod QtQuick.XmlListModel::XmlListModel::reload()
-
- Reloads the model.
-
- If no key roles have been specified, all existing model
- data is removed, and the model is rebuilt from scratch.
-
- Otherwise, items are only added if the model does not already
- contain items with matching key role values.
-
- \sa {Using key XML roles}, XmlRole::isKey
-*/
-void QQuickXmlListModel::reload()
-{
- Q_D(QQuickXmlListModel);
-
- if (!d->isComponentComplete)
- return;
-
- QQuickXmlQueryEngine::instance(qmlEngine(this))->abort(d->queryId);
- d->queryId = -1;
-
- if (d->size < 0)
- d->size = 0;
-
-#if QT_CONFIG(qml_network)
- if (d->reply) {
- d->reply->abort();
- d->deleteReply();
- }
-#endif
-
- if (!d->xml.isEmpty()) {
- d->queryId = QQuickXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache);
- d->notifyQueryStarted(false);
-
- } else if (d->src.isEmpty()) {
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- d->notifyQueryStarted(false);
- QTimer::singleShot(0, this, SLOT(dataCleared()));
-
- } else if (QQmlFile::isLocalFile(d->src)) {
- QFile file(QQmlFile::urlToLocalFileOrQrc(d->src));
- QByteArray data = file.open(QIODevice::ReadOnly) ? file.readAll() : QByteArray();
- d->notifyQueryStarted(false);
- if (data.isEmpty()) {
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- QTimer::singleShot(0, this, SLOT(dataCleared()));
- } else {
- d->queryId = QQuickXmlQueryEngine::instance(qmlEngine(this))->doQuery(
- d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
- }
- } else {
-#if QT_CONFIG(qml_network)
- d->notifyQueryStarted(true);
- QNetworkRequest req(d->src);
- req.setRawHeader("Accept", "application/xml,*/*");
- d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req);
- QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished()));
- QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
-#else
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- d->notifyQueryStarted(false);
- QTimer::singleShot(0, this, SLOT(dataCleared()));
-#endif
- }
-}
-
-#define XMLLISTMODEL_MAX_REDIRECT 16
-
-#if QT_CONFIG(qml_network)
-void QQuickXmlListModel::requestFinished()
-{
- Q_D(QQuickXmlListModel);
-
- d->redirectCount++;
- if (d->redirectCount < XMLLISTMODEL_MAX_REDIRECT) {
- QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- QUrl url = d->reply->url().resolved(redirect.toUrl());
- d->deleteReply();
- setSource(url);
- return;
- }
- }
- d->redirectCount = 0;
-
- if (d->reply->error() != QNetworkReply::NoError) {
- d->errorString = d->reply->errorString();
- d->deleteReply();
-
- if (d->size > 0) {
- beginRemoveRows(QModelIndex(), 0, d->size - 1);
- d->data.clear();
- d->size = 0;
- endRemoveRows();
- emit countChanged();
- }
-
- d->status = Error;
- d->queryId = -1;
- emit statusChanged(d->status);
- } else {
- QByteArray data = d->reply->readAll();
- if (data.isEmpty()) {
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- QTimer::singleShot(0, this, SLOT(dataCleared()));
- } else {
- d->queryId = QQuickXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
- }
- d->deleteReply();
-
- d->progress = 1.0;
- emit progressChanged(d->progress);
- }
-}
-#endif
-
-void QQuickXmlListModel::requestProgress(qint64 received, qint64 total)
-{
- Q_D(QQuickXmlListModel);
- if (d->status == Loading && total > 0) {
- d->progress = qreal(received)/total;
- emit progressChanged(d->progress);
- }
-}
-
-void QQuickXmlListModel::dataCleared()
-{
- Q_D(QQuickXmlListModel);
- QQuickXmlQueryResult r;
- r.queryId = XMLLISTMODEL_CLEAR_ID;
- r.size = 0;
- r.removed << qMakePair(0, count());
- r.keyRoleResultsCache = d->keyRoleResultsCache;
- queryCompleted(r);
-}
-
-void QQuickXmlListModel::queryError(void* object, const QString& error)
-{
- // Be extra careful, object may no longer exist, it's just an ID.
- Q_D(QQuickXmlListModel);
- for (int i=0; i<d->roleObjects.count(); i++) {
- if (d->roleObjects.at(i) == static_cast<QQuickXmlListModelRole*>(object)) {
- qmlWarning(d->roleObjects.at(i)) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
- return;
- }
- }
- qmlWarning(this) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
-}
-
-void QQuickXmlListModel::queryCompleted(const QQuickXmlQueryResult &result)
-{
- Q_D(QQuickXmlListModel);
- if (result.queryId != d->queryId)
- return;
-
- int origCount = d->size;
- bool sizeChanged = result.size != d->size;
-
- d->keyRoleResultsCache = result.keyRoleResultsCache;
- if (d->src.isEmpty() && d->xml.isEmpty())
- d->status = Null;
- else
- d->status = Ready;
- d->errorString.clear();
- d->queryId = -1;
-
- bool hasKeys = false;
- for (int i=0; i<d->roleObjects.count(); i++) {
- if (d->roleObjects[i]->isKey()) {
- hasKeys = true;
- break;
- }
- }
- if (!hasKeys) {
- if (origCount > 0) {
- beginRemoveRows(QModelIndex(), 0, origCount - 1);
- endRemoveRows();
- }
- d->size = result.size;
- d->data = result.data;
- if (d->size > 0) {
- beginInsertRows(QModelIndex(), 0, d->size - 1);
- endInsertRows();
- }
- } else {
- for (int i=0; i<result.removed.count(); i++) {
- const int index = result.removed[i].first;
- const int count = result.removed[i].second;
- if (count > 0) {
- beginRemoveRows(QModelIndex(), index, index + count - 1);
- endRemoveRows();
- }
- }
- d->size = result.size;
- d->data = result.data;
- for (int i=0; i<result.inserted.count(); i++) {
- const int index = result.inserted[i].first;
- const int count = result.inserted[i].second;
- if (count > 0) {
- beginInsertRows(QModelIndex(), index, index + count - 1);
- endInsertRows();
- }
- }
- }
- if (sizeChanged)
- emit countChanged();
-
- emit statusChanged(d->status);
-}
-
-QT_END_NAMESPACE
-
-#include <qqmlxmllistmodel.moc>
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
deleted file mode 100644
index 65f1299324..0000000000
--- a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKXMLLISTMODEL_H
-#define QQUICKXMLLISTMODEL_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qqml.h>
-#include <qqmlinfo.h>
-
-#include <QtCore/qurl.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qabstractitemmodel.h>
-#include <private/qv8engine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QQmlContext;
-class QQuickXmlListModelRole;
-class QQuickXmlListModelPrivate;
-
-struct QQuickXmlQueryResult {
- int queryId;
- int size;
- QList<QList<QVariant> > data;
- QList<QPair<int, int> > inserted;
- QList<QPair<int, int> > removed;
- QStringList keyRoleResultsCache;
-};
-
-class QQuickXmlListModel : public QAbstractListModel, public QQmlParserStatus
-{
- Q_OBJECT
- Q_INTERFACES(QQmlParserStatus)
-
- Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
- Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(QString xml READ xml WRITE setXml NOTIFY xmlChanged)
- Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
- Q_PROPERTY(QString namespaceDeclarations READ namespaceDeclarations WRITE setNamespaceDeclarations NOTIFY namespaceDeclarationsChanged)
- Q_PROPERTY(QQmlListProperty<QQuickXmlListModelRole> roles READ roleObjects)
- Q_PROPERTY(int count READ count NOTIFY countChanged)
- Q_CLASSINFO("DefaultProperty", "roles")
-
-public:
- QQuickXmlListModel(QObject *parent = 0);
- ~QQuickXmlListModel();
-
- QModelIndex index(int row, int column, const QModelIndex &parent) const override;
- int rowCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- QHash<int, QByteArray> roleNames() const override;
-
- int count() const;
-
- QQmlListProperty<QQuickXmlListModelRole> roleObjects();
-
- QUrl source() const;
- void setSource(const QUrl&);
-
- QString xml() const;
- void setXml(const QString&);
-
- QString query() const;
- void setQuery(const QString&);
-
- QString namespaceDeclarations() const;
- void setNamespaceDeclarations(const QString&);
-
- Q_INVOKABLE QQmlV4Handle get(int index) const;
-
- enum Status { Null, Ready, Loading, Error };
- Q_ENUM(Status)
- Status status() const;
- qreal progress() const;
-
- Q_INVOKABLE QString errorString() const;
-
- void classBegin() override;
- void componentComplete() override;
-
-Q_SIGNALS:
- void statusChanged(QQuickXmlListModel::Status);
- void progressChanged(qreal progress);
- void countChanged();
- void sourceChanged();
- void xmlChanged();
- void queryChanged();
- void namespaceDeclarationsChanged();
-
-public Q_SLOTS:
- // ### need to use/expose Expiry to guess when to call this?
- // ### property to auto-call this on reasonable Expiry?
- // ### LastModified/Age also useful to guess.
- // ### Probably also applies to other network-requesting types.
- void reload();
-
-private Q_SLOTS:
-#if QT_CONFIG(qml_network)
- void requestFinished();
-#endif
- void requestProgress(qint64,qint64);
- void dataCleared();
- void queryCompleted(const QQuickXmlQueryResult &);
- void queryError(void* object, const QString& error);
-
-private:
- Q_DECLARE_PRIVATE(QQuickXmlListModel)
- Q_DISABLE_COPY(QQuickXmlListModel)
-};
-
-class QQuickXmlListModelRole : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
- Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
- Q_PROPERTY(bool isKey READ isKey WRITE setIsKey NOTIFY isKeyChanged)
-public:
- QQuickXmlListModelRole() : m_isKey(false) {}
- ~QQuickXmlListModelRole() {}
-
- QString name() const { return m_name; }
- void setName(const QString &name) {
- if (name == m_name)
- return;
- m_name = name;
- Q_EMIT nameChanged();
- }
-
- QString query() const { return m_query; }
- void setQuery(const QString &query)
- {
- if (query.startsWith(QLatin1Char('/'))) {
- qmlWarning(this) << tr("An XmlRole query must not start with '/'");
- return;
- }
- if (m_query == query)
- return;
- m_query = query;
- Q_EMIT queryChanged();
- }
-
- bool isKey() const { return m_isKey; }
- void setIsKey(bool b) {
- if (m_isKey == b)
- return;
- m_isKey = b;
- Q_EMIT isKeyChanged();
- }
-
- bool isValid() const {
- return !m_name.isEmpty() && !m_query.isEmpty();
- }
-
-Q_SIGNALS:
- void nameChanged();
- void queryChanged();
- void isKeyChanged();
-
-private:
- QString m_name;
- QString m_query;
- bool m_isKey;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickXmlListModel)
-QML_DECLARE_TYPE(QQuickXmlListModelRole)
-
-#endif // QQUICKXMLLISTMODEL_H
diff --git a/src/imports/xmllistmodel/xmllistmodel.pro b/src/imports/xmllistmodel/xmllistmodel.pro
deleted file mode 100644
index 1e61f4d3d9..0000000000
--- a/src/imports/xmllistmodel/xmllistmodel.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-CXX_MODULE = qml
-TARGET = qmlxmllistmodelplugin
-TARGETPATH = QtQuick/XmlListModel
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
-
-QT = xmlpatterns qml-private core-private
-qtConfig(qml-network): QT += network
-
-SOURCES += qqmlxmllistmodel.cpp plugin.cpp
-HEADERS += qqmlxmllistmodel_p.h
-
-load(qml_plugin)
-
-requires(qtConfig(qml-network))
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index 6161760471..40acc7c13f 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -33,7 +33,7 @@ qhp.QtQml.subprojects.qmltypes.sortPages = true
tagfile = ../../../doc/qtqml/qtqml.tags
-depends += qtcore qtxmlpatterns qtgui qtquick qtdoc qtlinguist qmake qtscript qtwidgets
+depends += qtcore qtgui qtquick qtdoc qtlinguist qmake qtscript qtwidgets
headerdirs += .. \
../../imports/models
diff --git a/src/qmltest/doc/qtqmltest.qdocconf b/src/qmltest/doc/qtqmltest.qdocconf
index 33e8ae334c..a819546fba 100644
--- a/src/qmltest/doc/qtqmltest.qdocconf
+++ b/src/qmltest/doc/qtqmltest.qdocconf
@@ -31,7 +31,7 @@ qhp.QtQmlTest.subprojects.qmltypes.sortPages = true
tagfile = ../../../doc/qtqmltest/qtqmltest.tags
-depends += qtcore qtxmlpatterns qtgui qttestlib qtqml qtquick qtdoc
+depends += qtcore qtgui qttestlib qtqml qtquick qtdoc
headerdirs += ..
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 1dbf199bc8..8c69eba6a6 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -37,7 +37,7 @@ qhp.QtQuick.subprojects.examples.selectors = fake:example
tagfile = ../../../doc/qtquick/qtquick.tags
-depends += qtcore qtxmlpatterns qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql
+depends += qtcore qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols2 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql
headerdirs += ..\
../../quickwidgets
diff --git a/src/quick/doc/snippets/qml/xmlrole.qml b/src/quick/doc/snippets/qml/xmlrole.qml
deleted file mode 100644
index 9c5172ba45..0000000000
--- a/src/quick/doc/snippets/qml/xmlrole.qml
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-Rectangle {
- width: 300; height: 200
-
-//![0]
-XmlListModel {
- id: model
-//![0]
- source: "xmlrole.xml"
-
-//![1]
- // XmlRole queries will be made on <book> elements
- query: "/catalog/book"
-
- // query the book title
- XmlRole { name: "title"; query: "title/string()" }
-
- // query the book's year
- XmlRole { name: "year"; query: "year/number()" }
-
- // query the book's type (the '@' indicates 'type' is an attribute, not an element)
- XmlRole { name: "type"; query: "@type/string()" }
-
- // query the book's first listed author (note in XPath the first index is 1, not 0)
- XmlRole { name: "first_author"; query: "author[1]/string()" }
-
- // query the wanted attribute as a boolean
- XmlRole { name: "wanted"; query: "boolean(@wanted)" }
-}
-//![1]
-
-//![2]
-ListView {
- width: 300; height: 200
- model: model
- delegate: Column {
- Text { text: title + " (" + type + ")"; font.bold: wanted }
- Text { text: first_author }
- Text { text: year }
- }
-//![2]
-}
-
-}
diff --git a/tests/auto/quick/examples/examples.pro b/tests/auto/quick/examples/examples.pro
index fd8cfd83c8..c047f993ea 100644
--- a/tests/auto/quick/examples/examples.pro
+++ b/tests/auto/quick/examples/examples.pro
@@ -8,5 +8,4 @@ DEFINES += SRCDIR=\\\"$$PWD\\\"
#temporary
QT += core-private gui-private qml-private quick-private testlib
-!qtHaveModule(xmlpatterns): DEFINES += QT_NO_XMLPATTERNS
diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp
index b3fc87a8de..9b3fa8fd2c 100644
--- a/tests/auto/quick/examples/tst_examples.cpp
+++ b/tests/auto/quick/examples/tst_examples.cpp
@@ -88,12 +88,6 @@ tst_examples::tst_examples()
excludedFiles << "examples/quick/shapes/content/main.qml"; // relies on resources
excludedFiles << "examples/quick/shapes/content/interactive.qml"; // relies on resources
-#ifdef QT_NO_XMLPATTERNS
- excludedFiles << "snippets/qml/xmlrole.qml";
- excludedFiles << "particles/itemparticle/particleview.qml";
- excludedFiles << "views/visualdatamodel/slideshow.qml";
-#endif
-
#if !QT_CONFIG(opengl)
//No support for Particles
excludedFiles << "examples/qml/dynamicscene/dynamicscene.qml";
diff --git a/tests/auto/quick/qquickxmllistmodel/data/empty.xml b/tests/auto/quick/qquickxmllistmodel/data/empty.xml
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/empty.xml
+++ /dev/null
diff --git a/tests/auto/quick/qquickxmllistmodel/data/get.qml b/tests/auto/quick/qquickxmllistmodel/data/get.qml
deleted file mode 100644
index 509da7174b..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/get.qml
+++ /dev/null
@@ -1,61 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "name/string()" }
- XmlRole { name: "type"; query: "type/string()" }
- XmlRole { name: "age"; query: "age/number()" }
- XmlRole { name: "size"; query: "size/string()" }
-
- id: root
-
- property bool preTest: false
- property bool postTest: false
-
- function runPreTest() {
- if (root.get(0) != undefined)
- return;
-
- preTest = true;
- }
-
- function runPostTest() {
- if (root.get(-1) != undefined)
- return;
-
- var row = root.get(0);
- if (row.name != "Polly" ||
- row.type != "Parrot" ||
- row.age != 12 ||
- row.size != "Small")
- return;
-
- row = root.get(1);
- if (row.name != "Penny" ||
- row.type != "Turtle" ||
- row.age != 4 ||
- row.size != "Small")
- return;
-
- row = root.get(7);
- if (row.name != "Rover" ||
- row.type != "Dog" ||
- row.age != 0 ||
- row.size != "Large")
- return;
-
- row = root.get(8);
- if (row.name != "Tiny" ||
- row.type != "Elephant" ||
- row.age != 15 ||
- row.size != "Large")
- return;
-
- if (root.get(9) != undefined)
- return;
-
- postTest = true;
- }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/groups.qml b/tests/auto/quick/qquickxmllistmodel/data/groups.qml
deleted file mode 100644
index c1b574a822..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/groups.qml
+++ /dev/null
@@ -1,10 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "groups.xml"
- query: "//animal[@name='Garfield']/parent::group"
-
- XmlRole { name: "id"; query: "@id/string()" }
- XmlRole { name: "name"; query: "@name/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/groups.xml b/tests/auto/quick/qquickxmllistmodel/data/groups.xml
deleted file mode 100644
index 5de4d2ec71..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/groups.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<groups version="2.0">
- <group id="1" name="Animals" type="root">
- <group id="11" name="dogs">
- <animal id="111" name="Lassie"/>
- <animal id="112" name="Laika"/>
- <animal id="113" name="Wile E. Coyote" type="fictional"/>
- </group>
- <group id="12" name="cats">
- <animal id="121" name="Garfield" type="fictional"/>
- <animal id="122" name="Sylvester" type="fictional"/>
- </group>
- <group id="13" name="birds">
- <animal id="131" name="Donald Duck" type="fictional"/>
- <animal id="132" name="Phoenix" type="fictional"/>
- </group>
- </group>
-</groups>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/model.qml b/tests/auto/quick/qquickxmllistmodel/data/model.qml
deleted file mode 100644
index 2df3927479..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/model.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "name/string()" }
- XmlRole { name: "type"; query: "type/string()" }
- XmlRole { name: "age"; query: "age/number()" }
- XmlRole { name: "size"; query: "size/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/model.xml b/tests/auto/quick/qquickxmllistmodel/data/model.xml
deleted file mode 100644
index 40cd6d0432..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/model.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<Pets>
- <Pet>
- <name>Polly</name>
- <type>Parrot</type>
- <age>12</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Penny</name>
- <type>Turtle</type>
- <age>4</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Warren</name>
- <type>Rabbit</type>
- <age>2</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Spot</name>
- <type>Dog</type>
- <age>9</age>
- <size>Medium</size>
- </Pet>
- <Pet>
- <name>Whiskers</name>
- <type>Cat</type>
- <age>2</age>
- <size>Medium</size>
- </Pet>
- <Pet>
- <name>Joey</name>
- <type>Kangaroo</type>
- <age>1</age>
- </Pet>
- <Pet>
- <name>Kimba</name>
- <type>Bunny</type>
- <age>65</age>
- <size>Large</size>
- </Pet>
- <Pet>
- <name>Rover</name>
- <type>Dog</type>
- <size>Large</size>
- </Pet>
- <Pet>
- <name>Tiny</name>
- <type>Elephant</type>
- <age>15</age>
- <size>Large</size>
- </Pet>
-</Pets>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/model2.xml b/tests/auto/quick/qquickxmllistmodel/data/model2.xml
deleted file mode 100644
index dab2ec6dc0..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/model2.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<Pets>
- <Pet>
- <name>Polly</name>
- <type>Parrot</type>
- <age>12</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Penny</name>
- <type>Turtle</type>
- <age>4</age>
- <size>Small</size>
- </Pet>
-</Pets>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml b/tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml
deleted file mode 100644
index f8a97bffc3..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { objectName: "role"; name: "name"; query: "name/string()" }
- XmlRole { name: "type"; query: "type/string()" }
- XmlRole { name: "age"; query: "age/number()" }
- XmlRole { name: "size"; query: "size/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml b/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml
deleted file mode 100644
index c0c5a25e3c..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml
+++ /dev/null
@@ -1,9 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-import SortFilterProxyModel 1.0
-
-SortFilterProxyModel {
- source: XmlListModel {
- XmlRole { }
- }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/recipes.qml b/tests/auto/quick/qquickxmllistmodel/data/recipes.qml
deleted file mode 100644
index dc609e95e3..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/recipes.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "recipes.xml"
- query: "/recipes/recipe"
- XmlRole { name: "title"; query: "@title/string()" }
- XmlRole { name: "picture"; query: "picture/string()" }
- XmlRole { name: "ingredients"; query: "ingredients/string()" }
- XmlRole { name: "preparation"; query: "method/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/recipes.xml b/tests/auto/quick/qquickxmllistmodel/data/recipes.xml
deleted file mode 100644
index d71de60710..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/recipes.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<recipes>
- <recipe title="Pancakes">
- <picture>content/pics/pancakes.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 1 cup (150g) self-raising flour
- <li> 1 tbs caster sugar
- <li> 3/4 cup (185ml) milk
- <li> 1 egg
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Sift flour and sugar together into a bowl. Add a pinch of salt.
- <li> Beat milk and egg together, then add to dry ingredients. Beat until smooth.
- <li> Pour mixture into a pan on medium heat and cook until bubbles appear on the surface.
- <li> Turn over and cook other side until golden.
- </ol>
- </html>
- ]]></method>
- </recipe>
- <recipe title="Fruit Salad">
- <picture>content/pics/fruit-salad.jpg</picture>
- <ingredients><![CDATA[* Seasonal Fruit]]></ingredients>
- <method><![CDATA[* Chop fruit and place in a bowl.]]></method>
- </recipe>
- <recipe title="Vegetable Soup">
- <picture>content/pics/vegetable-soup.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 1 onion
- <li> 1 turnip
- <li> 1 potato
- <li> 1 carrot
- <li> 1 head of celery
- <li> 1 1/2 litres of water
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Chop vegetables.
- <li> Boil in water until vegetables soften.
- <li> Season with salt and pepper to taste.
- </ol>
- </html>
- ]]></method>
- </recipe>
- <recipe title="Hamburger">
- <picture>content/pics/hamburger.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 500g minced beef
- <li> Seasoning
- <li> lettuce, tomato, onion, cheese
- <li> 1 hamburger bun for each burger
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Mix the beef, together with seasoning, in a food processor.
- <li> Shape the beef into burgers.
- <li> Grill the burgers for about 5 mins on each side (until cooked through)
- <li> Serve each burger on a bun with ketchup, cheese, lettuce, tomato and onion.
- </ol>
- </html>
- ]]></method>
- </recipe>
- <recipe title="Lemonade">
- <picture>content/pics/lemonade.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 1 cup Lemon Juice
- <li> 1 cup Sugar
- <li> 6 Cups of Water (2 cups warm water, 4 cups cold water)
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Pour 2 cups of warm water into a pitcher and stir in sugar until it dissolves.
- <li> Pour in lemon juice, stir again, and add 4 cups of cold water.
- <li> Chill or serve over ice cubes.
- </ol>
- </html>
- ]]></method>
- </recipe>
-</recipes>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml b/tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml
deleted file mode 100644
index 6a7059bb45..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml
+++ /dev/null
@@ -1,8 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- id: model
- XmlRole {}
- Component.onCompleted: model.roles = 0
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml b/tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml
deleted file mode 100644
index 91664b6d4a..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "/name/string()" } //starts with '/'
- XmlRole { name: "type"; query: "type" } //no type
- XmlRole { name: "age"; query: "age/" } //ends with '/'
- XmlRole { name: "size"; query: "size/number()" } //wrong type
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml b/tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml
deleted file mode 100644
index 9f667d86e5..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml
+++ /dev/null
@@ -1,13 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- query: "/data/item"
- XmlRole { id: nameRole; name: "name"; query: "name/string()"; isKey: true }
- XmlRole { name: "age"; query: "age/number()"; isKey: true }
- XmlRole { name: "sport"; query: "sport/string()" }
-
- function disableNameKey() {
- nameRole.isKey = false;
- }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/testtypes.qml b/tests/auto/quick/qquickxmllistmodel/data/testtypes.qml
deleted file mode 100644
index 5ec1ffa35f..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/testtypes.qml
+++ /dev/null
@@ -1,8 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- query: "/data"
- XmlRole { name: "stringValue"; query: "a-string/string()" }
- XmlRole { name: "numberValue"; query: "a-number/number()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/unique.qml b/tests/auto/quick/qquickxmllistmodel/data/unique.qml
deleted file mode 100644
index 322a2e4e5c..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/unique.qml
+++ /dev/null
@@ -1,9 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "name/string()" }
- XmlRole { name: "name"; query: "type/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
deleted file mode 100644
index 902325802c..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qquickxmllistmodel
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qquickxmllistmodel.cpp \
- ../../../../src/imports/xmllistmodel/qqmlxmllistmodel.cpp
-HEADERS += ../../../../src/imports/xmllistmodel/qqmlxmllistmodel_p.h
-
-include (../../shared/util.pri)
-
-TESTDATA = data/*
-
-QT += core-private gui-private qml-private network testlib xmlpatterns
-
-OTHER_FILES += \
- data/groups.qml
diff --git a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
deleted file mode 100644
index bcff0c46fb..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
+++ /dev/null
@@ -1,1011 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtGlobal>
-#include <math.h>
-#include <QMetaObject>
-#include <qtest.h>
-#include <QtTest/qsignalspy.h>
-#include <QtQml/qqmlnetworkaccessmanagerfactory.h>
-#include <QtNetwork/qnetworkaccessmanager.h>
-#include <QtNetwork/qnetworkrequest.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qtemporaryfile.h>
-#include <QtCore/qsortfilterproxymodel.h>
-#include "../../shared/util.h"
-#include <private/qqmlengine_p.h>
-
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlcomponent.h>
-#include "../../../../src/imports/xmllistmodel/qqmlxmllistmodel_p.h"
-
-#include <algorithm>
-
-typedef QPair<int, int> QQuickXmlListRange;
-typedef QList<QVariantList> QQmlXmlModelData;
-
-Q_DECLARE_METATYPE(QList<QQuickXmlListRange>)
-Q_DECLARE_METATYPE(QQmlXmlModelData)
-Q_DECLARE_METATYPE(QQuickXmlListModel::Status)
-
-class tst_qquickxmllistmodel : public QQmlDataTest
-
-{
- Q_OBJECT
-public:
- tst_qquickxmllistmodel() {}
-
-private slots:
- void initTestCase() {
- QQmlDataTest::initTestCase();
- qRegisterMetaType<QQuickXmlListModel::Status>();
- }
-
- void buildModel();
- void testTypes();
- void testTypes_data();
- void cdata();
- void attributes();
- void roles();
- void roleErrors();
- void uniqueRoleNames();
- void headers();
- void xml();
- void xml_data();
- void source();
- void source_data();
- void data();
- void get();
- void reload();
- void useKeys();
- void useKeys_data();
- void noKeysValueChanges();
- void keysChanged();
- void threading();
- void threading_data();
- void propertyChanges();
- void selectAncestor();
-
- void roleCrash();
- void proxyCrash();
-
-private:
- QString errorString(QAbstractItemModel *model) {
- QString ret;
- QMetaObject::invokeMethod(model, "errorString", Q_RETURN_ARG(QString, ret));
- return ret;
- }
-
- QString makeItemXmlAndData(const QString &data, QQmlXmlModelData *modelData = 0) const
- {
- if (modelData)
- modelData->clear();
- QString xml;
-
- if (!data.isEmpty()) {
- QStringList items = data.split(QLatin1Char(';'));
- foreach(const QString &item, items) {
- if (item.isEmpty())
- continue;
- QVariantList variants;
- xml += QLatin1String("<item>");
- QStringList fields = item.split(QLatin1Char(','));
- foreach(const QString &field, fields) {
- QStringList values = field.split(QLatin1Char('='));
- if (values.count() != 2) {
- qWarning() << "makeItemXmlAndData: invalid field:" << field;
- continue;
- }
- xml += QString("<%1>%2</%1>").arg(values[0], values[1]);
- if (!modelData)
- continue;
- bool isNum = false;
- int number = values[1].toInt(&isNum);
- if (isNum)
- variants << number;
- else
- variants << values[1];
- }
- xml += QLatin1String("</item>");
- if (modelData)
- modelData->append(variants);
- }
- }
-
- QString decl = "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>";
- return decl + QLatin1String("<data>") + xml + QLatin1String("</data>");
- }
-
- QQmlEngine engine;
-};
-
-class CustomNetworkAccessManagerFactory : public QObject, public QQmlNetworkAccessManagerFactory
-{
- Q_OBJECT
-public:
- QVariantMap lastSentHeaders;
-
-protected:
- QNetworkAccessManager *create(QObject *parent);
-};
-
-class CustomNetworkAccessManager : public QNetworkAccessManager
-{
- Q_OBJECT
-public:
- CustomNetworkAccessManager(CustomNetworkAccessManagerFactory *factory, QObject *parent)
- : QNetworkAccessManager(parent), m_factory(factory) {}
-
-protected:
- QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice * outgoingData = 0)
- {
- if (m_factory) {
- QVariantMap map;
- foreach (const QString &header, req.rawHeaderList())
- map[header] = req.rawHeader(header.toUtf8());
- m_factory->lastSentHeaders = map;
- }
- return QNetworkAccessManager::createRequest(op, req, outgoingData);
- }
-
- QPointer<CustomNetworkAccessManagerFactory> m_factory;
-};
-
-QNetworkAccessManager *CustomNetworkAccessManagerFactory::create(QObject *parent)
-{
- return new CustomNetworkAccessManager(this, parent);
-}
-
-
-void tst_qquickxmllistmodel::buildModel()
-{
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QModelIndex index = model->index(3, 0);
- QCOMPARE(model->data(index, Qt::UserRole).toString(), QLatin1String("Spot"));
- QCOMPARE(model->data(index, Qt::UserRole+1).toString(), QLatin1String("Dog"));
- QCOMPARE(model->data(index, Qt::UserRole+2).toInt(), 9);
- QCOMPARE(model->data(index, Qt::UserRole+3).toString(), QLatin1String("Medium"));
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::testTypes()
-{
- QFETCH(QString, xml);
- QFETCH(QString, roleName);
- QFETCH(QVariant, expectedValue);
-
- QQmlComponent component(&engine, testFileUrl("testtypes.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- model->setProperty("xml",xml.toUtf8());
- QMetaObject::invokeMethod(model, "reload");
- QTRY_COMPARE(model->rowCount(), 1);
-
- int role = model->roleNames().key(roleName.toUtf8(), -1);
- QVERIFY(role >= 0);
-
- QModelIndex index = model->index(0, 0);
- if (expectedValue.toString() == "nan")
- QVERIFY(qIsNaN(model->data(index, role).toDouble()));
- else
- QCOMPARE(model->data(index, role), expectedValue);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::testTypes_data()
-{
- QTest::addColumn<QString>("xml");
- QTest::addColumn<QString>("roleName");
- QTest::addColumn<QVariant>("expectedValue");
-
- QTest::newRow("missing string field") << "<data></data>"
- << "stringValue" << QVariant("");
- QTest::newRow("empty string") << "<data><a-string></a-string></data>"
- << "stringValue" << QVariant("");
- QTest::newRow("1-char string") << "<data><a-string>5</a-string></data>"
- << "stringValue" << QVariant("5");
- QTest::newRow("string ok") << "<data><a-string>abc def g</a-string></data>"
- << "stringValue" << QVariant("abc def g");
-
- QTest::newRow("missing number field") << "<data></data>"
- << "numberValue" << QVariant("");
- double nan = qQNaN();
- QTest::newRow("empty number field") << "<data><a-number></a-number></data>"
- << "numberValue" << QVariant(nan);
- QTest::newRow("number field with string") << "<data><a-number>a string</a-number></data>"
- << "numberValue" << QVariant(nan);
- QTest::newRow("-1") << "<data><a-number>-1</a-number></data>"
- << "numberValue" << QVariant("-1");
- QTest::newRow("-1.5") << "<data><a-number>-1.5</a-number></data>"
- << "numberValue" << QVariant("-1.5");
- QTest::newRow("0") << "<data><a-number>0</a-number></data>"
- << "numberValue" << QVariant("0");
- QTest::newRow("+1") << "<data><a-number>1</a-number></data>"
- << "numberValue" << QVariant("1");
- QTest::newRow("+1.5") << "<data><a-number>1.5</a-number></data>"
- << "numberValue" << QVariant("1.5");
-}
-
-void tst_qquickxmllistmodel::cdata()
-{
- QQmlComponent component(&engine, testFileUrl("recipes.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 5);
-
- QVERIFY(model->data(model->index(2, 0), Qt::UserRole+2).toString().startsWith(QLatin1String("<html>")));
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::attributes()
-{
- QQmlComponent component(&engine, testFileUrl("recipes.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 5);
- QCOMPARE(model->data(model->index(2, 0), Qt::UserRole).toString(), QLatin1String("Vegetable Soup"));
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::roles()
-{
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QHash<int, QByteArray> roleNames = model->roleNames();
- QCOMPARE(roleNames.count(), 4);
- QVERIFY(roleNames.key("name", -1) >= 0);
- QVERIFY(roleNames.key("type", -1) >= 0);
- QVERIFY(roleNames.key("age", -1) >= 0);
- QVERIFY(roleNames.key("size", -1) >= 0);
-
- QSet<int> roles;
- roles.insert(roleNames.key("name"));
- roles.insert(roleNames.key("type"));
- roles.insert(roleNames.key("age"));
- roles.insert(roleNames.key("size"));
- QCOMPARE(roles.count(), 4);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::roleErrors()
-{
- QQmlComponent component(&engine, testFileUrl("roleErrors.qml"));
- QTest::ignoreMessage(QtWarningMsg, (testFileUrl("roleErrors.qml").toString() + ":7:5: QML XmlRole: An XmlRole query must not start with '/'").toUtf8().constData());
- QTest::ignoreMessage(QtWarningMsg, (testFileUrl("roleErrors.qml").toString() + ":10:5: QML XmlRole: invalid query: \"age/\"").toUtf8().constData());
-
- //### make sure we receive all expected warning messages.
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QModelIndex index = model->index(3, 0);
- //### should any of these return valid values?
- QCOMPARE(model->data(index, Qt::UserRole), QVariant());
- QCOMPARE(model->data(index, Qt::UserRole+1), QVariant());
- QCOMPARE(model->data(index, Qt::UserRole+2), QVariant());
-
- QEXPECT_FAIL("", "QTBUG-10797", Continue);
- QCOMPARE(model->data(index, Qt::UserRole+3), QVariant());
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::uniqueRoleNames()
-{
- QQmlComponent component(&engine, testFileUrl("unique.qml"));
- QTest::ignoreMessage(QtWarningMsg, (testFileUrl("unique.qml").toString() + ":8:5: QML XmlRole: \"name\" duplicates a previous role name and will be disabled.").toUtf8().constData());
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QHash<int, QByteArray> roleNames = model->roleNames();
- QCOMPARE(roleNames.count(), 1);
-
- delete model;
-}
-
-
-void tst_qquickxmllistmodel::xml()
-{
- QFETCH(QString, xml);
- QFETCH(int, count);
-
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
-
- QSignalSpy spy(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)));
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QTest::qWait(50);
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(model->rowCount(), 9);
-
- // if xml is empty (i.e. clearing) it won't have any effect if a source is set
- if (xml.isEmpty())
- model->setProperty("source",QUrl());
- model->setProperty("xml",xml);
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); // immediately goes to 1.0 if using setXml()
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- if (xml.isEmpty())
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Null);
- else
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->rowCount(), count);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::xml_data()
-{
- QTest::addColumn<QString>("xml");
- QTest::addColumn<int>("count");
-
- QTest::newRow("xml with no items") << "<Pets></Pets>" << 0;
- QTest::newRow("empty xml") << "" << 0;
- QTest::newRow("one item") << "<Pets><Pet><name>Hobbes</name><type>Tiger</type><age>7</age><size>Large</size></Pet></Pets>" << 1;
-}
-
-void tst_qquickxmllistmodel::headers()
-{
- // ensure the QNetworkAccessManagers created for this test are immediately deleted
- QQmlEngine qmlEng;
-
- CustomNetworkAccessManagerFactory factory;
- qmlEng.setNetworkAccessManagerFactory(&factory);
-
- QQmlComponent component(&qmlEng, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
-
- // It doesn't do a network request for a local file
- QCOMPARE(factory.lastSentHeaders.count(), 0);
-
- model->setProperty("source", QUrl("http://localhost/filethatdoesnotexist.xml"));
- QTRY_COMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Error);
-
- QVariantMap expectedHeaders;
- expectedHeaders["Accept"] = "application/xml,*/*";
-
- QCOMPARE(factory.lastSentHeaders.count(), expectedHeaders.count());
- foreach (const QString &header, expectedHeaders.keys()) {
- QVERIFY(factory.lastSentHeaders.contains(header));
- QCOMPARE(factory.lastSentHeaders[header].toString(), expectedHeaders[header].toString());
- }
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::source()
-{
- QFETCH(QUrl, source);
- QFETCH(int, count);
- QFETCH(QQuickXmlListModel::Status, status);
-
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QSignalSpy spy(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)));
-
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(model->rowCount(), 9);
-
- model->setProperty("source",source);
- if (model->property("source").toString().isEmpty())
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Null);
- QCOMPARE(model->property("progress").toDouble(), qreal(source.isLocalFile() ? 1.0 : 0.0));
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QVERIFY(errorString(model).isEmpty());
-
- QEventLoop loop;
- QTimer timer;
- timer.setSingleShot(true);
- connect(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)), &loop, SLOT(quit()));
- connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
- timer.start(20000);
- loop.exec();
-
- if (spy.count() == 0 && status != QQuickXmlListModel::Ready) {
- qWarning("QQuickXmlListModel invalid source test timed out");
- } else {
- QCOMPARE(spy.count(), 1); spy.clear();
- }
-
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")), status);
- QCOMPARE(model->rowCount(), count);
-
- if (status == QQuickXmlListModel::Ready)
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
-
- QCOMPARE(errorString(model).isEmpty(), status == QQuickXmlListModel::Ready);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::source_data()
-{
- QTest::addColumn<QUrl>("source");
- QTest::addColumn<int>("count");
- QTest::addColumn<QQuickXmlListModel::Status>("status");
-
- QTest::newRow("valid") << testFileUrl("model2.xml") << 2
- << QQuickXmlListModel::Ready;
- QTest::newRow("invalid") << QUrl("http://blah.blah/blah.xml") << 0
- << QQuickXmlListModel::Error;
-
- // empty file
- QTemporaryFile *temp = new QTemporaryFile(this);
- if (temp->open())
- QTest::newRow("empty file") << QUrl::fromLocalFile(temp->fileName()) << 0
- << QQuickXmlListModel::Ready;
- temp->close();
-}
-
-void tst_qquickxmllistmodel::data()
-{
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- for (int i=0; i<9; i++) {
- QModelIndex index = model->index(i, 0);
- for (int j=0; j<model->roleNames().count(); j++) {
- QCOMPARE(model->data(index, j), QVariant());
- }
- }
- QTRY_COMPARE(model->rowCount(), 9);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::get()
-{
- QQmlComponent component(&engine, testFileUrl("get.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
-
- QVERIFY(model != 0);
-
- QVERIFY(QMetaObject::invokeMethod(model, "runPreTest"));
- QCOMPARE(model->property("preTest").toBool(), true);
-
- QTRY_COMPARE(model->rowCount(), 9);
-
- QVERIFY(QMetaObject::invokeMethod(model, "runPostTest"));
- QCOMPARE(model->property("postTest").toBool(), true);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::reload()
-{
- // If no keys are used, the model should be rebuilt from scratch when
- // reload() is called.
-
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
- //reload multiple times to test the xml query aborting
- QMetaObject::invokeMethod(model, "reload");
- QMetaObject::invokeMethod(model, "reload");
- QCoreApplication::processEvents();
- QMetaObject::invokeMethod(model, "reload");
- QMetaObject::invokeMethod(model, "reload");
- QTRY_COMPARE(spyCount.count(), 0);
- QTRY_COMPARE(spyInsert.count(), 1);
- QTRY_COMPARE(spyRemove.count(), 1);
-
- QCOMPARE(spyInsert[0][1].toInt(), 0);
- QCOMPARE(spyInsert[0][2].toInt(), 8);
-
- QCOMPARE(spyRemove[0][1].toInt(), 0);
- QCOMPARE(spyRemove[0][2].toInt(), 8);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::useKeys()
-{
- // If using incremental updates through keys, the model should only
- // insert & remove some of the items, instead of throwing everything
- // away and causing the view to repaint the whole view.
-
- QFETCH(QString, oldXml);
- QFETCH(int, oldCount);
- QFETCH(QString, newXml);
- QFETCH(QQmlXmlModelData, newData);
- QFETCH(QList<QQuickXmlListRange>, insertRanges);
- QFETCH(QList<QQuickXmlListRange>, removeRanges);
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- model->setProperty("xml",oldXml);
- QTRY_COMPARE(model->rowCount(), oldCount);
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
-
- model->setProperty("xml",newXml);
-
- if (oldCount != newData.count()) {
- QTRY_COMPARE(model->rowCount(), newData.count());
- QCOMPARE(spyCount.count(), 1);
- } else {
- QTRY_VERIFY(spyInsert.count() > 0 || spyRemove.count() > 0);
- QCOMPARE(spyCount.count(), 0);
- }
-
- QList<int> roles = model->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- for (int i=0; i<model->rowCount(); i++) {
- QModelIndex index = model->index(i, 0);
- for (int j=0; j<roles.count(); j++)
- QCOMPARE(model->data(index, roles.at(j)), newData[i][j]);
- }
-
- QCOMPARE(spyInsert.count(), insertRanges.count());
- for (int i=0; i<spyInsert.count(); i++) {
- QCOMPARE(spyInsert[i][1].toInt(), insertRanges[i].first);
- QCOMPARE(spyInsert[i][2].toInt(), insertRanges[i].first + insertRanges[i].second - 1);
- }
-
- QCOMPARE(spyRemove.count(), removeRanges.count());
- for (int i=0; i<spyRemove.count(); i++) {
- QCOMPARE(spyRemove[i][1].toInt(), removeRanges[i].first);
- QCOMPARE(spyRemove[i][2].toInt(), removeRanges[i].first + removeRanges[i].second - 1);
- }
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::useKeys_data()
-{
- QTest::addColumn<QString>("oldXml");
- QTest::addColumn<int>("oldCount");
- QTest::addColumn<QString>("newXml");
- QTest::addColumn<QQmlXmlModelData>("newData");
- QTest::addColumn<QList<QQuickXmlListRange> >("insertRanges");
- QTest::addColumn<QList<QQuickXmlListRange> >("removeRanges");
-
- QQmlXmlModelData modelData;
-
- QTest::newRow("append 1")
- << makeItemXmlAndData("name=A,age=25,sport=Football") << 1
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("append multiple")
- << makeItemXmlAndData("name=A,age=25,sport=Football") << 1
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("insert in different spots")
- << makeItemXmlAndData("name=B,age=35,sport=Athletics") << 1
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1) << qMakePair(2,2))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("insert in middle")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=D,age=55,sport=Golf") << 2
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("remove first")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2
- << makeItemXmlAndData("name=B,age=35,sport=Athletics", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1));
-
- QTest::newRow("remove last")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2
- << makeItemXmlAndData("name=A,age=25,sport=Football", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1));
-
- QTest::newRow("remove from multiple spots")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 5
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=C,age=45,sport=Curling", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1) << qMakePair(3,2));
-
- QTest::newRow("remove all")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3
- << makeItemXmlAndData("", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(0, 3));
-
- QTest::newRow("replace item")
- << makeItemXmlAndData("name=A,age=25,sport=Football") << 1
- << makeItemXmlAndData("name=ZZZ,age=25,sport=Football", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1));
-
- QTest::newRow("add and remove simultaneously, in different spots")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf") << 4
- << makeItemXmlAndData("name=B,age=35,sport=Athletics;name=E,age=65,sport=Fencing", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1) << qMakePair(2,2));
-
- QTest::newRow("insert at start, remove at end i.e. rss feed")
- << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 3
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2))
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2));
-
- QTest::newRow("remove at start, insert at end")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3
- << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2));
-
- QTest::newRow("all data has changed")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35") << 2
- << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2));
-}
-
-void tst_qquickxmllistmodel::noKeysValueChanges()
-{
- // The 'key' roles are 'name' and 'age', as defined in roleKeys.qml.
- // If a 'sport' value is changed, the model should not be reloaded,
- // since 'sport' is not marked as a key.
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- QString xml;
-
- xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics");
- model->setProperty("xml",xml);
- QTRY_COMPARE(model->rowCount(), 2);
-
- model->setProperty("xml","");
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
-
- xml = makeItemXmlAndData("name=A,age=25,sport=AussieRules;name=B,age=35,sport=Athletics");
- model->setProperty("xml",xml);
-
- QList<int> roles = model->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- // wait for the new xml data to be set, and verify no signals were emitted
- QTRY_VERIFY(model->data(model->index(0, 0), roles.at(2)).toString() != QLatin1String("Football"));
- QCOMPARE(model->data(model->index(0, 0), roles.at(2)).toString(), QLatin1String("AussieRules"));
-
- QCOMPARE(spyInsert.count(), 0);
- QCOMPARE(spyRemove.count(), 0);
- QCOMPARE(spyCount.count(), 0);
-
- QCOMPARE(model->rowCount(), 2);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::keysChanged()
-{
- // If the key roles change, the next time the data is reloaded, it should
- // delete all its data and build a clean model (i.e. same behaviour as
- // if no keys are set).
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- QString xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics");
- model->setProperty("xml",xml);
- QTRY_COMPARE(model->rowCount(), 2);
-
- model->setProperty("xml","");
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
-
- QVERIFY(QMetaObject::invokeMethod(model, "disableNameKey"));
- model->setProperty("xml",xml);
-
- QTRY_VERIFY(spyInsert.count() > 0 && spyRemove.count() > 0);
-
- QCOMPARE(spyInsert.count(), 1);
- QCOMPARE(spyInsert[0][1].toInt(), 0);
- QCOMPARE(spyInsert[0][2].toInt(), 1);
-
- QCOMPARE(spyRemove.count(), 1);
- QCOMPARE(spyRemove[0][1].toInt(), 0);
- QCOMPARE(spyRemove[0][2].toInt(), 1);
-
- QCOMPARE(spyCount.count(), 0);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::threading()
-{
- QFETCH(int, xmlDataCount);
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
-
- QAbstractItemModel *m1 = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(m1 != 0);
- QAbstractItemModel *m2 = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(m2 != 0);
- QAbstractItemModel *m3 = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(m3 != 0);
-
- for (int dataCount=0; dataCount<xmlDataCount; dataCount++) {
-
- QString data1, data2, data3;
- for (int i=0; i<dataCount; i++) {
- data1 += "name=A" + QString::number(i) + ",age=1" + QString::number(i) + ",sport=Football;";
- data2 += "name=B" + QString::number(i) + ",age=2" + QString::number(i) + ",sport=Athletics;";
- data3 += "name=C" + QString::number(i) + ",age=3" + QString::number(i) + ",sport=Curling;";
- }
-
- //Set the xml data multiple times with randomized order and mixed with multiple event loops
- //to test the xml query reloading/aborting, the result should be stable.
- m1->setProperty("xml",makeItemXmlAndData(data1));
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m1->setProperty("xml",makeItemXmlAndData(data1));
- m2->setProperty("xml",makeItemXmlAndData(data2));
- QCoreApplication::processEvents();
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m1->setProperty("xml",makeItemXmlAndData(data1));
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
-
- QTRY_VERIFY(m1->rowCount() == dataCount && m2->rowCount() == dataCount && m3->rowCount() == dataCount);
-
- for (int i=0; i<dataCount; i++) {
- QModelIndex index = m1->index(i, 0);
- QList<int> roles = m1->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- QCOMPARE(m1->data(index, roles.at(0)).toString(), QLatin1Char('A') + QString::number(i));
- QCOMPARE(m1->data(index, roles.at(1)).toString(), QLatin1Char('1') + QString::number(i));
- QCOMPARE(m1->data(index, roles.at(2)).toString(), QString("Football"));
-
- index = m2->index(i, 0);
- roles = m2->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- QCOMPARE(m2->data(index, roles.at(0)).toString(), QLatin1Char('B') + QString::number(i));
- QCOMPARE(m2->data(index, roles.at(1)).toString(), QLatin1Char('2') + QString::number(i));
- QCOMPARE(m2->data(index, roles.at(2)).toString(), QString("Athletics"));
-
- index = m3->index(i, 0);
- roles = m3->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- QCOMPARE(m3->data(index, roles.at(0)).toString(), QLatin1Char('C') + QString::number(i));
- QCOMPARE(m3->data(index, roles.at(1)).toString(), QLatin1Char('3') + QString::number(i));
- QCOMPARE(m3->data(index, roles.at(2)).toString(), QString("Curling"));
- }
- }
-
- delete m1;
- delete m2;
- delete m3;
-}
-
-void tst_qquickxmllistmodel::threading_data()
-{
- QTest::addColumn<int>("xmlDataCount");
-
- QTest::newRow("1") << 1;
- QTest::newRow("2") << 2;
- QTest::newRow("10") << 10;
-}
-
-void tst_qquickxmllistmodel::propertyChanges()
-{
- QQmlComponent component(&engine, testFileUrl("propertychanges.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QObject *role = model->findChild<QObject*>("role");
- QVERIFY(role);
-
- QSignalSpy nameSpy(role, SIGNAL(nameChanged()));
- QSignalSpy querySpy(role, SIGNAL(queryChanged()));
- QSignalSpy isKeySpy(role, SIGNAL(isKeyChanged()));
-
- role->setProperty("name","size");
- role->setProperty("query","size/string()");
- role->setProperty("isKey",true);
-
- QCOMPARE(role->property("name").toString(), QString("size"));
- QCOMPARE(role->property("query").toString(), QString("size/string()"));
- QVERIFY(role->property("isKey").toBool());
-
- QCOMPARE(nameSpy.count(),1);
- QCOMPARE(querySpy.count(),1);
- QCOMPARE(isKeySpy.count(),1);
-
- role->setProperty("name","size");
- role->setProperty("query","size/string()");
- role->setProperty("isKey",true);
-
- QCOMPARE(nameSpy.count(),1);
- QCOMPARE(querySpy.count(),1);
- QCOMPARE(isKeySpy.count(),1);
-
- QSignalSpy sourceSpy(model, SIGNAL(sourceChanged()));
- QSignalSpy xmlSpy(model, SIGNAL(xmlChanged()));
- QSignalSpy modelQuerySpy(model, SIGNAL(queryChanged()));
- QSignalSpy namespaceDeclarationsSpy(model, SIGNAL(namespaceDeclarationsChanged()));
-
- model->setProperty("source",QUrl(""));
- model->setProperty("xml","<Pets><Pet><name>Polly</name><type>Parrot</type><age>12</age><size>Small</size></Pet></Pets>");
- model->setProperty("query","/Pets");
- model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";");
-
- QCOMPARE(model->property("source").toUrl(), QUrl(""));
- QCOMPARE(model->property("xml").toString(), QString("<Pets><Pet><name>Polly</name><type>Parrot</type><age>12</age><size>Small</size></Pet></Pets>"));
- QCOMPARE(model->property("query").toString(), QString("/Pets"));
- QCOMPARE(model->property("namespaceDeclarations").toString(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";"));
-
- QTRY_COMPARE(model->rowCount(), 1);
-
- QCOMPARE(sourceSpy.count(),1);
- QCOMPARE(xmlSpy.count(),1);
- QCOMPARE(modelQuerySpy.count(),1);
- QCOMPARE(namespaceDeclarationsSpy.count(),1);
-
- model->setProperty("source",QUrl(""));
- model->setProperty("xml","<Pets><Pet><name>Polly</name><type>Parrot</type><age>12</age><size>Small</size></Pet></Pets>");
- model->setProperty("query","/Pets");
- model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";");
-
- QCOMPARE(sourceSpy.count(),1);
- QCOMPARE(xmlSpy.count(),1);
- QCOMPARE(modelQuerySpy.count(),1);
- QCOMPARE(namespaceDeclarationsSpy.count(),1);
-
- QTRY_COMPARE(model->rowCount(), 1);
- delete model;
-}
-
-void tst_qquickxmllistmodel::selectAncestor()
-{
- QQmlComponent component(&engine, testFileUrl("groups.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 1);
-
- QModelIndex index = model->index(0, 0);
- QCOMPARE(model->data(index, Qt::UserRole).toInt(), 12);
- QCOMPARE(model->data(index, Qt::UserRole+1).toString(), QLatin1String("cats"));
-}
-
-void tst_qquickxmllistmodel::roleCrash()
-{
- // don't crash
- QQmlComponent component(&engine, testFileUrl("roleCrash.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- delete model;
-}
-
-class SortFilterProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
- Q_PROPERTY(QObject *source READ source WRITE setSource)
-
-public:
- SortFilterProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) { sort(0); }
- QObject *source() const { return sourceModel(); }
- void setSource(QObject *source) { setSourceModel(qobject_cast<QAbstractItemModel *>(source)); }
-};
-
-void tst_qquickxmllistmodel::proxyCrash()
-{
- qmlRegisterType<SortFilterProxyModel>("SortFilterProxyModel", 1, 0, "SortFilterProxyModel");
-
- // don't crash
- QQmlComponent component(&engine, testFileUrl("proxyCrash.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- delete model;
-}
-
-QTEST_MAIN(tst_qquickxmllistmodel)
-
-#include "tst_qquickxmllistmodel.moc"
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 6fc3bb5b1b..7257a99d2a 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -41,11 +41,7 @@ PRIVATETESTS += \
qquickstyledtext \
qquickstates \
qquicksystempalette \
- qquicktimeline \
- qquickxmllistmodel
-
-# This test requires the xmlpatterns module
-!qtHaveModule(xmlpatterns): PRIVATETESTS -= qquickxmllistmodel
+ qquicktimeline
QUICKTESTS += \
pointerhandlers \