Merge branch 'master' 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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
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 QScriptEngineDebugger;
102 class QNetworkReply;
103 class QNetworkAccessManager;
104 class QDeclarativeNetworkAccessManagerFactory;
105 class QDeclarativeAbstractBinding;
106 class QScriptDeclarativeClass;
107 class QDeclarativeTypeNameScriptClass;
108 class QDeclarativeTypeNameCache;
109 class QDeclarativeComponentAttached;
110 class QDeclarativeListScriptClass;
111 class QDeclarativeCleanup;
112 class QDeclarativeDelayedError;
113 class QDeclarativeWorkerScriptEngine;
114 class QDeclarativeGlobalScriptClass;
115 class QDir;
116 class QSGTexture;
117 class QSGContext;
118
119 class QDeclarativeScriptEngine : public QScriptEngine
120 {
121 public:
122     QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv);
123     virtual ~QDeclarativeScriptEngine();
124
125     QUrl resolvedUrl(QScriptContext *context, const QUrl& url); // resolved against p's context, or baseUrl if no p
126     static QScriptValue resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine);
127
128     static QDeclarativeScriptEngine *get(QScriptEngine* e) { return static_cast<QDeclarativeScriptEngine*>(e); }
129
130     QDeclarativeEnginePrivate *p;
131
132     // User by SQL API
133     QScriptClass *sqlQueryClass;
134     QString offlineStoragePath;
135
136     // Used by DOM Core 3 API
137     QScriptClass *namedNodeMapClass;
138     QScriptClass *nodeListClass;
139
140     QUrl baseUrl;
141
142     virtual QNetworkAccessManager *networkAccessManager();
143 };
144
145 class Q_AUTOTEST_EXPORT QDeclarativeEnginePrivate : public QObjectPrivate
146 {
147     Q_DECLARE_PUBLIC(QDeclarativeEngine)
148 public:
149     QDeclarativeEnginePrivate(QDeclarativeEngine *);
150     ~QDeclarativeEnginePrivate();
151
152     void init();
153
154     struct CapturedProperty {
155         CapturedProperty(QObject *o, int c, int n)
156             : object(o), coreIndex(c), notifier(0), notifyIndex(n) {}
157         CapturedProperty(QDeclarativeNotifier *n)
158             : object(0), coreIndex(-1), notifier(n), notifyIndex(-1) {}
159
160         QObject *object;
161         int coreIndex;
162         QDeclarativeNotifier *notifier;
163         int notifyIndex;
164     };
165     bool captureProperties;
166     QPODVector<CapturedProperty> capturedProperties;
167
168     QDeclarativeContext *rootContext;
169     bool isDebugging;
170
171     bool outputWarningsToStdErr;
172
173     QDeclarativeContextScriptClass *contextClass;
174     QDeclarativeContextData *sharedContext;
175     QObject *sharedScope;
176     QDeclarativeObjectScriptClass *objectClass;
177     QDeclarativeScarceResourceScriptClass *scarceResourceClass;
178     QDeclarativeValueTypeScriptClass *valueTypeClass;
179     QDeclarativeTypeNameScriptClass *typeNameClass;
180     QDeclarativeListScriptClass *listClass;
181     // Global script class
182     QDeclarativeGlobalScriptClass *globalClass;
183
184     // Registered cleanup handlers
185     QDeclarativeCleanup *cleanup;
186
187     // Bindings that have had errors during startup
188     QDeclarativeDelayedError *erroredBindings;
189     int inProgressCreations;
190
191     QDeclarativeScriptEngine scriptEngine;
192
193     QDeclarativeWorkerScriptEngine *getWorkerScriptEngine();
194     QDeclarativeWorkerScriptEngine *workerScriptEngine;
195
196     QUrl baseUrl;
197
198     template<class T>
199     struct SimpleList {
200         SimpleList()
201             : count(0), values(0) {}
202         SimpleList(int r)
203             : count(0), values(new T*[r]) {}
204
205         int count;
206         T **values;
207
208         void append(T *v) {
209             values[count++] = v;
210         }
211
212         T *at(int idx) const {
213             return values[idx];
214         }
215
216         void clear() {
217             delete [] values;
218         }
219     };
220
221     static void clear(SimpleList<QDeclarativeAbstractBinding> &);
222     static void clear(SimpleList<QDeclarativeParserStatus> &);
223
224     QList<SimpleList<QDeclarativeAbstractBinding> > bindValues;
225     QList<SimpleList<QDeclarativeParserStatus> > parserStatus;
226     QList<QPair<QDeclarativeGuard<QObject>,int> > finalizedParserStatus;
227     QDeclarativeComponentAttached *componentAttached;
228
229     void registerFinalizedParserStatusObject(QObject *obj, int index) {
230         finalizedParserStatus.append(qMakePair(QDeclarativeGuard<QObject>(obj), index));
231     }
232
233     bool inBeginCreate;
234
235     QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const;
236     QNetworkAccessManager *getNetworkAccessManager() const;
237     mutable QNetworkAccessManager *networkAccessManager;
238     mutable QDeclarativeNetworkAccessManagerFactory *networkAccessManagerFactory;
239
240     QHash<QString,QSharedPointer<QDeclarativeImageProvider> > imageProviders;
241     QDeclarativeImageProvider::ImageType getImageProviderType(const QUrl &url);
242     QSGTexture *getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
243     QImage getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
244     QPixmap getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
245
246     /*
247        A scarce resource (like a large pixmap or texture) will be cached in a
248        JavaScript wrapper object when accessed in a binding or other js expression.
249        We need some way to automatically release that scarce resource prior to normal
250        garbage collection (unless the user explicitly preserves the resource).
251      */
252     ScarceResourceData* scarceResources;
253     int scarceResourcesRefCount;
254     static bool variantIsScarceResource(const QVariant& val);
255     void referenceScarceResources();
256     void dereferenceScarceResources();
257
258     mutable QMutex mutex;
259
260     QDeclarativeTypeLoader typeLoader;
261     QDeclarativeImportDatabase importDatabase;
262
263     QString offlineStoragePath;
264
265     mutable quint32 uniqueId;
266     quint32 getUniqueId() const {
267         return uniqueId++;
268     }
269
270     QDeclarativeValueTypeFactory valueTypes;
271
272     QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *> moduleApiInstances;
273
274     QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache;
275     QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *> typePropertyCache;
276     inline QDeclarativePropertyCache *cache(QObject *obj);
277     inline QDeclarativePropertyCache *cache(const QMetaObject *);
278     inline QDeclarativePropertyCache *cache(QDeclarativeType *, int, QDeclarativeError &error);
279     QDeclarativePropertyCache *createCache(const QMetaObject *);
280     QDeclarativePropertyCache *createCache(QDeclarativeType *, int, QDeclarativeError &error);
281
282     void registerCompositeType(QDeclarativeCompiledData *);
283
284     bool isQObject(int);
285     QObject *toQObject(const QVariant &, bool *ok = 0) const;
286     QDeclarativeMetaType::TypeCategory typeCategory(int) const;
287     bool isList(int) const;
288     int listType(int) const;
289     const QMetaObject *rawMetaObjectForType(int) const;
290     const QMetaObject *metaObjectForType(int) const;
291     QHash<int, int> m_qmlLists;
292     QHash<int, QDeclarativeCompiledData *> m_compositeTypes;
293
294     QScriptValue scriptValueFromVariant(const QVariant &);
295     QVariant scriptValueToVariant(const QScriptValue &, int hint = QVariant::Invalid);
296
297     void sendQuit();
298     void warning(const QDeclarativeError &);
299     void warning(const QList<QDeclarativeError> &);
300     static void warning(QDeclarativeEngine *, const QDeclarativeError &);
301     static void warning(QDeclarativeEngine *, const QList<QDeclarativeError> &);
302     static void warning(QDeclarativeEnginePrivate *, const QDeclarativeError &);
303     static void warning(QDeclarativeEnginePrivate *, const QList<QDeclarativeError> &);
304
305     static QScriptValue qmlScriptObject(QObject*, QDeclarativeEngine*);
306
307     static QScriptValue createComponent(QScriptContext*, QScriptEngine*);
308     static QScriptValue createQmlObject(QScriptContext*, QScriptEngine*);
309     static QScriptValue isQtObject(QScriptContext*, QScriptEngine*);
310     static QScriptValue vector3d(QScriptContext*, QScriptEngine*);
311     static QScriptValue rgba(QScriptContext*, QScriptEngine*);
312     static QScriptValue hsla(QScriptContext*, QScriptEngine*);
313     static QScriptValue point(QScriptContext*, QScriptEngine*);
314     static QScriptValue size(QScriptContext*, QScriptEngine*);
315     static QScriptValue rect(QScriptContext*, QScriptEngine*);
316
317     static QScriptValue lighter(QScriptContext*, QScriptEngine*);
318     static QScriptValue darker(QScriptContext*, QScriptEngine*);
319     static QScriptValue tint(QScriptContext*, QScriptEngine*);
320
321     static QScriptValue desktopOpenUrl(QScriptContext*, QScriptEngine*);
322     static QScriptValue fontFamilies(QScriptContext*, QScriptEngine*);
323     static QScriptValue md5(QScriptContext*, QScriptEngine*);
324     static QScriptValue btoa(QScriptContext*, QScriptEngine*);
325     static QScriptValue atob(QScriptContext*, QScriptEngine*);
326     static QScriptValue consoleLog(QScriptContext*, QScriptEngine*);
327     static QScriptValue quit(QScriptContext*, QScriptEngine*);
328
329 #ifndef QT_NO_DATESTRING
330     static QScriptValue formatDate(QScriptContext*, QScriptEngine*);
331     static QScriptValue formatTime(QScriptContext*, QScriptEngine*);
332     static QScriptValue formatDateTime(QScriptContext*, QScriptEngine*);
333 #endif
334     static QScriptEngine *getScriptEngine(QDeclarativeEngine *e) { return &e->d_func()->scriptEngine; }
335     static QDeclarativeEngine *getEngine(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p->q_func(); }
336     static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); }
337     static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; }
338     static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; }
339     static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p; }
340     static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); }
341     QDeclarativeContextData *getContext(QScriptContext *);
342     QUrl getUrl(QScriptContext *);
343
344     static QString urlToLocalFileOrQrc(const QUrl& url);
345
346     static void defineModule();
347
348     static bool qml_debugging_enabled;
349
350     QSGContext *sgContext;
351 };
352
353 /*!
354 Returns a QDeclarativePropertyCache for \a obj if one is available.
355
356 If \a obj is null, being deleted or contains a dynamic meta object 0 
357 is returned.
358
359 The returned cache is not referenced, so if it is to be stored, call addref().
360 */
361 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj) 
362 {
363     if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) 
364         return 0;
365
366     const QMetaObject *mo = obj->metaObject();
367     QDeclarativePropertyCache *rv = propertyCache.value(mo);
368     if (!rv) rv = createCache(mo);
369     return rv;
370 }
371
372 /*!
373 Returns a QDeclarativePropertyCache for \a metaObject.  
374
375 As the cache is persisted for the life of the engine, \a metaObject must be
376 a static "compile time" meta-object, or a meta-object that is otherwise known to 
377 exist for the lifetime of the QDeclarativeEngine.
378
379 The returned cache is not referenced, so if it is to be stored, call addref().
380 */
381 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(const QMetaObject *metaObject)
382 {
383     Q_ASSERT(metaObject);
384
385     QDeclarativePropertyCache *rv = propertyCache.value(metaObject);
386     if (!rv) rv = createCache(metaObject);
387     return rv;
388 }
389
390 /*!
391 Returns a QDeclarativePropertyCache for \a type with \a minorVersion.
392
393 The returned cache is not referenced, so if it is to be stored, call addref().
394 */
395 QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QDeclarativeType *type, int minorVersion, QDeclarativeError &error)
396 {
397     Q_ASSERT(type);
398
399     if (minorVersion == -1 || !type->containsRevisionedAttributes())
400         return cache(type->metaObject());
401
402     QDeclarativePropertyCache *rv = typePropertyCache.value(qMakePair(type, minorVersion));
403     if (!rv) rv = createCache(type, minorVersion, error);
404     return rv;
405 }
406
407 QT_END_NAMESPACE
408
409 #endif // QDECLARATIVEENGINE_P_H