Merge branch 'qtquick2' of scm.dev.nokia.troll.no:qt/qtdeclarative-staging into qtquick2
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativeengine_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 QDECLARATIVEENGINE_P_H
43 #define QDECLARATIVEENGINE_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 "qdeclarativeengine.h"
57
58 #include "private/qdeclarativetypeloader_p.h"
59 #include "private/qdeclarativeimport_p.h"
60 #include "private/qpodvector_p.h"
61 #include "qdeclarative.h"
62 #include "private/qdeclarativevaluetype_p.h"
63 #include "qdeclarativecontext.h"
64 #include "private/qdeclarativecontext_p.h"
65 #include "qdeclarativeexpression.h"
66 #include "qdeclarativeimageprovider.h"
67 #include "private/qdeclarativeproperty_p.h"
68 #include "private/qdeclarativepropertycache_p.h"
69 #include "private/qdeclarativeobjectscriptclass_p.h"
70 #include "private/qdeclarativescarceresourcescriptclass_p.h"
71 #include "private/qdeclarativecontextscriptclass_p.h"
72 #include "private/qdeclarativevaluetypescriptclass_p.h"
73 #include "private/qdeclarativemetatype_p.h"
74 #include "private/qdeclarativedirparser_p.h"
75
76 #include <QtScript/QScriptClass>
77 #include <QtScript/QScriptValue>
78 #include <QtScript/QScriptString>
79 #include <QtCore/qstring.h>
80 #include <QtCore/qlist.h>
81 #include <QtCore/qpair.h>
82 #include <QtCore/qstack.h>
83 #include <QtCore/qmutex.h>
84 #include <QtScript/qscriptengine.h>
85
86 #include <private/qobject_p.h>
87
88 QT_BEGIN_NAMESPACE
89
90 class QDeclarativeContext;
91 class QDeclarativeEngine;
92 class QDeclarativeContextPrivate;
93 class QDeclarativeExpression;
94 class QDeclarativeContextScriptClass;
95 class QDeclarativeImportDatabase;
96 class QDeclarativeObjectScriptClass;
97 class QDeclarativeScarceResourceScriptClass;
98 class ScarceResourceData;
99 class QDeclarativeTypeNameScriptClass;
100 class QDeclarativeValueTypeScriptClass;
101 class QNetworkReply;
102 class QNetworkAccessManager;
103 class QDeclarativeNetworkAccessManagerFactory;
104 class QDeclarativeAbstractBinding;
105 class QScriptDeclarativeClass;
106 class QDeclarativeTypeNameScriptClass;
107 class QDeclarativeTypeNameCache;
108 class QDeclarativeComponentAttached;
109 class QDeclarativeListScriptClass;
110 class QDeclarativeCleanup;
111 class QDeclarativeDelayedError;
112 class QDeclarativeWorkerScriptEngine;
113 class QDeclarativeGlobalScriptClass;
114 class QDir;
115 class QSGTexture;
116 class QSGContext;
117
118 class QDeclarativeScriptEngine : public QScriptEngine
119 {
120 public:
121     QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv);
122     virtual ~QDeclarativeScriptEngine();
123
124     QUrl resolvedUrl(QScriptContext *context, const QUrl& url); // resolved against p's context, or baseUrl if no p
125     static QScriptValue resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine);
126
127     static QDeclarativeScriptEngine *get(QScriptEngine* e) { return static_cast<QDeclarativeScriptEngine*>(e); }
128
129     QDeclarativeEnginePrivate *p;
130
131     // User by SQL API
132     QScriptClass *sqlQueryClass;
133     QString offlineStoragePath;
134
135     // Used by DOM Core 3 API
136     QScriptClass *namedNodeMapClass;
137     QScriptClass *nodeListClass;
138
139     QUrl baseUrl;
140
141     virtual QNetworkAccessManager *networkAccessManager();
142 };
143
144 class Q_AUTOTEST_EXPORT QDeclarativeEnginePrivate : public QObjectPrivate
145 {
146     Q_DECLARE_PUBLIC(QDeclarativeEngine)
147 public:
148     QDeclarativeEnginePrivate(QDeclarativeEngine *);
149     ~QDeclarativeEnginePrivate();
150
151     void init();
152
153     struct CapturedProperty {
154         CapturedProperty(QObject *o, int c, int n)
155             : object(o), coreIndex(c), notifier(0), notifyIndex(n) {}
156         CapturedProperty(QDeclarativeNotifier *n)
157             : object(0), coreIndex(-1), notifier(n), notifyIndex(-1) {}
158
159         QObject *object;
160         int coreIndex;
161         QDeclarativeNotifier *notifier;
162         int notifyIndex;
163     };
164     bool captureProperties;
165     QPODVector<CapturedProperty> capturedProperties;
166
167     QDeclarativeContext *rootContext;
168     bool isDebugging;
169
170     bool outputWarningsToStdErr;
171
172     QDeclarativeContextScriptClass *contextClass;
173     QDeclarativeContextData *sharedContext;
174     QObject *sharedScope;
175     QDeclarativeObjectScriptClass *objectClass;
176     QDeclarativeScarceResourceScriptClass *scarceResourceClass;
177     QDeclarativeValueTypeScriptClass *valueTypeClass;
178     QDeclarativeTypeNameScriptClass *typeNameClass;
179     QDeclarativeListScriptClass *listClass;
180     // Global script class
181     QDeclarativeGlobalScriptClass *globalClass;
182
183     // Registered cleanup handlers
184     QDeclarativeCleanup *cleanup;
185
186     // Bindings that have had errors during startup
187     QDeclarativeDelayedError *erroredBindings;
188     int inProgressCreations;
189
190     QDeclarativeScriptEngine scriptEngine;
191
192     QDeclarativeWorkerScriptEngine *getWorkerScriptEngine();
193     QDeclarativeWorkerScriptEngine *workerScriptEngine;
194
195     QUrl baseUrl;
196
197     template<class T>
198     struct SimpleList {
199         SimpleList()
200             : count(0), values(0) {}
201         SimpleList(int r)
202             : count(0), values(new T*[r]) {}
203
204         int count;
205         T **values;
206
207         void append(T *v) {
208             values[count++] = v;
209         }
210
211         T *at(int idx) const {
212             return values[idx];
213         }
214
215         void clear() {
216             delete [] values;
217         }
218     };
219
220     static void clear(SimpleList<QDeclarativeAbstractBinding> &);
221     static void clear(SimpleList<QDeclarativeParserStatus> &);
222
223     QList<SimpleList<QDeclarativeAbstractBinding> > bindValues;
224     QList<SimpleList<QDeclarativeParserStatus> > parserStatus;
225     QList<QPair<QDeclarativeGuard<QObject>,int> > finalizedParserStatus;
226     QDeclarativeComponentAttached *componentAttached;
227
228     void registerFinalizedParserStatusObject(QObject *obj, int index) {
229         finalizedParserStatus.append(qMakePair(QDeclarativeGuard<QObject>(obj), index));
230     }
231
232     bool inBeginCreate;
233
234     QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const;
235     QNetworkAccessManager *getNetworkAccessManager() const;
236     mutable QNetworkAccessManager *networkAccessManager;
237     mutable QDeclarativeNetworkAccessManagerFactory *networkAccessManagerFactory;
238
239     QHash<QString,QSharedPointer<QDeclarativeImageProvider> > imageProviders;
240     QDeclarativeImageProvider::ImageType getImageProviderType(const QUrl &url);
241     QSGTexture *getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
242     QImage getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
243     QPixmap getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
244
245     /*
246        A scarce resource (like a large pixmap or texture) will be cached in a
247        JavaScript wrapper object when accessed in a binding or other js expression.
248        We need some way to automatically release that scarce resource prior to normal
249        garbage collection (unless the user explicitly preserves the resource).
250      */
251     ScarceResourceData* scarceResources;
252     int scarceResourcesRefCount;
253     static bool variantIsScarceResource(const QVariant& val);
254     void referenceScarceResources();
255     void dereferenceScarceResources();
256
257     mutable QMutex mutex;
258
259     QDeclarativeTypeLoader typeLoader;
260     QDeclarativeImportDatabase importDatabase;
261
262     QString offlineStoragePath;
263
264     mutable quint32 uniqueId;
265     quint32 getUniqueId() const {
266         return uniqueId++;
267     }
268
269     QDeclarativeValueTypeFactory valueTypes;
270
271     QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *> moduleApiInstances;
272
273     QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache;
274     QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *> typePropertyCache;
275     inline QDeclarativePropertyCache *cache(QObject *obj);
276     inline QDeclarativePropertyCache *cache(const QMetaObject *);
277     inline QDeclarativePropertyCache *cache(QDeclarativeType *, int, QDeclarativeError &error);
278     QDeclarativePropertyCache *createCache(const QMetaObject *);
279     QDeclarativePropertyCache *createCache(QDeclarativeType *, int, QDeclarativeError &error);
280
281     void registerCompositeType(QDeclarativeCompiledData *);
282
283     bool isQObject(int);
284     QObject *toQObject(const QVariant &, bool *ok = 0) const;
285     QDeclarativeMetaType::TypeCategory typeCategory(int) const;
286     bool isList(int) const;
287     int listType(int) const;
288     const QMetaObject *rawMetaObjectForType(int) const;
289     const QMetaObject *metaObjectForType(int) const;
290     QHash<int, int> m_qmlLists;
291     QHash<int, QDeclarativeCompiledData *> m_compositeTypes;
292
293     QScriptValue scriptValueFromVariant(const QVariant &);
294     QVariant scriptValueToVariant(const QScriptValue &, int hint = QVariant::Invalid);
295
296     void sendQuit();
297     void warning(const QDeclarativeError &);
298     void warning(const QList<QDeclarativeError> &);
299     static void warning(QDeclarativeEngine *, const QDeclarativeError &);
300     static void warning(QDeclarativeEngine *, const QList<QDeclarativeError> &);
301     static void warning(QDeclarativeEnginePrivate *, const QDeclarativeError &);
302     static void warning(QDeclarativeEnginePrivate *, const QList<QDeclarativeError> &);
303
304     static QScriptValue qmlScriptObject(QObject*, QDeclarativeEngine*);
305
306     static QScriptValue createComponent(QScriptContext*, QScriptEngine*);
307     static QScriptValue createQmlObject(QScriptContext*, QScriptEngine*);
308     static QScriptValue isQtObject(QScriptContext*, QScriptEngine*);
309     static QScriptValue vector3d(QScriptContext*, QScriptEngine*);
310     static QScriptValue rgba(QScriptContext*, QScriptEngine*);
311     static QScriptValue hsla(QScriptContext*, QScriptEngine*);
312     static QScriptValue point(QScriptContext*, QScriptEngine*);
313     static QScriptValue size(QScriptContext*, QScriptEngine*);
314     static QScriptValue rect(QScriptContext*, QScriptEngine*);
315
316     static QScriptValue lighter(QScriptContext*, QScriptEngine*);
317     static QScriptValue darker(QScriptContext*, QScriptEngine*);
318     static QScriptValue tint(QScriptContext*, QScriptEngine*);
319
320     static QScriptValue desktopOpenUrl(QScriptContext*, QScriptEngine*);
321     static QScriptValue fontFamilies(QScriptContext*, QScriptEngine*);
322     static QScriptValue md5(QScriptContext*, QScriptEngine*);
323     static QScriptValue btoa(QScriptContext*, QScriptEngine*);
324     static QScriptValue atob(QScriptContext*, QScriptEngine*);
325     static QScriptValue consoleLog(QScriptContext*, QScriptEngine*);
326     static QScriptValue quit(QScriptContext*, QScriptEngine*);
327
328 #ifndef QT_NO_DATESTRING
329     static QScriptValue formatDate(QScriptContext*, QScriptEngine*);
330     static QScriptValue formatTime(QScriptContext*, QScriptEngine*);
331     static QScriptValue formatDateTime(QScriptContext*, QScriptEngine*);
332 #endif
333     static QScriptEngine *getScriptEngine(QDeclarativeEngine *e) { return &e->d_func()->scriptEngine; }
334     static QDeclarativeEngine *getEngine(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p->q_func(); }
335     static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); }
336     static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; }
337     static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; }
338     static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p; }
339     static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); }
340     QDeclarativeContextData *getContext(QScriptContext *);
341     QUrl getUrl(QScriptContext *);
342
343     static QString urlToLocalFileOrQrc(const QUrl& url);
344
345     static void defineModule();
346
347     static bool qml_debugging_enabled;
348
349     QSGContext *sgContext;
350 };
351
352 /*!
353 Returns a QDeclarativePropertyCache for \a obj if one is available.
354
355 If \a obj is null, being deleted or contains a dynamic meta object 0
356 is returned.
357
358 The returned cache is not referenced, so if it is to be stored, call addref().
359 */
360 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj)
361 {
362     if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
363         return 0;
364
365     const QMetaObject *mo = obj->metaObject();
366     QDeclarativePropertyCache *rv = propertyCache.value(mo);
367     if (!rv) rv = createCache(mo);
368     return rv;
369 }
370
371 /*!
372 Returns a QDeclarativePropertyCache for \a metaObject.
373
374 As the cache is persisted for the life of the engine, \a metaObject must be
375 a static "compile time" meta-object, or a meta-object that is otherwise known to
376 exist for the lifetime of the QDeclarativeEngine.
377
378 The returned cache is not referenced, so if it is to be stored, call addref().
379 */
380 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(const QMetaObject *metaObject)
381 {
382     Q_ASSERT(metaObject);
383
384     QDeclarativePropertyCache *rv = propertyCache.value(metaObject);
385     if (!rv) rv = createCache(metaObject);
386     return rv;
387 }
388
389 /*!
390 Returns a QDeclarativePropertyCache for \a type with \a minorVersion.
391
392 The returned cache is not referenced, so if it is to be stored, call addref().
393 */
394 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QDeclarativeType *type, int minorVersion, QDeclarativeError &error)
395 {
396     Q_ASSERT(type);
397
398     if (minorVersion == -1 || !type->containsRevisionedAttributes())
399         return cache(type->metaObject());
400
401     QDeclarativePropertyCache *rv = typePropertyCache.value(qMakePair(type, minorVersion));
402     if (!rv) rv = createCache(type, minorVersion, error);
403     return rv;
404 }
405
406 QT_END_NAMESPACE
407
408 #endif // QDECLARATIVEENGINE_P_H