b840ca8ff6b69c6f854a83a18c873c1e7e6493fb
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickvisualdatamodel_p_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQUICKVISUALDATAMODEL_P_P_H
43 #define QQUICKVISUALDATAMODEL_P_P_H
44
45 #include "qquickvisualdatamodel_p.h"
46
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/qdeclarativeincubator.h>
49
50 #include <private/qdeclarativeopenmetaobject_p.h>
51
52 //
53 //  W A R N I N G
54 //  -------------
55 //
56 // This file is not part of the Qt API.  It exists purely as an
57 // implementation detail.  This header file may change from version to
58 // version without notice, or even be removed.
59 //
60 // We mean it.
61 //
62
63 QT_BEGIN_NAMESPACE
64
65 typedef QDeclarativeListCompositor Compositor;
66
67 class QQuickVisualDataModelItemMetaType : public QDeclarativeRefCount
68 {
69 public:
70     QQuickVisualDataModelItemMetaType(QV8Engine *engine, QQuickVisualDataModel *model, const QStringList &groupNames);
71     ~QQuickVisualDataModelItemMetaType();
72
73     int parseGroups(const QStringList &groupNames) const;
74     int parseGroups(const v8::Local<v8::Value> &groupNames) const;
75
76     static void release_index(v8::Persistent<v8::Value> object, void *parameter);
77     static void release_model(v8::Persistent<v8::Value> object, void *parameter);
78
79     static v8::Handle<v8::Value> get_model(v8::Local<v8::String>, const v8::AccessorInfo &info);
80     static v8::Handle<v8::Value> get_groups(v8::Local<v8::String>, const v8::AccessorInfo &info);
81     static void set_groups(
82             v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
83     static v8::Handle<v8::Value> get_member(v8::Local<v8::String>, const v8::AccessorInfo &info);
84     static void set_member(
85             v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
86     static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info);
87
88     QDeclarativeGuard<QQuickVisualDataModel> model;
89     const int groupCount;
90     const int memberPropertyOffset;
91     const int indexPropertyOffset;
92     QV8Engine * const v8Engine;
93     QMetaObject *metaObject;
94     const QStringList groupNames;
95     v8::Persistent<v8::Function> constructor;
96 };
97
98 class QQuickVisualAdaptorModel;
99 class QVDMIncubationTask;
100
101 class QQuickVisualDataModelItem : public QObject, public QV8ObjectResource
102 {
103     Q_OBJECT
104     Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged)
105     Q_PROPERTY(QObject *model READ modelObject CONSTANT)
106     V8_RESOURCE_TYPE(VisualDataItemType)
107 public:
108     QQuickVisualDataModelItem(
109             QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int modelIndex);
110     ~QQuickVisualDataModelItem();
111
112     void referenceObject() { ++objectRef; }
113     bool releaseObject() { return --objectRef == 0 && !(groups & Compositor::PersistedFlag); }
114     bool isObjectReferenced() const { return objectRef != 0 || (groups & Compositor::PersistedFlag); }
115
116     bool isReferenced() const {
117         return scriptRef
118                 || incubationTask
119                 || ((groups & Compositor::UnresolvedFlag) && (groups & Compositor::GroupMask));
120     }
121
122     void Dispose();
123
124     QObject *modelObject() { return this; }
125
126     int modelIndex() const { return index[0]; }
127     void setModelIndex(int idx) { index[0] = idx; emit modelIndexChanged(); }
128
129     virtual v8::Handle<v8::Value> get() { return engine->newQObject(this); }
130
131     virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
132     virtual bool resolveIndex(int) { return false; }
133
134 Q_SIGNALS:
135     void modelIndexChanged();
136
137 public:
138     QQuickVisualDataModelItemMetaType * const metaType;
139     QDeclarativeGuard<QQuickVisualAdaptorModel> model;
140     QDeclarativeGuard<QObject> object;
141     QQuickVisualDataModelAttached *attached;
142     v8::Persistent<v8::Object> indexHandle;
143     v8::Persistent<v8::Value> modelHandle;
144     QIntrusiveListNode cacheNode;
145     int objectRef;
146     int scriptRef;
147     int groups;
148     int index[QDeclarativeListCompositor::MaximumGroupCount];
149     QVDMIncubationTask *incubationTask;
150 };
151
152
153 class QQuickVisualDataModelPrivate;
154 class QVDMIncubationTask : public QDeclarativeIncubator
155 {
156 public:
157     QVDMIncubationTask(QQuickVisualDataModelPrivate *l, IncubationMode mode)
158         : QDeclarativeIncubator(mode)
159         , incubating(0)
160         , incubatingContext(0)
161         , vdm(l) {}
162
163     virtual void statusChanged(Status);
164     virtual void setInitialState(QObject *);
165
166     QQuickVisualDataModelItem *incubating;
167     QDeclarativeContext *incubatingContext;
168
169 private:
170     QQuickVisualDataModelPrivate *vdm;
171 };
172
173
174 class QQuickVisualDataGroupEmitter
175 {
176 public:
177     virtual void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset) = 0;
178     virtual void createdPackage(int, QDeclarativePackage *) {}
179     virtual void initPackage(int, QDeclarativePackage *) {}
180     virtual void destroyingPackage(QDeclarativePackage *) {}
181
182     QIntrusiveListNode emitterNode;
183 };
184
185 typedef QIntrusiveList<QQuickVisualDataGroupEmitter, &QQuickVisualDataGroupEmitter::emitterNode> QQuickVisualDataGroupEmitterList;
186
187 class QQuickVisualDataGroupPrivate : public QObjectPrivate
188 {
189 public:
190     Q_DECLARE_PUBLIC(QQuickVisualDataGroup)
191
192     QQuickVisualDataGroupPrivate() : group(Compositor::Cache), defaultInclude(false) {}
193
194     static QQuickVisualDataGroupPrivate *get(QQuickVisualDataGroup *group) {
195         return static_cast<QQuickVisualDataGroupPrivate *>(QObjectPrivate::get(group)); }
196
197     void setModel(QQuickVisualDataModel *model, Compositor::Group group);
198     void emitChanges(QV8Engine *engine);
199     void emitModelUpdated(bool reset);
200
201     void createdPackage(int index, QDeclarativePackage *package);
202     void initPackage(int index, QDeclarativePackage *package);
203     void destroyingPackage(QDeclarativePackage *package);
204
205     bool parseIndex(const v8::Local<v8::Value> &value, int *index, Compositor::Group *group) const;
206     bool parseGroupArgs(
207             QDeclarativeV8Function *args, Compositor::Group *group, int *index, int *count, int *groups) const;
208
209     Compositor::Group group;
210     QDeclarativeGuard<QQuickVisualDataModel> model;
211     QQuickVisualDataGroupEmitterList emitters;
212     QDeclarativeChangeSet changeSet;
213     QString name;
214     bool defaultInclude;
215 };
216
217 class QQuickVisualDataModelParts;
218
219 class QQuickVisualDataModelPrivate : public QObjectPrivate, public QQuickVisualDataGroupEmitter
220 {
221     Q_DECLARE_PUBLIC(QQuickVisualDataModel)
222 public:
223     QQuickVisualDataModelPrivate(QDeclarativeContext *);
224     ~QQuickVisualDataModelPrivate();
225
226     static QQuickVisualDataModelPrivate *get(QQuickVisualDataModel *m) {
227         return static_cast<QQuickVisualDataModelPrivate *>(QObjectPrivate::get(m));
228     }
229
230     void init();
231     void connectModel(QQuickVisualAdaptorModel *model);
232
233     QObject *object(Compositor::Group group, int index, bool asynchronous, bool reference);
234     void destroy(QObject *object);
235     QQuickVisualDataModel::ReleaseFlags release(QObject *object);
236     QString stringValue(Compositor::Group group, int index, const QString &name);
237     void emitCreatedPackage(QQuickVisualDataModelItem *cacheItem, QDeclarativePackage *package);
238     void emitInitPackage(QQuickVisualDataModelItem *cacheItem, QDeclarativePackage *package);
239     void emitCreatedItem(QQuickVisualDataModelItem *cacheItem, QQuickItem *item) {
240         emit q_func()->createdItem(cacheItem->index[m_compositorGroup], item); }
241     void emitInitItem(QQuickVisualDataModelItem *cacheItem, QQuickItem *item) {
242         emit q_func()->initItem(cacheItem->index[m_compositorGroup], item); }
243     void emitDestroyingPackage(QDeclarativePackage *package);
244     void emitDestroyingItem(QQuickItem *item) { emit q_func()->destroyingItem(item); }
245
246     void updateFilterGroup();
247
248     void addGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
249     void removeGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
250     void setGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
251
252     void itemsInserted(
253             const QVector<Compositor::Insert> &inserts,
254             QVarLengthArray<QVector<QDeclarativeChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts,
255             QHash<int, QList<QQuickVisualDataModelItem *> > *movedItems = 0);
256     void itemsInserted(const QVector<Compositor::Insert> &inserts);
257     void itemsRemoved(
258             const QVector<Compositor::Remove> &removes,
259             QVarLengthArray<QVector<QDeclarativeChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves,
260             QHash<int, QList<QQuickVisualDataModelItem *> > *movedItems = 0);
261     void itemsRemoved(const QVector<Compositor::Remove> &removes);
262     void itemsMoved(
263             const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts);
264     void itemsChanged(const QVector<Compositor::Change> &changes);
265     template <typename T> static v8::Local<v8::Array> buildChangeList(const QVector<T> &changes);
266     void emitChanges();
267     void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
268
269     bool insert(Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups);
270
271     static void group_append(QDeclarativeListProperty<QQuickVisualDataGroup> *property, QQuickVisualDataGroup *group);
272     static int group_count(QDeclarativeListProperty<QQuickVisualDataGroup> *property);
273     static QQuickVisualDataGroup *group_at(QDeclarativeListProperty<QQuickVisualDataGroup> *property, int index);
274
275     void releaseIncubator(QVDMIncubationTask *incubationTask);
276     void incubatorStatusChanged(QVDMIncubationTask *incubationTask, QDeclarativeIncubator::Status status);
277     void setInitialState(QVDMIncubationTask *incubationTask, QObject *o);
278
279     QQuickVisualAdaptorModel *m_adaptorModel;
280     QDeclarativeComponent *m_delegate;
281     QQuickVisualDataModelItemMetaType *m_cacheMetaType;
282     QDeclarativeGuard<QDeclarativeContext> m_context;
283
284     QList<QQuickVisualDataModelItem *> m_cache;
285     QQuickVisualDataModelParts *m_parts;
286     QQuickVisualDataGroupEmitterList m_pendingParts;
287
288     QDeclarativeListCompositor m_compositor;
289     QDeclarativeListCompositor::Group m_compositorGroup;
290     bool m_complete : 1;
291     bool m_delegateValidated : 1;
292     bool m_reset : 1;
293     bool m_transaction : 1;
294     bool m_incubatorCleanupScheduled : 1;
295
296     QString m_filterGroup;
297     QList<QByteArray> watchedRoles;
298
299     union {
300         struct {
301             QQuickVisualDataGroup *m_cacheItems;
302             QQuickVisualDataGroup *m_items;
303             QQuickVisualDataGroup *m_persistedItems;
304         };
305         QQuickVisualDataGroup *m_groups[Compositor::MaximumGroupCount];
306     };
307     int m_groupCount;
308
309     QList<QVDMIncubationTask *> m_finishedIncubating;
310 };
311
312 class QQuickVisualPartsModel : public QQuickVisualModel, public QQuickVisualDataGroupEmitter
313 {
314     Q_OBJECT
315     Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
316 public:
317     QQuickVisualPartsModel(QQuickVisualDataModel *model, const QString &part, QObject *parent = 0);
318     ~QQuickVisualPartsModel();
319
320     QString filterGroup() const;
321     void setFilterGroup(const QString &group);
322     void resetFilterGroup();
323     void updateFilterGroup();
324     void updateFilterGroup(Compositor::Group group, const QDeclarativeChangeSet &changeSet);
325
326     int count() const;
327     bool isValid() const;
328     QQuickItem *item(int index, bool asynchronous=false);
329     ReleaseFlags release(QQuickItem *item);
330     QString stringValue(int index, const QString &role);
331     void setWatchedRoles(QList<QByteArray> roles);
332
333     int indexOf(QQuickItem *item, QObject *objectContext) const;
334
335     void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
336
337     void createdPackage(int index, QDeclarativePackage *package);
338     void initPackage(int index, QDeclarativePackage *package);
339     void destroyingPackage(QDeclarativePackage *package);
340
341 Q_SIGNALS:
342     void filterGroupChanged();
343
344 private:
345     QQuickVisualDataModel *m_model;
346     QHash<QObject *, QDeclarativePackage *> m_packaged;
347     QString m_part;
348     QString m_filterGroup;
349     QList<QByteArray> m_watchedRoles;
350     Compositor::Group m_compositorGroup;
351     bool m_inheritGroup;
352 };
353
354 class QMetaPropertyBuilder;
355
356 class QQuickVisualDataModelPartsMetaObject : public QDeclarativeOpenMetaObject
357 {
358 public:
359     QQuickVisualDataModelPartsMetaObject(QObject *parent)
360     : QDeclarativeOpenMetaObject(parent) {}
361
362     virtual void propertyCreated(int, QMetaPropertyBuilder &);
363     virtual QVariant initialValue(int);
364 };
365
366 class QQuickVisualDataModelParts : public QObject
367 {
368 Q_OBJECT
369 public:
370     QQuickVisualDataModelParts(QQuickVisualDataModel *parent);
371
372     QQuickVisualDataModel *model;
373     QList<QQuickVisualPartsModel *> models;
374 };
375
376 class QQuickVisualDataModelAttachedMetaObject : public QAbstractDynamicMetaObject
377 {
378 public:
379     QQuickVisualDataModelAttachedMetaObject(
380             QQuickVisualDataModelAttached *attached, QQuickVisualDataModelItemMetaType *metaType);
381     ~QQuickVisualDataModelAttachedMetaObject();
382
383     int metaCall(QMetaObject::Call, int _id, void **);
384
385 private:
386     QQuickVisualDataModelAttached *attached;
387     QQuickVisualDataModelItemMetaType *metaType;
388 };
389
390 class QQuickVisualDataModelContext : public QDeclarativeContext
391 {
392     Q_OBJECT
393 public:
394     QQuickVisualDataModelContext(
395             QQuickVisualDataModelItem *cacheItem,
396             QDeclarativeContext *parentContext,
397             QObject *parent = 0)
398         : QDeclarativeContext(parentContext, parent)
399         , cacheItem(cacheItem)
400     {
401         ++cacheItem->scriptRef;
402     }
403
404     ~QQuickVisualDataModelContext()
405     {
406         cacheItem->Dispose();
407     }
408
409     QQuickVisualDataModelItem *cacheItem;
410 };
411
412 QT_END_NAMESPACE
413
414 #endif