1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #ifndef QQMLCONTEXT_P_H
43 #define QQMLCONTEXT_P_H
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.
56 #include "qqmlcontext.h"
58 #include "qqmldata_p.h"
59 #include "qqmlintegercache_p.h"
60 #include "qqmltypenamecache_p.h"
61 #include "qqmlnotifier_p.h"
63 #include "qqmlscript_p.h"
65 #include <QtCore/qhash.h>
66 #include <QtQml/qjsvalue.h>
67 #include <QtCore/qset.h>
69 #include <private/qobject_p.h>
70 #include <private/qflagpointer_p.h>
71 #include <private/qqmlguard_p.h>
73 #include <private/qv8_p.h>
83 class QQmlExpressionPrivate;
84 class QQmlAbstractExpression;
86 class QQmlContextData;
88 class QQmlContextPrivate : public QObjectPrivate
90 Q_DECLARE_PUBLIC(QQmlContext)
94 QQmlContextData *data;
96 QList<QVariant> propertyValues;
99 static QQmlContextPrivate *get(QQmlContext *context) {
100 return static_cast<QQmlContextPrivate *>(QObjectPrivate::get(context));
102 static QQmlContext *get(QQmlContextPrivate *context) {
103 return static_cast<QQmlContext *>(context->q_func());
106 // Only used for debugging
107 QList<QPointer<QObject> > instances;
109 static int context_count(QQmlListProperty<QObject> *);
110 static QObject *context_at(QQmlListProperty<QObject> *, int);
114 class QQmlComponentAttached;
115 class QQmlGuardedContextData;
116 class Q_QML_PRIVATE_EXPORT QQmlContextData
120 QQmlContextData(QQmlContext *);
121 void emitDestruction();
126 inline bool isValid() const {
127 return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted);
130 // My parent context and engine
131 QQmlContextData *parent;
134 void setParent(QQmlContextData *, bool parentTakesOwnership = false);
135 void refreshExpressions();
137 void addObject(QObject *);
139 QUrl resolvedUrl(const QUrl &);
141 // My containing QQmlContext. If isInternal is true this owns publicContext.
142 // If internal is false publicContext owns this.
143 QQmlContext *asQQmlContext();
144 QQmlContextPrivate *asQQmlContextPrivate();
145 quint32 isInternal:1;
146 quint32 ownedByParent:1; // unrelated to isInternal; parent context deletes children if true.
147 quint32 isJSContext:1;
148 quint32 isPragmaLibraryContext:1;
149 quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
150 quint32 hasEmittedDestruction:1;
151 quint32 isRootObjectInCreation:1;
153 QQmlContext *publicContext;
155 // VME data that is constructing this context if any
158 // Property name cache
159 QQmlIntegerCache *propertyNames;
162 QObject *contextObject;
164 // Any script blocks that exist on this context
165 QList<v8::Persistent<v8::Object> > importedScripts;
171 // List of imports that apply to this context
172 QQmlTypeNameCache *imports;
175 QQmlContextData *childContexts;
177 // My peers in parent's childContexts list
178 QQmlContextData *nextChild;
179 QQmlContextData **prevChild;
181 // Expressions that use this context
182 QQmlAbstractExpression *expressions;
184 // Doubly-linked list of objects that are owned by this context
185 QQmlData *contextObjects;
187 // Doubly-linked list of context guards (XXX merge with contextObjects)
188 QQmlGuardedContextData *contextGuards;
191 struct ContextGuard : public QQmlGuard<QObject>
193 inline ContextGuard();
194 inline ContextGuard &operator=(QObject *obj);
195 inline void objectDestroyed(QObject *);
197 inline bool wasSet() const;
199 QFlagPointer<QQmlContextData> context;
200 QQmlNotifier bindings;
202 ContextGuard *idValues;
204 void setIdProperty(int, QObject *);
205 void setIdPropertyData(QQmlIntegerCache *);
207 // Linked contexts. this owns linkedContext.
208 QQmlContextData *linkedContext;
210 // Linked list of uses of the Component attached property in this
212 QQmlComponentAttached *componentAttached;
214 // Optimized binding objects. Needed for deferred properties.
215 QV4Bindings *v4bindings;
216 QV8Bindings *v8bindings;
218 // Return the outermost id for obj, if any.
219 QString findObjectId(const QObject *obj) const;
221 static QQmlContextData *get(QQmlContext *context) {
222 return QQmlContextPrivate::get(context)->data;
226 void refreshExpressionsRecursive(bool isGlobal);
227 void refreshExpressionsRecursive(QQmlAbstractExpression *);
228 ~QQmlContextData() {}
231 class QQmlGuardedContextData
234 inline QQmlGuardedContextData();
235 inline QQmlGuardedContextData(QQmlContextData *);
236 inline ~QQmlGuardedContextData();
238 inline QQmlContextData *contextData();
239 inline void setContextData(QQmlContextData *);
241 inline bool isNull() const { return !m_contextData; }
243 inline operator QQmlContextData*() const { return m_contextData; }
244 inline QQmlContextData* operator->() const { return m_contextData; }
245 inline QQmlGuardedContextData &operator=(QQmlContextData *d);
248 QQmlGuardedContextData &operator=(const QQmlGuardedContextData &);
249 QQmlGuardedContextData(const QQmlGuardedContextData &);
250 friend class QQmlContextData;
254 QQmlContextData *m_contextData;
255 QQmlGuardedContextData *m_next;
256 QQmlGuardedContextData **m_prev;
259 QQmlGuardedContextData::QQmlGuardedContextData()
260 : m_contextData(0), m_next(0), m_prev(0)
264 QQmlGuardedContextData::QQmlGuardedContextData(QQmlContextData *data)
265 : m_contextData(0), m_next(0), m_prev(0)
267 setContextData(data);
270 QQmlGuardedContextData::~QQmlGuardedContextData()
275 void QQmlGuardedContextData::setContextData(QQmlContextData *contextData)
280 m_contextData = contextData;
281 m_next = contextData->contextGuards;
282 if (m_next) m_next->m_prev = &m_next;
283 m_prev = &contextData->contextGuards;
284 contextData->contextGuards = this;
288 QQmlContextData *QQmlGuardedContextData::contextData()
290 return m_contextData;
293 void QQmlGuardedContextData::clear()
297 if (m_next) m_next->m_prev = m_prev;
304 QQmlGuardedContextData &
305 QQmlGuardedContextData::operator=(QQmlContextData *d)
311 QQmlContextData::ContextGuard::ContextGuard()
316 QQmlContextData::ContextGuard &QQmlContextData::ContextGuard::operator=(QObject *obj)
318 QQmlGuard<QObject>::operator=(obj);
320 bindings.notify(); // For alias connections
324 void QQmlContextData::ContextGuard::objectDestroyed(QObject *)
326 if (context->contextObject && !QObjectPrivate::get(context->contextObject)->wasDeleted)
330 bool QQmlContextData::ContextGuard::wasSet() const
332 return context.flag();
337 #endif // QQMLCONTEXT_P_H