1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQMLLISTMODEL_H
41#define QQMLLISTMODEL_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <private/qtqmlmodelsglobal_p.h>
55#include <private/qqmlcustomparser_p.h>
56
57#include <QtCore/QObject>
58#include <QtCore/QStringList>
59#include <QtCore/QHash>
60#include <QtCore/QList>
61#include <QtCore/QVariant>
62#include <QtCore/qabstractitemmodel.h>
63
64#include <private/qv4engine_p.h>
65#include <private/qpodvector_p.h>
66
67QT_REQUIRE_CONFIG(qml_list_model);
68
69QT_BEGIN_NAMESPACE
70
71
72class QQmlListModelWorkerAgent;
73class ListModel;
74class ListLayout;
75
76namespace QV4 {
77struct ModelObject;
78}
79
80class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel
81{
82 Q_OBJECT
83 Q_PROPERTY(int count READ count NOTIFY countChanged)
84 Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles)
85 Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(14))
86 QML_NAMED_ELEMENT(ListModel)
87 QML_ADDED_IN_MINOR_VERSION(1)
88
89public:
90 QQmlListModel(QObject *parent=nullptr);
91 ~QQmlListModel();
92
93 QModelIndex index(int row, int column, const QModelIndex &parent) const override;
94 int rowCount(const QModelIndex &parent) const override;
95 QVariant data(const QModelIndex &index, int role) const override;
96 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
97 QHash<int,QByteArray> roleNames() const override;
98
99 QVariant data(int index, int role) const;
100 int count() const;
101
102 Q_INVOKABLE void clear();
103 Q_INVOKABLE void remove(QQmlV4Function *args);
104 Q_INVOKABLE void append(QQmlV4Function *args);
105 Q_INVOKABLE void insert(QQmlV4Function *args);
106 Q_INVOKABLE QJSValue get(int index) const;
107 Q_INVOKABLE void set(int index, const QJSValue &value);
108 Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value);
109 Q_INVOKABLE void move(int from, int to, int count);
110 Q_INVOKABLE void sync();
111
112 QQmlListModelWorkerAgent *agent();
113
114 bool dynamicRoles() const { return m_dynamicRoles; }
115 void setDynamicRoles(bool enableDynamicRoles);
116
117Q_SIGNALS:
118 void countChanged();
119
120private:
121 friend class QQmlListModelParser;
122 friend class QQmlListModelWorkerAgent;
123 friend class ModelObject;
124 friend struct QV4::ModelObject;
125 friend class ModelNodeMetaObject;
126 friend class ListModel;
127 friend class ListElement;
128 friend class DynamicRoleModelNode;
129 friend class DynamicRoleModelNodeMetaObject;
130 friend struct StringOrTranslation;
131
132 // Constructs a flat list model for a worker agent
133 QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agent);
134 QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::ExecutionEngine *engine, QObject *parent=nullptr);
135
136 QV4::ExecutionEngine *engine() const;
137
138 inline bool canMove(int from, int to, int n) const { return !(from+n > count() || to+n > count() || from < 0 || to < 0 || n < 0); }
139
140 mutable QQmlListModelWorkerAgent *m_agent;
141 mutable QV4::ExecutionEngine *m_engine;
142 QQmlRefPointer<QV4::ExecutableCompilationUnit> m_compilationUnit;
143 bool m_mainThread;
144 bool m_primary;
145
146 bool m_dynamicRoles;
147
148 ListLayout *m_layout;
149 ListModel *m_listModel;
150
151 QVector<class DynamicRoleModelNode *> m_modelObjects;
152 QVector<QString> m_roles;
153
154 struct ElementSync
155 {
156 DynamicRoleModelNode *src = nullptr;
157 DynamicRoleModelNode *target = nullptr;
158 int srcIndex = -1;
159 int targetIndex = -1;
160 QVector<int> changedRoles;
161 };
162
163 static bool sync(QQmlListModel *src, QQmlListModel *target);
164 static QQmlListModel *createWithOwner(QQmlListModel *newOwner);
165
166 void emitItemsChanged(int index, int count, const QVector<int> &roles);
167 void emitItemsAboutToBeInserted(int index, int count);
168 void emitItemsInserted();
169
170 void removeElements(int index, int removeCount);
171};
172
173// ### FIXME
174class QQmlListElement : public QObject
175{
176 Q_OBJECT
177 QML_NAMED_ELEMENT(ListElement)
178 QML_ADDED_IN_MINOR_VERSION(1)
179};
180
181class QQmlListModelParser : public QQmlCustomParser
182{
183public:
184 enum PropertyType {
185 Invalid,
186 Boolean,
187 Number,
188 String,
189 Script
190 };
191
192
193 QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
194
195 void verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
196 void applyBindings(QObject *obj, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
197
198private:
199 bool verifyProperty(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding);
200 // returns true if a role was set
201 bool applyProperty(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex);
202
203 static bool definesEmptyList(const QString &);
204
205 QString listElementTypeName;
206};
207
208template<>
209inline QQmlCustomParser *qmlCreateCustomParser<QQmlListModel>()
210{
211 return new QQmlListModelParser;
212}
213
214QT_END_NAMESPACE
215
216QML_DECLARE_TYPE(QQmlListModel)
217QML_DECLARE_TYPE(QQmlListElement)
218
219#endif // QQMLLISTMODEL_H
220

source code of qtdeclarative/src/qmlmodels/qqmllistmodel_p.h