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 ** 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
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
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);
663 if (d->isDebugging) {
664 QDeclarativeEngineDebugServer::instance()->remEngine(this);
667 // if we are the parent of any of the qobject module api instances,
668 // we need to remove them from our internal list, in order to prevent
669 // a segfault in engine private dtor.
670 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
671 QObject *currQObjectApi = 0;
672 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
673 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
674 currInstance = d->moduleApiInstances.value(key);
675 currQObjectApi = currInstance->qobjectApi;
676 if (this->children().contains(currQObjectApi)) {
677 delete currQObjectApi;
679 d->moduleApiInstances.remove(key);
684 /*! \fn void QDeclarativeEngine::quit()
685 This signal is emitted when the QML loaded by the engine would like to quit.
688 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
689 This signal is emitted when \a warnings messages are generated by QML.
693 Clears the engine's internal component cache.
695 Normally the QDeclarativeEngine caches components loaded from qml
696 files. This method clears this cache and forces the component to be
699 void QDeclarativeEngine::clearComponentCache()
701 Q_D(QDeclarativeEngine);
702 d->typeLoader.clearCache();
706 Returns the engine's root context.
708 The root context is automatically created by the QDeclarativeEngine.
709 Data that should be available to all QML component instances
710 instantiated by the engine should be put in the root context.
712 Additional data that should only be available to a subset of
713 component instances should be added to sub-contexts parented to the
716 QDeclarativeContext *QDeclarativeEngine::rootContext() const
718 Q_D(const QDeclarativeEngine);
719 return d->rootContext;
723 Sets the \a factory to use for creating QNetworkAccessManager(s).
725 QNetworkAccessManager is used for all network access by QML. By
726 implementing a factory it is possible to create custom
727 QNetworkAccessManager with specialized caching, proxy and cookie
730 The factory must be set before executing the engine.
732 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
734 Q_D(QDeclarativeEngine);
735 QMutexLocker locker(&d->mutex);
736 d->networkAccessManagerFactory = factory;
740 Returns the current QDeclarativeNetworkAccessManagerFactory.
742 \sa setNetworkAccessManagerFactory()
744 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
746 Q_D(const QDeclarativeEngine);
747 return d->networkAccessManagerFactory;
750 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
752 QMutexLocker locker(&mutex);
753 QNetworkAccessManager *nam;
754 if (networkAccessManagerFactory) {
755 nam = networkAccessManagerFactory->create(parent);
757 nam = new QNetworkAccessManager(parent);
763 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
765 Q_Q(const QDeclarativeEngine);
766 if (!networkAccessManager)
767 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
768 return networkAccessManager;
772 Returns a common QNetworkAccessManager which can be used by any QML
773 element instantiated by this engine.
775 If a QDeclarativeNetworkAccessManagerFactory has been set and a
776 QNetworkAccessManager has not yet been created, the
777 QDeclarativeNetworkAccessManagerFactory will be used to create the
778 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
779 will have no proxy or cache set.
781 \sa setNetworkAccessManagerFactory()
783 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
785 Q_D(const QDeclarativeEngine);
786 return d->getNetworkAccessManager();
791 Sets the \a provider to use for images requested via the \e
792 image: url scheme, with host \a providerId. The QDeclarativeEngine
793 takes ownership of \a provider.
795 Image providers enable support for pixmap and threaded image
796 requests. See the QDeclarativeImageProvider documentation for details on
797 implementing and using image providers.
799 All required image providers should be added to the engine before any
800 QML sources files are loaded.
802 Note that images loaded from a QDeclarativeImageProvider are cached
803 by QPixmapCache, similar to any image loaded by QML.
805 \sa removeImageProvider()
807 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
809 Q_D(QDeclarativeEngine);
810 QMutexLocker locker(&d->mutex);
811 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
815 Returns the QDeclarativeImageProvider set for \a providerId.
817 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
819 Q_D(const QDeclarativeEngine);
820 QMutexLocker locker(&d->mutex);
821 return d->imageProviders.value(providerId).data();
825 Removes the QDeclarativeImageProvider for \a providerId.
827 Returns the provider if it was found; otherwise returns 0.
829 \sa addImageProvider()
831 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
833 Q_D(QDeclarativeEngine);
834 QMutexLocker locker(&d->mutex);
835 d->imageProviders.take(providerId);
838 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
840 QMutexLocker locker(&mutex);
841 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
844 return provider->imageType();
845 return QDeclarativeImageProvider::Invalid;
848 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
850 QMutexLocker locker(&mutex);
851 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
854 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
855 return provider->requestTexture(imageId, size, req_size);
860 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
862 QMutexLocker locker(&mutex);
864 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
867 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
868 image = provider->requestImage(imageId, size, req_size);
873 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
875 QMutexLocker locker(&mutex);
877 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
880 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
881 pixmap = provider->requestPixmap(imageId, size, req_size);
887 Return the base URL for this engine. The base URL is only used to
888 resolve components when a relative URL is passed to the
889 QDeclarativeComponent constructor.
891 If a base URL has not been explicitly set, this method returns the
892 application's current working directory.
896 QUrl QDeclarativeEngine::baseUrl() const
898 Q_D(const QDeclarativeEngine);
899 if (d->baseUrl.isEmpty()) {
900 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
907 Set the base URL for this engine to \a url.
911 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
913 Q_D(QDeclarativeEngine);
918 Returns true if warning messages will be output to stderr in addition
919 to being emitted by the warnings() signal, otherwise false.
921 The default value is true.
923 bool QDeclarativeEngine::outputWarningsToStandardError() const
925 Q_D(const QDeclarativeEngine);
926 return d->outputWarningsToStdErr;
930 Set whether warning messages will be output to stderr to \a enabled.
932 If \a enabled is true, any warning messages generated by QML will be
933 output to stderr and emitted by the warnings() signal. If \a enabled
934 is false, on the warnings() signal will be emitted. This allows
935 applications to handle warning output themselves.
937 The default value is true.
939 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
941 Q_D(QDeclarativeEngine);
942 d->outputWarningsToStdErr = enabled;
946 Returns the QDeclarativeContext for the \a object, or 0 if no
947 context has been set.
949 When the QDeclarativeEngine instantiates a QObject, the context is
952 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
957 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
959 QDeclarativeData *data =
960 static_cast<QDeclarativeData *>(priv->declarativeData);
964 else if (data->outerContext)
965 return data->outerContext->asQDeclarativeContext();
971 Sets the QDeclarativeContext for the \a object to \a context.
972 If the \a object already has a context, a warning is
973 output, but the context is not changed.
975 When the QDeclarativeEngine instantiates a QObject, the context is
978 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
980 if (!object || !context)
983 QDeclarativeData *data = QDeclarativeData::get(object, true);
985 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
989 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
990 contextData->addObject(object);
994 \enum QDeclarativeEngine::ObjectOwnership
996 Ownership controls whether or not QML automatically destroys the
997 QObject when the object is garbage collected by the JavaScript
998 engine. The two ownership options are:
1000 \value CppOwnership The object is owned by C++ code, and will
1001 never be deleted by QML. The JavaScript destroy() method cannot be
1002 used on objects with CppOwnership. This option is similar to
1003 QScriptEngine::QtOwnership.
1005 \value JavaScriptOwnership The object is owned by JavaScript.
1006 When the object is returned to QML as the return value of a method
1007 call or property access, QML will delete the object if there are no
1008 remaining JavaScript references to it and it has no
1009 QObject::parent(). This option is similar to
1010 QScriptEngine::ScriptOwnership.
1012 Generally an application doesn't need to set an object's ownership
1013 explicitly. QML uses a heuristic to set the default object
1014 ownership. By default, an object that is created by QML has
1015 JavaScriptOwnership. The exception to this are the root objects
1016 created by calling QDeclarativeCompnent::create() or
1017 QDeclarativeComponent::beginCreate() which have CppOwnership by
1018 default. The ownership of these root-level objects is considered to
1019 have been transferred to the C++ caller.
1021 Objects not-created by QML have CppOwnership by default. The
1022 exception to this is objects returned from a C++ method call. The
1023 ownership of these objects is passed to JavaScript.
1025 Calling setObjectOwnership() overrides the default ownership
1026 heuristic used by QML.
1030 Sets the \a ownership of \a object.
1032 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
1037 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
1041 ddata->indestructible = (ownership == CppOwnership)?true:false;
1042 ddata->explicitIndestructibleSet = true;
1046 Returns the ownership of \a object.
1048 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
1051 return CppOwnership;
1053 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
1055 return CppOwnership;
1057 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
1060 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
1062 QDeclarativeData *data = QDeclarativeData::get(object);
1064 if (data && data->deferredComponent) {
1065 if (QDeclarativeDebugService::isDebuggingEnabled()) {
1066 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
1067 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
1068 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
1069 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
1070 if (data->outerContext)
1071 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
1073 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
1075 QDeclarativeComponentPrivate::ConstructionState state;
1076 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
1078 data->deferredComponent->release();
1079 data->deferredComponent = 0;
1081 QDeclarativeComponentPrivate::complete(ep, &state);
1082 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
1086 QDeclarativeContext *qmlContext(const QObject *obj)
1088 return QDeclarativeEngine::contextForObject(obj);
1091 QDeclarativeEngine *qmlEngine(const QObject *obj)
1093 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
1094 return context?context->engine():0;
1097 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
1099 QDeclarativeData *data = QDeclarativeData::get(object);
1101 return 0; // Attached properties are only on objects created by QML
1103 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
1107 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
1111 rv = pf(const_cast<QObject *>(object));
1114 data->attachedProperties()->insert(id, rv);
1119 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1120 const QMetaObject *attachedMetaObject, bool create)
1123 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1125 if (*idCache == -1 || !object)
1128 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1131 class QDeclarativeDataExtended {
1133 QDeclarativeDataExtended();
1134 ~QDeclarativeDataExtended();
1136 QHash<int, QObject *> attachedProperties;
1137 QDeclarativeNotifier objectNameNotifier;
1140 QDeclarativeDataExtended::QDeclarativeDataExtended()
1144 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1148 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1150 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1151 return &extendedData->objectNameNotifier;
1154 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1156 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1157 return &extendedData->attachedProperties;
1160 void QDeclarativeData::destroyed(QObject *object)
1162 if (deferredComponent)
1163 deferredComponent->release();
1165 if (nextContextObject)
1166 nextContextObject->prevContextObject = prevContextObject;
1167 if (prevContextObject)
1168 *prevContextObject = nextContextObject;
1170 QDeclarativeAbstractBinding *binding = bindings;
1172 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1173 binding->m_prevBinding = 0;
1174 binding->m_nextBinding = 0;
1183 propertyCache->release();
1185 if (ownContext && context)
1189 QDeclarativeGuard<QObject> *guard = guards;
1190 *guard = (QObject *)0;
1191 guard->objectDestroyed(object);
1198 delete extendedData;
1204 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
1206 if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
1209 void QDeclarativeData::objectNameChanged(QObject *)
1211 if (extendedData) objectNameNotifier()->notify();
1214 bool QDeclarativeData::hasBindingBit(int bit) const
1216 if (bindingBitsSize > bit)
1217 return bindingBits[bit / 32] & (1 << (bit % 32));
1222 void QDeclarativeData::clearBindingBit(int bit)
1224 if (bindingBitsSize > bit)
1225 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1228 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1230 if (bindingBitsSize <= bit) {
1231 int props = obj->metaObject()->propertyCount();
1232 Q_ASSERT(bit < props);
1234 int arraySize = (props + 31) / 32;
1235 int oldArraySize = bindingBitsSize / 32;
1237 bindingBits = (quint32 *)realloc(bindingBits,
1238 arraySize * sizeof(quint32));
1240 memset(bindingBits + oldArraySize,
1242 sizeof(quint32) * (arraySize - oldArraySize));
1244 bindingBitsSize = arraySize * 32;
1247 bindingBits[bit / 32] |= (1 << (bit % 32));
1251 Creates a QScriptValue allowing you to use \a object in QML script.
1252 \a engine is the QDeclarativeEngine it is to be created in.
1254 The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
1255 to the special needs of QML requiring more functionality than a standard
1258 QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
1259 QDeclarativeEngine* engine)
1261 QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
1262 return enginePriv->objectClass->newQObject(object);
1266 Returns the QDeclarativeContext for the executing QScript \a ctxt.
1268 QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
1270 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1271 Q_ASSERT(scopeNode.isValid());
1272 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1273 return contextClass->contextFromValue(scopeNode);
1277 Returns the QUrl associated with the script \a ctxt for the case that there is
1278 no QDeclarativeContext.
1280 QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt)
1282 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1283 Q_ASSERT(scopeNode.isValid());
1284 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1285 return contextClass->urlFromValue(scopeNode);
1288 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1290 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1291 if (url.authority().isEmpty())
1292 return QLatin1Char(':') + url.path();
1295 return url.toLocalFile();
1299 \qmlmethod object Qt::createComponent(url)
1301 Returns a \l Component object created using the QML file at the specified \a url,
1302 or \c null if an empty string was given.
1304 The returned component's \l Component::status property indicates whether the
1305 component was successfully created. If the status is \c Component.Error,
1306 see \l Component::errorString() for an error description.
1308 Call \l {Component::createObject()}{Component.createObject()} on the returned
1309 component to create an object instance of the component.
1313 \snippet doc/src/snippets/declarative/createComponent-simple.qml 0
1315 See \l {Dynamic Object Management in QML} for more information on using this function.
1317 To create a QML object from an arbitrary string of QML (instead of a file),
1318 use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
1321 QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
1323 QDeclarativeEnginePrivate *activeEnginePriv =
1324 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1325 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1327 if(ctxt->argumentCount() != 1) {
1328 return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments"));
1331 QString arg = ctxt->argument(0).toString();
1333 return engine->nullValue();
1334 QUrl url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt, QUrl(arg));
1335 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1336 QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
1337 QDeclarativeComponentPrivate::get(c)->creationContext = context;
1338 QDeclarativeData::get(c, true)->setImplicitDestructible();
1339 return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
1344 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
1346 Returns a new object created from the given \a string of QML which will have the specified \a parent,
1347 or \c null if there was an error in creating the object.
1349 If \a filepath is specified, it will be used for error reporting for the created object.
1351 Example (where \c parentItem is the id of an existing QML item):
1353 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
1355 In the case of an error, a QtScript Error object is thrown. This object has an additional property,
1356 \c qmlErrors, which is an array of the errors encountered.
1357 Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
1358 For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
1359 { "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
1361 Note that this function returns immediately, and therefore may not work if
1362 the \a qml string loads new components (that is, external QML files that have not yet been loaded).
1363 If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
1365 See \l {Dynamic Object Management in QML} for more information on using this function.
1368 QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
1370 QDeclarativeEnginePrivate *activeEnginePriv =
1371 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1372 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1374 if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
1375 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments"));
1377 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1380 QString qml = ctxt->argument(0).toString();
1382 return engine->nullValue();
1385 if(ctxt->argumentCount() > 2)
1386 url = QUrl(ctxt->argument(2).toString());
1388 url = QUrl(QLatin1String("inline"));
1390 if (url.isValid() && url.isRelative())
1391 url = context->resolvedUrl(url);
1393 QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
1395 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object"));
1397 QDeclarativeComponent component(activeEngine);
1398 component.setData(qml.toUtf8(), url);
1400 if(component.isError()) {
1401 QList<QDeclarativeError> errors = component.errors();
1402 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1403 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1405 foreach (const QDeclarativeError &error, errors){
1406 errstr += QLatin1String("\n ") + error.toString();
1407 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1408 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1409 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1410 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1411 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1412 arr.setProperty(i++, qmlErrObject);
1414 QScriptValue err = ctxt->throwError(errstr);
1415 err.setProperty(QLatin1String("qmlErrors"),arr);
1419 if (!component.isReady())
1420 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready"));
1422 QObject *obj = component.beginCreate(context->asQDeclarativeContext());
1424 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1425 component.completeCreate();
1427 if(component.isError()) {
1428 QList<QDeclarativeError> errors = component.errors();
1429 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1430 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1432 foreach (const QDeclarativeError &error, errors){
1433 errstr += QLatin1String("\n ") + error.toString();
1434 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1435 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1436 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1437 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1438 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1439 arr.setProperty(i++, qmlErrObject);
1441 QScriptValue err = ctxt->throwError(errstr);
1442 err.setProperty(QLatin1String("qmlErrors"),arr);
1448 obj->setParent(parentArg);
1450 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
1451 for (int ii = 0; ii < functions.count(); ++ii) {
1452 if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
1456 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1457 return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
1461 \qmlmethod bool Qt::isQtObject(object)
1462 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
1464 QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
1466 if (ctxt->argumentCount() == 0)
1467 return QScriptValue(engine, false);
1469 return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
1473 \qmlmethod Qt::vector3d(real x, real y, real z)
1474 Returns a Vector3D with the specified \c x, \c y and \c z.
1476 QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEngine *engine)
1478 if(ctxt->argumentCount() != 3)
1479 return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments"));
1480 qsreal x = ctxt->argument(0).toNumber();
1481 qsreal y = ctxt->argument(1).toNumber();
1482 qsreal z = ctxt->argument(2).toNumber();
1483 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QVector3D(x, y, z)));
1487 \qmlmethod string Qt::formatDate(datetime date, variant format)
1489 Returns a string representation of \c date, optionally formatted according
1492 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1493 property, a QDate, or QDateTime value. The \a format parameter may be any of
1494 the possible format values as described for
1495 \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1497 If \a format is not specified, \a date is formatted using
1498 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1500 #ifndef QT_NO_DATESTRING
1501 QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine)
1503 int argCount = ctxt->argumentCount();
1504 if(argCount == 0 || argCount > 2)
1505 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments"));
1507 QDate date = ctxt->argument(0).toDateTime().date();
1508 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1509 if (argCount == 2) {
1510 QScriptValue formatArg = ctxt->argument(1);
1511 if (formatArg.isString()) {
1512 QString format = formatArg.toString();
1513 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1514 } else if (formatArg.isNumber()) {
1515 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1517 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
1520 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1524 \qmlmethod string Qt::formatTime(datetime time, variant format)
1526 Returns a string representation of \c time, optionally formatted according to
1529 The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
1530 value. The \a format parameter may be any of the possible format values as
1531 described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1533 If \a format is not specified, \a time is formatted using
1534 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1536 QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptEngine*engine)
1538 int argCount = ctxt->argumentCount();
1539 if(argCount == 0 || argCount > 2)
1540 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments"));
1543 QScriptValue sv = ctxt->argument(0);
1545 time = sv.toDateTime().time();
1546 else if (sv.toVariant().type() == QVariant::Time)
1547 time = sv.toVariant().toTime();
1549 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1550 if (argCount == 2) {
1551 QScriptValue formatArg = ctxt->argument(1);
1552 if (formatArg.isString()) {
1553 QString format = formatArg.toString();
1554 return engine->newVariant(QVariant::fromValue(time.toString(format)));
1555 } else if (formatArg.isNumber()) {
1556 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1558 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
1561 return engine->newVariant(QVariant::fromValue(time.toString(enumFormat)));
1565 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
1567 Returns a string representation of \c datetime, optionally formatted according to
1570 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1571 property, a QDate, QTime, or QDateTime value.
1573 If \a format is not provided, \a dateTime is formatted using
1574 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
1575 \a format should be either.
1578 \o One of the Qt::DateFormat enumeration values, such as
1579 \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
1580 \o A string that specifies the format of the returned string, as detailed below.
1583 If \a format specifies a format string, it should use the following expressions
1584 to specify the date:
1587 \header \i Expression \i Output
1588 \row \i d \i the day as number without a leading zero (1 to 31)
1589 \row \i dd \i the day as number with a leading zero (01 to 31)
1591 \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
1592 Uses QDate::shortDayName().
1594 \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
1595 Uses QDate::longDayName().
1596 \row \i M \i the month as number without a leading zero (1-12)
1597 \row \i MM \i the month as number with a leading zero (01-12)
1599 \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
1600 Uses QDate::shortMonthName().
1602 \i the long localized month name (e.g. 'January' to 'December').
1603 Uses QDate::longMonthName().
1604 \row \i yy \i the year as two digit number (00-99)
1605 \row \i yyyy \i the year as four digit number
1608 In addition the following expressions can be used to specify the time:
1611 \header \i Expression \i Output
1613 \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1615 \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1616 \row \i m \i the minute without a leading zero (0 to 59)
1617 \row \i mm \i the minute with a leading zero (00 to 59)
1618 \row \i s \i the second without a leading zero (0 to 59)
1619 \row \i ss \i the second with a leading zero (00 to 59)
1620 \row \i z \i the milliseconds without leading zeroes (0 to 999)
1621 \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
1623 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1625 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
1628 All other input characters will be ignored. Any sequence of characters that
1629 are enclosed in single quotes will be treated as text and not be used as an
1630 expression. Two consecutive single quotes ("''") are replaced by a single quote
1633 For example, if the following date/time value was specified:
1636 // 21 May 2001 14:13:09
1637 var dateTime = new Date(2001, 5, 21, 14, 13, 09)
1640 This \a dateTime value could be passed to \c Qt.formatDateTime(),
1641 \l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
1642 with the \a format values below to produce the following results:
1645 \header \i Format \i Result
1646 \row \i "dd.MM.yyyy" \i 21.05.2001
1647 \row \i "ddd MMMM d yy" \i Tue May 21 01
1648 \row \i "hh:mm:ss.zzz" \i 14:13:09.042
1649 \row \i "h:m:s ap" \i 2:13:9 pm
1652 QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScriptEngine*engine)
1654 int argCount = ctxt->argumentCount();
1655 if(argCount == 0 || argCount > 2)
1656 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments"));
1658 QDateTime date = ctxt->argument(0).toDateTime();
1659 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1660 if (argCount == 2) {
1661 QScriptValue formatArg = ctxt->argument(1);
1662 if (formatArg.isString()) {
1663 QString format = formatArg.toString();
1664 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1665 } else if (formatArg.isNumber()) {
1666 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1668 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
1671 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1673 #endif // QT_NO_DATESTRING
1676 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
1678 Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
1679 All components should be in the range 0-1 inclusive.
1681 QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
1683 int argCount = ctxt->argumentCount();
1684 if(argCount < 3 || argCount > 4)
1685 return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments"));
1686 qsreal r = ctxt->argument(0).toNumber();
1687 qsreal g = ctxt->argument(1).toNumber();
1688 qsreal b = ctxt->argument(2).toNumber();
1689 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1700 return engine->toScriptValue(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
1704 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
1706 Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
1707 All components should be in the range 0-1 inclusive.
1709 QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
1711 int argCount = ctxt->argumentCount();
1712 if(argCount < 3 || argCount > 4)
1713 return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments"));
1714 qsreal h = ctxt->argument(0).toNumber();
1715 qsreal s = ctxt->argument(1).toNumber();
1716 qsreal l = ctxt->argument(2).toNumber();
1717 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1728 return engine->toScriptValue(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
1732 \qmlmethod rect Qt::rect(int x, int y, int width, int height)
1734 Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
1736 The returned object has \c x, \c y, \c width and \c height attributes with the given values.
1738 QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
1740 if(ctxt->argumentCount() != 4)
1741 return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments"));
1743 qsreal x = ctxt->argument(0).toNumber();
1744 qsreal y = ctxt->argument(1).toNumber();
1745 qsreal w = ctxt->argument(2).toNumber();
1746 qsreal h = ctxt->argument(3).toNumber();
1748 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
1752 \qmlmethod point Qt::point(int x, int y)
1753 Returns a Point with the specified \c x and \c y coordinates.
1755 QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
1757 if(ctxt->argumentCount() != 2)
1758 return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
1759 qsreal x = ctxt->argument(0).toNumber();
1760 qsreal y = ctxt->argument(1).toNumber();
1761 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QPointF(x, y)));
1765 \qmlmethod Qt::size(int width, int height)
1766 Returns a Size with the specified \c width and \c height.
1768 QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
1770 if(ctxt->argumentCount() != 2)
1771 return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
1772 qsreal w = ctxt->argument(0).toNumber();
1773 qsreal h = ctxt->argument(1).toNumber();
1774 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QSizeF(w, h)));
1778 \qmlmethod color Qt::lighter(color baseColor, real factor)
1779 Returns a color lighter than \c baseColor by the \c factor provided.
1781 If the factor is greater than 1.0, this functions returns a lighter color.
1782 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
1783 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
1784 If the factor is 0 or negative, the return value is unspecified.
1786 The function converts the current RGB color to HSV, multiplies the value (V) component
1787 by factor and converts the color back to RGB.
1789 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
1791 QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
1793 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1794 return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments"));
1795 QVariant v = ctxt->argument(0).toVariant();
1797 if (v.userType() == QVariant::Color)
1798 color = v.value<QColor>();
1799 else if (v.userType() == QVariant::String) {
1801 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1803 return engine->nullValue();
1805 return engine->nullValue();
1806 qsreal factor = 1.5;
1807 if (ctxt->argumentCount() == 2)
1808 factor = ctxt->argument(1).toNumber();
1809 color = color.lighter(int(qRound(factor*100.)));
1810 return engine->toScriptValue(QVariant::fromValue(color));
1814 \qmlmethod color Qt::darker(color baseColor, real factor)
1815 Returns a color darker than \c baseColor by the \c factor provided.
1817 If the factor is greater than 1.0, this function returns a darker color.
1818 Setting factor to 3.0 returns a color that has one-third the brightness.
1819 If the factor is less than 1.0, the return color is lighter, but we recommend using
1820 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
1821 value is unspecified.
1823 The function converts the current RGB color to HSV, divides the value (V) component
1824 by factor and converts the color back to RGB.
1826 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
1828 QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
1830 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1831 return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments"));
1832 QVariant v = ctxt->argument(0).toVariant();
1834 if (v.userType() == QVariant::Color)
1835 color = v.value<QColor>();
1836 else if (v.userType() == QVariant::String) {
1838 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1840 return engine->nullValue();
1842 return engine->nullValue();
1843 qsreal factor = 2.0;
1844 if (ctxt->argumentCount() == 2)
1845 factor = ctxt->argument(1).toNumber();
1846 color = color.darker(int(qRound(factor*100.)));
1847 return engine->toScriptValue(QVariant::fromValue(color));
1851 \qmlmethod bool Qt::openUrlExternally(url target)
1852 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.
1854 QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
1856 if(ctxt->argumentCount() < 1)
1857 return QScriptValue(e, false);
1859 #ifndef QT_NO_DESKTOPSERVICES
1860 ret = QDesktopServices::openUrl(QDeclarativeScriptEngine::get(e)->resolvedUrl(ctxt, QUrl(ctxt->argument(0).toString())));
1862 return QScriptValue(e, ret);
1866 \qmlmethod list<string> Qt::fontFamilies()
1867 Returns a list of the font families available to the application.
1870 QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e)
1872 if(ctxt->argumentCount() != 0)
1873 return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments"));
1875 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e);
1876 QFontDatabase database;
1877 return p->scriptValueFromVariant(database.families());
1881 \qmlmethod string Qt::md5(data)
1882 Returns a hex string of the md5 hash of \c data.
1884 QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
1886 if (ctxt->argumentCount() != 1)
1887 return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments"));
1889 QByteArray data = ctxt->argument(0).toString().toUtf8();
1890 QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
1892 return QScriptValue(QLatin1String(result.toHex()));
1896 \qmlmethod string Qt::btoa(data)
1897 Binary to ASCII - this function returns a base64 encoding of \c data.
1899 QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
1901 if (ctxt->argumentCount() != 1)
1902 return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments"));
1904 QByteArray data = ctxt->argument(0).toString().toUtf8();
1906 return QScriptValue(QLatin1String(data.toBase64()));
1910 \qmlmethod string Qt::atob(data)
1911 ASCII to binary - this function returns a base64 decoding of \c data.
1914 QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
1916 if (ctxt->argumentCount() != 1)
1917 return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments"));
1919 QByteArray data = ctxt->argument(0).toString().toUtf8();
1921 return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
1924 QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
1926 if(ctxt->argumentCount() < 1)
1927 return e->newVariant(QVariant(false));
1931 for (int i=0; i<ctxt->argumentCount(); ++i) {
1932 if (!msg.isEmpty()) msg += ' ';
1933 msg += ctxt->argument(i).toString().toLocal8Bit();
1934 // does not support firebug "%[a-z]" formatting, since firebug really
1935 // does just ignore the format letter, which makes it pointless.
1938 qDebug("%s",msg.constData());
1940 return e->newVariant(QVariant(true));
1943 void QDeclarativeEnginePrivate::sendQuit()
1945 Q_Q(QDeclarativeEngine);
1947 if (q->receivers(SIGNAL(quit())) == 0) {
1948 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1952 static void dumpwarning(const QDeclarativeError &error)
1954 qWarning().nospace() << qPrintable(error.toString());
1957 static void dumpwarning(const QList<QDeclarativeError> &errors)
1959 for (int ii = 0; ii < errors.count(); ++ii)
1960 dumpwarning(errors.at(ii));
1963 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1965 Q_Q(QDeclarativeEngine);
1966 q->warnings(QList<QDeclarativeError>() << error);
1967 if (outputWarningsToStdErr)
1971 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1973 Q_Q(QDeclarativeEngine);
1974 q->warnings(errors);
1975 if (outputWarningsToStdErr)
1976 dumpwarning(errors);
1979 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1982 QDeclarativeEnginePrivate::get(engine)->warning(error);
1987 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1990 QDeclarativeEnginePrivate::get(engine)->warning(error);
1995 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1998 engine->warning(error);
2003 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
2006 engine->warning(error);
2012 \qmlmethod Qt::quit()
2013 This function causes the QDeclarativeEngine::quit() signal to be emitted.
2014 Within the \l {QML Viewer}, this causes the launcher application to exit;
2015 to quit a C++ application when this method is called, connect the
2016 QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot.
2019 QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
2021 QDeclarativeEnginePrivate *qe = get (e);
2023 return QScriptValue();
2027 \qmlmethod color Qt::tint(color baseColor, color tintColor)
2028 This function allows tinting one color with another.
2030 The tint color should usually be mostly transparent, or you will not be
2031 able to see the underlying color. The below example provides a slight red
2032 tint by having the tint color be pure red which is only 1/16th opaque.
2037 x: 0; width: 80; height: 80
2038 color: "lightsteelblue"
2041 x: 100; width: 80; height: 80
2042 color: Qt.tint("lightsteelblue", "#10FF0000")
2046 \image declarative-rect_tint.png
2048 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.
2050 QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
2052 if(ctxt->argumentCount() != 2)
2053 return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments"));
2055 QVariant v = ctxt->argument(0).toVariant();
2057 if (v.userType() == QVariant::Color)
2058 color = v.value<QColor>();
2059 else if (v.userType() == QVariant::String) {
2061 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2063 return engine->nullValue();
2065 return engine->nullValue();
2068 v = ctxt->argument(1).toVariant();
2070 if (v.userType() == QVariant::Color)
2071 tintColor = v.value<QColor>();
2072 else if (v.userType() == QVariant::String) {
2074 tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2076 return engine->nullValue();
2078 return engine->nullValue();
2082 int a = tintColor.alpha();
2084 finalColor = tintColor;
2088 qreal a = tintColor.alphaF();
2089 qreal inv_a = 1.0 - a;
2091 finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
2092 tintColor.greenF() * a + color.greenF() * inv_a,
2093 tintColor.blueF() * a + color.blueF() * inv_a,
2094 a + inv_a * color.alphaF());
2097 return engine->toScriptValue(QVariant::fromValue(finalColor));
2100 QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
2102 if (variantIsScarceResource(val)) {
2103 return scarceResourceClass->newScarceResource(val);
2104 } else if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
2105 QDeclarativeListReferencePrivate *p =
2106 QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
2108 return listClass->newList(p->property, p->propertyType);
2110 return scriptEngine.nullValue();
2112 } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
2113 const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
2114 QScriptValue rv = scriptEngine.newArray(list.count());
2115 for (int ii = 0; ii < list.count(); ++ii) {
2116 QObject *object = list.at(ii);
2117 rv.setProperty(ii, objectClass->newQObject(object));
2120 } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
2121 return valueTypeClass->newObject(val, vt);
2125 QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
2127 return objectClass->newQObject(obj);
2129 return scriptEngine.toScriptValue(val);
2134 If the variant is a scarce resource (consumes a large amount of memory, or
2135 only a limited number of them can be held in memory at any given time without
2136 exhausting supply for future use) we need to release the scarce resource
2137 after evaluation of the javascript binding is complete.
2139 bool QDeclarativeEnginePrivate::variantIsScarceResource(const QVariant& val)
2141 if (val.type() == QVariant::Pixmap) {
2143 } else if (val.type() == QVariant::Image) {
2151 This function should be called prior to evaluation of any js expression,
2152 so that scarce resources are not freed prematurely (eg, if there is a
2153 nested javascript expression).
2155 void QDeclarativeEnginePrivate::referenceScarceResources()
2157 scarceResourcesRefCount += 1;
2161 This function should be called after evaluation of the js expression is
2162 complete, and so the scarce resources may be freed safely.
2164 void QDeclarativeEnginePrivate::dereferenceScarceResources()
2166 Q_ASSERT(scarceResourcesRefCount > 0);
2167 scarceResourcesRefCount -= 1;
2169 // if the refcount is zero, then evaluation of the "top level"
2170 // expression must have completed. We can safely release the
2171 // scarce resources.
2172 if (scarceResourcesRefCount == 0) {
2173 // iterate through the list and release them all.
2174 // note that the actual SRD is owned by the JS engine,
2175 // so we cannot delete the SRD; but we can free the
2176 // memory used by the variant in the SRD.
2177 ScarceResourceData *srd = 0;
2178 while (scarceResources) {
2179 srd = scarceResources; // srd points to the "old" (current) head of the list
2180 scarceResources = srd->next; // srd->next is the "new" head of the list
2181 if (srd->next) srd->next->prev = &scarceResources; // newHead->prev = listptr.
2184 srd->releaseResource(); // release the old head node.
2189 QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
2191 QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
2192 if (dc == objectClass)
2193 return QVariant::fromValue(objectClass->toQObject(val));
2194 else if (dc == scarceResourceClass)
2195 return scarceResourceClass->toVariant(val);
2196 else if (dc == valueTypeClass)
2197 return valueTypeClass->toVariant(val);
2198 else if (dc == contextClass)
2201 // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
2202 if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
2203 QList<QObject *> list;
2204 int length = val.property(QLatin1String("length")).toInt32();
2205 for (int ii = 0; ii < length; ++ii) {
2206 QScriptValue arrayItem = val.property(ii);
2207 QObject *d = arrayItem.toQObject();
2210 return QVariant::fromValue(list);
2213 return val.toVariant();
2217 Adds \a path as a directory where the engine searches for
2218 installed modules in a URL-based directory structure.
2219 The \a path may be a local filesystem directory or a URL.
2221 The newly added \a path will be first in the importPathList().
2223 \sa setImportPathList(), {QML Modules}
2225 void QDeclarativeEngine::addImportPath(const QString& path)
2227 Q_D(QDeclarativeEngine);
2228 d->importDatabase.addImportPath(path);
2232 Returns the list of directories where the engine searches for
2233 installed modules in a URL-based directory structure.
2235 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
2236 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
2237 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
2238 provided by that module. A \c qmldir file is required for defining the
2239 type version mapping and possibly declarative extensions plugins.
2241 By default, the list contains the directory of the application executable,
2242 paths specified in the \c QML_IMPORT_PATH environment variable,
2243 and the builtin \c ImportsPath from QLibraryInfo.
2245 \sa addImportPath() setImportPathList()
2247 QStringList QDeclarativeEngine::importPathList() const
2249 Q_D(const QDeclarativeEngine);
2250 return d->importDatabase.importPathList();
2254 Sets \a paths as the list of directories where the engine searches for
2255 installed modules in a URL-based directory structure.
2257 By default, the list contains the directory of the application executable,
2258 paths specified in the \c QML_IMPORT_PATH environment variable,
2259 and the builtin \c ImportsPath from QLibraryInfo.
2261 \sa importPathList() addImportPath()
2263 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
2265 Q_D(QDeclarativeEngine);
2266 d->importDatabase.setImportPathList(paths);
2271 Adds \a path as a directory where the engine searches for
2272 native plugins for imported modules (referenced in the \c qmldir file).
2274 By default, the list contains only \c ., i.e. the engine searches
2275 in the directory of the \c qmldir file itself.
2277 The newly added \a path will be first in the pluginPathList().
2279 \sa setPluginPathList()
2281 void QDeclarativeEngine::addPluginPath(const QString& path)
2283 Q_D(QDeclarativeEngine);
2284 d->importDatabase.addPluginPath(path);
2289 Returns the list of directories where the engine searches for
2290 native plugins for imported modules (referenced in the \c qmldir file).
2292 By default, the list contains only \c ., i.e. the engine searches
2293 in the directory of the \c qmldir file itself.
2295 \sa addPluginPath() setPluginPathList()
2297 QStringList QDeclarativeEngine::pluginPathList() const
2299 Q_D(const QDeclarativeEngine);
2300 return d->importDatabase.pluginPathList();
2304 Sets the list of directories where the engine searches for
2305 native plugins for imported modules (referenced in the \c qmldir file)
2308 By default, the list contains only \c ., i.e. the engine searches
2309 in the directory of the \c qmldir file itself.
2311 \sa pluginPathList() addPluginPath()
2313 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
2315 Q_D(QDeclarativeEngine);
2316 d->importDatabase.setPluginPathList(paths);
2321 Imports the plugin named \a filePath with the \a uri provided.
2322 Returns true if the plugin was successfully imported; otherwise returns false.
2324 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
2326 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2328 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
2330 Q_D(QDeclarativeEngine);
2331 return d->importDatabase.importPlugin(filePath, uri, errors);
2335 Imports the plugin named \a filePath with the \a uri provided.
2336 Returns true if the plugin was successfully imported; otherwise returns false.
2338 On failure and if non-null, *\a errorString will be set to a message describing the failure.
2340 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2342 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
2344 Q_D(QDeclarativeEngine);
2345 QList<QDeclarativeError> errors;
2346 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
2347 if (!errors.isEmpty()) {
2349 for (int i = 0; i < errors.size(); ++i) {
2350 builtError = QString(QLatin1String("%1\n %2"))
2352 .arg(errors.at(i).toString());
2354 *errorString = builtError;
2360 \property QDeclarativeEngine::offlineStoragePath
2361 \brief the directory for storing offline user data
2363 Returns the directory where SQL and other offline
2366 QDeclarativeWebView and the SQL databases created with openDatabase()
2369 The default is QML/OfflineStorage in the platform-standard
2370 user application data directory.
2372 Note that the path may not currently exist on the filesystem, so
2373 callers wanting to \e create new files at this location should create
2374 it first - see QDir::mkpath().
2376 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
2378 Q_D(QDeclarativeEngine);
2379 d->scriptEngine.offlineStoragePath = dir;
2382 QString QDeclarativeEngine::offlineStoragePath() const
2384 Q_D(const QDeclarativeEngine);
2385 return d->scriptEngine.offlineStoragePath;
2388 static void voidptr_destructor(void *v)
2390 void **ptr = (void **)v;
2394 static void *voidptr_constructor(const void *v)
2399 return new void*(*(void **)v);
2403 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
2405 Q_Q(QDeclarativeEngine);
2407 if (!mo->superClass()) {
2408 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
2409 propertyCache.insert(mo, rv);
2412 QDeclarativePropertyCache *super = cache(mo->superClass());
2413 QDeclarativePropertyCache *rv = super->copy();
2415 propertyCache.insert(mo, rv);
2420 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
2421 QDeclarativeError &error)
2423 QList<QDeclarativeType *> types;
2425 int maxMinorVersion = 0;
2427 const QMetaObject *metaObject = type->metaObject();
2428 while (metaObject) {
2429 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
2430 type->majorVersion(), minorVersion);
2432 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
2438 metaObject = metaObject->superClass();
2441 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
2443 typePropertyCache.insert(qMakePair(type, minorVersion), c);
2447 QDeclarativePropertyCache *raw = cache(type->metaObject());
2449 bool hasCopied = false;
2451 for (int ii = 0; ii < types.count(); ++ii) {
2452 QDeclarativeType *currentType = types.at(ii);
2456 int rev = currentType->metaObjectRevision();
2457 int moIndex = types.count() - 1 - ii;
2459 if (raw->allowedRevisionCache[moIndex] != rev) {
2464 raw->allowedRevisionCache[moIndex] = rev;
2468 // Test revision compatibility - the basic rule is:
2469 // * Anything that is excluded, cannot overload something that is not excluded *
2471 // Signals override:
2472 // * other signals and methods of the same name.
2473 // * properties named on<Signal Name>
2474 // * automatic <property name>Changed notify signals
2476 // Methods override:
2477 // * other methods of the same name
2479 // Properties override:
2480 // * other elements of the same name
2482 bool overloadError = false;
2483 QString overloadName;
2486 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
2487 !overloadError && iter != raw->stringCache.end();
2490 QDeclarativePropertyCache::Data *d = *iter;
2491 if (raw->isAllowedInRevision(d))
2492 continue; // Not excluded - no problems
2494 // check that a regular "name" overload isn't happening
2495 QDeclarativePropertyCache::Data *current = d;
2496 while (!overloadError && current) {
2497 current = d->overrideData(current);
2498 if (current && raw->isAllowedInRevision(current))
2499 overloadError = true;
2504 if (overloadError) {
2505 if (hasCopied) raw->release();
2507 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."));
2511 if (!hasCopied) raw->addref();
2512 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
2514 if (minorVersion != maxMinorVersion) {
2516 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
2522 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
2524 QByteArray name = data->root->className();
2526 QByteArray ptr = name + '*';
2527 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
2529 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
2530 voidptr_constructor);
2531 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
2532 voidptr_constructor);
2534 m_qmlLists.insert(lst_type, ptr_type);
2535 m_compositeTypes.insert(ptr_type, data);
2539 bool QDeclarativeEnginePrivate::isList(int t) const
2541 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
2544 int QDeclarativeEnginePrivate::listType(int t) const
2546 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
2547 if (iter != m_qmlLists.end())
2550 return QDeclarativeMetaType::listType(t);
2553 bool QDeclarativeEnginePrivate::isQObject(int t)
2555 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
2558 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
2560 int t = v.userType();
2561 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
2563 return *(QObject **)(v.constData());
2565 return QDeclarativeMetaType::toQObject(v, ok);
2569 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
2571 if (m_compositeTypes.contains(t))
2572 return QDeclarativeMetaType::Object;
2573 else if (m_qmlLists.contains(t))
2574 return QDeclarativeMetaType::List;
2576 return QDeclarativeMetaType::typeCategory(t);
2579 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
2581 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2582 if (iter != m_compositeTypes.end()) {
2583 return (*iter)->root;
2585 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2586 return type?type->baseMetaObject():0;
2590 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
2592 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2593 if (iter != m_compositeTypes.end()) {
2594 return (*iter)->root;
2596 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2597 return type?type->metaObject():0;
2601 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
2603 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
2604 QFileInfo info(fileName);
2606 QString absolute = info.absoluteFilePath();
2608 #if defined(Q_OS_MAC)
2609 QString canonical = info.canonicalFilePath();
2610 #elif defined(Q_OS_WIN32)
2611 wchar_t buffer[1024];
2613 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
2614 if (rv == 0 || rv >= 1024) return true;
2615 rv = ::GetLongPathName(buffer, buffer, 1024);
2616 if (rv == 0 || rv >= 1024) return true;
2618 QString canonical((QChar *)buffer);
2621 int absoluteLength = absolute.length();
2622 int canonicalLength = canonical.length();
2624 int length = qMin(absoluteLength, canonicalLength);
2625 for (int ii = 0; ii < length; ++ii) {
2626 const QChar &a = absolute.at(absoluteLength - 1 - ii);
2627 const QChar &c = canonical.at(canonicalLength - 1 - ii);
2629 if (a.toLower() != c.toLower())