Add missing QT_{BEGIN,END}_NAMESPACE
[profile/ivi/qtdeclarative.git] / src / qml / qml / qquicklistmodel_p_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQUICKLISTMODEL_P_P_H
43 #define QQUICKLISTMODEL_P_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qquicklistmodel_p.h"
57 #include <private/qqmlengine_p.h>
58 #include "qqmlopenmetaobject_p.h"
59 #include <qqml.h>
60
61 QT_BEGIN_HEADER
62
63 QT_BEGIN_NAMESPACE
64
65
66 class DynamicRoleModelNode;
67
68 class DynamicRoleModelNodeMetaObject : public QQmlOpenMetaObject
69 {
70 public:
71     DynamicRoleModelNodeMetaObject(DynamicRoleModelNode *object);
72     ~DynamicRoleModelNodeMetaObject();
73
74     bool m_enabled;
75
76 protected:
77     void propertyWrite(int index);
78     void propertyWritten(int index);
79
80 private:
81     DynamicRoleModelNode *m_owner;
82 };
83
84 class DynamicRoleModelNode : public QObject
85 {
86     Q_OBJECT
87 public:
88     DynamicRoleModelNode(QQuickListModel *owner, int uid);
89
90     static DynamicRoleModelNode *create(const QVariantMap &obj, QQuickListModel *owner);
91
92     void updateValues(const QVariantMap &object, QVector<int> &roles);
93
94     QVariant getValue(const QString &name)
95     {
96         return m_meta->value(name.toUtf8());
97     }
98
99     bool setValue(const QByteArray &name, const QVariant &val)
100     {
101         return m_meta->setValue(name, val);
102     }
103
104     void setNodeUpdatesEnabled(bool enable)
105     {
106         m_meta->m_enabled = enable;
107     }
108
109     int getUid() const
110     {
111         return m_uid;
112     }
113
114     static void sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQuickListModel *> *targetModelHash);
115
116 private:
117     QQuickListModel *m_owner;
118     int m_uid;
119     DynamicRoleModelNodeMetaObject *m_meta;
120
121     friend class DynamicRoleModelNodeMetaObject;
122 };
123
124 class ModelObject;
125
126 class ModelNodeMetaObject : public QQmlOpenMetaObject
127 {
128 public:
129     ModelNodeMetaObject(ModelObject *object);
130     ~ModelNodeMetaObject();
131
132     bool m_enabled;
133
134 protected:
135     void propertyWritten(int index);
136
137 private:
138
139     ModelObject *m_obj;
140 };
141
142 class ModelObject : public QObject
143 {
144     Q_OBJECT
145 public:
146     ModelObject(QQuickListModel *model, int elementIndex);
147
148     void setValue(const QByteArray &name, const QVariant &val, bool force)
149     {
150         if (force) {
151             QVariant existingValue = m_meta->value(name);
152             if (existingValue.isValid()) {
153                 (*m_meta)[name] = QVariant();
154             }
155         }
156         m_meta->setValue(name, val);
157     }
158
159     void setNodeUpdatesEnabled(bool enable)
160     {
161         m_meta->m_enabled = enable;
162     }
163
164     void updateValues();
165     void updateValues(const QVector<int> &roles);
166
167     QQuickListModel *m_model;
168     int m_elementIndex;
169
170 private:
171     ModelNodeMetaObject *m_meta;
172 };
173
174 class ListLayout
175 {
176 public:
177     ListLayout() : currentBlock(0), currentBlockOffset(0) {}
178     ListLayout(const ListLayout *other);
179     ~ListLayout();
180
181     class Role
182     {
183     public:
184
185         Role() : type(Invalid), blockIndex(-1), blockOffset(-1), index(-1), subLayout(0) {}
186         explicit Role(const Role *other);
187         ~Role();
188
189         // This enum must be kept in sync with the roleTypeNames variable in qdeclarativelistmodel.cpp
190         enum DataType
191         {
192             Invalid = -1,
193
194             String,
195             Number,
196             Bool,
197             List,
198             QObject,
199             VariantMap,
200             DateTime,
201
202             MaxDataType
203         };
204
205         QString name;
206         DataType type;
207         int blockIndex;
208         int blockOffset;
209         int index;
210         ListLayout *subLayout;
211     };
212
213     const Role *getRoleOrCreate(const QString &key, const QVariant &data);
214     const Role &getRoleOrCreate(v8::Handle<v8::String> key, Role::DataType type);
215     const Role &getRoleOrCreate(const QString &key, Role::DataType type);
216
217     const Role &getExistingRole(int index) { return *roles.at(index); }
218     const Role *getExistingRole(const QString &key);
219     const Role *getExistingRole(v8::Handle<v8::String> key);
220
221     int roleCount() const { return roles.count(); }
222
223     static void sync(ListLayout *src, ListLayout *target);
224
225 private:
226     const Role &createRole(const QString &key, Role::DataType type);
227
228     int currentBlock;
229     int currentBlockOffset;
230     QVector<Role *> roles;
231     QStringHash<Role *> roleHash;
232 };
233
234 class ListElement
235 {
236 public:
237
238     ListElement();
239     ListElement(int existingUid);
240     ~ListElement();
241
242     static void sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout, QHash<int, ListModel *> *targetModelHash);
243
244     enum
245     {
246         BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelObject *)
247     };
248
249 private:
250
251     void destroy(ListLayout *layout);
252
253     int setVariantProperty(const ListLayout::Role &role, const QVariant &d);
254
255     int setJsProperty(const ListLayout::Role &role, v8::Handle<v8::Value> d, QV8Engine *eng);
256
257     int setStringProperty(const ListLayout::Role &role, const QString &s);
258     int setDoubleProperty(const ListLayout::Role &role, double n);
259     int setBoolProperty(const ListLayout::Role &role, bool b);
260     int setListProperty(const ListLayout::Role &role, ListModel *m);
261     int setQObjectProperty(const ListLayout::Role &role, QObject *o);
262     int setVariantMapProperty(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng);
263     int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m);
264     int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt);
265
266     void setStringPropertyFast(const ListLayout::Role &role, const QString &s);
267     void setDoublePropertyFast(const ListLayout::Role &role, double n);
268     void setBoolPropertyFast(const ListLayout::Role &role, bool b);
269     void setQObjectPropertyFast(const ListLayout::Role &role, QObject *o);
270     void setListPropertyFast(const ListLayout::Role &role, ListModel *m);
271     void setVariantMapFast(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng);
272     void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt);
273
274     void clearProperty(const ListLayout::Role &role);
275
276     QVariant getProperty(const ListLayout::Role &role, const QQuickListModel *owner, QV8Engine *eng);
277     ListModel *getListProperty(const ListLayout::Role &role);
278     QString *getStringProperty(const ListLayout::Role &role);
279     QObject *getQObjectProperty(const ListLayout::Role &role);
280     QQmlGuard<QObject> *getGuardProperty(const ListLayout::Role &role);
281     QVariantMap *getVariantMapProperty(const ListLayout::Role &role);
282     QDateTime *getDateTimeProperty(const ListLayout::Role &role);
283
284     inline char *getPropertyMemory(const ListLayout::Role &role);
285
286     int getUid() const { return uid; }
287
288     char data[BLOCK_SIZE];
289     ListElement *next;
290
291     int uid;
292     ModelObject *m_objectCache;
293
294     friend class ListModel;
295 };
296
297 class ListModel
298 {
299 public:
300
301     ListModel(ListLayout *layout, QQuickListModel *modelCache, int uid);
302     ~ListModel() {}
303
304     void destroy();
305
306     int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data);
307     int setExistingProperty(int uid, const QString &key, v8::Handle<v8::Value> data, QV8Engine *eng);
308
309     QVariant getProperty(int elementIndex, int roleIndex, const QQuickListModel *owner, QV8Engine *eng);
310     ListModel *getListProperty(int elementIndex, const ListLayout::Role &role);
311
312     int roleCount() const
313     {
314         return m_layout->roleCount();
315     }
316
317     const ListLayout::Role &getExistingRole(int index)
318     {
319         return m_layout->getExistingRole(index);
320     }
321
322     const ListLayout::Role &getOrCreateListRole(const QString &name)
323     {
324         return m_layout->getRoleOrCreate(name, ListLayout::Role::List);
325     }
326
327     int elementCount() const
328     {
329         return elements.count();
330     }
331
332     void set(int elementIndex, v8::Handle<v8::Object> object, QVector<int> *roles, QV8Engine *eng);
333     void set(int elementIndex, v8::Handle<v8::Object> object, QV8Engine *eng);
334
335     int append(v8::Handle<v8::Object> object, QV8Engine *eng);
336     void insert(int elementIndex, v8::Handle<v8::Object> object, QV8Engine *eng);
337
338     void clear();
339     void remove(int index, int count);
340
341     int appendElement();
342     void insertElement(int index);
343
344     void move(int from, int to, int n);
345
346     int getUid() const { return m_uid; }
347
348     static void sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *srcModelHash);
349
350     ModelObject *getOrCreateModelObject(QQuickListModel *model, int elementIndex);
351
352 private:
353     QPODVector<ListElement *, 4> elements;
354     ListLayout *m_layout;
355     int m_uid;
356
357     QQuickListModel *m_modelCache;
358
359     struct ElementSync
360     {
361         ElementSync() : src(0), target(0) {}
362
363         ListElement *src;
364         ListElement *target;
365     };
366
367     void newElement(int index);
368
369     void updateCacheIndices();
370
371     friend class ListElement;
372     friend class QQuickListModelWorkerAgent;
373 };
374
375 QT_END_NAMESPACE
376
377 Q_DECLARE_METATYPE(ListModel *);
378
379 QT_END_HEADER
380
381 #endif // QQUICKLISTMODEL_P_P_H
382