1// Copyright (C) 2016 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 QQMLLISTMODEL_H
5#define QQMLLISTMODEL_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/qtqmlmodelsglobal_p.h>
19#include <private/qqmlcustomparser_p.h>
20
21#include <QtCore/QObject>
22#include <QtCore/QStringList>
23#include <QtCore/QHash>
24#include <QtCore/QList>
25#include <QtCore/QVariant>
26#include <QtCore/qabstractitemmodel.h>
27
28#include <private/qv4engine_p.h>
29#include <private/qpodvector_p.h>
30
31QT_REQUIRE_CONFIG(qml_list_model);
32
33QT_BEGIN_NAMESPACE
34
35
36class QQmlListModelWorkerAgent;
37class ListModel;
38class ListLayout;
39
40namespace QV4 {
41struct ModelObject;
42}
43
44class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel
45{
46 Q_OBJECT
47 Q_PROPERTY(int count READ count NOTIFY countChanged FINAL)
48 Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles FINAL)
49 Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(2, 14) FINAL)
50 QML_NAMED_ELEMENT(ListModel)
51 QML_ADDED_IN_VERSION(2, 0)
52 QML_CUSTOMPARSER
53
54public:
55 QQmlListModel(QObject *parent=nullptr);
56 ~QQmlListModel();
57
58 QModelIndex index(int row, int column, const QModelIndex &parent) const override;
59 int rowCount(const QModelIndex &parent) const override;
60 QVariant data(const QModelIndex &index, int role) const override;
61 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
62 QHash<int,QByteArray> roleNames() const override;
63
64 QVariant data(int index, int role) const;
65 int count() const;
66
67 Q_INVOKABLE void clear();
68 Q_INVOKABLE void remove(QQmlV4Function *args);
69 Q_INVOKABLE void append(QQmlV4Function *args);
70 Q_INVOKABLE void insert(QQmlV4Function *args);
71 Q_INVOKABLE QJSValue get(int index) const;
72 Q_INVOKABLE void set(int index, const QJSValue &value);
73 Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value);
74 Q_INVOKABLE void move(int from, int to, int count);
75 Q_INVOKABLE void sync();
76
77 QQmlListModelWorkerAgent *agent();
78
79 bool dynamicRoles() const { return m_dynamicRoles; }
80 void setDynamicRoles(bool enableDynamicRoles);
81
82Q_SIGNALS:
83 void countChanged();
84
85private:
86 friend class QQmlListModelParser;
87 friend class QQmlListModelWorkerAgent;
88 friend class ModelObject;
89 friend struct QV4::ModelObject;
90 friend class ModelNodeMetaObject;
91 friend class ListModel;
92 friend class ListElement;
93 friend class DynamicRoleModelNode;
94 friend class DynamicRoleModelNodeMetaObject;
95 friend struct StringOrTranslation;
96
97 // Constructs a flat list model for a worker agent
98 QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agent);
99 QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::ExecutionEngine *engine, QObject *parent=nullptr);
100
101 QV4::ExecutionEngine *engine() const;
102
103 inline bool canMove(int from, int to, int n) const { return !(from+n > count() || to+n > count() || from < 0 || to < 0 || n < 0); }
104
105 mutable QQmlListModelWorkerAgent *m_agent;
106 mutable QV4::ExecutionEngine *m_engine;
107 QQmlRefPointer<QV4::ExecutableCompilationUnit> m_compilationUnit;
108 bool m_mainThread;
109 bool m_primary;
110
111 bool m_dynamicRoles;
112
113 ListLayout *m_layout;
114 ListModel *m_listModel;
115 std::unique_ptr<QPropertyNotifier> translationChangeHandler;
116
117 QVector<class DynamicRoleModelNode *> m_modelObjects;
118 QVector<QString> m_roles;
119
120 struct ElementSync
121 {
122 DynamicRoleModelNode *src = nullptr;
123 DynamicRoleModelNode *target = nullptr;
124 int srcIndex = -1;
125 int targetIndex = -1;
126 QVector<int> changedRoles;
127 };
128
129 static bool sync(QQmlListModel *src, QQmlListModel *target);
130 static QQmlListModel *createWithOwner(QQmlListModel *newOwner);
131
132 void emitItemsChanged(int index, int count, const QVector<int> &roles);
133 void emitItemsAboutToBeInserted(int index, int count);
134 void emitItemsInserted();
135
136 void removeElements(int index, int removeCount);
137
138 void updateTranslations();
139};
140
141// ### FIXME
142class QQmlListElement : public QObject
143{
144 Q_OBJECT
145 QML_NAMED_ELEMENT(ListElement)
146 QML_ADDED_IN_VERSION(2, 0)
147};
148
149class QQmlListModelParser : public QQmlCustomParser
150{
151public:
152 enum PropertyType {
153 Invalid,
154 Boolean,
155 Number,
156 String,
157 Script
158 };
159
160
161 QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
162
163 void verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
164 void applyBindings(QObject *obj, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
165
166private:
167 bool verifyProperty(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding);
168 // returns true if a role was set
169 bool applyProperty(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex);
170
171 static bool definesEmptyList(const QString &);
172
173 QString listElementTypeName;
174};
175
176template<>
177inline QQmlCustomParser *qmlCreateCustomParser<QQmlListModel>()
178{
179 return new QQmlListModelParser;
180}
181
182QT_END_NAMESPACE
183
184QML_DECLARE_TYPE(QQmlListModel)
185QML_DECLARE_TYPE(QQmlListElement)
186
187#endif // QQMLLISTMODEL_H
188

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