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 67 QT_REQUIRE_CONFIG(qml_list_model); 68 69 QT_BEGIN_NAMESPACE 70 71 72 class QQmlListModelWorkerAgent; 73 class ListModel; 74 class ListLayout; 75 76 namespace QV4 { 77 struct ModelObject; 78 } 79 80 class 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 89 public: 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 dynamicRoles()114 bool dynamicRoles() const { return m_dynamicRoles; } 115 void setDynamicRoles(bool enableDynamicRoles); 116 117 Q_SIGNALS: 118 void countChanged(); 119 120 private: 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 canMove(int from,int to,int n)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 174 class QQmlListElement : public QObject 175 { 176 Q_OBJECT 177 QML_NAMED_ELEMENT(ListElement) 178 QML_ADDED_IN_MINOR_VERSION(1) 179 }; 180 181 class QQmlListModelParser : public QQmlCustomParser 182 { 183 public: 184 enum PropertyType { 185 Invalid, 186 Boolean, 187 Number, 188 String, 189 Script 190 }; 191 192 QQmlListModelParser()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 198 private: 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 208 template<> 209 inline QQmlCustomParser *qmlCreateCustomParser<QQmlListModel>() 210 { 211 return new QQmlListModelParser; 212 } 213 214 QT_END_NAMESPACE 215 216 QML_DECLARE_TYPE(QQmlListModel) 217 QML_DECLARE_TYPE(QQmlListElement) 218 219 #endif // QQMLLISTMODEL_H 220