Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtdeclarative
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativecontext_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
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 QDECLARATIVECONTEXT_P_H
43 #define QDECLARATIVECONTEXT_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 "qdeclarativecontext.h"
57
58 #include "private/qdeclarativedata_p.h"
59 #include "private/qdeclarativeintegercache_p.h"
60 #include "private/qdeclarativetypenamecache_p.h"
61 #include "private/qdeclarativenotifier_p.h"
62 #include "qdeclarativelist.h"
63 #include "private/qdeclarativeparser_p.h"
64
65 #include <QtCore/qhash.h>
66 #include <QtScript/qscriptvalue.h>
67 #include <QtCore/qset.h>
68
69 #include <private/qobject_p.h>
70 #include "private/qdeclarativeguard_p.h"
71
72 QT_BEGIN_NAMESPACE
73
74 class QDeclarativeContext;
75 class QDeclarativeExpression;
76 class QDeclarativeEngine;
77 class QDeclarativeExpression;
78 class QDeclarativeExpressionPrivate;
79 class QDeclarativeAbstractExpression;
80 class QDeclarativeV4Bindings;
81 class QDeclarativeContextData;
82
83 class QDeclarativeContextPrivate : public QObjectPrivate
84 {
85     Q_DECLARE_PUBLIC(QDeclarativeContext)
86 public:
87     QDeclarativeContextPrivate();
88
89     QDeclarativeContextData *data;
90
91     QList<QVariant> propertyValues;
92     int notifyIndex;
93
94     static QDeclarativeContextPrivate *get(QDeclarativeContext *context) {
95         return static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context));
96     }
97     static QDeclarativeContext *get(QDeclarativeContextPrivate *context) {
98         return static_cast<QDeclarativeContext *>(context->q_func());
99     }
100
101     // Only used for debugging
102     QList<QPointer<QObject> > instances;
103
104     static int context_count(QDeclarativeListProperty<QObject> *);
105     static QObject *context_at(QDeclarativeListProperty<QObject> *, int);
106 };
107
108 class QDeclarativeComponentAttached;
109 class QDeclarativeGuardedContextData;
110 class Q_AUTOTEST_EXPORT QDeclarativeContextData
111 {
112 public:
113     QDeclarativeContextData();
114     QDeclarativeContextData(QDeclarativeContext *);
115     void clearContext();
116     void destroy();
117     void invalidate();
118
119     inline bool isValid() const {
120         return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted);
121     }
122
123     // My parent context and engine
124     QDeclarativeContextData *parent;
125     QDeclarativeEngine *engine;
126
127     void setParent(QDeclarativeContextData *, bool parentTakesOwnership = false);
128     void refreshExpressions();
129
130     void addObject(QObject *);
131
132     QUrl resolvedUrl(const QUrl &);
133
134     // My containing QDeclarativeContext.  If isInternal is true this owns publicContext.  
135     // If internal is false publicContext owns this.
136     QDeclarativeContext *asQDeclarativeContext();
137     QDeclarativeContextPrivate *asQDeclarativeContextPrivate();
138     quint32 isInternal:1;
139     quint32 ownedByParent:1; // unrelated to isInternal; parent context deletes children if true.
140     quint32 dummy:30;
141     QDeclarativeContext *publicContext;
142
143     // Property name cache
144     QDeclarativeIntegerCache *propertyNames;
145
146     // Context object
147     QObject *contextObject;
148
149     // Any script blocks that exist on this context
150     QList<QScriptValue> importedScripts;
151
152     // Context base url
153     QUrl url;
154
155     // List of imports that apply to this context
156     QDeclarativeTypeNameCache *imports;
157
158     // My children
159     QDeclarativeContextData *childContexts;
160
161     // My peers in parent's childContexts list
162     QDeclarativeContextData  *nextChild;
163     QDeclarativeContextData **prevChild;
164
165     // Expressions that use this context
166     QDeclarativeAbstractExpression *expressions;
167
168     // Doubly-linked list of objects that are owned by this context
169     QDeclarativeData *contextObjects;
170
171     // Doubly-linked list of context guards (XXX merge with contextObjects)
172     QDeclarativeGuardedContextData *contextGuards;
173
174     // id guards
175     struct ContextGuard : public QDeclarativeGuard<QObject>
176     {
177         ContextGuard() : context(0) {}
178         inline ContextGuard &operator=(QObject *obj)
179         { QDeclarativeGuard<QObject>::operator=(obj); return *this; }
180         virtual void objectDestroyed(QObject *) { 
181             if (context->contextObject && !QObjectPrivate::get(context->contextObject)->wasDeleted) bindings.notify(); 
182         }
183         QDeclarativeContextData *context;
184         QDeclarativeNotifier bindings;
185     };
186     ContextGuard *idValues;
187     int idValueCount;
188     void setIdProperty(int, QObject *);
189     void setIdPropertyData(QDeclarativeIntegerCache *);
190
191     // Optimized binding pointer
192     QDeclarativeV4Bindings *optimizedBindings;
193
194     // Linked contexts. this owns linkedContext.
195     QDeclarativeContextData *linkedContext;
196
197     // Linked list of uses of the Component attached property in this
198     // context
199     QDeclarativeComponentAttached *componentAttached;
200
201     // Return the outermost id for obj, if any.
202     QString findObjectId(const QObject *obj) const;
203
204     static QDeclarativeContextData *get(QDeclarativeContext *context) {
205         return QDeclarativeContextPrivate::get(context)->data;
206     }
207
208 private:
209     ~QDeclarativeContextData() {}
210 };
211
212 class QDeclarativeGuardedContextData
213 {
214 public:
215     inline QDeclarativeGuardedContextData();
216     inline QDeclarativeGuardedContextData(QDeclarativeContextData *);
217     inline ~QDeclarativeGuardedContextData();
218
219     inline void setContextData(QDeclarativeContextData *);
220
221     inline QDeclarativeContextData *contextData();
222
223     inline operator QDeclarativeContextData*() const { return m_contextData; }
224     inline QDeclarativeContextData* operator->() const { return m_contextData; }
225     inline QDeclarativeGuardedContextData &operator=(QDeclarativeContextData *d);
226
227 private:
228     QDeclarativeGuardedContextData &operator=(const QDeclarativeGuardedContextData &);
229     QDeclarativeGuardedContextData(const QDeclarativeGuardedContextData &);
230     friend class QDeclarativeContextData;
231
232     inline void clear();
233
234     QDeclarativeContextData *m_contextData;
235     QDeclarativeGuardedContextData  *m_next;
236     QDeclarativeGuardedContextData **m_prev;
237 };
238
239 QDeclarativeGuardedContextData::QDeclarativeGuardedContextData()
240 : m_contextData(0), m_next(0), m_prev(0)
241 {
242 }
243
244 QDeclarativeGuardedContextData::QDeclarativeGuardedContextData(QDeclarativeContextData *data)
245 : m_contextData(0), m_next(0), m_prev(0)
246 {
247     setContextData(data);
248 }
249
250 QDeclarativeGuardedContextData::~QDeclarativeGuardedContextData()
251 {
252     clear();
253 }
254
255 void QDeclarativeGuardedContextData::setContextData(QDeclarativeContextData *contextData)
256 {
257     clear();
258
259     if (contextData) {
260         m_contextData = contextData;
261         m_next = contextData->contextGuards;
262         if (m_next) m_next->m_prev = &m_next;
263         m_prev = &contextData->contextGuards;
264         contextData->contextGuards = this;
265     }
266 }
267
268 QDeclarativeContextData *QDeclarativeGuardedContextData::contextData()
269 {
270     return m_contextData;
271 }
272
273 void QDeclarativeGuardedContextData::clear()
274 {
275     if (m_prev) {
276         *m_prev = m_next;
277         if (m_next) m_next->m_prev = m_prev;
278         m_contextData = 0;
279         m_next = 0;
280         m_prev = 0;
281     }
282 }
283
284 QDeclarativeGuardedContextData &
285 QDeclarativeGuardedContextData::operator=(QDeclarativeContextData *d)
286 {
287     setContextData(d);
288     return *this;
289 }
290
291 QT_END_NAMESPACE
292
293 #endif // QDECLARATIVECONTEXT_P_H