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 <qsgtexture.h>
111 #ifdef Q_OS_WIN // for %APPDATA%
112 #include <qt_windows.h>
113 #include <qlibrary.h>
116 #define CSIDL_APPDATA 0x001a // <username>\Application Data
119 Q_DECLARE_METATYPE(QDeclarativeProperty)
124 \qmlclass QtObject QObject
125 \ingroup qml-utility-elements
127 \brief The QtObject element is the most basic element in QML.
129 The QtObject element is a non-visual element which contains only the
132 It can be useful to create a QtObject if you need an extremely
133 lightweight element to enclose a set of custom properties:
135 \snippet doc/src/snippets/declarative/qtobject.qml 0
137 It can also be useful for C++ integration, as it is just a plain
138 QObject. See the QObject documentation for further details.
141 \qmlproperty string QML:QtObject::objectName
142 This property holds the QObject::objectName for this specific object instance.
144 This allows a C++ application to locate an item within a QML component
145 using the QObject::findChild() method. For example, the following C++
146 application locates the child \l Rectangle item and dynamically changes its
155 width: 200; height: 200
168 QDeclarativeView view;
169 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
172 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
174 item->setProperty("color", QColor(Qt::yellow));
178 struct StaticQtMetaObject : public QObject
180 static const QMetaObject *get()
181 { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
184 static bool qt_QmlQtModule_registered = false;
185 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
187 void QDeclarativeEnginePrivate::defineModule()
189 qmlRegisterType<QDeclarativeComponent>("QtQuick",1,0,"Component");
190 qmlRegisterType<QObject>("QtQuick",1,0,"QtObject");
191 qmlRegisterType<QDeclarativeWorkerScript>("QtQuick",1,0,"WorkerScript");
193 #ifndef QT_NO_IMPORT_QT47_QML
194 qmlRegisterType<QDeclarativeComponent>("Qt",4,7,"Component");
195 qmlRegisterType<QObject>("Qt",4,7,"QtObject");
196 qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,7,"WorkerScript");
199 qmlRegisterType<QDeclarativeBinding>();
203 \qmlclass QML:Qt QDeclarativeEnginePrivate
204 \ingroup qml-utility-elements
205 \brief The QML global Qt object provides useful enums and functions from Qt.
207 \keyword QmlGlobalQtObject
209 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
211 The \c Qt object is a global object with utility functions, properties and enums.
213 It is not instantiable; to use it, call the members of the global \c Qt object directly.
220 color: Qt.rgba(1, 0, 0, 1)
221 text: Qt.md5("hello, world")
228 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
229 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
233 The Qt object also contains helper functions for creating objects of specific
234 data types. This is primarily useful when setting the properties of an item
235 when the property has one of the following types:
238 \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()}
239 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
240 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
241 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
242 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
245 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
247 \section1 Date/Time Formatters
249 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
252 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
253 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
254 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
257 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
260 \section1 Dynamic Object Creation
261 The following functions on the global object allow you to dynamically create QML
262 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
266 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
267 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
273 \qmlproperty object QML:Qt::application
276 The \c application object provides access to global application state
277 properties shared by many QML components.
283 \o \c application.active
285 This read-only property indicates whether the application is the top-most and focused
286 application, and the user is able to interact with the application. The property
287 is false when the application is in the background, the device keylock or screen
288 saver is active, the screen backlight is turned off, or the global system dialog
289 is being displayed on top of the application. It can be used for stopping and
290 pausing animations, timers and active processing of data in order to save device
291 battery power and free device memory and processor load when the application is not
295 \o \c application.layoutDirection
297 This read-only property can be used to query the default layout direction of the
298 application. On system start-up, the default layout direction depends on the
299 application's language. The property has a value of \c Qt.RightToLeft in locales
300 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
301 where the reading direction flows from left to right. You can bind to this
302 property to customize your application layouts to support both layout directions.
307 \o Qt.LeftToRight - Text and graphics elements should be positioned
309 \o Qt.RightToLeft - Text and graphics elements should be positioned
314 The following example uses the \c application object to indicate
315 whether the application is currently active:
317 \snippet doc/src/snippets/declarative/application.qml document
323 \qmlmethod object Qt::include(string url, jsobject callback)
325 Includes another JavaScript file. This method can only be used from within JavaScript files,
326 and not regular QML files.
328 This imports all functions from \a url into the current script's namespace.
330 Qt.include() returns an object that describes the status of the operation. The object has
331 a single property, \c {status}, that is set to one of the following values:
334 \header \o Symbol \o Value \o Description
335 \row \o result.OK \o 0 \o The include completed successfully.
336 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
337 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
338 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
339 An additional \c exception property will be set in this case.
342 The \c status property will be updated as the operation progresses.
344 If provided, \a callback is invoked when the operation completes. The callback is passed
345 the same object as is returned from the Qt.include() call.
347 // Qt.include() is implemented in qdeclarativeinclude.cpp
350 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
351 : captureProperties(false), rootContext(0), isDebugging(false),
352 outputWarningsToStdErr(true), contextClass(0), sharedContext(0), sharedScope(0),
353 objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
354 inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
355 inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
356 scarceResources(0), scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
359 if (!qt_QmlQtModule_registered) {
360 qt_QmlQtModule_registered = true;
361 QDeclarativeItemModule::defineModule();
362 QDeclarativeUtilModule::defineModule();
363 QDeclarativeEnginePrivate::defineModule();
364 QSGItemsModule::defineModule();
365 QDeclarativeValueTypeFactory::registerValueTypes();
367 globalClass = new QDeclarativeGlobalScriptClass(&scriptEngine);
371 \qmlmethod url Qt::resolvedUrl(url url)
372 Returns \a url resolved relative to the URL of the caller.
374 QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
377 QDeclarativeContextData *ctxt = p->getContext(context);
379 return ctxt->resolvedUrl(url);
381 return p->getUrl(context).resolved(url);
383 return baseUrl.resolved(url);
386 QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv)
387 : p(priv), sqlQueryClass(0), namedNodeMapClass(0), nodeListClass(0)
389 // Note that all documentation for stuff put on the global object goes in
390 // doc/src/declarative/globalobject.qdoc
392 bool mainthread = priv != 0;
394 QScriptValue qtObject =
395 newQMetaObject(StaticQtMetaObject::get());
396 globalObject().setProperty(QLatin1String("Qt"), qtObject);
398 #ifndef QT_NO_DESKTOPSERVICES
399 offlineStoragePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation).replace(QLatin1Char('/'), QDir::separator())
400 + QDir::separator() + QLatin1String("QML")
401 + QDir::separator() + QLatin1String("OfflineStorage");
404 #ifndef QT_NO_XMLSTREAMREADER
405 qt_add_qmlxmlhttprequest(this);
407 qt_add_qmlsqldatabase(this);
408 // XXX A Multimedia "Qt.Sound" class also needs to be made available,
409 // XXX but we don't want a dependency in that cirection.
410 // XXX When the above a done some better way, that way should also be
411 // XXX used to add Qt.Sound class.
415 qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::include, 2));
417 qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::worker_include, 2));
419 qtObject.setProperty(QLatin1String("isQtObject"), newFunction(QDeclarativeEnginePrivate::isQtObject, 1));
420 qtObject.setProperty(QLatin1String("rgba"), newFunction(QDeclarativeEnginePrivate::rgba, 4));
421 qtObject.setProperty(QLatin1String("hsla"), newFunction(QDeclarativeEnginePrivate::hsla, 4));
422 qtObject.setProperty(QLatin1String("rect"), newFunction(QDeclarativeEnginePrivate::rect, 4));
423 qtObject.setProperty(QLatin1String("point"), newFunction(QDeclarativeEnginePrivate::point, 2));
424 qtObject.setProperty(QLatin1String("size"), newFunction(QDeclarativeEnginePrivate::size, 2));
425 qtObject.setProperty(QLatin1String("vector3d"), newFunction(QDeclarativeEnginePrivate::vector3d, 3));
429 qtObject.setProperty(QLatin1String("lighter"), newFunction(QDeclarativeEnginePrivate::lighter, 1));
430 qtObject.setProperty(QLatin1String("darker"), newFunction(QDeclarativeEnginePrivate::darker, 1));
431 qtObject.setProperty(QLatin1String("tint"), newFunction(QDeclarativeEnginePrivate::tint, 2));
434 #ifndef QT_NO_DATESTRING
435 //date/time formatting
436 qtObject.setProperty(QLatin1String("formatDate"),newFunction(QDeclarativeEnginePrivate::formatDate, 2));
437 qtObject.setProperty(QLatin1String("formatTime"),newFunction(QDeclarativeEnginePrivate::formatTime, 2));
438 qtObject.setProperty(QLatin1String("formatDateTime"),newFunction(QDeclarativeEnginePrivate::formatDateTime, 2));
442 qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1));
443 qtObject.setProperty(QLatin1String("fontFamilies"),newFunction(QDeclarativeEnginePrivate::fontFamilies, 0));
444 qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1));
445 qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1));
446 qtObject.setProperty(QLatin1String("atob"),newFunction(QDeclarativeEnginePrivate::atob, 1));
447 qtObject.setProperty(QLatin1String("quit"), newFunction(QDeclarativeEnginePrivate::quit, 0));
448 qtObject.setProperty(QLatin1String("resolvedUrl"),newFunction(QDeclarativeScriptEngine::resolvedUrl, 1));
451 qtObject.setProperty(QLatin1String("createQmlObject"),
452 newFunction(QDeclarativeEnginePrivate::createQmlObject, 1));
453 qtObject.setProperty(QLatin1String("createComponent"),
454 newFunction(QDeclarativeEnginePrivate::createComponent, 1));
457 //firebug/webkit compat
458 QScriptValue consoleObject = newObject();
459 consoleObject.setProperty(QLatin1String("log"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
460 consoleObject.setProperty(QLatin1String("debug"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
461 globalObject().setProperty(QLatin1String("console"), consoleObject);
463 // translation functions need to be installed
464 // before the global script class is constructed (QTBUG-6437)
465 installTranslatorFunctions();
468 QDeclarativeScriptEngine::~QDeclarativeScriptEngine()
470 delete sqlQueryClass;
471 delete nodeListClass;
472 delete namedNodeMapClass;
475 QScriptValue QDeclarativeScriptEngine::resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine)
477 QString arg = ctxt->argument(0).toString();
478 QUrl r = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt,QUrl(arg));
479 return QScriptValue(r.toString());
482 QNetworkAccessManager *QDeclarativeScriptEngine::networkAccessManager()
484 return p->getNetworkAccessManager();
487 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
489 Q_ASSERT(inProgressCreations == 0);
490 Q_ASSERT(bindValues.isEmpty());
491 Q_ASSERT(parserStatus.isEmpty());
494 QDeclarativeCleanup *c = cleanup;
496 if (cleanup) cleanup->prev = &cleanup;
508 delete scarceResourceClass;
509 scarceResourceClass = 0;
510 delete valueTypeClass;
512 delete typeNameClass;
519 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
521 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
523 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
525 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
526 delete (*iter)->qobjectApi;
531 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
536 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
538 for (int ii = 0; ii < pss.count; ++ii) {
539 QDeclarativeParserStatus *ps = pss.at(ii);
546 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
548 QObjectPrivate *p = QObjectPrivate::get(o);
549 if (p->declarativeData) {
550 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
551 if (d->ownContext && d->context) {
552 d->context->destroy();
558 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
560 static_cast<QDeclarativeData *>(d)->destroyed(o);
563 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
565 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
568 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
570 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
573 void QDeclarativeEnginePrivate::init()
575 Q_Q(QDeclarativeEngine);
576 qRegisterMetaType<QVariant>("QVariant");
577 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
578 qRegisterMetaType<QScriptValue>("QScriptValue");
579 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
581 QDeclarativeData::init();
583 contextClass = new QDeclarativeContextScriptClass(q);
584 objectClass = new QDeclarativeObjectScriptClass(q);
585 scarceResourceClass = new QDeclarativeScarceResourceScriptClass(q);
586 valueTypeClass = new QDeclarativeValueTypeScriptClass(q);
587 typeNameClass = new QDeclarativeTypeNameScriptClass(q);
588 listClass = new QDeclarativeListScriptClass(q);
589 rootContext = new QDeclarativeContext(q,true);
591 QScriptValue applicationObject = objectClass->newQObject(new QDeclarativeApplication(q));
592 scriptEngine.globalObject().property(QLatin1String("Qt")).setProperty(QLatin1String("application"), applicationObject);
594 if (QCoreApplication::instance()->thread() == q->thread() &&
595 QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
597 QDeclarativeEngineDebugServer::instance()->addEngine(q);
598 QJSDebugService::instance()->addEngine(q);
602 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
604 Q_Q(QDeclarativeEngine);
605 if (!workerScriptEngine)
606 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
607 return workerScriptEngine;
611 \class QDeclarativeEngine
613 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
616 Each QML component is instantiated in a QDeclarativeContext.
617 QDeclarativeContext's are essential for passing data to QML
618 components. In QML, contexts are arranged hierarchically and this
619 hierarchy is managed by the QDeclarativeEngine.
621 Prior to creating any QML components, an application must have
622 created a QDeclarativeEngine to gain access to a QML context. The
623 following example shows how to create a simple Text item.
626 QDeclarativeEngine engine;
627 QDeclarativeComponent component(&engine);
628 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
629 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
631 //add item to view, etc
635 In this case, the Text item will be created in the engine's
636 \l {QDeclarativeEngine::rootContext()}{root context}.
638 \sa QDeclarativeComponent QDeclarativeContext
642 Create a new QDeclarativeEngine with the given \a parent.
644 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
645 : QObject(*new QDeclarativeEnginePrivate(this), parent)
647 Q_D(QDeclarativeEngine);
652 Destroys the QDeclarativeEngine.
654 Any QDeclarativeContext's created on this engine will be
655 invalidated, but not destroyed (unless they are parented to the
656 QDeclarativeEngine object).
658 QDeclarativeEngine::~QDeclarativeEngine()
660 Q_D(QDeclarativeEngine);
661 if (d->isDebugging) {
662 QDeclarativeEngineDebugServer::instance()->remEngine(this);
665 // if we are the parent of any of the qobject module api instances,
666 // we need to remove them from our internal list, in order to prevent
667 // a segfault in engine private dtor.
668 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
669 QObject *currQObjectApi = 0;
670 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
671 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
672 currInstance = d->moduleApiInstances.value(key);
673 currQObjectApi = currInstance->qobjectApi;
674 if (this->children().contains(currQObjectApi)) {
675 delete currQObjectApi;
677 d->moduleApiInstances.remove(key);
682 /*! \fn void QDeclarativeEngine::quit()
683 This signal is emitted when the QML loaded by the engine would like to quit.
686 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
687 This signal is emitted when \a warnings messages are generated by QML.
691 Clears the engine's internal component cache.
693 Normally the QDeclarativeEngine caches components loaded from qml
694 files. This method clears this cache and forces the component to be
697 void QDeclarativeEngine::clearComponentCache()
699 Q_D(QDeclarativeEngine);
700 d->typeLoader.clearCache();
704 Returns the engine's root context.
706 The root context is automatically created by the QDeclarativeEngine.
707 Data that should be available to all QML component instances
708 instantiated by the engine should be put in the root context.
710 Additional data that should only be available to a subset of
711 component instances should be added to sub-contexts parented to the
714 QDeclarativeContext *QDeclarativeEngine::rootContext() const
716 Q_D(const QDeclarativeEngine);
717 return d->rootContext;
721 Sets the \a factory to use for creating QNetworkAccessManager(s).
723 QNetworkAccessManager is used for all network access by QML. By
724 implementing a factory it is possible to create custom
725 QNetworkAccessManager with specialized caching, proxy and cookie
728 The factory must be set before executing the engine.
730 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
732 Q_D(QDeclarativeEngine);
733 QMutexLocker locker(&d->mutex);
734 d->networkAccessManagerFactory = factory;
738 Returns the current QDeclarativeNetworkAccessManagerFactory.
740 \sa setNetworkAccessManagerFactory()
742 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
744 Q_D(const QDeclarativeEngine);
745 return d->networkAccessManagerFactory;
748 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
750 QMutexLocker locker(&mutex);
751 QNetworkAccessManager *nam;
752 if (networkAccessManagerFactory) {
753 nam = networkAccessManagerFactory->create(parent);
755 nam = new QNetworkAccessManager(parent);
761 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
763 Q_Q(const QDeclarativeEngine);
764 if (!networkAccessManager)
765 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
766 return networkAccessManager;
770 Returns a common QNetworkAccessManager which can be used by any QML
771 element instantiated by this engine.
773 If a QDeclarativeNetworkAccessManagerFactory has been set and a
774 QNetworkAccessManager has not yet been created, the
775 QDeclarativeNetworkAccessManagerFactory will be used to create the
776 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
777 will have no proxy or cache set.
779 \sa setNetworkAccessManagerFactory()
781 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
783 Q_D(const QDeclarativeEngine);
784 return d->getNetworkAccessManager();
789 Sets the \a provider to use for images requested via the \e
790 image: url scheme, with host \a providerId. The QDeclarativeEngine
791 takes ownership of \a provider.
793 Image providers enable support for pixmap and threaded image
794 requests. See the QDeclarativeImageProvider documentation for details on
795 implementing and using image providers.
797 All required image providers should be added to the engine before any
798 QML sources files are loaded.
800 Note that images loaded from a QDeclarativeImageProvider are cached
801 by QPixmapCache, similar to any image loaded by QML.
803 \sa removeImageProvider()
805 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
807 Q_D(QDeclarativeEngine);
808 QMutexLocker locker(&d->mutex);
809 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
813 Returns the QDeclarativeImageProvider set for \a providerId.
815 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
817 Q_D(const QDeclarativeEngine);
818 QMutexLocker locker(&d->mutex);
819 return d->imageProviders.value(providerId).data();
823 Removes the QDeclarativeImageProvider for \a providerId.
825 Returns the provider if it was found; otherwise returns 0.
827 \sa addImageProvider()
829 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
831 Q_D(QDeclarativeEngine);
832 QMutexLocker locker(&d->mutex);
833 d->imageProviders.take(providerId);
836 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
838 QMutexLocker locker(&mutex);
839 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
842 return provider->imageType();
843 return QDeclarativeImageProvider::Invalid;
846 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
848 QMutexLocker locker(&mutex);
849 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
852 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
853 return provider->requestTexture(imageId, size, req_size);
858 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
860 QMutexLocker locker(&mutex);
862 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
865 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
866 image = provider->requestImage(imageId, size, req_size);
871 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
873 QMutexLocker locker(&mutex);
875 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
878 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
879 pixmap = provider->requestPixmap(imageId, size, req_size);
885 Return the base URL for this engine. The base URL is only used to
886 resolve components when a relative URL is passed to the
887 QDeclarativeComponent constructor.
889 If a base URL has not been explicitly set, this method returns the
890 application's current working directory.
894 QUrl QDeclarativeEngine::baseUrl() const
896 Q_D(const QDeclarativeEngine);
897 if (d->baseUrl.isEmpty()) {
898 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
905 Set the base URL for this engine to \a url.
909 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
911 Q_D(QDeclarativeEngine);
916 Returns true if warning messages will be output to stderr in addition
917 to being emitted by the warnings() signal, otherwise false.
919 The default value is true.
921 bool QDeclarativeEngine::outputWarningsToStandardError() const
923 Q_D(const QDeclarativeEngine);
924 return d->outputWarningsToStdErr;
928 Set whether warning messages will be output to stderr to \a enabled.
930 If \a enabled is true, any warning messages generated by QML will be
931 output to stderr and emitted by the warnings() signal. If \a enabled
932 is false, on the warnings() signal will be emitted. This allows
933 applications to handle warning output themselves.
935 The default value is true.
937 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
939 Q_D(QDeclarativeEngine);
940 d->outputWarningsToStdErr = enabled;
944 Returns the QDeclarativeContext for the \a object, or 0 if no
945 context has been set.
947 When the QDeclarativeEngine instantiates a QObject, the context is
950 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
955 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
957 QDeclarativeData *data =
958 static_cast<QDeclarativeData *>(priv->declarativeData);
962 else if (data->outerContext)
963 return data->outerContext->asQDeclarativeContext();
969 Sets the QDeclarativeContext for the \a object to \a context.
970 If the \a object already has a context, a warning is
971 output, but the context is not changed.
973 When the QDeclarativeEngine instantiates a QObject, the context is
976 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
978 if (!object || !context)
981 QDeclarativeData *data = QDeclarativeData::get(object, true);
983 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
987 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
988 contextData->addObject(object);
992 \enum QDeclarativeEngine::ObjectOwnership
994 Ownership controls whether or not QML automatically destroys the
995 QObject when the object is garbage collected by the JavaScript
996 engine. The two ownership options are:
998 \value CppOwnership The object is owned by C++ code, and will
999 never be deleted by QML. The JavaScript destroy() method cannot be
1000 used on objects with CppOwnership. This option is similar to
1001 QScriptEngine::QtOwnership.
1003 \value JavaScriptOwnership The object is owned by JavaScript.
1004 When the object is returned to QML as the return value of a method
1005 call or property access, QML will delete the object if there are no
1006 remaining JavaScript references to it and it has no
1007 QObject::parent(). This option is similar to
1008 QScriptEngine::ScriptOwnership.
1010 Generally an application doesn't need to set an object's ownership
1011 explicitly. QML uses a heuristic to set the default object
1012 ownership. By default, an object that is created by QML has
1013 JavaScriptOwnership. The exception to this are the root objects
1014 created by calling QDeclarativeCompnent::create() or
1015 QDeclarativeComponent::beginCreate() which have CppOwnership by
1016 default. The ownership of these root-level objects is considered to
1017 have been transferred to the C++ caller.
1019 Objects not-created by QML have CppOwnership by default. The
1020 exception to this is objects returned from a C++ method call. The
1021 ownership of these objects is passed to JavaScript.
1023 Calling setObjectOwnership() overrides the default ownership
1024 heuristic used by QML.
1028 Sets the \a ownership of \a object.
1030 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
1035 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
1039 ddata->indestructible = (ownership == CppOwnership)?true:false;
1040 ddata->explicitIndestructibleSet = true;
1044 Returns the ownership of \a object.
1046 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
1049 return CppOwnership;
1051 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
1053 return CppOwnership;
1055 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
1058 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
1060 QDeclarativeData *data = QDeclarativeData::get(object);
1062 if (data && data->deferredComponent) {
1063 if (QDeclarativeDebugService::isDebuggingEnabled()) {
1064 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
1065 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
1066 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
1067 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
1068 if (data->outerContext)
1069 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
1071 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
1073 QDeclarativeComponentPrivate::ConstructionState state;
1074 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
1076 data->deferredComponent->release();
1077 data->deferredComponent = 0;
1079 QDeclarativeComponentPrivate::complete(ep, &state);
1080 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
1084 QDeclarativeContext *qmlContext(const QObject *obj)
1086 return QDeclarativeEngine::contextForObject(obj);
1089 QDeclarativeEngine *qmlEngine(const QObject *obj)
1091 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
1092 return context?context->engine():0;
1095 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
1097 QDeclarativeData *data = QDeclarativeData::get(object);
1099 return 0; // Attached properties are only on objects created by QML
1101 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
1105 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
1109 rv = pf(const_cast<QObject *>(object));
1112 data->attachedProperties()->insert(id, rv);
1117 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1118 const QMetaObject *attachedMetaObject, bool create)
1121 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1123 if (*idCache == -1 || !object)
1126 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1129 class QDeclarativeDataExtended {
1131 QDeclarativeDataExtended();
1132 ~QDeclarativeDataExtended();
1134 QHash<int, QObject *> attachedProperties;
1135 QDeclarativeNotifier objectNameNotifier;
1138 QDeclarativeDataExtended::QDeclarativeDataExtended()
1142 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1146 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1148 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1149 return &extendedData->objectNameNotifier;
1152 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1154 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1155 return &extendedData->attachedProperties;
1158 void QDeclarativeData::destroyed(QObject *object)
1160 if (deferredComponent)
1161 deferredComponent->release();
1163 if (nextContextObject)
1164 nextContextObject->prevContextObject = prevContextObject;
1165 if (prevContextObject)
1166 *prevContextObject = nextContextObject;
1168 QDeclarativeAbstractBinding *binding = bindings;
1170 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1171 binding->m_prevBinding = 0;
1172 binding->m_nextBinding = 0;
1181 propertyCache->release();
1183 if (ownContext && context)
1187 QDeclarativeGuard<QObject> *guard = guards;
1188 *guard = (QObject *)0;
1189 guard->objectDestroyed(object);
1196 delete extendedData;
1202 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
1204 if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
1207 void QDeclarativeData::objectNameChanged(QObject *)
1209 if (extendedData) objectNameNotifier()->notify();
1212 bool QDeclarativeData::hasBindingBit(int bit) const
1214 if (bindingBitsSize > bit)
1215 return bindingBits[bit / 32] & (1 << (bit % 32));
1220 void QDeclarativeData::clearBindingBit(int bit)
1222 if (bindingBitsSize > bit)
1223 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1226 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1228 if (bindingBitsSize <= bit) {
1229 int props = obj->metaObject()->propertyCount();
1230 Q_ASSERT(bit < props);
1232 int arraySize = (props + 31) / 32;
1233 int oldArraySize = bindingBitsSize / 32;
1235 bindingBits = (quint32 *)realloc(bindingBits,
1236 arraySize * sizeof(quint32));
1238 memset(bindingBits + oldArraySize,
1240 sizeof(quint32) * (arraySize - oldArraySize));
1242 bindingBitsSize = arraySize * 32;
1245 bindingBits[bit / 32] |= (1 << (bit % 32));
1249 Creates a QScriptValue allowing you to use \a object in QML script.
1250 \a engine is the QDeclarativeEngine it is to be created in.
1252 The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
1253 to the special needs of QML requiring more functionality than a standard
1256 QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
1257 QDeclarativeEngine* engine)
1259 QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
1260 return enginePriv->objectClass->newQObject(object);
1264 Returns the QDeclarativeContext for the executing QScript \a ctxt.
1266 QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
1268 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1269 Q_ASSERT(scopeNode.isValid());
1270 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1271 return contextClass->contextFromValue(scopeNode);
1275 Returns the QUrl associated with the script \a ctxt for the case that there is
1276 no QDeclarativeContext.
1278 QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt)
1280 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1281 Q_ASSERT(scopeNode.isValid());
1282 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1283 return contextClass->urlFromValue(scopeNode);
1286 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1288 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1289 if (url.authority().isEmpty())
1290 return QLatin1Char(':') + url.path();
1293 return url.toLocalFile();
1297 \qmlmethod object Qt::createComponent(url)
1299 Returns a \l Component object created using the QML file at the specified \a url,
1300 or \c null if an empty string was given.
1302 The returned component's \l Component::status property indicates whether the
1303 component was successfully created. If the status is \c Component.Error,
1304 see \l Component::errorString() for an error description.
1306 Call \l {Component::createObject()}{Component.createObject()} on the returned
1307 component to create an object instance of the component.
1311 \snippet doc/src/snippets/declarative/createComponent-simple.qml 0
1313 See \l {Dynamic Object Management in QML} for more information on using this function.
1315 To create a QML object from an arbitrary string of QML (instead of a file),
1316 use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
1319 QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
1321 QDeclarativeEnginePrivate *activeEnginePriv =
1322 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1323 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1325 if(ctxt->argumentCount() != 1) {
1326 return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments"));
1329 QString arg = ctxt->argument(0).toString();
1331 return engine->nullValue();
1332 QUrl url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt, QUrl(arg));
1333 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1334 QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
1335 QDeclarativeComponentPrivate::get(c)->creationContext = context;
1336 QDeclarativeData::get(c, true)->setImplicitDestructible();
1337 return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
1342 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
1344 Returns a new object created from the given \a string of QML which will have the specified \a parent,
1345 or \c null if there was an error in creating the object.
1347 If \a filepath is specified, it will be used for error reporting for the created object.
1349 Example (where \c parentItem is the id of an existing QML item):
1351 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
1353 In the case of an error, a QtScript Error object is thrown. This object has an additional property,
1354 \c qmlErrors, which is an array of the errors encountered.
1355 Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
1356 For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
1357 { "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
1359 Note that this function returns immediately, and therefore may not work if
1360 the \a qml string loads new components (that is, external QML files that have not yet been loaded).
1361 If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
1363 See \l {Dynamic Object Management in QML} for more information on using this function.
1366 QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
1368 QDeclarativeEnginePrivate *activeEnginePriv =
1369 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1370 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1372 if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
1373 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments"));
1375 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1378 QString qml = ctxt->argument(0).toString();
1380 return engine->nullValue();
1383 if(ctxt->argumentCount() > 2)
1384 url = QUrl(ctxt->argument(2).toString());
1386 url = QUrl(QLatin1String("inline"));
1388 if (url.isValid() && url.isRelative())
1389 url = context->resolvedUrl(url);
1391 QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
1393 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object"));
1395 QDeclarativeComponent component(activeEngine);
1396 component.setData(qml.toUtf8(), url);
1398 if(component.isError()) {
1399 QList<QDeclarativeError> errors = component.errors();
1400 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1401 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1403 foreach (const QDeclarativeError &error, errors){
1404 errstr += QLatin1String("\n ") + error.toString();
1405 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1406 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1407 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1408 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1409 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1410 arr.setProperty(i++, qmlErrObject);
1412 QScriptValue err = ctxt->throwError(errstr);
1413 err.setProperty(QLatin1String("qmlErrors"),arr);
1417 if (!component.isReady())
1418 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready"));
1420 QObject *obj = component.beginCreate(context->asQDeclarativeContext());
1422 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1423 component.completeCreate();
1425 if(component.isError()) {
1426 QList<QDeclarativeError> errors = component.errors();
1427 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1428 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1430 foreach (const QDeclarativeError &error, errors){
1431 errstr += QLatin1String("\n ") + error.toString();
1432 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1433 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1434 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1435 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1436 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1437 arr.setProperty(i++, qmlErrObject);
1439 QScriptValue err = ctxt->throwError(errstr);
1440 err.setProperty(QLatin1String("qmlErrors"),arr);
1446 obj->setParent(parentArg);
1448 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
1449 for (int ii = 0; ii < functions.count(); ++ii) {
1450 if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
1454 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1455 return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
1459 \qmlmethod bool Qt::isQtObject(object)
1460 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
1462 QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
1464 if (ctxt->argumentCount() == 0)
1465 return QScriptValue(engine, false);
1467 return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
1471 \qmlmethod Qt::vector3d(real x, real y, real z)
1472 Returns a Vector3D with the specified \c x, \c y and \c z.
1474 QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEngine *engine)
1476 if(ctxt->argumentCount() != 3)
1477 return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments"));
1478 qsreal x = ctxt->argument(0).toNumber();
1479 qsreal y = ctxt->argument(1).toNumber();
1480 qsreal z = ctxt->argument(2).toNumber();
1481 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QVector3D(x, y, z)));
1485 \qmlmethod string Qt::formatDate(datetime date, variant format)
1487 Returns a string representation of \c date, optionally formatted according
1490 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1491 property, a QDate, or QDateTime value. The \a format parameter may be any of
1492 the possible format values as described for
1493 \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1495 If \a format is not specified, \a date is formatted using
1496 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1498 #ifndef QT_NO_DATESTRING
1499 QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine)
1501 int argCount = ctxt->argumentCount();
1502 if(argCount == 0 || argCount > 2)
1503 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments"));
1505 QDate date = ctxt->argument(0).toDateTime().date();
1506 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1507 if (argCount == 2) {
1508 QScriptValue formatArg = ctxt->argument(1);
1509 if (formatArg.isString()) {
1510 QString format = formatArg.toString();
1511 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1512 } else if (formatArg.isNumber()) {
1513 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1515 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
1518 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1522 \qmlmethod string Qt::formatTime(datetime time, variant format)
1524 Returns a string representation of \c time, optionally formatted according to
1527 The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
1528 value. The \a format parameter may be any of the possible format values as
1529 described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1531 If \a format is not specified, \a time is formatted using
1532 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1534 QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptEngine*engine)
1536 int argCount = ctxt->argumentCount();
1537 if(argCount == 0 || argCount > 2)
1538 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments"));
1541 QScriptValue sv = ctxt->argument(0);
1543 time = sv.toDateTime().time();
1544 else if (sv.toVariant().type() == QVariant::Time)
1545 time = sv.toVariant().toTime();
1547 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1548 if (argCount == 2) {
1549 QScriptValue formatArg = ctxt->argument(1);
1550 if (formatArg.isString()) {
1551 QString format = formatArg.toString();
1552 return engine->newVariant(QVariant::fromValue(time.toString(format)));
1553 } else if (formatArg.isNumber()) {
1554 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1556 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
1559 return engine->newVariant(QVariant::fromValue(time.toString(enumFormat)));
1563 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
1565 Returns a string representation of \c datetime, optionally formatted according to
1568 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1569 property, a QDate, QTime, or QDateTime value.
1571 If \a format is not provided, \a dateTime is formatted using
1572 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
1573 \a format should be either.
1576 \o One of the Qt::DateFormat enumeration values, such as
1577 \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
1578 \o A string that specifies the format of the returned string, as detailed below.
1581 If \a format specifies a format string, it should use the following expressions
1582 to specify the date:
1585 \header \i Expression \i Output
1586 \row \i d \i the day as number without a leading zero (1 to 31)
1587 \row \i dd \i the day as number with a leading zero (01 to 31)
1589 \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
1590 Uses QDate::shortDayName().
1592 \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
1593 Uses QDate::longDayName().
1594 \row \i M \i the month as number without a leading zero (1-12)
1595 \row \i MM \i the month as number with a leading zero (01-12)
1597 \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
1598 Uses QDate::shortMonthName().
1600 \i the long localized month name (e.g. 'January' to 'December').
1601 Uses QDate::longMonthName().
1602 \row \i yy \i the year as two digit number (00-99)
1603 \row \i yyyy \i the year as four digit number
1606 In addition the following expressions can be used to specify the time:
1609 \header \i Expression \i Output
1611 \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1613 \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1614 \row \i m \i the minute without a leading zero (0 to 59)
1615 \row \i mm \i the minute with a leading zero (00 to 59)
1616 \row \i s \i the second without a leading zero (0 to 59)
1617 \row \i ss \i the second with a leading zero (00 to 59)
1618 \row \i z \i the milliseconds without leading zeroes (0 to 999)
1619 \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
1621 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1623 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
1626 All other input characters will be ignored. Any sequence of characters that
1627 are enclosed in single quotes will be treated as text and not be used as an
1628 expression. Two consecutive single quotes ("''") are replaced by a single quote
1631 For example, if the following date/time value was specified:
1634 // 21 May 2001 14:13:09
1635 var dateTime = new Date(2001, 5, 21, 14, 13, 09)
1638 This \a dateTime value could be passed to \c Qt.formatDateTime(),
1639 \l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
1640 with the \a format values below to produce the following results:
1643 \header \i Format \i Result
1644 \row \i "dd.MM.yyyy" \i 21.05.2001
1645 \row \i "ddd MMMM d yy" \i Tue May 21 01
1646 \row \i "hh:mm:ss.zzz" \i 14:13:09.042
1647 \row \i "h:m:s ap" \i 2:13:9 pm
1650 QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScriptEngine*engine)
1652 int argCount = ctxt->argumentCount();
1653 if(argCount == 0 || argCount > 2)
1654 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments"));
1656 QDateTime date = ctxt->argument(0).toDateTime();
1657 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1658 if (argCount == 2) {
1659 QScriptValue formatArg = ctxt->argument(1);
1660 if (formatArg.isString()) {
1661 QString format = formatArg.toString();
1662 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1663 } else if (formatArg.isNumber()) {
1664 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1666 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
1669 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1671 #endif // QT_NO_DATESTRING
1674 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
1676 Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
1677 All components should be in the range 0-1 inclusive.
1679 QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
1681 int argCount = ctxt->argumentCount();
1682 if(argCount < 3 || argCount > 4)
1683 return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments"));
1684 qsreal r = ctxt->argument(0).toNumber();
1685 qsreal g = ctxt->argument(1).toNumber();
1686 qsreal b = ctxt->argument(2).toNumber();
1687 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1698 return engine->toScriptValue(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
1702 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
1704 Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
1705 All components should be in the range 0-1 inclusive.
1707 QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
1709 int argCount = ctxt->argumentCount();
1710 if(argCount < 3 || argCount > 4)
1711 return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments"));
1712 qsreal h = ctxt->argument(0).toNumber();
1713 qsreal s = ctxt->argument(1).toNumber();
1714 qsreal l = ctxt->argument(2).toNumber();
1715 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1726 return engine->toScriptValue(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
1730 \qmlmethod rect Qt::rect(int x, int y, int width, int height)
1732 Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
1734 The returned object has \c x, \c y, \c width and \c height attributes with the given values.
1736 QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
1738 if(ctxt->argumentCount() != 4)
1739 return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments"));
1741 qsreal x = ctxt->argument(0).toNumber();
1742 qsreal y = ctxt->argument(1).toNumber();
1743 qsreal w = ctxt->argument(2).toNumber();
1744 qsreal h = ctxt->argument(3).toNumber();
1746 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
1750 \qmlmethod point Qt::point(int x, int y)
1751 Returns a Point with the specified \c x and \c y coordinates.
1753 QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
1755 if(ctxt->argumentCount() != 2)
1756 return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
1757 qsreal x = ctxt->argument(0).toNumber();
1758 qsreal y = ctxt->argument(1).toNumber();
1759 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QPointF(x, y)));
1763 \qmlmethod Qt::size(int width, int height)
1764 Returns a Size with the specified \c width and \c height.
1766 QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
1768 if(ctxt->argumentCount() != 2)
1769 return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
1770 qsreal w = ctxt->argument(0).toNumber();
1771 qsreal h = ctxt->argument(1).toNumber();
1772 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QSizeF(w, h)));
1776 \qmlmethod color Qt::lighter(color baseColor, real factor)
1777 Returns a color lighter than \c baseColor by the \c factor provided.
1779 If the factor is greater than 1.0, this functions returns a lighter color.
1780 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
1781 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
1782 If the factor is 0 or negative, the return value is unspecified.
1784 The function converts the current RGB color to HSV, multiplies the value (V) component
1785 by factor and converts the color back to RGB.
1787 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
1789 QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
1791 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1792 return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments"));
1793 QVariant v = ctxt->argument(0).toVariant();
1795 if (v.userType() == QVariant::Color)
1796 color = v.value<QColor>();
1797 else if (v.userType() == QVariant::String) {
1799 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1801 return engine->nullValue();
1803 return engine->nullValue();
1804 qsreal factor = 1.5;
1805 if (ctxt->argumentCount() == 2)
1806 factor = ctxt->argument(1).toNumber();
1807 color = color.lighter(int(qRound(factor*100.)));
1808 return engine->toScriptValue(QVariant::fromValue(color));
1812 \qmlmethod color Qt::darker(color baseColor, real factor)
1813 Returns a color darker than \c baseColor by the \c factor provided.
1815 If the factor is greater than 1.0, this function returns a darker color.
1816 Setting factor to 3.0 returns a color that has one-third the brightness.
1817 If the factor is less than 1.0, the return color is lighter, but we recommend using
1818 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
1819 value is unspecified.
1821 The function converts the current RGB color to HSV, divides the value (V) component
1822 by factor and converts the color back to RGB.
1824 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
1826 QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
1828 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1829 return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments"));
1830 QVariant v = ctxt->argument(0).toVariant();
1832 if (v.userType() == QVariant::Color)
1833 color = v.value<QColor>();
1834 else if (v.userType() == QVariant::String) {
1836 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1838 return engine->nullValue();
1840 return engine->nullValue();
1841 qsreal factor = 2.0;
1842 if (ctxt->argumentCount() == 2)
1843 factor = ctxt->argument(1).toNumber();
1844 color = color.darker(int(qRound(factor*100.)));
1845 return engine->toScriptValue(QVariant::fromValue(color));
1849 \qmlmethod bool Qt::openUrlExternally(url target)
1850 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.
1852 QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
1854 if(ctxt->argumentCount() < 1)
1855 return QScriptValue(e, false);
1857 #ifndef QT_NO_DESKTOPSERVICES
1858 ret = QDesktopServices::openUrl(QDeclarativeScriptEngine::get(e)->resolvedUrl(ctxt, QUrl(ctxt->argument(0).toString())));
1860 return QScriptValue(e, ret);
1864 \qmlmethod list<string> Qt::fontFamilies()
1865 Returns a list of the font families available to the application.
1868 QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e)
1870 if(ctxt->argumentCount() != 0)
1871 return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments"));
1873 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e);
1874 QFontDatabase database;
1875 return p->scriptValueFromVariant(database.families());
1879 \qmlmethod string Qt::md5(data)
1880 Returns a hex string of the md5 hash of \c data.
1882 QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
1884 if (ctxt->argumentCount() != 1)
1885 return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments"));
1887 QByteArray data = ctxt->argument(0).toString().toUtf8();
1888 QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
1890 return QScriptValue(QLatin1String(result.toHex()));
1894 \qmlmethod string Qt::btoa(data)
1895 Binary to ASCII - this function returns a base64 encoding of \c data.
1897 QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
1899 if (ctxt->argumentCount() != 1)
1900 return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments"));
1902 QByteArray data = ctxt->argument(0).toString().toUtf8();
1904 return QScriptValue(QLatin1String(data.toBase64()));
1908 \qmlmethod string Qt::atob(data)
1909 ASCII to binary - this function returns a base64 decoding of \c data.
1912 QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
1914 if (ctxt->argumentCount() != 1)
1915 return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments"));
1917 QByteArray data = ctxt->argument(0).toString().toUtf8();
1919 return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
1922 QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
1924 if(ctxt->argumentCount() < 1)
1925 return e->newVariant(QVariant(false));
1929 for (int i=0; i<ctxt->argumentCount(); ++i) {
1930 if (!msg.isEmpty()) msg += ' ';
1931 msg += ctxt->argument(i).toString().toLocal8Bit();
1932 // does not support firebug "%[a-z]" formatting, since firebug really
1933 // does just ignore the format letter, which makes it pointless.
1936 qDebug("%s",msg.constData());
1938 return e->newVariant(QVariant(true));
1941 void QDeclarativeEnginePrivate::sendQuit()
1943 Q_Q(QDeclarativeEngine);
1945 if (q->receivers(SIGNAL(quit())) == 0) {
1946 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1950 static void dumpwarning(const QDeclarativeError &error)
1952 qWarning().nospace() << qPrintable(error.toString());
1955 static void dumpwarning(const QList<QDeclarativeError> &errors)
1957 for (int ii = 0; ii < errors.count(); ++ii)
1958 dumpwarning(errors.at(ii));
1961 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1963 Q_Q(QDeclarativeEngine);
1964 q->warnings(QList<QDeclarativeError>() << error);
1965 if (outputWarningsToStdErr)
1969 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1971 Q_Q(QDeclarativeEngine);
1972 q->warnings(errors);
1973 if (outputWarningsToStdErr)
1974 dumpwarning(errors);
1977 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1980 QDeclarativeEnginePrivate::get(engine)->warning(error);
1985 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1988 QDeclarativeEnginePrivate::get(engine)->warning(error);
1993 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1996 engine->warning(error);
2001 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
2004 engine->warning(error);
2010 \qmlmethod Qt::quit()
2011 This function causes the QDeclarativeEngine::quit() signal to be emitted.
2012 Within the \l {QML Viewer}, this causes the launcher application to exit;
2013 to quit a C++ application when this method is called, connect the
2014 QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot.
2017 QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
2019 QDeclarativeEnginePrivate *qe = get (e);
2021 return QScriptValue();
2025 \qmlmethod color Qt::tint(color baseColor, color tintColor)
2026 This function allows tinting one color with another.
2028 The tint color should usually be mostly transparent, or you will not be
2029 able to see the underlying color. The below example provides a slight red
2030 tint by having the tint color be pure red which is only 1/16th opaque.
2035 x: 0; width: 80; height: 80
2036 color: "lightsteelblue"
2039 x: 100; width: 80; height: 80
2040 color: Qt.tint("lightsteelblue", "#10FF0000")
2044 \image declarative-rect_tint.png
2046 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.
2048 QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
2050 if(ctxt->argumentCount() != 2)
2051 return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments"));
2053 QVariant v = ctxt->argument(0).toVariant();
2055 if (v.userType() == QVariant::Color)
2056 color = v.value<QColor>();
2057 else if (v.userType() == QVariant::String) {
2059 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2061 return engine->nullValue();
2063 return engine->nullValue();
2066 v = ctxt->argument(1).toVariant();
2068 if (v.userType() == QVariant::Color)
2069 tintColor = v.value<QColor>();
2070 else if (v.userType() == QVariant::String) {
2072 tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2074 return engine->nullValue();
2076 return engine->nullValue();
2080 int a = tintColor.alpha();
2082 finalColor = tintColor;
2086 qreal a = tintColor.alphaF();
2087 qreal inv_a = 1.0 - a;
2089 finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
2090 tintColor.greenF() * a + color.greenF() * inv_a,
2091 tintColor.blueF() * a + color.blueF() * inv_a,
2092 a + inv_a * color.alphaF());
2095 return engine->toScriptValue(QVariant::fromValue(finalColor));
2098 QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
2100 if (variantIsScarceResource(val)) {
2101 return scarceResourceClass->newScarceResource(val);
2102 } else if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
2103 QDeclarativeListReferencePrivate *p =
2104 QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
2106 return listClass->newList(p->property, p->propertyType);
2108 return scriptEngine.nullValue();
2110 } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
2111 const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
2112 QScriptValue rv = scriptEngine.newArray(list.count());
2113 for (int ii = 0; ii < list.count(); ++ii) {
2114 QObject *object = list.at(ii);
2115 rv.setProperty(ii, objectClass->newQObject(object));
2118 } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
2119 return valueTypeClass->newObject(val, vt);
2123 QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
2125 return objectClass->newQObject(obj);
2127 return scriptEngine.toScriptValue(val);
2132 If the variant is a scarce resource (consumes a large amount of memory, or
2133 only a limited number of them can be held in memory at any given time without
2134 exhausting supply for future use) we need to release the scarce resource
2135 after evaluation of the javascript binding is complete.
2137 bool QDeclarativeEnginePrivate::variantIsScarceResource(const QVariant& val)
2139 if (val.type() == QVariant::Pixmap) {
2141 } else if (val.type() == QVariant::Image) {
2149 This function should be called prior to evaluation of any js expression,
2150 so that scarce resources are not freed prematurely (eg, if there is a
2151 nested javascript expression).
2153 void QDeclarativeEnginePrivate::referenceScarceResources()
2155 scarceResourcesRefCount += 1;
2159 This function should be called after evaluation of the js expression is
2160 complete, and so the scarce resources may be freed safely.
2162 void QDeclarativeEnginePrivate::dereferenceScarceResources()
2164 Q_ASSERT(scarceResourcesRefCount > 0);
2165 scarceResourcesRefCount -= 1;
2167 // if the refcount is zero, then evaluation of the "top level"
2168 // expression must have completed. We can safely release the
2169 // scarce resources.
2170 if (scarceResourcesRefCount == 0) {
2171 // iterate through the list and release them all.
2172 // note that the actual SRD is owned by the JS engine,
2173 // so we cannot delete the SRD; but we can free the
2174 // memory used by the variant in the SRD.
2175 ScarceResourceData *srd = 0;
2176 while (scarceResources) {
2177 srd = scarceResources; // srd points to the "old" (current) head of the list
2178 scarceResources = srd->next; // srd->next is the "new" head of the list
2179 if (srd->next) srd->next->prev = &scarceResources; // newHead->prev = listptr.
2182 srd->releaseResource(); // release the old head node.
2187 QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
2189 QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
2190 if (dc == objectClass)
2191 return QVariant::fromValue(objectClass->toQObject(val));
2192 else if (dc == scarceResourceClass)
2193 return scarceResourceClass->toVariant(val);
2194 else if (dc == valueTypeClass)
2195 return valueTypeClass->toVariant(val);
2196 else if (dc == contextClass)
2199 // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
2200 if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
2201 QList<QObject *> list;
2202 int length = val.property(QLatin1String("length")).toInt32();
2203 for (int ii = 0; ii < length; ++ii) {
2204 QScriptValue arrayItem = val.property(ii);
2205 QObject *d = arrayItem.toQObject();
2208 return QVariant::fromValue(list);
2211 return val.toVariant();
2215 Adds \a path as a directory where the engine searches for
2216 installed modules in a URL-based directory structure.
2217 The \a path may be a local filesystem directory or a URL.
2219 The newly added \a path will be first in the importPathList().
2221 \sa setImportPathList(), {QML Modules}
2223 void QDeclarativeEngine::addImportPath(const QString& path)
2225 Q_D(QDeclarativeEngine);
2226 d->importDatabase.addImportPath(path);
2230 Returns the list of directories where the engine searches for
2231 installed modules in a URL-based directory structure.
2233 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
2234 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
2235 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
2236 provided by that module. A \c qmldir file is required for defining the
2237 type version mapping and possibly declarative extensions plugins.
2239 By default, the list contains the directory of the application executable,
2240 paths specified in the \c QML_IMPORT_PATH environment variable,
2241 and the builtin \c ImportsPath from QLibraryInfo.
2243 \sa addImportPath() setImportPathList()
2245 QStringList QDeclarativeEngine::importPathList() const
2247 Q_D(const QDeclarativeEngine);
2248 return d->importDatabase.importPathList();
2252 Sets \a paths as the list of directories where the engine searches for
2253 installed modules in a URL-based directory structure.
2255 By default, the list contains the directory of the application executable,
2256 paths specified in the \c QML_IMPORT_PATH environment variable,
2257 and the builtin \c ImportsPath from QLibraryInfo.
2259 \sa importPathList() addImportPath()
2261 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
2263 Q_D(QDeclarativeEngine);
2264 d->importDatabase.setImportPathList(paths);
2269 Adds \a path as a directory where the engine searches for
2270 native plugins for imported modules (referenced in the \c qmldir file).
2272 By default, the list contains only \c ., i.e. the engine searches
2273 in the directory of the \c qmldir file itself.
2275 The newly added \a path will be first in the pluginPathList().
2277 \sa setPluginPathList()
2279 void QDeclarativeEngine::addPluginPath(const QString& path)
2281 Q_D(QDeclarativeEngine);
2282 d->importDatabase.addPluginPath(path);
2287 Returns the list of directories where the engine searches for
2288 native plugins for imported modules (referenced in the \c qmldir file).
2290 By default, the list contains only \c ., i.e. the engine searches
2291 in the directory of the \c qmldir file itself.
2293 \sa addPluginPath() setPluginPathList()
2295 QStringList QDeclarativeEngine::pluginPathList() const
2297 Q_D(const QDeclarativeEngine);
2298 return d->importDatabase.pluginPathList();
2302 Sets the list of directories where the engine searches for
2303 native plugins for imported modules (referenced in the \c qmldir file)
2306 By default, the list contains only \c ., i.e. the engine searches
2307 in the directory of the \c qmldir file itself.
2309 \sa pluginPathList() addPluginPath()
2311 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
2313 Q_D(QDeclarativeEngine);
2314 d->importDatabase.setPluginPathList(paths);
2319 Imports the plugin named \a filePath with the \a uri provided.
2320 Returns true if the plugin was successfully imported; otherwise returns false.
2322 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
2324 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2326 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
2328 Q_D(QDeclarativeEngine);
2329 return d->importDatabase.importPlugin(filePath, uri, errors);
2333 Imports the plugin named \a filePath with the \a uri provided.
2334 Returns true if the plugin was successfully imported; otherwise returns false.
2336 On failure and if non-null, *\a errorString will be set to a message describing the failure.
2338 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2340 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
2342 Q_D(QDeclarativeEngine);
2343 QList<QDeclarativeError> errors;
2344 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
2345 if (!errors.isEmpty()) {
2347 for (int i = 0; i < errors.size(); ++i) {
2348 builtError = QString(QLatin1String("%1\n %2"))
2350 .arg(errors.at(i).toString());
2352 *errorString = builtError;
2358 \property QDeclarativeEngine::offlineStoragePath
2359 \brief the directory for storing offline user data
2361 Returns the directory where SQL and other offline
2364 QDeclarativeWebView and the SQL databases created with openDatabase()
2367 The default is QML/OfflineStorage in the platform-standard
2368 user application data directory.
2370 Note that the path may not currently exist on the filesystem, so
2371 callers wanting to \e create new files at this location should create
2372 it first - see QDir::mkpath().
2374 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
2376 Q_D(QDeclarativeEngine);
2377 d->scriptEngine.offlineStoragePath = dir;
2380 QString QDeclarativeEngine::offlineStoragePath() const
2382 Q_D(const QDeclarativeEngine);
2383 return d->scriptEngine.offlineStoragePath;
2386 static void voidptr_destructor(void *v)
2388 void **ptr = (void **)v;
2392 static void *voidptr_constructor(const void *v)
2397 return new void*(*(void **)v);
2401 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
2403 Q_Q(QDeclarativeEngine);
2405 if (!mo->superClass()) {
2406 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
2407 propertyCache.insert(mo, rv);
2410 QDeclarativePropertyCache *super = cache(mo->superClass());
2411 QDeclarativePropertyCache *rv = super->copy();
2413 propertyCache.insert(mo, rv);
2418 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
2419 QDeclarativeError &error)
2421 QList<QDeclarativeType *> types;
2423 int maxMinorVersion = 0;
2425 const QMetaObject *metaObject = type->metaObject();
2426 while (metaObject) {
2427 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
2428 type->majorVersion(), minorVersion);
2430 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
2436 metaObject = metaObject->superClass();
2439 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
2441 typePropertyCache.insert(qMakePair(type, minorVersion), c);
2445 QDeclarativePropertyCache *raw = cache(type->metaObject());
2447 bool hasCopied = false;
2449 for (int ii = 0; ii < types.count(); ++ii) {
2450 QDeclarativeType *currentType = types.at(ii);
2454 int rev = currentType->metaObjectRevision();
2455 int moIndex = types.count() - 1 - ii;
2457 if (raw->allowedRevisionCache[moIndex] != rev) {
2462 raw->allowedRevisionCache[moIndex] = rev;
2466 // Test revision compatibility - the basic rule is:
2467 // * Anything that is excluded, cannot overload something that is not excluded *
2469 // Signals override:
2470 // * other signals and methods of the same name.
2471 // * properties named on<Signal Name>
2472 // * automatic <property name>Changed notify signals
2474 // Methods override:
2475 // * other methods of the same name
2477 // Properties override:
2478 // * other elements of the same name
2480 bool overloadError = false;
2481 QString overloadName;
2484 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
2485 !overloadError && iter != raw->stringCache.end();
2488 QDeclarativePropertyCache::Data *d = *iter;
2489 if (raw->isAllowedInRevision(d))
2490 continue; // Not excluded - no problems
2492 // check that a regular "name" overload isn't happening
2493 QDeclarativePropertyCache::Data *current = d;
2494 while (!overloadError && current) {
2495 current = d->overrideData(current);
2496 if (current && raw->isAllowedInRevision(current))
2497 overloadError = true;
2502 if (overloadError) {
2503 if (hasCopied) raw->release();
2505 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."));
2509 if (!hasCopied) raw->addref();
2510 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
2512 if (minorVersion != maxMinorVersion) {
2514 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
2520 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
2522 QByteArray name = data->root->className();
2524 QByteArray ptr = name + '*';
2525 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
2527 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
2528 voidptr_constructor);
2529 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
2530 voidptr_constructor);
2532 m_qmlLists.insert(lst_type, ptr_type);
2533 m_compositeTypes.insert(ptr_type, data);
2537 bool QDeclarativeEnginePrivate::isList(int t) const
2539 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
2542 int QDeclarativeEnginePrivate::listType(int t) const
2544 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
2545 if (iter != m_qmlLists.end())
2548 return QDeclarativeMetaType::listType(t);
2551 bool QDeclarativeEnginePrivate::isQObject(int t)
2553 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
2556 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
2558 int t = v.userType();
2559 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
2561 return *(QObject **)(v.constData());
2563 return QDeclarativeMetaType::toQObject(v, ok);
2567 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
2569 if (m_compositeTypes.contains(t))
2570 return QDeclarativeMetaType::Object;
2571 else if (m_qmlLists.contains(t))
2572 return QDeclarativeMetaType::List;
2574 return QDeclarativeMetaType::typeCategory(t);
2577 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
2579 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2580 if (iter != m_compositeTypes.end()) {
2581 return (*iter)->root;
2583 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2584 return type?type->baseMetaObject():0;
2588 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
2590 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2591 if (iter != m_compositeTypes.end()) {
2592 return (*iter)->root;
2594 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2595 return type?type->metaObject():0;
2599 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
2601 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
2602 QFileInfo info(fileName);
2604 QString absolute = info.absoluteFilePath();
2606 #if defined(Q_OS_MAC)
2607 QString canonical = info.canonicalFilePath();
2608 #elif defined(Q_OS_WIN32)
2609 wchar_t buffer[1024];
2611 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
2612 if (rv == 0 || rv >= 1024) return true;
2613 rv = ::GetLongPathName(buffer, buffer, 1024);
2614 if (rv == 0 || rv >= 1024) return true;
2616 QString canonical((QChar *)buffer);
2619 int absoluteLength = absolute.length();
2620 int canonicalLength = canonical.length();
2622 int length = qMin(absoluteLength, canonicalLength);
2623 for (int ii = 0; ii < length; ++ii) {
2624 const QChar &a = absolute.at(absoluteLength - 1 - ii);
2625 const QChar &c = canonical.at(canonicalLength - 1 - ii);
2627 if (a.toLower() != c.toLower())