1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include "private/qdeclarativeengine_p.h"
43 #include "qdeclarativeengine.h"
45 #include "private/qdeclarativecontext_p.h"
46 #include "private/qdeclarativecompiler_p.h"
47 #include "private/qdeclarativeglobalscriptclass_p.h"
48 #include "qdeclarative.h"
49 #include "qdeclarativecontext.h"
50 #include "qdeclarativeexpression.h"
51 #include "qdeclarativecomponent.h"
52 #include "private/qdeclarativebinding_p_p.h"
53 #include "private/qdeclarativevme_p.h"
54 #include "private/qdeclarativeenginedebug_p.h"
55 #include "private/qdeclarativestringconverters_p.h"
56 #include "private/qdeclarativexmlhttprequest_p.h"
57 #include "private/qdeclarativesqldatabase_p.h"
58 #include "private/qdeclarativescarceresourcescriptclass_p.h"
59 #include "private/qdeclarativetypenamescriptclass_p.h"
60 #include "private/qdeclarativelistscriptclass_p.h"
61 #include "qdeclarativescriptstring.h"
62 #include "private/qdeclarativeglobal_p.h"
63 #include "private/qdeclarativeworkerscript_p.h"
64 #include "private/qdeclarativecomponent_p.h"
65 #include "qdeclarativenetworkaccessmanagerfactory.h"
66 #include "qdeclarativeimageprovider.h"
67 #include "private/qdeclarativedirparser_p.h"
68 #include "qdeclarativeextensioninterface.h"
69 #include "private/qdeclarativelist_p.h"
70 #include "private/qdeclarativetypenamecache_p.h"
71 #include "private/qdeclarativeinclude_p.h"
72 #include "private/qdeclarativenotifier_p.h"
73 #include "private/qdeclarativedebugtrace_p.h"
74 #include "private/qdeclarativeapplication_p.h"
75 #include "private/qjsdebugservice_p.h"
77 #include <QtCore/qmetaobject.h>
78 #include <QScriptClass>
79 #include <QNetworkReply>
80 #include <QNetworkRequest>
81 #include <QNetworkAccessManager>
82 #include <QDesktopServices>
87 #include <QMetaObject>
90 #include <QPluginLoader>
91 #include <QtGui/qfontdatabase.h>
92 #include <QtCore/qlibraryinfo.h>
93 #include <QtCore/qthreadstorage.h>
94 #include <QtCore/qthread.h>
95 #include <QtCore/qcoreapplication.h>
96 #include <QtCore/qdir.h>
97 #include <QtCore/qmutex.h>
98 #include <QtGui/qcolor.h>
99 #include <QtGui/qvector3d.h>
100 #include <QtGui/qsound.h>
101 #include <QtCore/qcryptographichash.h>
103 #include <private/qobject_p.h>
104 #include <private/qscriptdeclarativeclass_p.h>
106 #include <private/qdeclarativeitemsmodule_p.h>
107 #include <private/qdeclarativeutilmodule_p.h>
108 #include <private/qsgitemsmodule_p.h>
109 #include <private/qsgparticlesmodule_p.h>
110 #include <qsgtexture.h>
112 #ifdef Q_OS_WIN // for %APPDATA%
113 #include <qt_windows.h>
114 #include <qlibrary.h>
117 #define CSIDL_APPDATA 0x001a // <username>\Application Data
120 Q_DECLARE_METATYPE(QDeclarativeProperty)
125 \qmlclass QtObject QObject
126 \ingroup qml-utility-elements
128 \brief The QtObject element is the most basic element in QML.
130 The QtObject element is a non-visual element which contains only the
133 It can be useful to create a QtObject if you need an extremely
134 lightweight element to enclose a set of custom properties:
136 \snippet doc/src/snippets/declarative/qtobject.qml 0
138 It can also be useful for C++ integration, as it is just a plain
139 QObject. See the QObject documentation for further details.
142 \qmlproperty string QML:QtObject::objectName
143 This property holds the QObject::objectName for this specific object instance.
145 This allows a C++ application to locate an item within a QML component
146 using the QObject::findChild() method. For example, the following C++
147 application locates the child \l Rectangle item and dynamically changes its
156 width: 200; height: 200
169 QDeclarativeView view;
170 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
173 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
175 item->setProperty("color", QColor(Qt::yellow));
179 struct StaticQtMetaObject : public QObject
181 static const QMetaObject *get()
182 { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
185 static bool qt_QmlQtModule_registered = false;
186 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
188 void QDeclarativeEnginePrivate::defineModule()
190 qmlRegisterType<QDeclarativeComponent>("QtQuick",1,0,"Component");
191 qmlRegisterType<QObject>("QtQuick",1,0,"QtObject");
192 qmlRegisterType<QDeclarativeWorkerScript>("QtQuick",1,0,"WorkerScript");
194 #ifndef QT_NO_IMPORT_QT47_QML
195 qmlRegisterType<QDeclarativeComponent>("Qt",4,7,"Component");
196 qmlRegisterType<QObject>("Qt",4,7,"QtObject");
197 qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,7,"WorkerScript");
200 qmlRegisterType<QDeclarativeBinding>();
204 \qmlclass QML:Qt QDeclarativeEnginePrivate
205 \ingroup qml-utility-elements
206 \brief The QML global Qt object provides useful enums and functions from Qt.
208 \keyword QmlGlobalQtObject
210 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
212 The \c Qt object is a global object with utility functions, properties and enums.
214 It is not instantiable; to use it, call the members of the global \c Qt object directly.
221 color: Qt.rgba(1, 0, 0, 1)
222 text: Qt.md5("hello, world")
229 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
230 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
234 The Qt object also contains helper functions for creating objects of specific
235 data types. This is primarily useful when setting the properties of an item
236 when the property has one of the following types:
239 \o \c color - use \l{QML:Qt::rgba()}{Qt.rgba()}, \l{QML:Qt::hsla()}{Qt.hsla()}, \l{QML:Qt::darker()}{Qt.darker()}, \l{QML:Qt::lighter()}{Qt.lighter()} or \l{QML:Qt::tint()}{Qt.tint()}
240 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
241 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
242 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
243 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
246 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
248 \section1 Date/Time Formatters
250 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
253 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
254 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
255 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
258 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
261 \section1 Dynamic Object Creation
262 The following functions on the global object allow you to dynamically create QML
263 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
267 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
268 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
274 \qmlproperty object QML:Qt::application
277 The \c application object provides access to global application state
278 properties shared by many QML components.
284 \o \c application.active
286 This read-only property indicates whether the application is the top-most and focused
287 application, and the user is able to interact with the application. The property
288 is false when the application is in the background, the device keylock or screen
289 saver is active, the screen backlight is turned off, or the global system dialog
290 is being displayed on top of the application. It can be used for stopping and
291 pausing animations, timers and active processing of data in order to save device
292 battery power and free device memory and processor load when the application is not
296 \o \c application.layoutDirection
298 This read-only property can be used to query the default layout direction of the
299 application. On system start-up, the default layout direction depends on the
300 application's language. The property has a value of \c Qt.RightToLeft in locales
301 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
302 where the reading direction flows from left to right. You can bind to this
303 property to customize your application layouts to support both layout directions.
308 \o Qt.LeftToRight - Text and graphics elements should be positioned
310 \o Qt.RightToLeft - Text and graphics elements should be positioned
315 The following example uses the \c application object to indicate
316 whether the application is currently active:
318 \snippet doc/src/snippets/declarative/application.qml document
324 \qmlmethod object Qt::include(string url, jsobject callback)
326 Includes another JavaScript file. This method can only be used from within JavaScript files,
327 and not regular QML files.
329 This imports all functions from \a url into the current script's namespace.
331 Qt.include() returns an object that describes the status of the operation. The object has
332 a single property, \c {status}, that is set to one of the following values:
335 \header \o Symbol \o Value \o Description
336 \row \o result.OK \o 0 \o The include completed successfully.
337 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
338 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
339 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
340 An additional \c exception property will be set in this case.
343 The \c status property will be updated as the operation progresses.
345 If provided, \a callback is invoked when the operation completes. The callback is passed
346 the same object as is returned from the Qt.include() call.
348 // Qt.include() is implemented in qdeclarativeinclude.cpp
351 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
352 : captureProperties(false), rootContext(0), isDebugging(false),
353 outputWarningsToStdErr(true), contextClass(0), sharedContext(0), sharedScope(0),
354 objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
355 inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
356 inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
357 scarceResources(0), scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
360 if (!qt_QmlQtModule_registered) {
361 qt_QmlQtModule_registered = true;
362 QDeclarativeItemModule::defineModule();
363 QDeclarativeUtilModule::defineModule();
364 QDeclarativeEnginePrivate::defineModule();
365 QSGItemsModule::defineModule();
366 QSGParticlesModule::defineModule();
367 QDeclarativeValueTypeFactory::registerValueTypes();
369 globalClass = new QDeclarativeGlobalScriptClass(&scriptEngine);
373 \qmlmethod url Qt::resolvedUrl(url url)
374 Returns \a url resolved relative to the URL of the caller.
376 QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
379 QDeclarativeContextData *ctxt = p->getContext(context);
381 return ctxt->resolvedUrl(url);
383 return p->getUrl(context).resolved(url);
385 return baseUrl.resolved(url);
388 QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv)
389 : p(priv), sqlQueryClass(0), namedNodeMapClass(0), nodeListClass(0)
391 // Note that all documentation for stuff put on the global object goes in
392 // doc/src/declarative/globalobject.qdoc
394 bool mainthread = priv != 0;
396 QScriptValue qtObject =
397 newQMetaObject(StaticQtMetaObject::get());
398 globalObject().setProperty(QLatin1String("Qt"), qtObject);
400 #ifndef QT_NO_DESKTOPSERVICES
401 offlineStoragePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation).replace(QLatin1Char('/'), QDir::separator())
402 + QDir::separator() + QLatin1String("QML")
403 + QDir::separator() + QLatin1String("OfflineStorage");
406 #ifndef QT_NO_XMLSTREAMREADER
407 qt_add_qmlxmlhttprequest(this);
409 qt_add_qmlsqldatabase(this);
410 // XXX A Multimedia "Qt.Sound" class also needs to be made available,
411 // XXX but we don't want a dependency in that cirection.
412 // XXX When the above a done some better way, that way should also be
413 // XXX used to add Qt.Sound class.
417 qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::include, 2));
419 qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::worker_include, 2));
421 qtObject.setProperty(QLatin1String("isQtObject"), newFunction(QDeclarativeEnginePrivate::isQtObject, 1));
422 qtObject.setProperty(QLatin1String("rgba"), newFunction(QDeclarativeEnginePrivate::rgba, 4));
423 qtObject.setProperty(QLatin1String("hsla"), newFunction(QDeclarativeEnginePrivate::hsla, 4));
424 qtObject.setProperty(QLatin1String("rect"), newFunction(QDeclarativeEnginePrivate::rect, 4));
425 qtObject.setProperty(QLatin1String("point"), newFunction(QDeclarativeEnginePrivate::point, 2));
426 qtObject.setProperty(QLatin1String("size"), newFunction(QDeclarativeEnginePrivate::size, 2));
427 qtObject.setProperty(QLatin1String("vector3d"), newFunction(QDeclarativeEnginePrivate::vector3d, 3));
431 qtObject.setProperty(QLatin1String("lighter"), newFunction(QDeclarativeEnginePrivate::lighter, 1));
432 qtObject.setProperty(QLatin1String("darker"), newFunction(QDeclarativeEnginePrivate::darker, 1));
433 qtObject.setProperty(QLatin1String("tint"), newFunction(QDeclarativeEnginePrivate::tint, 2));
436 #ifndef QT_NO_DATESTRING
437 //date/time formatting
438 qtObject.setProperty(QLatin1String("formatDate"),newFunction(QDeclarativeEnginePrivate::formatDate, 2));
439 qtObject.setProperty(QLatin1String("formatTime"),newFunction(QDeclarativeEnginePrivate::formatTime, 2));
440 qtObject.setProperty(QLatin1String("formatDateTime"),newFunction(QDeclarativeEnginePrivate::formatDateTime, 2));
444 qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1));
445 qtObject.setProperty(QLatin1String("fontFamilies"),newFunction(QDeclarativeEnginePrivate::fontFamilies, 0));
446 qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1));
447 qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1));
448 qtObject.setProperty(QLatin1String("atob"),newFunction(QDeclarativeEnginePrivate::atob, 1));
449 qtObject.setProperty(QLatin1String("quit"), newFunction(QDeclarativeEnginePrivate::quit, 0));
450 qtObject.setProperty(QLatin1String("resolvedUrl"),newFunction(QDeclarativeScriptEngine::resolvedUrl, 1));
453 qtObject.setProperty(QLatin1String("createQmlObject"),
454 newFunction(QDeclarativeEnginePrivate::createQmlObject, 1));
455 qtObject.setProperty(QLatin1String("createComponent"),
456 newFunction(QDeclarativeEnginePrivate::createComponent, 1));
459 //firebug/webkit compat
460 QScriptValue consoleObject = newObject();
461 consoleObject.setProperty(QLatin1String("log"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
462 consoleObject.setProperty(QLatin1String("debug"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
463 globalObject().setProperty(QLatin1String("console"), consoleObject);
465 // translation functions need to be installed
466 // before the global script class is constructed (QTBUG-6437)
467 installTranslatorFunctions();
470 QDeclarativeScriptEngine::~QDeclarativeScriptEngine()
472 delete sqlQueryClass;
473 delete nodeListClass;
474 delete namedNodeMapClass;
477 QScriptValue QDeclarativeScriptEngine::resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine)
479 QString arg = ctxt->argument(0).toString();
480 QUrl r = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt,QUrl(arg));
481 return QScriptValue(r.toString());
484 QNetworkAccessManager *QDeclarativeScriptEngine::networkAccessManager()
486 return p->getNetworkAccessManager();
489 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
491 Q_ASSERT(inProgressCreations == 0);
492 Q_ASSERT(bindValues.isEmpty());
493 Q_ASSERT(parserStatus.isEmpty());
496 QDeclarativeCleanup *c = cleanup;
498 if (cleanup) cleanup->prev = &cleanup;
510 delete scarceResourceClass;
511 scarceResourceClass = 0;
512 delete valueTypeClass;
514 delete typeNameClass;
521 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
523 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
525 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
527 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
528 delete (*iter)->qobjectApi;
533 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
538 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
540 for (int ii = 0; ii < pss.count; ++ii) {
541 QDeclarativeParserStatus *ps = pss.at(ii);
548 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
550 QObjectPrivate *p = QObjectPrivate::get(o);
551 if (p->declarativeData) {
552 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
553 if (d->ownContext && d->context) {
554 d->context->destroy();
560 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
562 static_cast<QDeclarativeData *>(d)->destroyed(o);
565 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
567 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
570 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
572 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
575 void QDeclarativeEnginePrivate::init()
577 Q_Q(QDeclarativeEngine);
578 qRegisterMetaType<QVariant>("QVariant");
579 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
580 qRegisterMetaType<QScriptValue>("QScriptValue");
581 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
583 QDeclarativeData::init();
585 contextClass = new QDeclarativeContextScriptClass(q);
586 objectClass = new QDeclarativeObjectScriptClass(q);
587 scarceResourceClass = new QDeclarativeScarceResourceScriptClass(q);
588 valueTypeClass = new QDeclarativeValueTypeScriptClass(q);
589 typeNameClass = new QDeclarativeTypeNameScriptClass(q);
590 listClass = new QDeclarativeListScriptClass(q);
591 rootContext = new QDeclarativeContext(q,true);
593 QScriptValue applicationObject = objectClass->newQObject(new QDeclarativeApplication(q));
594 scriptEngine.globalObject().property(QLatin1String("Qt")).setProperty(QLatin1String("application"), applicationObject);
596 if (QCoreApplication::instance()->thread() == q->thread() &&
597 QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
599 QDeclarativeEngineDebugServer::instance()->addEngine(q);
600 QJSDebugService::instance()->addEngine(q);
604 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
606 Q_Q(QDeclarativeEngine);
607 if (!workerScriptEngine)
608 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
609 return workerScriptEngine;
613 \class QDeclarativeEngine
615 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
618 Each QML component is instantiated in a QDeclarativeContext.
619 QDeclarativeContext's are essential for passing data to QML
620 components. In QML, contexts are arranged hierarchically and this
621 hierarchy is managed by the QDeclarativeEngine.
623 Prior to creating any QML components, an application must have
624 created a QDeclarativeEngine to gain access to a QML context. The
625 following example shows how to create a simple Text item.
628 QDeclarativeEngine engine;
629 QDeclarativeComponent component(&engine);
630 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
631 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
633 //add item to view, etc
637 In this case, the Text item will be created in the engine's
638 \l {QDeclarativeEngine::rootContext()}{root context}.
640 \sa QDeclarativeComponent QDeclarativeContext
644 Create a new QDeclarativeEngine with the given \a parent.
646 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
647 : QObject(*new QDeclarativeEnginePrivate(this), parent)
649 Q_D(QDeclarativeEngine);
654 Destroys the QDeclarativeEngine.
656 Any QDeclarativeContext's created on this engine will be
657 invalidated, but not destroyed (unless they are parented to the
658 QDeclarativeEngine object).
660 QDeclarativeEngine::~QDeclarativeEngine()
662 Q_D(QDeclarativeEngine);
664 QDeclarativeEngineDebugServer::instance()->remEngine(this);
666 // if we are the parent of any of the qobject module api instances,
667 // we need to remove them from our internal list, in order to prevent
668 // a segfault in engine private dtor.
669 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
670 QObject *currQObjectApi = 0;
671 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
672 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
673 currInstance = d->moduleApiInstances.value(key);
674 currQObjectApi = currInstance->qobjectApi;
675 if (this->children().contains(currQObjectApi)) {
676 delete currQObjectApi;
678 d->moduleApiInstances.remove(key);
683 /*! \fn void QDeclarativeEngine::quit()
684 This signal is emitted when the QML loaded by the engine would like to quit.
687 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
688 This signal is emitted when \a warnings messages are generated by QML.
692 Clears the engine's internal component cache.
694 Normally the QDeclarativeEngine caches components loaded from qml
695 files. This method clears this cache and forces the component to be
698 void QDeclarativeEngine::clearComponentCache()
700 Q_D(QDeclarativeEngine);
701 d->typeLoader.clearCache();
705 Returns the engine's root context.
707 The root context is automatically created by the QDeclarativeEngine.
708 Data that should be available to all QML component instances
709 instantiated by the engine should be put in the root context.
711 Additional data that should only be available to a subset of
712 component instances should be added to sub-contexts parented to the
715 QDeclarativeContext *QDeclarativeEngine::rootContext() const
717 Q_D(const QDeclarativeEngine);
718 return d->rootContext;
722 Sets the \a factory to use for creating QNetworkAccessManager(s).
724 QNetworkAccessManager is used for all network access by QML. By
725 implementing a factory it is possible to create custom
726 QNetworkAccessManager with specialized caching, proxy and cookie
729 The factory must be set before executing the engine.
731 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
733 Q_D(QDeclarativeEngine);
734 QMutexLocker locker(&d->mutex);
735 d->networkAccessManagerFactory = factory;
739 Returns the current QDeclarativeNetworkAccessManagerFactory.
741 \sa setNetworkAccessManagerFactory()
743 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
745 Q_D(const QDeclarativeEngine);
746 return d->networkAccessManagerFactory;
749 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
751 QMutexLocker locker(&mutex);
752 QNetworkAccessManager *nam;
753 if (networkAccessManagerFactory) {
754 nam = networkAccessManagerFactory->create(parent);
756 nam = new QNetworkAccessManager(parent);
762 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
764 Q_Q(const QDeclarativeEngine);
765 if (!networkAccessManager)
766 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
767 return networkAccessManager;
771 Returns a common QNetworkAccessManager which can be used by any QML
772 element instantiated by this engine.
774 If a QDeclarativeNetworkAccessManagerFactory has been set and a
775 QNetworkAccessManager has not yet been created, the
776 QDeclarativeNetworkAccessManagerFactory will be used to create the
777 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
778 will have no proxy or cache set.
780 \sa setNetworkAccessManagerFactory()
782 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
784 Q_D(const QDeclarativeEngine);
785 return d->getNetworkAccessManager();
790 Sets the \a provider to use for images requested via the \e
791 image: url scheme, with host \a providerId. The QDeclarativeEngine
792 takes ownership of \a provider.
794 Image providers enable support for pixmap and threaded image
795 requests. See the QDeclarativeImageProvider documentation for details on
796 implementing and using image providers.
798 All required image providers should be added to the engine before any
799 QML sources files are loaded.
801 \sa removeImageProvider()
803 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
805 Q_D(QDeclarativeEngine);
806 QMutexLocker locker(&d->mutex);
807 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
811 Returns the QDeclarativeImageProvider set for \a providerId.
813 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
815 Q_D(const QDeclarativeEngine);
816 QMutexLocker locker(&d->mutex);
817 return d->imageProviders.value(providerId).data();
821 Removes the QDeclarativeImageProvider for \a providerId.
823 Returns the provider if it was found; otherwise returns 0.
825 \sa addImageProvider()
827 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
829 Q_D(QDeclarativeEngine);
830 QMutexLocker locker(&d->mutex);
831 d->imageProviders.take(providerId);
834 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
836 QMutexLocker locker(&mutex);
837 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
840 return provider->imageType();
841 return QDeclarativeImageProvider::Invalid;
844 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
846 QMutexLocker locker(&mutex);
847 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
850 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
851 return provider->requestTexture(imageId, size, req_size);
856 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
858 QMutexLocker locker(&mutex);
860 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
863 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
864 image = provider->requestImage(imageId, size, req_size);
869 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
871 QMutexLocker locker(&mutex);
873 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
876 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
877 pixmap = provider->requestPixmap(imageId, size, req_size);
883 Return the base URL for this engine. The base URL is only used to
884 resolve components when a relative URL is passed to the
885 QDeclarativeComponent constructor.
887 If a base URL has not been explicitly set, this method returns the
888 application's current working directory.
892 QUrl QDeclarativeEngine::baseUrl() const
894 Q_D(const QDeclarativeEngine);
895 if (d->baseUrl.isEmpty()) {
896 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
903 Set the base URL for this engine to \a url.
907 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
909 Q_D(QDeclarativeEngine);
914 Returns true if warning messages will be output to stderr in addition
915 to being emitted by the warnings() signal, otherwise false.
917 The default value is true.
919 bool QDeclarativeEngine::outputWarningsToStandardError() const
921 Q_D(const QDeclarativeEngine);
922 return d->outputWarningsToStdErr;
926 Set whether warning messages will be output to stderr to \a enabled.
928 If \a enabled is true, any warning messages generated by QML will be
929 output to stderr and emitted by the warnings() signal. If \a enabled
930 is false, on the warnings() signal will be emitted. This allows
931 applications to handle warning output themselves.
933 The default value is true.
935 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
937 Q_D(QDeclarativeEngine);
938 d->outputWarningsToStdErr = enabled;
942 Returns the QDeclarativeContext for the \a object, or 0 if no
943 context has been set.
945 When the QDeclarativeEngine instantiates a QObject, the context is
948 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
953 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
955 QDeclarativeData *data =
956 static_cast<QDeclarativeData *>(priv->declarativeData);
960 else if (data->outerContext)
961 return data->outerContext->asQDeclarativeContext();
967 Sets the QDeclarativeContext for the \a object to \a context.
968 If the \a object already has a context, a warning is
969 output, but the context is not changed.
971 When the QDeclarativeEngine instantiates a QObject, the context is
974 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
976 if (!object || !context)
979 QDeclarativeData *data = QDeclarativeData::get(object, true);
981 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
985 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
986 contextData->addObject(object);
990 \enum QDeclarativeEngine::ObjectOwnership
992 Ownership controls whether or not QML automatically destroys the
993 QObject when the object is garbage collected by the JavaScript
994 engine. The two ownership options are:
996 \value CppOwnership The object is owned by C++ code, and will
997 never be deleted by QML. The JavaScript destroy() method cannot be
998 used on objects with CppOwnership. This option is similar to
999 QScriptEngine::QtOwnership.
1001 \value JavaScriptOwnership The object is owned by JavaScript.
1002 When the object is returned to QML as the return value of a method
1003 call or property access, QML will delete the object if there are no
1004 remaining JavaScript references to it and it has no
1005 QObject::parent(). This option is similar to
1006 QScriptEngine::ScriptOwnership.
1008 Generally an application doesn't need to set an object's ownership
1009 explicitly. QML uses a heuristic to set the default object
1010 ownership. By default, an object that is created by QML has
1011 JavaScriptOwnership. The exception to this are the root objects
1012 created by calling QDeclarativeCompnent::create() or
1013 QDeclarativeComponent::beginCreate() which have CppOwnership by
1014 default. The ownership of these root-level objects is considered to
1015 have been transferred to the C++ caller.
1017 Objects not-created by QML have CppOwnership by default. The
1018 exception to this is objects returned from a C++ method call. The
1019 ownership of these objects is passed to JavaScript.
1021 Calling setObjectOwnership() overrides the default ownership
1022 heuristic used by QML.
1026 Sets the \a ownership of \a object.
1028 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
1033 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
1037 ddata->indestructible = (ownership == CppOwnership)?true:false;
1038 ddata->explicitIndestructibleSet = true;
1042 Returns the ownership of \a object.
1044 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
1047 return CppOwnership;
1049 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
1051 return CppOwnership;
1053 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
1056 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
1058 QDeclarativeData *data = QDeclarativeData::get(object);
1060 if (data && data->deferredComponent) {
1061 if (QDeclarativeDebugService::isDebuggingEnabled()) {
1062 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
1063 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
1064 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
1065 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
1066 if (data->outerContext)
1067 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
1069 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
1071 QDeclarativeComponentPrivate::ConstructionState state;
1072 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
1074 data->deferredComponent->release();
1075 data->deferredComponent = 0;
1077 QDeclarativeComponentPrivate::complete(ep, &state);
1078 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
1082 QDeclarativeContext *qmlContext(const QObject *obj)
1084 return QDeclarativeEngine::contextForObject(obj);
1087 QDeclarativeEngine *qmlEngine(const QObject *obj)
1089 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
1090 return context?context->engine():0;
1093 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
1095 QDeclarativeData *data = QDeclarativeData::get(object);
1097 return 0; // Attached properties are only on objects created by QML
1099 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
1103 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
1107 rv = pf(const_cast<QObject *>(object));
1110 data->attachedProperties()->insert(id, rv);
1115 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1116 const QMetaObject *attachedMetaObject, bool create)
1119 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1121 if (*idCache == -1 || !object)
1124 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1127 class QDeclarativeDataExtended {
1129 QDeclarativeDataExtended();
1130 ~QDeclarativeDataExtended();
1132 QHash<int, QObject *> attachedProperties;
1133 QDeclarativeNotifier objectNameNotifier;
1136 QDeclarativeDataExtended::QDeclarativeDataExtended()
1140 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1144 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1146 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1147 return &extendedData->objectNameNotifier;
1150 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1152 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1153 return &extendedData->attachedProperties;
1156 void QDeclarativeData::destroyed(QObject *object)
1158 if (deferredComponent)
1159 deferredComponent->release();
1161 if (nextContextObject)
1162 nextContextObject->prevContextObject = prevContextObject;
1163 if (prevContextObject)
1164 *prevContextObject = nextContextObject;
1166 QDeclarativeAbstractBinding *binding = bindings;
1168 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1169 binding->m_prevBinding = 0;
1170 binding->m_nextBinding = 0;
1179 propertyCache->release();
1181 if (ownContext && context)
1185 QDeclarativeGuard<QObject> *guard = guards;
1186 *guard = (QObject *)0;
1187 guard->objectDestroyed(object);
1194 delete extendedData;
1200 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
1202 if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
1205 void QDeclarativeData::objectNameChanged(QObject *)
1207 if (extendedData) objectNameNotifier()->notify();
1210 bool QDeclarativeData::hasBindingBit(int bit) const
1212 if (bindingBitsSize > bit)
1213 return bindingBits[bit / 32] & (1 << (bit % 32));
1218 void QDeclarativeData::clearBindingBit(int bit)
1220 if (bindingBitsSize > bit)
1221 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1224 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1226 if (bindingBitsSize <= bit) {
1227 int props = obj->metaObject()->propertyCount();
1228 Q_ASSERT(bit < props);
1230 int arraySize = (props + 31) / 32;
1231 int oldArraySize = bindingBitsSize / 32;
1233 bindingBits = (quint32 *)realloc(bindingBits,
1234 arraySize * sizeof(quint32));
1236 memset(bindingBits + oldArraySize,
1238 sizeof(quint32) * (arraySize - oldArraySize));
1240 bindingBitsSize = arraySize * 32;
1243 bindingBits[bit / 32] |= (1 << (bit % 32));
1247 Creates a QScriptValue allowing you to use \a object in QML script.
1248 \a engine is the QDeclarativeEngine it is to be created in.
1250 The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
1251 to the special needs of QML requiring more functionality than a standard
1254 QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
1255 QDeclarativeEngine* engine)
1257 QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
1258 return enginePriv->objectClass->newQObject(object);
1262 Returns the QDeclarativeContext for the executing QScript \a ctxt.
1264 QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
1266 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1267 Q_ASSERT(scopeNode.isValid());
1268 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1269 return contextClass->contextFromValue(scopeNode);
1273 Returns the QUrl associated with the script \a ctxt for the case that there is
1274 no QDeclarativeContext.
1276 QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt)
1278 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1279 Q_ASSERT(scopeNode.isValid());
1280 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1281 return contextClass->urlFromValue(scopeNode);
1284 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1286 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1287 if (url.authority().isEmpty())
1288 return QLatin1Char(':') + url.path();
1291 return url.toLocalFile();
1295 \qmlmethod object Qt::createComponent(url)
1297 Returns a \l Component object created using the QML file at the specified \a url,
1298 or \c null if an empty string was given.
1300 The returned component's \l Component::status property indicates whether the
1301 component was successfully created. If the status is \c Component.Error,
1302 see \l Component::errorString() for an error description.
1304 Call \l {Component::createObject()}{Component.createObject()} on the returned
1305 component to create an object instance of the component.
1309 \snippet doc/src/snippets/declarative/createComponent-simple.qml 0
1311 See \l {Dynamic Object Management in QML} for more information on using this function.
1313 To create a QML object from an arbitrary string of QML (instead of a file),
1314 use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
1317 QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
1319 QDeclarativeEnginePrivate *activeEnginePriv =
1320 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1321 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1323 if(ctxt->argumentCount() != 1) {
1324 return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments"));
1327 QString arg = ctxt->argument(0).toString();
1329 return engine->nullValue();
1330 QUrl url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt, QUrl(arg));
1331 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1332 QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
1333 QDeclarativeComponentPrivate::get(c)->creationContext = context;
1334 QDeclarativeData::get(c, true)->setImplicitDestructible();
1335 return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
1340 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
1342 Returns a new object created from the given \a string of QML which will have the specified \a parent,
1343 or \c null if there was an error in creating the object.
1345 If \a filepath is specified, it will be used for error reporting for the created object.
1347 Example (where \c parentItem is the id of an existing QML item):
1349 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
1351 In the case of an error, a QtScript Error object is thrown. This object has an additional property,
1352 \c qmlErrors, which is an array of the errors encountered.
1353 Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
1354 For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
1355 { "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
1357 Note that this function returns immediately, and therefore may not work if
1358 the \a qml string loads new components (that is, external QML files that have not yet been loaded).
1359 If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
1361 See \l {Dynamic Object Management in QML} for more information on using this function.
1364 QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
1366 QDeclarativeEnginePrivate *activeEnginePriv =
1367 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1368 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1370 if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
1371 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments"));
1373 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1376 QString qml = ctxt->argument(0).toString();
1378 return engine->nullValue();
1381 if(ctxt->argumentCount() > 2)
1382 url = QUrl(ctxt->argument(2).toString());
1384 url = QUrl(QLatin1String("inline"));
1386 if (url.isValid() && url.isRelative())
1387 url = context->resolvedUrl(url);
1389 QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
1391 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object"));
1393 QDeclarativeComponent component(activeEngine);
1394 component.setData(qml.toUtf8(), url);
1396 if(component.isError()) {
1397 QList<QDeclarativeError> errors = component.errors();
1398 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1399 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1401 foreach (const QDeclarativeError &error, errors){
1402 errstr += QLatin1String("\n ") + error.toString();
1403 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1404 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1405 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1406 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1407 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1408 arr.setProperty(i++, qmlErrObject);
1410 QScriptValue err = ctxt->throwError(errstr);
1411 err.setProperty(QLatin1String("qmlErrors"),arr);
1415 if (!component.isReady())
1416 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready"));
1418 QObject *obj = component.beginCreate(context->asQDeclarativeContext());
1420 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1421 component.completeCreate();
1423 if(component.isError()) {
1424 QList<QDeclarativeError> errors = component.errors();
1425 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1426 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1428 foreach (const QDeclarativeError &error, errors){
1429 errstr += QLatin1String("\n ") + error.toString();
1430 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1431 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1432 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1433 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1434 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1435 arr.setProperty(i++, qmlErrObject);
1437 QScriptValue err = ctxt->throwError(errstr);
1438 err.setProperty(QLatin1String("qmlErrors"),arr);
1444 obj->setParent(parentArg);
1446 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
1447 for (int ii = 0; ii < functions.count(); ++ii) {
1448 if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
1452 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1453 return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
1457 \qmlmethod bool Qt::isQtObject(object)
1458 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
1460 QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
1462 if (ctxt->argumentCount() == 0)
1463 return QScriptValue(engine, false);
1465 return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
1469 \qmlmethod Qt::vector3d(real x, real y, real z)
1470 Returns a Vector3D with the specified \c x, \c y and \c z.
1472 QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEngine *engine)
1474 if(ctxt->argumentCount() != 3)
1475 return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments"));
1476 qsreal x = ctxt->argument(0).toNumber();
1477 qsreal y = ctxt->argument(1).toNumber();
1478 qsreal z = ctxt->argument(2).toNumber();
1479 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QVector3D(x, y, z)));
1483 \qmlmethod string Qt::formatDate(datetime date, variant format)
1485 Returns a string representation of \c date, optionally formatted according
1488 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1489 property, a QDate, or QDateTime value. The \a format parameter may be any of
1490 the possible format values as described for
1491 \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1493 If \a format is not specified, \a date is formatted using
1494 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1496 #ifndef QT_NO_DATESTRING
1497 QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine)
1499 int argCount = ctxt->argumentCount();
1500 if(argCount == 0 || argCount > 2)
1501 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments"));
1503 QDate date = ctxt->argument(0).toDateTime().date();
1504 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1505 if (argCount == 2) {
1506 QScriptValue formatArg = ctxt->argument(1);
1507 if (formatArg.isString()) {
1508 QString format = formatArg.toString();
1509 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1510 } else if (formatArg.isNumber()) {
1511 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1513 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
1516 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1520 \qmlmethod string Qt::formatTime(datetime time, variant format)
1522 Returns a string representation of \c time, optionally formatted according to
1525 The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
1526 value. The \a format parameter may be any of the possible format values as
1527 described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1529 If \a format is not specified, \a time is formatted using
1530 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1532 QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptEngine*engine)
1534 int argCount = ctxt->argumentCount();
1535 if(argCount == 0 || argCount > 2)
1536 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments"));
1539 QScriptValue sv = ctxt->argument(0);
1541 time = sv.toDateTime().time();
1542 else if (sv.toVariant().type() == QVariant::Time)
1543 time = sv.toVariant().toTime();
1545 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1546 if (argCount == 2) {
1547 QScriptValue formatArg = ctxt->argument(1);
1548 if (formatArg.isString()) {
1549 QString format = formatArg.toString();
1550 return engine->newVariant(QVariant::fromValue(time.toString(format)));
1551 } else if (formatArg.isNumber()) {
1552 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1554 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
1557 return engine->newVariant(QVariant::fromValue(time.toString(enumFormat)));
1561 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
1563 Returns a string representation of \c datetime, optionally formatted according to
1566 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1567 property, a QDate, QTime, or QDateTime value.
1569 If \a format is not provided, \a dateTime is formatted using
1570 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
1571 \a format should be either.
1574 \o One of the Qt::DateFormat enumeration values, such as
1575 \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
1576 \o A string that specifies the format of the returned string, as detailed below.
1579 If \a format specifies a format string, it should use the following expressions
1580 to specify the date:
1583 \header \i Expression \i Output
1584 \row \i d \i the day as number without a leading zero (1 to 31)
1585 \row \i dd \i the day as number with a leading zero (01 to 31)
1587 \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
1588 Uses QDate::shortDayName().
1590 \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
1591 Uses QDate::longDayName().
1592 \row \i M \i the month as number without a leading zero (1-12)
1593 \row \i MM \i the month as number with a leading zero (01-12)
1595 \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
1596 Uses QDate::shortMonthName().
1598 \i the long localized month name (e.g. 'January' to 'December').
1599 Uses QDate::longMonthName().
1600 \row \i yy \i the year as two digit number (00-99)
1601 \row \i yyyy \i the year as four digit number
1604 In addition the following expressions can be used to specify the time:
1607 \header \i Expression \i Output
1609 \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1611 \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1612 \row \i m \i the minute without a leading zero (0 to 59)
1613 \row \i mm \i the minute with a leading zero (00 to 59)
1614 \row \i s \i the second without a leading zero (0 to 59)
1615 \row \i ss \i the second with a leading zero (00 to 59)
1616 \row \i z \i the milliseconds without leading zeroes (0 to 999)
1617 \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
1619 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1621 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
1624 All other input characters will be ignored. Any sequence of characters that
1625 are enclosed in single quotes will be treated as text and not be used as an
1626 expression. Two consecutive single quotes ("''") are replaced by a single quote
1629 For example, if the following date/time value was specified:
1632 // 21 May 2001 14:13:09
1633 var dateTime = new Date(2001, 5, 21, 14, 13, 09)
1636 This \a dateTime value could be passed to \c Qt.formatDateTime(),
1637 \l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
1638 with the \a format values below to produce the following results:
1641 \header \i Format \i Result
1642 \row \i "dd.MM.yyyy" \i 21.05.2001
1643 \row \i "ddd MMMM d yy" \i Tue May 21 01
1644 \row \i "hh:mm:ss.zzz" \i 14:13:09.042
1645 \row \i "h:m:s ap" \i 2:13:9 pm
1648 QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScriptEngine*engine)
1650 int argCount = ctxt->argumentCount();
1651 if(argCount == 0 || argCount > 2)
1652 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments"));
1654 QDateTime date = ctxt->argument(0).toDateTime();
1655 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1656 if (argCount == 2) {
1657 QScriptValue formatArg = ctxt->argument(1);
1658 if (formatArg.isString()) {
1659 QString format = formatArg.toString();
1660 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1661 } else if (formatArg.isNumber()) {
1662 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1664 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
1667 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1669 #endif // QT_NO_DATESTRING
1672 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
1674 Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
1675 All components should be in the range 0-1 inclusive.
1677 QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
1679 int argCount = ctxt->argumentCount();
1680 if(argCount < 3 || argCount > 4)
1681 return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments"));
1682 qsreal r = ctxt->argument(0).toNumber();
1683 qsreal g = ctxt->argument(1).toNumber();
1684 qsreal b = ctxt->argument(2).toNumber();
1685 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1696 return engine->toScriptValue(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
1700 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
1702 Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
1703 All components should be in the range 0-1 inclusive.
1705 QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
1707 int argCount = ctxt->argumentCount();
1708 if(argCount < 3 || argCount > 4)
1709 return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments"));
1710 qsreal h = ctxt->argument(0).toNumber();
1711 qsreal s = ctxt->argument(1).toNumber();
1712 qsreal l = ctxt->argument(2).toNumber();
1713 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1724 return engine->toScriptValue(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
1728 \qmlmethod rect Qt::rect(int x, int y, int width, int height)
1730 Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
1732 The returned object has \c x, \c y, \c width and \c height attributes with the given values.
1734 QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
1736 if(ctxt->argumentCount() != 4)
1737 return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments"));
1739 qsreal x = ctxt->argument(0).toNumber();
1740 qsreal y = ctxt->argument(1).toNumber();
1741 qsreal w = ctxt->argument(2).toNumber();
1742 qsreal h = ctxt->argument(3).toNumber();
1744 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
1748 \qmlmethod point Qt::point(int x, int y)
1749 Returns a Point with the specified \c x and \c y coordinates.
1751 QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
1753 if(ctxt->argumentCount() != 2)
1754 return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
1755 qsreal x = ctxt->argument(0).toNumber();
1756 qsreal y = ctxt->argument(1).toNumber();
1757 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QPointF(x, y)));
1761 \qmlmethod Qt::size(int width, int height)
1762 Returns a Size with the specified \c width and \c height.
1764 QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
1766 if(ctxt->argumentCount() != 2)
1767 return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
1768 qsreal w = ctxt->argument(0).toNumber();
1769 qsreal h = ctxt->argument(1).toNumber();
1770 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QSizeF(w, h)));
1774 \qmlmethod color Qt::lighter(color baseColor, real factor)
1775 Returns a color lighter than \c baseColor by the \c factor provided.
1777 If the factor is greater than 1.0, this functions returns a lighter color.
1778 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
1779 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
1780 If the factor is 0 or negative, the return value is unspecified.
1782 The function converts the current RGB color to HSV, multiplies the value (V) component
1783 by factor and converts the color back to RGB.
1785 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
1787 QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
1789 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1790 return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments"));
1791 QVariant v = ctxt->argument(0).toVariant();
1793 if (v.userType() == QVariant::Color)
1794 color = v.value<QColor>();
1795 else if (v.userType() == QVariant::String) {
1797 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1799 return engine->nullValue();
1801 return engine->nullValue();
1802 qsreal factor = 1.5;
1803 if (ctxt->argumentCount() == 2)
1804 factor = ctxt->argument(1).toNumber();
1805 color = color.lighter(int(qRound(factor*100.)));
1806 return engine->toScriptValue(QVariant::fromValue(color));
1810 \qmlmethod color Qt::darker(color baseColor, real factor)
1811 Returns a color darker than \c baseColor by the \c factor provided.
1813 If the factor is greater than 1.0, this function returns a darker color.
1814 Setting factor to 3.0 returns a color that has one-third the brightness.
1815 If the factor is less than 1.0, the return color is lighter, but we recommend using
1816 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
1817 value is unspecified.
1819 The function converts the current RGB color to HSV, divides the value (V) component
1820 by factor and converts the color back to RGB.
1822 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
1824 QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
1826 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1827 return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments"));
1828 QVariant v = ctxt->argument(0).toVariant();
1830 if (v.userType() == QVariant::Color)
1831 color = v.value<QColor>();
1832 else if (v.userType() == QVariant::String) {
1834 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1836 return engine->nullValue();
1838 return engine->nullValue();
1839 qsreal factor = 2.0;
1840 if (ctxt->argumentCount() == 2)
1841 factor = ctxt->argument(1).toNumber();
1842 color = color.darker(int(qRound(factor*100.)));
1843 return engine->toScriptValue(QVariant::fromValue(color));
1847 \qmlmethod bool Qt::openUrlExternally(url target)
1848 Attempts to open the specified \c target url in an external application, based on the user's desktop preferences. Returns true if it succeeds, and false otherwise.
1850 QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
1852 if(ctxt->argumentCount() < 1)
1853 return QScriptValue(e, false);
1855 #ifndef QT_NO_DESKTOPSERVICES
1856 ret = QDesktopServices::openUrl(QDeclarativeScriptEngine::get(e)->resolvedUrl(ctxt, QUrl(ctxt->argument(0).toString())));
1858 return QScriptValue(e, ret);
1862 \qmlmethod list<string> Qt::fontFamilies()
1863 Returns a list of the font families available to the application.
1866 QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e)
1868 if(ctxt->argumentCount() != 0)
1869 return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments"));
1871 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e);
1872 QFontDatabase database;
1873 return p->scriptValueFromVariant(database.families());
1877 \qmlmethod string Qt::md5(data)
1878 Returns a hex string of the md5 hash of \c data.
1880 QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
1882 if (ctxt->argumentCount() != 1)
1883 return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments"));
1885 QByteArray data = ctxt->argument(0).toString().toUtf8();
1886 QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
1888 return QScriptValue(QLatin1String(result.toHex()));
1892 \qmlmethod string Qt::btoa(data)
1893 Binary to ASCII - this function returns a base64 encoding of \c data.
1895 QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
1897 if (ctxt->argumentCount() != 1)
1898 return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments"));
1900 QByteArray data = ctxt->argument(0).toString().toUtf8();
1902 return QScriptValue(QLatin1String(data.toBase64()));
1906 \qmlmethod string Qt::atob(data)
1907 ASCII to binary - this function returns a base64 decoding of \c data.
1910 QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
1912 if (ctxt->argumentCount() != 1)
1913 return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments"));
1915 QByteArray data = ctxt->argument(0).toString().toUtf8();
1917 return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
1920 QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
1922 if(ctxt->argumentCount() < 1)
1923 return e->newVariant(QVariant(false));
1927 for (int i=0; i<ctxt->argumentCount(); ++i) {
1928 if (!msg.isEmpty()) msg += ' ';
1929 msg += ctxt->argument(i).toString().toLocal8Bit();
1930 // does not support firebug "%[a-z]" formatting, since firebug really
1931 // does just ignore the format letter, which makes it pointless.
1934 qDebug("%s",msg.constData());
1936 return e->newVariant(QVariant(true));
1939 void QDeclarativeEnginePrivate::sendQuit()
1941 Q_Q(QDeclarativeEngine);
1943 if (q->receivers(SIGNAL(quit())) == 0) {
1944 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1948 static void dumpwarning(const QDeclarativeError &error)
1950 qWarning().nospace() << qPrintable(error.toString());
1953 static void dumpwarning(const QList<QDeclarativeError> &errors)
1955 for (int ii = 0; ii < errors.count(); ++ii)
1956 dumpwarning(errors.at(ii));
1959 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1961 Q_Q(QDeclarativeEngine);
1962 q->warnings(QList<QDeclarativeError>() << error);
1963 if (outputWarningsToStdErr)
1967 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1969 Q_Q(QDeclarativeEngine);
1970 q->warnings(errors);
1971 if (outputWarningsToStdErr)
1972 dumpwarning(errors);
1975 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1978 QDeclarativeEnginePrivate::get(engine)->warning(error);
1983 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1986 QDeclarativeEnginePrivate::get(engine)->warning(error);
1991 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1994 engine->warning(error);
1999 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
2002 engine->warning(error);
2008 \qmlmethod Qt::quit()
2009 This function causes the QDeclarativeEngine::quit() signal to be emitted.
2010 Within the \l {QML Viewer}, this causes the launcher application to exit;
2011 to quit a C++ application when this method is called, connect the
2012 QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot.
2015 QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
2017 QDeclarativeEnginePrivate *qe = get (e);
2019 return QScriptValue();
2023 \qmlmethod color Qt::tint(color baseColor, color tintColor)
2024 This function allows tinting one color with another.
2026 The tint color should usually be mostly transparent, or you will not be
2027 able to see the underlying color. The below example provides a slight red
2028 tint by having the tint color be pure red which is only 1/16th opaque.
2033 x: 0; width: 80; height: 80
2034 color: "lightsteelblue"
2037 x: 100; width: 80; height: 80
2038 color: Qt.tint("lightsteelblue", "#10FF0000")
2042 \image declarative-rect_tint.png
2044 Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
2046 QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
2048 if(ctxt->argumentCount() != 2)
2049 return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments"));
2051 QVariant v = ctxt->argument(0).toVariant();
2053 if (v.userType() == QVariant::Color)
2054 color = v.value<QColor>();
2055 else if (v.userType() == QVariant::String) {
2057 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2059 return engine->nullValue();
2061 return engine->nullValue();
2064 v = ctxt->argument(1).toVariant();
2066 if (v.userType() == QVariant::Color)
2067 tintColor = v.value<QColor>();
2068 else if (v.userType() == QVariant::String) {
2070 tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2072 return engine->nullValue();
2074 return engine->nullValue();
2078 int a = tintColor.alpha();
2080 finalColor = tintColor;
2084 qreal a = tintColor.alphaF();
2085 qreal inv_a = 1.0 - a;
2087 finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
2088 tintColor.greenF() * a + color.greenF() * inv_a,
2089 tintColor.blueF() * a + color.blueF() * inv_a,
2090 a + inv_a * color.alphaF());
2093 return engine->toScriptValue(QVariant::fromValue(finalColor));
2096 QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
2098 if (variantIsScarceResource(val)) {
2099 return scarceResourceClass->newScarceResource(val);
2100 } else if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
2101 QDeclarativeListReferencePrivate *p =
2102 QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
2104 return listClass->newList(p->property, p->propertyType);
2106 return scriptEngine.nullValue();
2108 } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
2109 const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
2110 QScriptValue rv = scriptEngine.newArray(list.count());
2111 for (int ii = 0; ii < list.count(); ++ii) {
2112 QObject *object = list.at(ii);
2113 rv.setProperty(ii, objectClass->newQObject(object));
2116 } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
2117 return valueTypeClass->newObject(val, vt);
2121 QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
2123 return objectClass->newQObject(obj);
2125 return scriptEngine.toScriptValue(val);
2130 If the variant is a scarce resource (consumes a large amount of memory, or
2131 only a limited number of them can be held in memory at any given time without
2132 exhausting supply for future use) we need to release the scarce resource
2133 after evaluation of the javascript binding is complete.
2135 bool QDeclarativeEnginePrivate::variantIsScarceResource(const QVariant& val)
2137 if (val.type() == QVariant::Pixmap) {
2139 } else if (val.type() == QVariant::Image) {
2147 This function should be called prior to evaluation of any js expression,
2148 so that scarce resources are not freed prematurely (eg, if there is a
2149 nested javascript expression).
2151 void QDeclarativeEnginePrivate::referenceScarceResources()
2153 scarceResourcesRefCount += 1;
2157 This function should be called after evaluation of the js expression is
2158 complete, and so the scarce resources may be freed safely.
2160 void QDeclarativeEnginePrivate::dereferenceScarceResources()
2162 Q_ASSERT(scarceResourcesRefCount > 0);
2163 scarceResourcesRefCount -= 1;
2165 // if the refcount is zero, then evaluation of the "top level"
2166 // expression must have completed. We can safely release the
2167 // scarce resources.
2168 if (scarceResourcesRefCount == 0) {
2169 // iterate through the list and release them all.
2170 // note that the actual SRD is owned by the JS engine,
2171 // so we cannot delete the SRD; but we can free the
2172 // memory used by the variant in the SRD.
2173 ScarceResourceData *srd = 0;
2174 while (scarceResources) {
2175 srd = scarceResources; // srd points to the "old" (current) head of the list
2176 scarceResources = srd->next; // srd->next is the "new" head of the list
2177 if (srd->next) srd->next->prev = &scarceResources; // newHead->prev = listptr.
2180 srd->releaseResource(); // release the old head node.
2185 QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
2187 QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
2188 if (dc == objectClass)
2189 return QVariant::fromValue(objectClass->toQObject(val));
2190 else if (dc == scarceResourceClass)
2191 return scarceResourceClass->toVariant(val);
2192 else if (dc == valueTypeClass)
2193 return valueTypeClass->toVariant(val);
2194 else if (dc == contextClass)
2197 // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
2198 if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
2199 QList<QObject *> list;
2200 int length = val.property(QLatin1String("length")).toInt32();
2201 for (int ii = 0; ii < length; ++ii) {
2202 QScriptValue arrayItem = val.property(ii);
2203 QObject *d = arrayItem.toQObject();
2206 return QVariant::fromValue(list);
2209 return val.toVariant();
2213 Adds \a path as a directory where the engine searches for
2214 installed modules in a URL-based directory structure.
2215 The \a path may be a local filesystem directory or a URL.
2217 The newly added \a path will be first in the importPathList().
2219 \sa setImportPathList(), {QML Modules}
2221 void QDeclarativeEngine::addImportPath(const QString& path)
2223 Q_D(QDeclarativeEngine);
2224 d->importDatabase.addImportPath(path);
2228 Returns the list of directories where the engine searches for
2229 installed modules in a URL-based directory structure.
2231 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
2232 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
2233 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
2234 provided by that module. A \c qmldir file is required for defining the
2235 type version mapping and possibly declarative extensions plugins.
2237 By default, the list contains the directory of the application executable,
2238 paths specified in the \c QML_IMPORT_PATH environment variable,
2239 and the builtin \c ImportsPath from QLibraryInfo.
2241 \sa addImportPath() setImportPathList()
2243 QStringList QDeclarativeEngine::importPathList() const
2245 Q_D(const QDeclarativeEngine);
2246 return d->importDatabase.importPathList();
2250 Sets \a paths as the list of directories where the engine searches for
2251 installed modules in a URL-based directory structure.
2253 By default, the list contains the directory of the application executable,
2254 paths specified in the \c QML_IMPORT_PATH environment variable,
2255 and the builtin \c ImportsPath from QLibraryInfo.
2257 \sa importPathList() addImportPath()
2259 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
2261 Q_D(QDeclarativeEngine);
2262 d->importDatabase.setImportPathList(paths);
2267 Adds \a path as a directory where the engine searches for
2268 native plugins for imported modules (referenced in the \c qmldir file).
2270 By default, the list contains only \c ., i.e. the engine searches
2271 in the directory of the \c qmldir file itself.
2273 The newly added \a path will be first in the pluginPathList().
2275 \sa setPluginPathList()
2277 void QDeclarativeEngine::addPluginPath(const QString& path)
2279 Q_D(QDeclarativeEngine);
2280 d->importDatabase.addPluginPath(path);
2285 Returns the list of directories where the engine searches for
2286 native plugins for imported modules (referenced in the \c qmldir file).
2288 By default, the list contains only \c ., i.e. the engine searches
2289 in the directory of the \c qmldir file itself.
2291 \sa addPluginPath() setPluginPathList()
2293 QStringList QDeclarativeEngine::pluginPathList() const
2295 Q_D(const QDeclarativeEngine);
2296 return d->importDatabase.pluginPathList();
2300 Sets the list of directories where the engine searches for
2301 native plugins for imported modules (referenced in the \c qmldir file)
2304 By default, the list contains only \c ., i.e. the engine searches
2305 in the directory of the \c qmldir file itself.
2307 \sa pluginPathList() addPluginPath()
2309 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
2311 Q_D(QDeclarativeEngine);
2312 d->importDatabase.setPluginPathList(paths);
2317 Imports the plugin named \a filePath with the \a uri provided.
2318 Returns true if the plugin was successfully imported; otherwise returns false.
2320 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
2322 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2324 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
2326 Q_D(QDeclarativeEngine);
2327 return d->importDatabase.importPlugin(filePath, uri, errors);
2331 Imports the plugin named \a filePath with the \a uri provided.
2332 Returns true if the plugin was successfully imported; otherwise returns false.
2334 On failure and if non-null, *\a errorString will be set to a message describing the failure.
2336 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2338 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
2340 Q_D(QDeclarativeEngine);
2341 QList<QDeclarativeError> errors;
2342 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
2343 if (!errors.isEmpty()) {
2345 for (int i = 0; i < errors.size(); ++i) {
2346 builtError = QString(QLatin1String("%1\n %2"))
2348 .arg(errors.at(i).toString());
2350 *errorString = builtError;
2356 \property QDeclarativeEngine::offlineStoragePath
2357 \brief the directory for storing offline user data
2359 Returns the directory where SQL and other offline
2362 QDeclarativeWebView and the SQL databases created with openDatabase()
2365 The default is QML/OfflineStorage in the platform-standard
2366 user application data directory.
2368 Note that the path may not currently exist on the filesystem, so
2369 callers wanting to \e create new files at this location should create
2370 it first - see QDir::mkpath().
2372 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
2374 Q_D(QDeclarativeEngine);
2375 d->scriptEngine.offlineStoragePath = dir;
2378 QString QDeclarativeEngine::offlineStoragePath() const
2380 Q_D(const QDeclarativeEngine);
2381 return d->scriptEngine.offlineStoragePath;
2384 static void voidptr_destructor(void *v)
2386 void **ptr = (void **)v;
2390 static void *voidptr_constructor(const void *v)
2395 return new void*(*(void **)v);
2399 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
2401 Q_Q(QDeclarativeEngine);
2403 if (!mo->superClass()) {
2404 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
2405 propertyCache.insert(mo, rv);
2408 QDeclarativePropertyCache *super = cache(mo->superClass());
2409 QDeclarativePropertyCache *rv = super->copy();
2411 propertyCache.insert(mo, rv);
2416 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
2417 QDeclarativeError &error)
2419 QList<QDeclarativeType *> types;
2421 int maxMinorVersion = 0;
2423 const QMetaObject *metaObject = type->metaObject();
2424 while (metaObject) {
2425 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
2426 type->majorVersion(), minorVersion);
2428 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
2434 metaObject = metaObject->superClass();
2437 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
2439 typePropertyCache.insert(qMakePair(type, minorVersion), c);
2443 QDeclarativePropertyCache *raw = cache(type->metaObject());
2445 bool hasCopied = false;
2447 for (int ii = 0; ii < types.count(); ++ii) {
2448 QDeclarativeType *currentType = types.at(ii);
2452 int rev = currentType->metaObjectRevision();
2453 int moIndex = types.count() - 1 - ii;
2455 if (raw->allowedRevisionCache[moIndex] != rev) {
2460 raw->allowedRevisionCache[moIndex] = rev;
2464 // Test revision compatibility - the basic rule is:
2465 // * Anything that is excluded, cannot overload something that is not excluded *
2467 // Signals override:
2468 // * other signals and methods of the same name.
2469 // * properties named on<Signal Name>
2470 // * automatic <property name>Changed notify signals
2472 // Methods override:
2473 // * other methods of the same name
2475 // Properties override:
2476 // * other elements of the same name
2478 bool overloadError = false;
2479 QString overloadName;
2482 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
2483 !overloadError && iter != raw->stringCache.end();
2486 QDeclarativePropertyCache::Data *d = *iter;
2487 if (raw->isAllowedInRevision(d))
2488 continue; // Not excluded - no problems
2490 // check that a regular "name" overload isn't happening
2491 QDeclarativePropertyCache::Data *current = d;
2492 while (!overloadError && current) {
2493 current = d->overrideData(current);
2494 if (current && raw->isAllowedInRevision(current))
2495 overloadError = true;
2500 if (overloadError) {
2501 if (hasCopied) raw->release();
2503 error.setDescription(QLatin1String("Type ") + QString::fromUtf8(type->qmlTypeName()) + QLatin1String(" ") + QString::number(type->majorVersion()) + QLatin1String(".") + QString::number(minorVersion) + QLatin1String(" contains an illegal property \"") + overloadName + QLatin1String("\". This is an error in the type's implementation."));
2507 if (!hasCopied) raw->addref();
2508 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
2510 if (minorVersion != maxMinorVersion) {
2512 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
2518 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
2520 QByteArray name = data->root->className();
2522 QByteArray ptr = name + '*';
2523 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
2525 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
2526 voidptr_constructor);
2527 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
2528 voidptr_constructor);
2530 m_qmlLists.insert(lst_type, ptr_type);
2531 m_compositeTypes.insert(ptr_type, data);
2535 bool QDeclarativeEnginePrivate::isList(int t) const
2537 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
2540 int QDeclarativeEnginePrivate::listType(int t) const
2542 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
2543 if (iter != m_qmlLists.end())
2546 return QDeclarativeMetaType::listType(t);
2549 bool QDeclarativeEnginePrivate::isQObject(int t)
2551 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
2554 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
2556 int t = v.userType();
2557 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
2559 return *(QObject **)(v.constData());
2561 return QDeclarativeMetaType::toQObject(v, ok);
2565 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
2567 if (m_compositeTypes.contains(t))
2568 return QDeclarativeMetaType::Object;
2569 else if (m_qmlLists.contains(t))
2570 return QDeclarativeMetaType::List;
2572 return QDeclarativeMetaType::typeCategory(t);
2575 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
2577 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2578 if (iter != m_compositeTypes.end()) {
2579 return (*iter)->root;
2581 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2582 return type?type->baseMetaObject():0;
2586 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
2588 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2589 if (iter != m_compositeTypes.end()) {
2590 return (*iter)->root;
2592 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2593 return type?type->metaObject():0;
2597 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
2599 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
2600 QFileInfo info(fileName);
2602 QString absolute = info.absoluteFilePath();
2604 #if defined(Q_OS_MAC)
2605 QString canonical = info.canonicalFilePath();
2606 #elif defined(Q_OS_WIN32)
2607 wchar_t buffer[1024];
2609 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
2610 if (rv == 0 || rv >= 1024) return true;
2611 rv = ::GetLongPathName(buffer, buffer, 1024);
2612 if (rv == 0 || rv >= 1024) return true;
2614 QString canonical((QChar *)buffer);
2617 int absoluteLength = absolute.length();
2618 int canonicalLength = canonical.length();
2620 int length = qMin(absoluteLength, canonicalLength);
2621 for (int ii = 0; ii < length; ++ii) {
2622 const QChar &a = absolute.at(absoluteLength - 1 - ii);
2623 const QChar &c = canonical.at(canonicalLength - 1 - ii);
2625 if (a.toLower() != c.toLower())