1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLXMLLISTMODEL_H
5#define QQMLXMLLISTMODEL_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qflatmap_p.h>
19#include <private/qtqmlxmllistmodelglobal_p.h>
20
21#include <QtQml/qqmllist.h>
22#include <QtQml/qqmlparserstatus.h>
23
24#include <QtQmlIntegration/qqmlintegration.h>
25
26#include <QtCore/qabstractitemmodel.h>
27#include <QtCore/qbytearray.h>
28#include <QtCore/qfuture.h>
29#include <QtCore/qhash.h>
30#include <QtCore/qstringlist.h>
31#include <QtCore/qurl.h>
32
33QT_BEGIN_NAMESPACE
34
35#if QT_CONFIG(qml_network)
36class QNetworkReply;
37#endif
38
39class QXmlStreamReader;
40class QQmlContext;
41struct QQmlXmlListModelQueryJob
42{
43 int queryId;
44 QByteArray data;
45 QString query;
46 QStringList roleNames;
47 QStringList elementNames;
48 QStringList elementAttributes;
49 QList<void *> roleQueryErrorId;
50};
51struct QQmlXmlListModelQueryResult
52{
53 QML_ANONYMOUS
54 int queryId;
55 QList<QFlatMap<int, QString>> data;
56 QList<QPair<void *, QString>> errors;
57};
58
59class Q_QMLXMLLISTMODEL_PRIVATE_EXPORT QQmlXmlListModelRole : public QObject
60{
61 Q_OBJECT
62 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
63 Q_PROPERTY(QString elementName READ elementName WRITE setElementName NOTIFY elementNameChanged)
64 Q_PROPERTY(QString attributeName READ attributeName WRITE setAttributeName NOTIFY
65 attributeNameChanged)
66 QML_NAMED_ELEMENT(XmlListModelRole)
67
68public:
69 QQmlXmlListModelRole() = default;
70 ~QQmlXmlListModelRole() = default;
71
72 QString name() const;
73 void setName(const QString &name);
74 QString elementName() const;
75 void setElementName(const QString &name);
76 QString attributeName() const;
77 void setAttributeName(const QString &attributeName);
78 bool isValid() const;
79
80Q_SIGNALS:
81 void nameChanged();
82 void elementNameChanged();
83 void attributeNameChanged();
84
85private:
86 QString m_name;
87 QString m_elementName;
88 QString m_attributeName;
89};
90
91class QQmlXmlListModelQueryExecutor;
92
93class Q_QMLXMLLISTMODEL_PRIVATE_EXPORT QQmlXmlListModel : public QAbstractListModel,
94 public QQmlParserStatus
95{
96 Q_OBJECT
97 Q_INTERFACES(QQmlParserStatus)
98
99 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
100 Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
101 Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
102 Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
103 Q_PROPERTY(QQmlListProperty<QQmlXmlListModelRole> roles READ roleObjects)
104 Q_PROPERTY(int count READ count NOTIFY countChanged)
105 QML_NAMED_ELEMENT(XmlListModel)
106 Q_CLASSINFO("DefaultProperty", "roles")
107
108public:
109 QQmlXmlListModel(QObject *parent = nullptr);
110 ~QQmlXmlListModel();
111
112 QModelIndex index(int row, int column, const QModelIndex &parent) const override;
113 int rowCount(const QModelIndex &parent) const override;
114 QVariant data(const QModelIndex &index, int role) const override;
115 QHash<int, QByteArray> roleNames() const override;
116
117 int count() const;
118
119 QUrl source() const;
120 void setSource(const QUrl &);
121
122 QString query() const;
123 void setQuery(const QString &);
124
125 QQmlListProperty<QQmlXmlListModelRole> roleObjects();
126
127 void appendRole(QQmlXmlListModelRole *);
128 void clearRole();
129
130 enum Status { Null, Ready, Loading, Error };
131 Q_ENUM(Status)
132 Status status() const;
133 qreal progress() const;
134
135 Q_INVOKABLE QString errorString() const;
136
137 void classBegin() override;
138 void componentComplete() override;
139
140Q_SIGNALS:
141 void statusChanged(QQmlXmlListModel::Status);
142 void progressChanged(qreal progress);
143 void countChanged();
144 void sourceChanged();
145 void queryChanged();
146
147public Q_SLOTS:
148 void reload();
149
150private Q_SLOTS:
151#if QT_CONFIG(qml_network)
152 void requestFinished();
153#endif
154 void requestProgress(qint64, qint64);
155 void dataCleared();
156 void queryCompleted(const QQmlXmlListModelQueryResult &);
157 void queryError(void *object, const QString &error);
158
159private:
160 Q_DISABLE_COPY(QQmlXmlListModel)
161
162 void notifyQueryStarted(bool remoteSource);
163
164 static void appendRole(QQmlListProperty<QQmlXmlListModelRole> *, QQmlXmlListModelRole *);
165 static void clearRole(QQmlListProperty<QQmlXmlListModelRole> *);
166
167 void tryExecuteQuery(const QByteArray &data);
168
169 QQmlXmlListModelQueryJob createJob(const QByteArray &data);
170 int nextQueryId();
171
172#if QT_CONFIG(qml_network)
173 void deleteReply();
174
175 QNetworkReply *m_reply = nullptr;
176#endif
177
178 int m_size = 0;
179 QUrl m_source;
180 QString m_query;
181 QStringList m_roleNames;
182 QList<int> m_roles;
183 QList<QQmlXmlListModelRole *> m_roleObjects;
184 QList<QFlatMap<int, QString>> m_data;
185 bool m_isComponentComplete = true;
186 Status m_status = QQmlXmlListModel::Null;
187 QString m_errorString;
188 qreal m_progress = 0;
189 int m_queryId = -1;
190 int m_nextQueryIdGenerator = -1;
191 int m_redirectCount = 0;
192 int m_highestRole = Qt::UserRole;
193 using ResultFutureWatcher = QFutureWatcher<QQmlXmlListModelQueryResult>;
194 QFlatMap<int, ResultFutureWatcher *> m_watchers;
195};
196
197class QQmlXmlListModelQueryRunnable : public QRunnable
198{
199public:
200 explicit QQmlXmlListModelQueryRunnable(QQmlXmlListModelQueryJob &&job);
201 void run() override;
202
203 QFuture<QQmlXmlListModelQueryResult> future() const;
204
205private:
206 void doQueryJob(QQmlXmlListModelQueryResult *currentResult);
207 void processElement(QQmlXmlListModelQueryResult *currentResult, const QString &element,
208 QXmlStreamReader &reader);
209 void readSubTree(const QString &prefix, QXmlStreamReader &reader,
210 QFlatMap<int, QString> &results, QList<QPair<void *, QString>> *errors);
211
212 QQmlXmlListModelQueryJob m_job;
213 QPromise<QQmlXmlListModelQueryResult> m_promise;
214};
215
216QT_END_NAMESPACE
217
218#endif // QQMLXMLLISTMODEL_H
219

source code of qtdeclarative/src/qmlxmllistmodel/qqmlxmllistmodel_p.h